private static MethodHandle getBlockEscape(Signature signature) { Signature voidSignature = signature.changeReturn(void.class); MethodHandle escape = BLOCK_ESCAPES.get(voidSignature); if (escape == null) { escape = SmartBinder.from(voidSignature) .permute("block") .invoke(ESCAPE_BLOCK) .handle(); BLOCK_ESCAPES.put(voidSignature, escape); } return escape; }
/** * Pass all arguments to the given function and drop any result. * * @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 foldVoid(SmartHandle function) { if (Arrays.equals(signature().argNames(), function.signature().argNames())) { return foldVoid(function.handle()); } else { return foldVoid(signature().asFold(void.class).permuteWith(function).handle()); } }
public static RubyString string(MutableCallSite site, ByteList value, int cr, ThreadContext context) throws Throwable { MethodHandle handle = SmartBinder .from(STRING_SIGNATURE) .invoke(NEW_STRING_SHARED_HANDLE.apply("byteList", value)) .handle(); site.setTarget(handle); return RubyString.newStringShared(context.runtime, value, cr); }
/** * Terminate this binder by invoking the given target handle. The signature * of this binder is not compared to the signature of the given * SmartHandle. * * @param target the handle to invoke * @return a new SmartHandle with this binder's starting signature, bound * through to the given handle */ public SmartHandle invoke(SmartHandle target) { return new SmartHandle(start, binder.invoke(target.handle())); }
/** * Produce a new SmartHandle by permuting this Signature's arguments to the * Signature of a target SmartHandle. The new SmartHandle's signature will * match this one, permuting those arguments and invoking the target handle. * * @param target the SmartHandle to use as a permutation target * @return a new SmartHandle that permutes this Signature's args into a call * to the target SmartHandle. * @see Signature#permuteWith(java.lang.invoke.MethodHandle, java.lang.String[]) */ public SmartHandle permuteWith(SmartHandle target) { String[] argNames = target.signature().argNames(); return new SmartHandle(this, permuteWith(target.handle(), argNames)); }
.from(VARIABLE_ARITY_SIGNATURE.prependArg("script", scriptClass)) .invokeStaticQuiet(LOOKUP, scriptClass, javaName) .bindTo(scriptObject); } else { .from(SPECIFIC_ARITY_SIGNATURES[specificArity].prependArg("script", scriptClass)) .invokeStaticQuiet(LOOKUP, scriptClass, javaName) .bindTo(scriptObject); .from(directCall.signature(), InvocationLinker.wrapWithFraming(directCall.signature(), callConfig, implementationClass, rubyName, directCall.handle(), scope)); targets[specificArity] = directCall.handle(); targets[4] = variableCall.handle(); } else { targets[4] = directCall.handle();
private static MethodHandle createGWT(SmartHandle test, MethodHandle target, MethodHandle fallback, CacheEntry entry, JRubyCallSite site, boolean curryFallback) { MethodHandle myFallback = curryFallback ? insertArguments(fallback, 0, site) : fallback; MethodHandle guardWithTest = test.guard(target, myFallback); return guardWithTest; }
.from(VARIABLE_ARITY_SIGNATURE.prependArg("script", scriptClass)) .invokeStaticQuiet(LOOKUP, scriptClass, javaName) .bindTo(scriptObject); } else { .from(SPECIFIC_ARITY_SIGNATURES[specificArity].prependArg("script", scriptClass)) .invokeStaticQuiet(LOOKUP, scriptClass, javaName) .bindTo(scriptObject); .from(directCall.signature(), InvocationLinker.wrapWithFraming(directCall.signature(), callConfig, implementationClass, rubyName, directCall.handle(), scope)); targets[specificArity] = directCall.handle(); targets[4] = variableCall.handle(); } else { targets[4] = directCall.handle();
private static MethodHandle createGWT(SmartHandle test, MethodHandle target, MethodHandle fallback, CacheEntry entry, JRubyCallSite site, boolean curryFallback) { MethodHandle myFallback = curryFallback ? insertArguments(fallback, 0, site) : fallback; MethodHandle guardWithTest = test.guard(target, myFallback); return guardWithTest; }
if (!callConfig.isNoop()) { target = SmartHandle .from(target.signature(), InvocationLinker.wrapWithFraming(baseSignature, callConfig, implementationClass, rubyName, target.handle(), null)); targets[specificArity] = target.handle(); } else { targets[4] = target.handle(); .spread("arg", i) .permute("context", "self", "arg*", "block") .invoke(targets[i]).handle(); .filterReturn(HANDLE_GETTER.bindTo(varargsTargets)) .cast(int.class, Object.class) .invokeStaticQuiet(LOOKUP, Array.class, "getLength"); .invoker(); targets[4] = variableCall.handle();
private static MethodHandle getBlockEscape(Signature signature) { Signature voidSignature = signature.changeReturn(void.class); MethodHandle escape = BLOCK_ESCAPES.get(voidSignature); if (escape == null) { escape = SmartBinder.from(voidSignature) .permute("block") .invoke(ESCAPE_BLOCK) .handle(); BLOCK_ESCAPES.put(voidSignature, escape); } return escape; }
/** * 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, SmartHandle function) { if (Arrays.equals(signature().argNames(), function.signature().argNames())) { return fold(newName, function.handle()); } else { return fold(newName, signature().changeReturn(function.signature().type().returnType()).permuteWith(function).handle()); } }
public static RubyString string(MutableCallSite site, ByteList value, int cr, ThreadContext context) throws Throwable { MethodHandle handle = SmartBinder .from(STRING_SIGNATURE) .invoke(NEW_STRING_SHARED_HANDLE.apply("byteList", value)) .handle(); site.setTarget(handle); return RubyString.newStringShared(context.runtime, value, cr); }
if (!callConfig.isNoop()) { target = SmartHandle .from(target.signature(), InvocationLinker.wrapWithFraming(baseSignature, callConfig, implementationClass, rubyName, target.handle(), null)); targets[specificArity] = target.handle(); } else { targets[4] = target.handle(); .spread("arg", i) .permute("context", "self", "arg*", "block") .invoke(targets[i]).handle(); .filterReturn(HANDLE_GETTER.bindTo(varargsTargets)) .cast(int.class, Object.class) .invokeStaticQuiet(LOOKUP, Array.class, "getLength"); .invoker(); targets[4] = variableCall.handle();
/** * Use the given filter function to transform the return value at this * point in the binder. The filter will be inserted into the handle, and * return values will pass through it before continuing. * * The filter's argument must match the expected return value downstream * from this point in the binder, and the return value must match the * return value at this point in the binder. * * @param filter the function to use to transform the return value at this point * @return a new SmartBinder with the filter applied */ public SmartBinder filterReturn(SmartHandle filter) { return new SmartBinder(this, signature().changeReturn(filter.signature().type().returnType()), binder.filterReturn(filter.handle())); }