@Override public MethodHandle getShadowCreator(Class<?> theClass) { ShadowInfo shadowInfo = getShadowInfo(theClass); if (shadowInfo == null) return dropArguments(NO_SHADOW_HANDLE, 0, theClass); String shadowClassName = shadowInfo.shadowClassName; try { Class<?> shadowClass = Class.forName(shadowClassName, false, theClass.getClassLoader()); ShadowMetadata shadowMetadata = getShadowMetadata(shadowClass); MethodHandle mh = identity(shadowClass); // (instance) mh = dropArguments(mh, 1, theClass); // (instance) for (Field field : shadowMetadata.realObjectFields) { MethodHandle setter = LOOKUP.unreflectSetter(field); MethodType setterType = mh.type().changeReturnType(void.class); mh = foldArguments(mh, setter.asType(setterType)); } mh = foldArguments(mh, LOOKUP.unreflectConstructor(shadowMetadata.constructor)); // (shadow, instance) return mh; // (instance) } catch (IllegalAccessException | ClassNotFoundException e) { throw new RuntimeException("Could not instantiate shadow " + shadowClassName + " for " + theClass, e); } }
/** * @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); }
cast = MethodHandles.dropArguments(cast, 1, int.class); cast = MethodHandles.dropArguments(cast, 1, Block.class); cast = MethodHandles.foldArguments(cast, getter.bindTo(type));
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; }
MethodHandle fhTU = MethodHandles.foldArguments(fVTU, h); return MethodHandles.foldArguments(fhUST, g);
foldTargetType = foldTargetType.insertParameterTypes(0, targetType.parameterType(1)); handle = MethodHandles.foldArguments(con, handle.asType(foldTargetType));
MethodHandle fhTU = MethodHandles.foldArguments(fVTU, h); return MethodHandles.foldArguments(fhUST, g);
private static MethodHandle buildSetter(Class arrayClass){ MethodHandle set = MethodHandles.arrayElementSetter(arrayClass); MethodHandle fallback = MethodHandles.explicitCastArguments(set, set.type().changeParameterType(0, Object.class)); fallback = MethodHandles.dropArguments(fallback, 3, int.class); MethodType reorderType = fallback.type(). insertParameterTypes(0, int.class). dropParameterTypes(4,5); fallback = MethodHandles.permuteArguments(fallback, reorderType, 1, 0, 3, 0); fallback = MethodHandles.foldArguments(fallback, normalizeIndex); fallback = MethodHandles.explicitCastArguments(fallback, set.type()); MethodHandle guard = MethodHandles.dropArguments(notNegative, 0, arrayClass); MethodHandle handle = MethodHandles.guardWithTest(guard, set, fallback); return handle; }
private static MethodHandle buildGetter(Class arrayClass) { MethodHandle get = MethodHandles.arrayElementGetter(arrayClass); MethodHandle fallback = MethodHandles.explicitCastArguments(get, get.type().changeParameterType(0, Object.class)); fallback = MethodHandles.dropArguments(fallback, 2, int.class); MethodType reorderType = fallback.type(). insertParameterTypes(0, int.class). dropParameterTypes(2,3); fallback = MethodHandles.permuteArguments(fallback, reorderType, 1, 0, 0); fallback = MethodHandles.foldArguments(fallback, normalizeIndex); fallback = MethodHandles.explicitCastArguments(fallback, get.type()); MethodHandle guard = MethodHandles.dropArguments(notNegative, 0, arrayClass); MethodHandle handle = MethodHandles.guardWithTest(guard, get, fallback); return handle; }
private static MethodHandle tailCallAdapter(MethodHandle mh) { MethodHandle result = TailCallInvocation.getTailCallHandler(); result = MethodHandles.dropArguments(result, 2, Object.class, Object[].class); result = MethodHandles.dropArguments(result, 1, ExecutionContext.class); result = MethodHandles.foldArguments(result, mh); return result; }
private static MethodHandle throwException(Supplier<Throwable> supplier, MethodType type) throws Exception { MethodHandle makeExn = PRIVATE_LOOKUP.findVirtual(Supplier.class, "get", methodType(Object.class)); makeExn = makeExn.bindTo(supplier); makeExn = makeExn.asType(methodType(Throwable.class)); MethodHandle throwExn = MethodHandles.throwException(type.returnType(), Throwable.class); throwExn = MethodHandles.foldArguments(throwExn, makeExn); // discard arguments specified by the provided type return MethodHandles.dropArguments(throwExn, 0, type.parameterArray()); } }
private static MutableCallSite createRuntimeCallSite(String name, MethodType type) { MutableCallSite callsite = new MutableCallSite(type); MethodHandle target = MethodHandles.insertArguments(nativeCallSetupMH, 0, callsite, name); callsite.setTarget(MethodHandles.foldArguments(MethodHandles.exactInvoker(type), target)); return callsite; }
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))); }
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 MethodHandle tailCallAdapter(RuntimeInfo.Function function, FunctionObject functionObject) { MethodHandle mh = function.callMethod(); if (function.is(RuntimeInfo.FunctionFlags.TailCall)) { assert !function.isGenerator() && !function.isAsync() && function.isStrict(); MethodHandle result = TailCallInvocation.getTailCallHandler(); result = MethodHandles.dropArguments(result, 1, functionObject.getClass()); result = MethodHandles.dropArguments(result, 3, Object.class, Object[].class); result = MethodHandles.foldArguments(result, mh); return result; } return mh; }
/** * Creates a method that rebuilds our call chain, pruning it of any invalidated switchpoints, and then invokes that * chain. * @param relink the ultimate fallback for the chain (the {@code DynamicLinker}'s relink). * @return a method handle for prune-and-invoke */ private MethodHandle makePruneAndInvokeMethod(final MethodHandle relink, final MethodHandle prune) { // Bind prune to (this, relink) final MethodHandle boundPrune = MethodHandles.insertArguments(prune, 0, this, relink); // Make it ignore all incoming arguments final MethodHandle ignoreArgsPrune = MethodHandles.dropArguments(boundPrune, 0, type().parameterList()); // Invoke prune, then invoke the call site target with original arguments return MethodHandles.foldArguments(MethodHandles.exactInvoker(type()), ignoreArgsPrune); }
/** Looks up generic method, with a dynamic cast to the receiver's type. (compound assignment) */ public static MethodHandle dynamicCast(MethodHandle target) { // adapt dynamic receiver cast to the generic method MethodHandle cast = DYNAMIC_RECEIVER_CAST.asType(MethodType.methodType(target.type().returnType(), target.type().returnType(), target.type().parameterType(0))); // drop the RHS parameter cast = MethodHandles.dropArguments(cast, 2, target.type().parameterType(1)); // combine: f(x,y) -> g(f(x,y), x, y); return MethodHandles.foldArguments(cast, target); }
private static MethodHandle bindWithFallback(MethodHandle mh, RoboCallSite site, MethodHandle fallback) { SwitchPoint switchPoint = getInvalidator(site.getCaller()); MethodType type = site.type(); MethodHandle boundFallback = foldArguments(exactInvoker(type), fallback.bindTo(site)); mh = switchPoint.guardWithTest(mh.asType(type), boundFallback); site.setTarget(mh); return mh; }
public CompiledIRBlockBody(MethodHandle handle, IRScope closure, long encodedSignature) { super(closure, Signature.decode(encodedSignature)); // evalType copied (shared) on MixedModeIRBlockBody#completeBuild this.handle = handle; MethodHandle callHandle = MethodHandles.insertArguments(handle, 2, closure.getStaticScope(), null); // This is gross and should be done in IR rather than in the handles. this.callHandle = MethodHandles.foldArguments(callHandle, CHECK_ARITY); this.yieldDirectHandle = MethodHandles.insertArguments( MethodHandles.insertArguments(handle, 2, closure.getStaticScope()), 4, Block.NULL_BLOCK); // Done in the interpreter (WrappedIRClosure) but we do it here closure.getStaticScope().determineModule(); }