@Override public Checksum create() { try { return (Checksum) CONSTRUCTOR.invoke(); } catch (Throwable throwable) { // Should never happen throw new RuntimeException(throwable); } } }
private static MethodHandle unmapJava9(MethodHandles.Lookup lookup) throws ReflectiveOperationException { Class<?> unsafeClass = Class.forName("sun.misc.Unsafe"); MethodHandle unmapper = lookup.findVirtual(unsafeClass, "invokeCleaner", methodType(void.class, ByteBuffer.class)); Field f = unsafeClass.getDeclaredField("theUnsafe"); f.setAccessible(true); Object theUnsafe = f.get(null); return unmapper.bindTo(theUnsafe); }
public static void unmap(String resourceDescription, MappedByteBuffer buffer) throws IOException { if (!buffer.isDirect()) throw new IllegalArgumentException("Unmapping only works with direct buffers"); if (UNMAP == null) throw UNMAP_NOT_SUPPORTED_EXCEPTION; try { UNMAP.invokeExact((ByteBuffer) buffer); } catch (Throwable throwable) { throw new IOException("Unable to unmap the mapped buffer: " + resourceDescription, throwable); } }
@Override Object invokeDefaultMethod(Method method, Class<?> declaringClass, Object object, @Nullable Object... args) throws Throwable { // Because the service interface might not be public, we need to use a MethodHandle lookup // that ignores the visibility of the declaringClass. Constructor<Lookup> constructor = Lookup.class.getDeclaredConstructor(Class.class, int.class); constructor.setAccessible(true); return constructor.newInstance(declaringClass, -1 /* trusted */) .unreflectSpecial(method, declaringClass) .bindTo(object) .invokeWithArguments(args); }
@Override Class<?> defineClass(String className, byte[] b, int off, int len, Class<?> neighbor, ClassLoader loader, ProtectionDomain protectionDomain) { try { Object module = getModule.invokeWithArguments(DefineClassHelper.class); Object neighborModule = getModule.invokeWithArguments(neighbor); addReads.invokeWithArguments(module, neighborModule); MethodHandles.Lookup prvlookup = (MethodHandles.Lookup) privateLookupIn.invokeExact(neighbor, lookup); return (Class<?>) defineClass.invokeExact(prvlookup, b); } catch (Throwable e) { throw new ObjenesisException(neighbor.getName() + " has no permission to define the class", e); } } }
@Override public ScalarFunctionImplementation specialize(BoundVariables boundVariables, int arity, TypeManager typeManager, FunctionRegistry functionRegistry) { List<Type> types = this.typeParameters.stream().map(boundVariables::getTypeVariable).collect(toImmutableList()); List<ArgumentProperty> argumentProperties = nCopies(types.size(), valueTypeArgumentProperty(RETURN_NULL_ON_NULL)); List<Class<?>> javaArgumentTypes = nCopies(types.size(), Block.class); MethodHandle methodHandle = METHOD_HANDLE.bindTo(types).asVarargsCollector(Block[].class).asType(methodType(Block.class, javaArgumentTypes)); return new ScalarFunctionImplementation(false, argumentProperties, methodHandle, isDeterministic()); }
private static MethodHandle bindInstanceFactory(MethodHandle method, ScalarFunctionImplementation implementation) { if (!implementation.getInstanceFactory().isPresent()) { return method; } try { return method.bindTo(implementation.getInstanceFactory().get().invoke()); } catch (Throwable throwable) { throw propagate(throwable); } }
@Override protected Object visitArithmeticUnary(ArithmeticUnaryExpression node, Object context) { Object value = process(node.getValue(), context); if (value == null) { return null; } if (value instanceof Expression) { return new ArithmeticUnaryExpression(node.getSign(), toExpression(value, type(node.getValue()))); } switch (node.getSign()) { case PLUS: return value; case MINUS: Signature operatorSignature = metadata.getFunctionRegistry().resolveOperator(OperatorType.NEGATION, types(node.getValue())); MethodHandle handle = metadata.getFunctionRegistry().getScalarFunctionImplementation(operatorSignature).getMethodHandle(); if (handle.type().parameterCount() > 0 && handle.type().parameterType(0) == ConnectorSession.class) { handle = handle.bindTo(session); } try { return handle.invokeWithArguments(value); } catch (Throwable throwable) { throwIfInstanceOf(throwable, RuntimeException.class); throwIfInstanceOf(throwable, Error.class); throw new RuntimeException(throwable.getMessage(), throwable); } } throw new UnsupportedOperationException("Unsupported unary operator: " + node.getSign()); }
@Override public ScalarFunctionImplementation specialize(BoundVariables boundVariables, int arity, TypeManager typeManager, FunctionRegistry functionRegistry) { Type inputType = boundVariables.getTypeVariable("T"); Type intermediateType = boundVariables.getTypeVariable("S"); Type outputType = boundVariables.getTypeVariable("R"); MethodHandle methodHandle = METHOD_HANDLE.bindTo(inputType); return new ScalarFunctionImplementation( true, ImmutableList.of( valueTypeArgumentProperty(RETURN_NULL_ON_NULL), valueTypeArgumentProperty(USE_BOXED_TYPE), functionTypeArgumentProperty(BinaryFunctionInterface.class), functionTypeArgumentProperty(UnaryFunctionInterface.class)), methodHandle.asType( methodHandle.type() .changeParameterType(1, Primitives.wrap(intermediateType.getJavaType())) .changeReturnType(Primitives.wrap(outputType.getJavaType()))), isDeterministic()); }
/** * Core method for indy method selection using runtime types. */ public static Object selectMethod(MutableCallSite callSite, Class sender, String methodName, int callID, Boolean safeNavigation, Boolean thisCall, Boolean spreadCall, Object dummyReceiver, Object[] arguments) throws Throwable { Selector selector = Selector.getSelector(callSite, sender, methodName, callID, safeNavigation, thisCall, spreadCall, arguments); selector.setCallSiteTarget(); MethodHandle call = selector.handle.asSpreader(Object[].class, arguments.length); call = call.asType(MethodType.methodType(Object.class,Object[].class)); return call.invokeExact(arguments); }
@Override public Object invokeHandle(Object handle, Object[] args) throws Throwable { MethodHandle mh = (MethodHandle) handle; return mh.invokeWithArguments(args); } }
private static MethodHandle bindWithFallback(RoboCallSite site, MethodHandle mh, MethodHandle fallback) { SwitchPoint switchPoint = getInvalidator(site.getTheClass()); MethodType type = site.type(); MethodHandle boundFallback = foldArguments(exactInvoker(type), fallback.bindTo(site)); try { mh = switchPoint.guardWithTest(mh.asType(type), boundFallback); } catch (WrongMethodTypeException e) { if (site instanceof MethodCallSite) { MethodCallSite methodCallSite = (MethodCallSite) site; throw new RuntimeException("failed to bind " + methodCallSite.thisType() + "." + methodCallSite.getName(), e); } else { throw e; } } site.setTarget(mh); return mh; }
public Binding bind(MethodHandle method) { long bindingId = nextId++; Binding binding = new Binding(bindingId, method.type()); bindings.put(bindingId, method); return binding; }
/** * Returns a correctly typed {@link MethodHandle} for the no-arg ctor of the given class. */ static final MethodHandle findAttributeImplCtor(Class<? extends AttributeImpl> clazz) { try { return lookup.findConstructor(clazz, NO_ARG_CTOR).asType(NO_ARG_RETURNING_ATTRIBUTEIMPL); } catch (NoSuchMethodException | IllegalAccessException e) { throw new IllegalArgumentException("Cannot lookup accessible no-arg constructor for: " + clazz.getName(), e); } }
public Procedure(String schema, String name, List<Argument> arguments, MethodHandle methodHandle) { this.schema = checkNotNullOrEmpty(schema, "schema").toLowerCase(ENGLISH); this.name = checkNotNullOrEmpty(name, "name").toLowerCase(ENGLISH); this.arguments = unmodifiableList(new ArrayList<>(arguments)); this.methodHandle = requireNonNull(methodHandle, "methodHandle is null"); Set<String> names = new HashSet<>(); for (Argument argument : arguments) { checkArgument(names.add(argument.getName()), "Duplicate argument name: " + argument.getName()); } checkArgument(!methodHandle.isVarargsCollector(), "Method must have fixed arity"); checkArgument(methodHandle.type().returnType() == void.class, "Method must return void"); long parameterCount = methodHandle.type().parameterList().stream() .filter(type -> !ConnectorSession.class.isAssignableFrom(type)) .count(); checkArgument(parameterCount == arguments.size(), "Method parameter count must match arguments"); }
/** * Sets a handle to call {@link GroovyInterceptable#invokeMethod(String, Object)} */ public boolean setInterceptor() { if (!(this.args[0] instanceof GroovyInterceptable)) return false; handle = MethodHandles.insertArguments(INTERCEPTABLE_INVOKER, 1, this.name); handle = handle.asCollector(Object[].class, targetType.parameterCount()-1); handle = handle.asType(targetType); return true; }
private Object invokeDefaultMethod(Object proxy, Method method, Object[] args) throws Throwable { final Constructor<MethodHandles.Lookup> constructor = MethodHandles.Lookup.class .getDeclaredConstructor(Class.class, int.class); if (!constructor.isAccessible()) { constructor.setAccessible(true); } final Class<?> declaringClass = method.getDeclaringClass(); return constructor .newInstance(declaringClass, MethodHandles.Lookup.PRIVATE | MethodHandles.Lookup.PROTECTED | MethodHandles.Lookup.PACKAGE | MethodHandles.Lookup.PUBLIC) .unreflectSpecial(method, declaringClass).bindTo(proxy).invokeWithArguments(args); }
private MethodHandle getMethodHandle(Method method) { MethodHandle methodHandle = methodHandle(FUNCTION_IMPLEMENTATION_ERROR, method); if (!isStatic(method.getModifiers())) { // Change type of "this" argument to Object to make sure callers won't have classloader issues methodHandle = methodHandle.asType(methodHandle.type().changeParameterType(0, Object.class)); // Re-arrange the parameters, so that the "this" parameter is after the meta parameters int[] permutedIndices = new int[methodHandle.type().parameterCount()]; permutedIndices[0] = dependencies.size(); MethodType newType = methodHandle.type().changeParameterType(dependencies.size(), methodHandle.type().parameterType(0)); for (int i = 0; i < dependencies.size(); i++) { permutedIndices[i + 1] = i; newType = newType.changeParameterType(i, methodHandle.type().parameterType(i + 1)); } for (int i = dependencies.size() + 1; i < permutedIndices.length; i++) { permutedIndices[i] = i; } methodHandle = permuteArguments(methodHandle, newType, permutedIndices); } return methodHandle; }
public T create(Config configNode) { List<Object> args = createArguments(configNode); try { Object obj = handle.invokeWithArguments(args); return type.cast(obj); } catch (ConfigException ex) { throw ex; } catch (Throwable throwable) { throw new ConfigException("Unable to create '" + type.getName() + "' instance.", throwable); } }