private void castToTypeFallBack() { if (handle!=null) return; // generic fallback to castToType handle = MethodHandles.insertArguments(DTT_CAST_TO_TYPE, 1, staticTargetType); }
/** * The MOP requires all get property operations to go through * {@link GroovyObject#getProperty(String)}. We do this in case * no property was found before. */ @Override public void setMetaClassCallHandleIfNedded(boolean standardMetaClass) { if (handle!=null) return; useMetaClass = true; if (LOG_ENABLED) LOG.info("set meta class invocation path for property get."); handle = MethodHandles.insertArguments(MOP_GET, 2, this.name); handle = MethodHandles.insertArguments(handle, 0, mc); } }
public static MethodHandle bindDependencies(MethodHandle handle, List<ImplementationDependency> dependencies, BoundVariables variables, TypeManager typeManager, FunctionRegistry functionRegistry) { for (ImplementationDependency dependency : dependencies) { handle = MethodHandles.insertArguments(handle, 0, dependency.resolve(variables, typeManager, functionRegistry)); } return handle; } }
private void handleSAM() { if (handle!=null) return; if (!(args[0] instanceof Closure)) return; Method m = CachedSAMClass.getSAMMethod(staticTargetType); if (m==null) return; //TODO: optimize: add guard based on type Closure handle = MethodHandles.insertArguments(SAM_CONVERSION, 1, m, staticTargetType); }
private MethodHandle correctClassForNameAndUnReflectOtherwise(Method m) throws IllegalAccessException { if (m.getDeclaringClass()==Class.class && m.getName().equals("forName") && m.getParameterTypes().length==1) { return MethodHandles.insertArguments(CLASS_FOR_NAME, 1, true, sender.getClassLoader()); } else { return LOOKUP.unreflect(m); } }
private static MethodHandle getMethodHandle(Type valueType, int arity) { final MethodHandle inputFunction; switch (valueType.getDisplayName()) { case StandardTypes.DOUBLE: inputFunction = INPUT_DOUBLE; break; case StandardTypes.REAL: inputFunction = INPUT_REAL; break; case StandardTypes.BIGINT: inputFunction = INPUT_BIGINT; break; default: throw new IllegalArgumentException(format("Unsupported type %s supplied", valueType.getDisplayName())); } switch (arity) { case 1: // weight and accuracy unspecified return insertArguments(inputFunction, 2, DEFAULT_WEIGHT, DEFAULT_ACCURACY); case 2: // weight specified, accuracy unspecified return insertArguments(inputFunction, 3, DEFAULT_ACCURACY); case 3: // weight and accuracy specified return inputFunction; default: throw new IllegalArgumentException(format("Unsupported number of arguments: %s", arity)); } }
private MethodHandle applyExtraParameters(Method matchingMethod, List<Object> extraParameters, List<ArgumentProperty> argumentProperties) { Signature signature = getSignature(); int expectedArgumentsCount = signature.getArgumentTypes().size() + getNullFlagsCount(argumentProperties) + getBlockPositionCount(argumentProperties) + extraParameters.size(); int matchingMethodArgumentCount = matchingMethod.getParameterCount(); checkState(matchingMethodArgumentCount == expectedArgumentsCount, "method %s has invalid number of arguments: %s (should have %s)", matchingMethod.getName(), matchingMethodArgumentCount, expectedArgumentsCount); MethodHandle matchingMethodHandle = Reflection.methodHandle(matchingMethod); matchingMethodHandle = MethodHandles.insertArguments( matchingMethodHandle, matchingMethodArgumentCount - extraParameters.size(), extraParameters.toArray()); return matchingMethodHandle; }
@Override public ScalarFunctionImplementation specialize(BoundVariables boundVariables, int arity, TypeManager typeManager, FunctionRegistry functionRegistry) { return new ScalarFunctionImplementation( false, ImmutableList.of(valueTypeArgumentProperty(RETURN_NULL_ON_NULL)), insertArguments(METHOD_HANDLE, 0, dfaStatesLimit, dfaRetries, padSpaces, boundVariables.getLongVariable("x")), true); }
private void handleNullWithoutBoolean() { if (handle!=null || args[0]!=null) return; if (staticTargetType.isPrimitive()) { handle = MethodHandles.insertArguments(GROOVY_CAST_EXCEPTION,1,staticTargetType); // need to call here here because we used the static target type // it won't be done otherwise because handle.type() == callSite.type() castAndSetGuards(); } else { handle = MethodHandles.identity(staticSourceType); } }
@Override protected Object visitBindExpression(BindExpression node, Object context) { List<Object> values = node.getValues().stream() .map(value -> process(value, context)) .collect(toImmutableList()); Object function = process(node.getFunction(), context); if (hasUnresolvedValue(values) || hasUnresolvedValue(function)) { ImmutableList.Builder<Expression> builder = ImmutableList.builder(); for (int i = 0; i < values.size(); i++) { builder.add(toExpression(values.get(i), type(node.getValues().get(i)))); } return new BindExpression( builder.build(), toExpression(function, type(node.getFunction()))); } return MethodHandles.insertArguments((MethodHandle) function, 0, values.toArray()); }
/** * Adds a type transformer applied at runtime. * This method handles transformations to String from GString, * array transformations and number based transformations */ protected static MethodHandle addTransformer(MethodHandle handle, int pos, Object arg, Class parameter) { MethodHandle transformer=null; if (arg instanceof GString) { transformer = TO_STRING; } else if (arg instanceof Closure) { transformer = createSAMTransform(arg, parameter); } else if (Number.class.isAssignableFrom(parameter)) { transformer = selectNumberTransformer(parameter, arg); } else if (parameter.isArray()) { transformer = MethodHandles.insertArguments(AS_ARRAY, 1, parameter); } if (transformer==null) throw new GroovyBugError("Unknown transformation for argument "+arg+" at position "+pos+" with "+arg.getClass()+" for parameter of type "+parameter); return applyUnsharpFilter(handle, pos, transformer); }
/** * Makes a fallback method for an invalidated method selection */ protected static MethodHandle makeFallBack(MutableCallSite mc, Class<?> sender, String name, int callID, MethodType type, boolean safeNavigation, boolean thisCall, boolean spreadCall) { MethodHandle mh = MethodHandles.insertArguments(SELECT_METHOD, 0, mc, sender, name, callID, safeNavigation, thisCall, spreadCall, /*dummy receiver:*/ 1); mh = mh.asCollector(Object[].class, type.parameterCount()). asType(type); return mh; }
/** * 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; }
if (params.length==2 && args.length==1) { handle = MethodHandles.insertArguments(handle, 1, new Object[]{null}); handle = MethodHandles.insertArguments(handle, params.length-1, Array.newInstance(lastParam.getComponentType(), 0)); if (LOG_ENABLED) LOG.info("added empty array for missing vargs part"); } else { //params.length < args.length
/** * Additionally to the normal {@link MethodSelector#setHandleForMetaMethod()} * task we have to also take care of generic getter methods, that depend * one the name. */ @Override public void setHandleForMetaMethod() { if (handle!=null) return; super.setHandleForMetaMethod(); if (handle != null && insertName && handle.type().parameterCount()==2) { handle = MethodHandles.insertArguments(handle, 1, name); } }
/** * Creates a MethodHandle, which will use the meta class path. * This method is called only if no handle has been created before. This * is usually the case if the method selection failed. */ public void setMetaClassCallHandleIfNedded(boolean standardMetaClass) { if (handle!=null) return; useMetaClass = true; if (LOG_ENABLED) LOG.info("set meta class invocation path"); Object receiver = getCorrectedReceiver(); if (receiver instanceof Class) { handle = META_CLASS_INVOKE_STATIC_METHOD.bindTo(mc); if (LOG_ENABLED) LOG.info("use invokeStaticMethod with bound meta class"); } else { handle = MOP_INVOKE_METHOD.bindTo(mc); if (LOG_ENABLED) LOG.info("use invokeMethod with bound meta class"); if (receiver instanceof GroovyObject) { // if the meta class call fails we may still want to fall back to call // GroovyObject#invokeMethod if the receiver is a GroovyObject if (LOG_ENABLED) LOG.info("add MissingMethod handler for GrooObject#invokeMethod fallback path"); handle = MethodHandles.catchException(handle, MissingMethodException.class, GROOVY_OBJECT_INVOKER); } } handle = MethodHandles.insertArguments(handle, 1, name); if (!spread) handle = handle.asCollector(Object[].class, targetType.parameterCount()-1); if (LOG_ENABLED) LOG.info("bind method name and create collector for arguments"); }
@Override public ScalarFunctionImplementation specialize(BoundVariables boundVariables, int arity, TypeManager typeManager, FunctionRegistry functionRegistry) { checkArgument(arity == 1, "Expected arity to be 1"); Type fromKeyType = boundVariables.getTypeVariable("FK"); Type fromValueType = boundVariables.getTypeVariable("FV"); Type toKeyType = boundVariables.getTypeVariable("TK"); Type toValueType = boundVariables.getTypeVariable("TV"); Type toMapType = typeManager.getParameterizedType( "map", ImmutableList.of( TypeSignatureParameter.of(toKeyType.getTypeSignature()), TypeSignatureParameter.of(toValueType.getTypeSignature()))); MethodHandle keyProcessor = buildProcessor(functionRegistry, fromKeyType, toKeyType, true); MethodHandle valueProcessor = buildProcessor(functionRegistry, fromValueType, toValueType, false); MethodHandle target = MethodHandles.insertArguments(METHOD_HANDLE, 0, keyProcessor, valueProcessor, toMapType); return new ScalarFunctionImplementation(true, ImmutableList.of(valueTypeArgumentProperty(RETURN_NULL_ON_NULL)), target, true); }
cast = MethodHandles.foldArguments(cast, getter.bindTo(type)); MethodHandle target = MethodHandles.insertArguments(methodHandle, 0, cast); return new ScalarFunctionImplementation( false,
@Override public MethodHandle findShadowMethodHandle(Class<?> theClass, String name, MethodType type, boolean isStatic) throws IllegalAccessException { String signature = getSignature(theClass, name, type, isStatic); InvocationProfile invocationProfile = new InvocationProfile(signature, isStatic, getClass().getClassLoader()); try { MethodHandle mh = MethodHandles.lookup().findVirtual(getClass(), "invoke", methodType(Object.class, InvocationProfile.class, Object.class, Object[].class)); mh = insertArguments(mh, 0, this, invocationProfile); if (isStatic) { return mh.bindTo(null).asCollector(Object[].class, type.parameterCount()); } else { return mh.asCollector(Object[].class, type.parameterCount() - 1); } } catch (NoSuchMethodException e) { throw new AssertionError(e); } }
methodHandle = METHOD_HANDLE_OBJECT; methodHandle = MethodHandles.insertArguments(methodHandle, 0, legacyMissingKey); InterpretedFunctionInvoker functionInvoker = new InterpretedFunctionInvoker(functionRegistry); methodHandle = methodHandle.bindTo(functionInvoker).bindTo(keyType).bindTo(valueType);