/** * Set MOP based constructor invocation path. */ @Override public void setMetaClassCallHandleIfNedded(boolean standardMetaClass) { if (handle!=null) return; useMetaClass = true; if (LOG_ENABLED) LOG.info("set meta class invocation path"); handle = MOP_INVOKE_CONSTRUCTOR.bindTo(mc); handle = handle.asCollector(Object[].class, targetType.parameterCount()-1); handle = MethodHandles.dropArguments(handle, 0, Class.class); if (LOG_ENABLED) LOG.info("create collector for 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; }
handle = handle.asCollector(lastParam, 1); } else if (params.length > args.length) { handle = handle.asCollector( lastParam, args.length - params.length + 1);
/** * 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; }
/** * 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 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); } }
} else { handle = handle.asCollector(Object[].class, targetType.parameterCount()-1);
public FunctionReference asCollector(Class<?> arrayType, int arrayLength) { return new FunctionReference(handle.asCollector(arrayType, arrayLength), this.parameterNames); }
private static MethodHandle toObjectArray(List<Class<?>> types) { MethodHandle mh = MethodHandles.identity(Object[].class); mh = mh.asCollector(Object[].class, types.size()); return mh.asType(MethodType.methodType(Object[].class, types)); }
public static CallSite runtimeBootstrap(MethodHandles.Lookup caller, String name, MethodType type) { assert "rt:stack".equals(name) || "rt:locals".equals(name); MethodHandle mh = MethodHandles.identity(Object[].class); mh = mh.asCollector(Object[].class, type.parameterCount()); mh = mh.asType(type); return new ConstantCallSite(mh); }
public MethodHandle wrapDNUHandle(MethodHandle dnuHandle) { Symbol sym = selectorConverter.functionNameAsSelector_(selector); MethodHandle withBoundSymbol = MethodHandles.insertArguments(dnuHandle, 1, sym); MethodHandle message = withBoundSymbol.asCollector(Object[].class, numArgs()); return message; }
/** * Creates a method handle out of the original target that will collect the varargs for the exact component type of * the varArg array. Note that this will nicely trigger language-specific type converters for exactly those varargs * for which it is necessary when later passed to linkerServices.convertArguments(). * * @param target the original method handle * @param parameterCount the total number of arguments in the new method handle * @return a collecting method handle */ static MethodHandle collectArguments(MethodHandle target, final int parameterCount) { final MethodType methodType = target.type(); final int fixParamsLen = methodType.parameterCount() - 1; final Class<?> arrayType = methodType.parameterType(fixParamsLen); return target.asCollector(arrayType, parameterCount - fixParamsLen); }
MIC(String name, MethodType type, int initialDepth, int flavor, int flags) { super(type); this.name = name; this.flavor = flavor; this.flags = flags; if (initialDepth > 0) { initialized = true; } MethodHandle fallback = FALLBACK.bindTo(this) .asCollector(Object[].class, type.parameterCount()) .asType(type); setTarget(fallback); }
public static CallSite bootstrap(Lookup caller, String name, MethodType type, Object... bsmArgs) { boolean nullSafeGuarded = ((int) bsmArgs[0]) == 1; String[] argumentNames = new String[bsmArgs.length - 1]; for (int i = 0; i < bsmArgs.length - 1; i++) { argumentNames[i] = (String) bsmArgs[i + 1]; } InlineCache callSite = new InlineCache(caller, name, type, nullSafeGuarded, argumentNames); MethodHandle fallbackHandle = FALLBACK .bindTo(callSite) .asCollector(Object[].class, type.parameterCount()) .asType(type); callSite.resetFallback = RESET_FALLBACK .bindTo(callSite) .asCollector(Object[].class, type.parameterCount()) .asType(type); callSite.setTarget(fallbackHandle); return callSite; }
public static CallSite bootstrap(Lookup caller, String name, MethodType type) { AdapterCallSite callSite = new AdapterCallSite(type, caller, name); MethodHandle fallbackHandle = FALLBACK .bindTo(callSite) .asCollector(Object[].class, type.parameterCount()) .asType(type); callSite.setTarget(fallbackHandle); return callSite; }
public MethodHandle up(MethodHandle target) { if (onlyTail()) { // fast path for tail args return target.asCollector(arrayType, count); } else { Permutes permutes = buildPermutes(source, target.type()); Binder binder = preparePermuteBinder(permutes); return binder.invoke(target); } }
private MethodHandle createRelinkAndInvokeMethod(final RelinkableCallSite callSite, final int relinkCount) { // Make a bound MH of invoke() for this linker and call site final MethodHandle boundRelinker = MethodHandles.insertArguments(RELINK, 0, this, callSite, Integer.valueOf( relinkCount)); // Make a MH that gathers all arguments to the invocation into an Object[] final MethodType type = callSite.getDescriptor().getMethodType(); final MethodHandle collectingRelinker = boundRelinker.asCollector(Object[].class, type.parameterCount()); return MethodHandles.foldArguments(MethodHandles.exactInvoker(type), collectingRelinker.asType( type.changeReturnType(MethodHandle.class))); }
public static CallSite bootstrap(Lookup caller, String name, MethodType type, Object... bsmArgs) { boolean constant = ((int) bsmArgs[0]) == 1; String[] argumentNames = new String[bsmArgs.length - 1]; for (int i = 0; i < bsmArgs.length - 1; i++) { argumentNames[i] = (String) bsmArgs[i + 1]; } InlineCache callSite = new InlineCache(type, constant, argumentNames); MethodHandle fallbackHandle = FALLBACK .bindTo(callSite) .asCollector(Object[].class, type.parameterCount()) .asType(type); callSite.fallback = fallbackHandle; callSite.setTarget(fallbackHandle); return callSite; }
private MethodHandle createRelinkAndInvokeMethod(final RelinkableCallSite callSite, int relinkCount) { // Make a bound MH of invoke() for this linker and call site final MethodHandle boundRelinker = MethodHandles.insertArguments(RELINK, 0, this, callSite, Integer.valueOf( relinkCount)); // Make a MH that gathers all arguments to the invocation into an Object[] final MethodType type = callSite.getDescriptor().getMethodType(); final MethodHandle collectingRelinker = boundRelinker.asCollector(Object[].class, type.parameterCount()); return MethodHandles.foldArguments(MethodHandles.exactInvoker(type), collectingRelinker.asType( type.changeReturnType(MethodHandle.class))); }
private static Object installVTableDispatch(InlineCache inlineCache, Object[] args) throws Throwable { if (inlineCache.vtable == null) { inlineCache.vtable = new WeakHashMap<>(); } MethodHandle lookup = VTABLE_LOOKUP .bindTo(inlineCache) .asCollector(Object[].class, args.length); MethodHandle exactInvoker = exactInvoker(inlineCache.type()); MethodHandle vtableTarget = foldArguments(exactInvoker, lookup); if (inlineCache.nullSafeGuarded) { vtableTarget = makeNullSafeGuarded(vtableTarget); } inlineCache.setTarget(vtableTarget); if (shouldReturnNull(inlineCache, args[0])) { return null; } return vtableTarget.invokeWithArguments(args); }