public GuardBuilder fold(MethodHandle function) { binder = binder.fold(function); return this; }
public static CallSite prepareBlock(Lookup lookup, String name, MethodType type, MethodHandle bodyHandle, MethodHandle scopeHandle, long encodedSignature) throws Throwable { IRScope scope = (IRScope)scopeHandle.invokeExact(); CompiledIRBlockBody body = new CompiledIRBlockBody(bodyHandle, scope, encodedSignature); Binder binder = Binder.from(type); binder = binder.fold(FRAME_SCOPE_BINDING); // This optimization can't happen until we can see into the method we're calling to know if it reifies the block if (false) { if (scope.needsBinding()) { if (scope.needsFrame()) { binder = binder.fold(FRAME_SCOPE_BINDING); } else { binder = binder.fold(SCOPE_BINDING); } } else { if (scope.needsFrame()) { binder = binder.fold(FRAME_BINDING); } else { binder = binder.fold(SELF_BINDING); } } } MethodHandle blockMaker = binder.drop(1, 3) .append(body) .invoke(CONSTRUCT_BLOCK); return new ConstantCallSite(blockMaker); }
public static CallSite prepareBlock(Lookup lookup, String name, MethodType type, MethodHandle bodyHandle, MethodHandle scopeHandle, long encodedSignature) throws Throwable { IRScope scope = (IRScope)scopeHandle.invokeExact(); CompiledIRBlockBody body = new CompiledIRBlockBody(bodyHandle, scope, encodedSignature); Binder binder = Binder.from(type); binder = binder.fold(FRAME_SCOPE_BINDING); // This optimization can't happen until we can see into the method we're calling to know if it reifies the block if (false) { if (scope.needsBinding()) { if (scope.needsFrame()) { binder = binder.fold(FRAME_SCOPE_BINDING); } else { binder = binder.fold(SCOPE_BINDING); } } else { if (scope.needsFrame()) { binder = binder.fold(FRAME_BINDING); } else { binder = binder.fold(SELF_BINDING); } } } MethodHandle blockMaker = binder.drop(1, 3) .append(body) .invoke(CONSTRUCT_BLOCK); return new ConstantCallSite(blockMaker); }
/** * Process the incoming arguments using the given handle, leaving the argument list * unmodified. * * @param function the function that will process the incoming arguments. Its * signature must match the current signature's arguments exactly. * @return a new Binder */ public Binder foldVoid(MethodHandle function) { if (type().returnType() == void.class) { return fold(function); } else { return fold(function.asType(function.type().changeReturnType(void.class))); } }
/** * Process the incoming arguments by calling the given static method on the * given class, inserting the result as the first argument. * * @param lookup the java.lang.invoke.MethodHandles.Lookup to use * @param target the class on which the method is defined * @param method the method to invoke on the first argument * @return a new Binder */ public Binder foldStatic(MethodHandles.Lookup lookup, Class<?> target, String method) { return fold(Binder.from(type()).invokeStaticQuiet(lookup, target, method)); }
/** * Process the incoming arguments by calling the given method on the first * argument, inserting the result as the first argument. * * @param lookup the java.lang.invoke.MethodHandles.Lookup to use * @param method the method to invoke on the first argument * @return a new Binder */ public Binder foldVirtual(MethodHandles.Lookup lookup, String method) { return fold(Binder.from(type()).invokeVirtualQuiet(lookup, method)); }
/** * Pass all arguments to the given function and insert the resulting value * as newName into the argument list. * * @param newName the name of the new first argument where the fold * function's result will be passed * @param function a function which will receive all arguments and have its * return value inserted into the call chain * @return a new SmartBinder with the fold applied */ public SmartBinder fold(String newName, MethodHandle function) { return new SmartBinder(this, signature().prependArg(newName, function.type().returnType()), binder.fold(function)); }
public static MethodHandle wrapWithFrameOnly(Signature signature, RubyModule implClass, String name, MethodHandle nativeTarget) { MethodHandle framePre = getFrameOnlyPre(signature, CallConfiguration.FrameFullScopeNone, implClass, name); MethodHandle framePost = getFramePost(signature, CallConfiguration.FrameFullScopeNone); // post logic for frame nativeTarget = Binder .from(nativeTarget.type()) .tryFinally(framePost) .invoke(nativeTarget); // pre logic for frame nativeTarget = foldArguments(nativeTarget, framePre); // call polling and call number increment nativeTarget = Binder .from(nativeTarget.type()) .fold(Binder .from(nativeTarget.type().changeReturnType(void.class)) .permute(0) .invokeStaticQuiet(lookup(), ThreadContext.class, "callThreadPoll")) .invoke(nativeTarget); return nativeTarget; }
public static MethodHandle wrapWithFrameOnly(Signature signature, RubyModule implClass, String name, MethodHandle nativeTarget) { MethodHandle framePre = getFrameOnlyPre(signature, CallConfiguration.FrameFullScopeNone, implClass, name); MethodHandle framePost = getFramePost(signature, CallConfiguration.FrameFullScopeNone); // post logic for frame nativeTarget = Binder .from(nativeTarget.type()) .tryFinally(framePost) .invoke(nativeTarget); // pre logic for frame nativeTarget = foldArguments(nativeTarget, framePre); // call polling and call number increment nativeTarget = Binder .from(nativeTarget.type()) .fold(Binder .from(nativeTarget.type().changeReturnType(void.class)) .permute(0) .invokeStaticQuiet(lookup(), ThreadContext.class, "callThreadPoll")) .invoke(nativeTarget); return nativeTarget; }
public static MethodHandle wrapWithFraming(Signature signature, CallConfiguration callConfig, RubyModule implClass, String name, MethodHandle nativeTarget, StaticScope scope) { MethodHandle framePre = getFramePre(signature, callConfig, implClass, name, scope); if (framePre != null) { MethodHandle framePost = getFramePost(signature, callConfig); // break, return, redo handling boolean heapScoped = callConfig.scoping() != Scoping.None; boolean framed = callConfig.framing() != Framing.None; // post logic for frame nativeTarget = Binder .from(nativeTarget.type()) .tryFinally(framePost) .invoke(nativeTarget); // pre logic for frame nativeTarget = foldArguments(nativeTarget, framePre); // call polling and call number increment nativeTarget = Binder .from(nativeTarget.type()) .fold(Binder .from(nativeTarget.type().changeReturnType(void.class)) .permute(0) .invokeStaticQuiet(lookup(), ThreadContext.class, "callThreadPoll")) .invoke(nativeTarget); } return nativeTarget; }
public static MethodHandle wrapWithFraming(Signature signature, CallConfiguration callConfig, RubyModule implClass, String name, MethodHandle nativeTarget, StaticScope scope) { MethodHandle framePre = getFramePre(signature, callConfig, implClass, name, scope); if (framePre != null) { MethodHandle framePost = getFramePost(signature, callConfig); // break, return, redo handling boolean heapScoped = callConfig.scoping() != Scoping.None; boolean framed = callConfig.framing() != Framing.None; // post logic for frame nativeTarget = Binder .from(nativeTarget.type()) .tryFinally(framePost) .invoke(nativeTarget); // pre logic for frame nativeTarget = foldArguments(nativeTarget, framePre); // call polling and call number increment nativeTarget = Binder .from(nativeTarget.type()) .fold(Binder .from(nativeTarget.type().changeReturnType(void.class)) .permute(0) .invokeStaticQuiet(lookup(), ThreadContext.class, "callThreadPoll")) .invoke(nativeTarget); } return nativeTarget; }
.fold(Binder .from(nativeTarget.type().changeReturnType(void.class)) .permute(0)
.fold(Binder .from(nativeTarget.type().changeReturnType(void.class)) .permute(0)
public MethodHandle up(MethodHandle target) { if (Util.isJava9()) return nativeTryFinally(target, post); MethodHandle exceptionHandler = Binder .from(target.type().insertParameterTypes(0, Throwable.class).changeReturnType(void.class)) .drop(0) .invoke(post); MethodHandle rethrow = Binder .from(target.type().insertParameterTypes(0, Throwable.class)) .fold(exceptionHandler) .drop(1, target.type().parameterCount()) .throwException(); target = MethodHandles.catchException(target, Throwable.class, rethrow); // if target returns a value, we must return it regardless of post MethodHandle realPost = post; if (target.type().returnType() != void.class) { // modify post to ignore return value MethodHandle newPost = Binder .from(target.type().insertParameterTypes(0, target.type().returnType()).changeReturnType(void.class)) .drop(0) .invoke(post); // fold post into an identity chain that only returns the value realPost = Binder .from(target.type().insertParameterTypes(0, target.type().returnType())) .fold(newPost) .drop(1, target.type().parameterCount()) .identity(); } return MethodHandles.foldArguments(realPost, target); }