private static void verifyMethodParameterType(MethodHandle method, int index, Class javaType, String sqlTypeDisplayName) { checkArgument(method.type().parameterArray()[index] == javaType, "Expected method %s parameter %s type to be %s (%s)", method, index, javaType.getName(), sqlTypeDisplayName); }
private static void verifyExactOutputFunction(MethodHandle method, List<AccumulatorStateDescriptor> stateDescriptors) { if (method == null) { return; } Class<?>[] parameterTypes = method.type().parameterArray(); checkArgument(parameterTypes.length == stateDescriptors.size() + 1, "Number of arguments for combine function must be exactly one plus than number of states."); for (int i = 0; i < stateDescriptors.size(); i++) { checkArgument(parameterTypes[i].equals(stateDescriptors.get(i).getStateInterface()), String.format("Type for Parameter index %d is unexpected", i)); } checkArgument(Arrays.stream(parameterTypes).filter(type -> type.equals(BlockBuilder.class)).count() == 1, "Output function must take exactly one BlockBuilder parameter"); }
private static void verifyCombineFunction(MethodHandle method, List<Class> lambdaInterfaces, List<AccumulatorStateDescriptor> stateDescriptors) { Class<?>[] parameterTypes = method.type().parameterArray(); checkArgument( parameterTypes.length == stateDescriptors.size() * 2 + lambdaInterfaces.size(), "Number of arguments for combine function must be 2 times the size of states plus number of lambda channels."); for (int i = 0; i < stateDescriptors.size() * 2; i++) { checkArgument( parameterTypes[i].equals(stateDescriptors.get(i % stateDescriptors.size()).getStateInterface()), String.format("Type for Parameter index %d is unexpected. Arguments for combine function must appear in the order of state1, state2, ..., otherState1, otherState2, ...", i)); } for (int i = 0; i < lambdaInterfaces.size(); i++) { verifyMethodParameterType(method, i + stateDescriptors.size() * 2, lambdaInterfaces.get(i), "function"); } }
/** * Sets the null constant for safe navigation. * In case of foo?.bar() and foo being null, we don't call the method, * instead we simply return null. This produces a handle, which will * return the constant. */ public boolean setNullForSafeNavigation() { if (!safeNavigation) return false; handle = MethodHandles.dropArguments(NULL_REF,0,targetType.parameterArray()); if (LOG_ENABLED) LOG.info("set null returning handle for safe navigation"); return true; }
/** * Helper method to manipulate the given type to replace Wrapper with Object. */ private MethodType removeWrapper(MethodType targetType) { Class[] types = targetType.parameterArray(); for (int i=0; i<types.length; i++) { if (types[i]==Wrapper.class) { targetType = targetType.changeParameterType(i, Object.class); } } return targetType; }
/** * Corrects method argument wrapping. * In cases in which we want to force a certain method selection * we use Wrapper classes to transport the static type information. * This method will be used to undo the wrapping. */ public void correctWrapping() { if (useMetaClass) return; Class[] pt = handle.type().parameterArray(); if (currentType!=null) pt = currentType.parameterArray(); for (int i=1; i<args.length; i++) { if (args[i] instanceof Wrapper) { Class type = pt[i]; MethodType mt = MethodType.methodType(type, Wrapper.class); handle = MethodHandles.filterArguments(handle, i, UNWRAP_METHOD.asType(mt)); if (LOG_ENABLED) LOG.info("added filter for Wrapper for argument at pos "+i); } } }
private static void verifyInputFunctionSignature(MethodHandle method, List<ParameterMetadata> dataChannelMetadata, List<Class> lambdaInterfaces, List<AccumulatorStateDescriptor> stateDescriptors) Class<?>[] parameters = method.type().parameterArray(); checkArgument(parameters.length > 0, "Aggregation input function must have at least one parameter"); checkArgument(parameters.length == dataChannelMetadata.size() + lambdaInterfaces.size(), "Wenlei TODO...");
@Override public MethodHandle getMethodHandle(String methodName, MethodType type) throws NoSuchMethodException, IllegalAccessException { MethodHandle nothing = constant(Void.class, null).asType(methodType(void.class)); if (type.parameterCount() != 0) { return dropArguments(nothing, 0, type.parameterArray()); } else { return nothing; } } }
private static MethodHandle getMethodHandle(String className, String methodName, MethodType type) { Interceptor interceptor = INTERCEPTORS.findInterceptor(className, methodName); if (interceptor != null) { try { // reload interceptor in sandbox... Class<Interceptor> theClass = (Class<Interceptor>) ReflectionHelpers.loadClass( RobolectricInternals.getClassLoader(), interceptor.getClass().getName()).asSubclass(Interceptor.class); return ReflectionHelpers.newInstance(theClass).getMethodHandle(methodName, type); } catch (NoSuchMethodException | IllegalAccessException e) { throw new RuntimeException(e); } } if (type.parameterCount() != 0) { return dropArguments(NOTHING, 0, type.parameterArray()); } else { return NOTHING; } }
if (handle==null) return; Class[] params = handle.type().parameterArray(); if (currentType!=null) params = currentType.parameterArray(); if (!isVargs) { if (spread && useMetaClass) return;
@SuppressWarnings("ReferenceEquality") @Override public MethodHandle findShadowMethodHandle(Class<?> definingClass, String name, MethodType methodType, boolean isStatic) throws IllegalAccessException { return PerfStatsCollector.getInstance().measure("find shadow method handle", () -> { MethodType actualType = isStatic ? methodType : methodType.dropParameterTypes(0, 1); Class<?>[] paramTypes = actualType.parameterArray(); Method shadowMethod = pickShadowMethod(definingClass, name, paramTypes); if (shadowMethod == CALL_REAL_CODE) { return null; } else if (shadowMethod == DO_NOTHING_METHOD) { return DO_NOTHING; } shadowMethod.setAccessible(true); MethodHandle mh = LOOKUP.unreflect(shadowMethod); // Robolectric doesn't actually look for static, this for example happens // in MessageQueue.nativeInit() which used to be void non-static in 4.2. if (!isStatic && Modifier.isStatic(shadowMethod.getModifiers())) { return dropArguments(mh, 0, Object.class); } else { return mh; } }); }
/** * 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()))); }
if (useMetaClass) return; Class[] parameters = handle.type().parameterArray(); if (currentType!=null) parameters = currentType.parameterArray(); if (args.length != parameters.length) { throw new GroovyBugError("At this point argument array length and parameter array length should be the same");
if (cast.type().parameterArray()[0] != ConnectorSession.class) { cast = MethodHandles.dropArguments(cast, 0, ConnectorSession.class); cast = MethodHandles.permuteArguments(cast, MethodType.methodType(Slice.class, cast.type().parameterArray()[1], cast.type().parameterArray()[0]), 1, 0); cast = MethodHandles.dropArguments(cast, 1, int.class); cast = MethodHandles.dropArguments(cast, 1, Block.class);
Class<?>[] genericTypes = MethodType.genericMethodType(types.length).parameterArray(); method = findShadowMethodDeclaredOnClass(shadowClass, name, genericTypes);
Class<?>[] parameters = inputFunction.type().parameterArray(); int inputChannel = 0; int stateIndex = 0;
Class[] pt = handle.type().parameterArray(); for (int i=0; i<args.length; i++) { Object arg = args[i];
while (currentParameterIndex < methodType.parameterArray().length) { Class<?> type = methodType.parameterArray()[currentParameterIndex]; stackTypes.add(type); if (bestChoice.getInstanceFactory().isPresent() && !boundInstance) {
getInvokeFunctionOnWindowIndexParameters( scope, inputFunction.type().parameterArray(), parameterMetadatas, lambdaInterfaces,
@Override public MethodHandle getMethodHandle(String methodName, MethodType type) throws NoSuchMethodException, IllegalAccessException { MethodHandle nothing = constant(Void.class, null).asType(methodType(void.class)); if (type.parameterCount() != 0) { return dropArguments(nothing, 0, type.parameterArray()); } else { return nothing; } } }