@Override public MethodHandle getMethodHandle(String methodName, MethodType type) throws NoSuchMethodException, IllegalAccessException { Class<?> shadowWindowClass; try { shadowWindowClass = type.returnType().getClassLoader().loadClass(ShadowWindow.class.getName()); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } return lookup.in(type.returnType()).findStatic(shadowWindowClass, "create", type); } }
public FieldDefinition getCachedInstance(MethodHandle methodHandle) { FieldDefinition field = classDefinition.declareField(a(PRIVATE, FINAL), "__cachedInstance" + nextId, methodHandle.type().returnType()); initializers.put(field, methodHandle); nextId++; return field; }
Class<?> instanceType = instanceFactory.get().type().returnType(); checkArgument(instanceFactory.get().type().parameterList().size() == 0, "instanceFactory should have no parameter"); checkArgument(instanceType.equals(methodHandle.type().parameterType(0)), "methodHandle is not an instance method");
public static BytecodeExpression loadConstant(Binding binding) { return invokeDynamic( BOOTSTRAP_METHOD, ImmutableList.of(binding.getBindingId()), "constant_" + binding.getBindingId(), binding.getType().returnType()); }
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"); }
private InvokeFunctionBytecodeExpression( Scope scope, CallSiteBinder binder, String name, ScalarFunctionImplementation function, Optional<BytecodeNode> instance, List<BytecodeExpression> parameters) { super(type(Primitives.unwrap(function.getMethodHandle().type().returnType()))); this.invocation = generateInvocation( scope, name, function, instance, parameters.stream().map(BytecodeNode.class::cast).collect(toImmutableList()), binder); this.oneLineDescription = name + "(" + Joiner.on(", ").join(parameters) + ")"; }
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"); }
private static MethodHandle unmapJava7Or8(MethodHandles.Lookup lookup) throws ReflectiveOperationException { /* "Compile" a MethodHandle that is roughly equivalent to the following lambda: * * (ByteBuffer buffer) -> { * sun.misc.Cleaner cleaner = ((java.nio.DirectByteBuffer) byteBuffer).cleaner(); * if (nonNull(cleaner)) * cleaner.clean(); * else * noop(cleaner); // the noop is needed because MethodHandles#guardWithTest always needs both if and else * } */ Class<?> directBufferClass = Class.forName("java.nio.DirectByteBuffer"); Method m = directBufferClass.getMethod("cleaner"); m.setAccessible(true); MethodHandle directBufferCleanerMethod = lookup.unreflect(m); Class<?> cleanerClass = directBufferCleanerMethod.type().returnType(); MethodHandle cleanMethod = lookup.findVirtual(cleanerClass, "clean", methodType(void.class)); MethodHandle nonNullTest = lookup.findStatic(MappedByteBuffers.class, "nonNull", methodType(boolean.class, Object.class)).asType(methodType(boolean.class, cleanerClass)); MethodHandle noop = dropArguments(constant(Void.class, null).asType(methodType(void.class)), 0, cleanerClass); MethodHandle unmapper = filterReturnValue(directBufferCleanerMethod, guardWithTest(nonNullTest, cleanMethod, noop)) .asType(methodType(void.class, ByteBuffer.class)); return unmapper; }
/** * Adds the standard exception handler. */ public void addExceptionHandler() { //TODO: if we would know exactly which paths require the exceptions // and which paths not, we can sometimes save this guard if (handle==null || !catchException) return; Class returnType = handle.type().returnType(); if (returnType!=Object.class) { MethodType mtype = MethodType.methodType(returnType, GroovyRuntimeException.class); handle = MethodHandles.catchException(handle, GroovyRuntimeException.class, UNWRAP_EXCEPTION.asType(mtype)); } else { handle = MethodHandles.catchException(handle, GroovyRuntimeException.class, UNWRAP_EXCEPTION); } if (LOG_ENABLED) LOG.info("added GroovyRuntimeException unwrapper"); }
public CastSelector(MutableCallSite callSite, Object[] arguments) { super(callSite, Selector.class, "", CALL_TYPES.CAST, false, false, false, arguments); this.staticSourceType = callSite.type().parameterType(0); this.staticTargetType = callSite.type().returnType(); }
private static MethodHandle cleanStackTraces(MethodHandle mh) { MethodType type = EXCEPTION_HANDLER.type().changeReturnType(mh.type().returnType()); return catchException(mh, Throwable.class, EXCEPTION_HANDLER.asType(type)); } }
/** * @param f (U, S1, S2, ..., Sm)R * @param g (T1, T2, ..., Tn)U * @return (T1, T2, ..., Tn, S1, S2, ..., Sm)R */ public static MethodHandle compose(MethodHandle f, MethodHandle g) { if (f.type().parameterType(0) != g.type().returnType()) { throw new IllegalArgumentException(format("f.parameter(0) != g.return(). f: %s g: %s", f.type(), g.type())); } // Semantics: f => f // Type: (U, S1, S2, ..., Sn)R => (U, T1, T2, ..., Tm, S1, S2, ..., Sn)R MethodHandle fUTS = MethodHandles.dropArguments(f, 1, g.type().parameterList()); // Semantics: f => fg // Type: (U, T1, T2, ..., Tm, S1, S2, ..., Sn)R => (T1, T2, ..., Tm, S1, S2, ..., Sn)R return MethodHandles.foldArguments(fUTS, g); }
/** * @param f (U, S1, S2, ..., Sm)R * @param g (T1, T2, ..., Tn)U * @return (T1, T2, ..., Tn, S1, S2, ..., Sm)R */ public static MethodHandle compose(MethodHandle f, MethodHandle g) { if (f.type().parameterType(0) != g.type().returnType()) { throw new IllegalArgumentException(format("f.parameter(0) != g.return(). f: %s g: %s", f.type(), g.type())); } // Semantics: f => f // Type: (U, S1, S2, ..., Sn)R => (U, T1, T2, ..., Tm, S1, S2, ..., Sn)R MethodHandle fUTS = MethodHandles.dropArguments(f, 1, g.type().parameterList()); // Semantics: f => fg // Type: (U, T1, T2, ..., Tm, S1, S2, ..., Sn)R => (T1, T2, ..., Tm, S1, S2, ..., Sn)R return MethodHandles.foldArguments(fUTS, g); }
@Test public void testCustomStateSerializerAggregationParse() { ParametricAggregation aggregation = parseFunctionDefinition(CustomStateSerializerAggregationFunction.class); AggregationImplementation implementation = getOnlyElement(aggregation.getImplementations().getExactImplementations().values()); assertTrue(implementation.getStateSerializerFactory().isPresent()); InternalAggregationFunction specialized = aggregation.specialize(BoundVariables.builder().build(), 1, new TypeRegistry(), null); AccumulatorStateSerializer<?> createdSerializer = getOnlyElement(((LazyAccumulatorFactoryBinder) specialized.getAccumulatorFactoryBinder()) .getGenericAccumulatorFactoryBinder().getStateDescriptors()).getSerializer(); Class<?> serializerFactory = implementation.getStateSerializerFactory().get().type().returnType(); assertTrue(serializerFactory.isInstance(createdSerializer)); }
m.setAccessible(true); final MethodHandle directBufferCleanerMethod = lookup.unreflect(m); final Class<?> cleanerClass = directBufferCleanerMethod.type().returnType();
/** * Apply a transformer as filter. * The filter may not match exactly in the types. In this case needed * additional type transformations are done by {@link MethodHandle#asType(MethodType)} */ public static MethodHandle applyUnsharpFilter(MethodHandle handle, int pos, MethodHandle transformer) { MethodType type = transformer.type(); Class given = handle.type().parameterType(pos); if (type.returnType() != given || type.parameterType(0) != given) { transformer = transformer.asType(MethodType.methodType(given, type.parameterType(0))); } return MethodHandles.filterArguments(handle, pos, transformer); }
checkArgument(methodType.returnType() == returnType, "returnType does not match"); checkArgument(methodType.parameterList().equals(ImmutableList.of(Object.class, javaArrayType)), "parameter types do not match");
/** * The signature of the returned MethodHandle is (Block fromMap, int position, ConnectorSession session, BlockBuilder mapBlockBuilder)void. * The processor will get the value from fromMap, cast it and write to toBlock. */ private MethodHandle buildProcessor(FunctionRegistry functionRegistry, Type fromType, Type toType, boolean isKey) { MethodHandle getter = nativeValueGetter(fromType); // Adapt cast that takes ([ConnectorSession,] ?) to one that takes (?, ConnectorSession), where ? is the return type of getter. ScalarFunctionImplementation castImplementation = functionRegistry.getScalarFunctionImplementation(functionRegistry.getCoercion(fromType, toType)); MethodHandle cast = castImplementation.getMethodHandle(); if (cast.type().parameterArray()[0] != ConnectorSession.class) { cast = MethodHandles.dropArguments(cast, 0, ConnectorSession.class); } cast = permuteArguments(cast, methodType(cast.type().returnType(), cast.type().parameterArray()[1], cast.type().parameterArray()[0]), 1, 0); MethodHandle target = compose(cast, getter); // If the key cast function is nullable, check the result is not null. if (isKey && castImplementation.isNullable()) { target = compose(nullChecker(target.type().returnType()), target); } MethodHandle writer = nativeValueWriter(toType); writer = permuteArguments(writer, methodType(void.class, writer.type().parameterArray()[1], writer.type().parameterArray()[0]), 1, 0); return compose(writer, target.asType(methodType(unwrap(target.type().returnType()), target.type().parameterArray()))); }
throw new IllegalArgumentException(format("f.parameterCount != 2. f: %s", f.type())); if (f.type().parameterType(0) != g.type().returnType()) { throw new IllegalArgumentException(format("f.parameter(0) != g.return. f: %s g: %s", f.type(), g.type())); if (f.type().parameterType(1) != h.type().returnType()) { throw new IllegalArgumentException(format("f.parameter(0) != h.return. f: %s h: %s", f.type(), h.type()));
throw new IllegalArgumentException(format("f.parameterCount != 2. f: %s", f.type())); if (f.type().parameterType(0) != g.type().returnType()) { throw new IllegalArgumentException(format("f.parameter(0) != g.return. f: %s g: %s", f.type(), g.type())); if (f.type().parameterType(1) != h.type().returnType()) { throw new IllegalArgumentException(format("f.parameter(0) != h.return. f: %s h: %s", f.type(), h.type()));