Refine search
public MethodHandle getNormalYieldHandle() { MethodHandle normalYieldHandle = this.normalYieldHandle; if (normalYieldHandle != null) return normalYieldHandle; return this.normalYieldHandle = Binder.from(IRubyObject.class, ThreadContext.class, Block.class, IRubyObject.class) .filter(2, WRAP_VALUE) .insert(2, new Class[]{StaticScope.class, IRubyObject.class}, getStaticScope(), null) .append(Block.class, Block.NULL_BLOCK) .invoke(handle); }
public static CallSite array(Lookup lookup, String name, MethodType type) { MethodHandle handle = Binder .from(type) .collect(1, IRubyObject[].class) .invokeStaticQuiet(LOOKUP, Bootstrap.class, "array"); CallSite site = new ConstantCallSite(handle); return site; }
/** * 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)); }
public boolean init(IRubyObject obj) { Ruby runtime = obj.getRuntime(); IRubyObject nil = runtime.getNil(); IRubyObject fals = runtime.getFalse(); setTarget( Binder.from(type()) .insert(0, RubyBoolean.False.class, fals) .insert(0, RubyNil.class, nil) .invokeStaticQuiet(LOOKUP, IsTrueSite.class, "isTruthy") ); return nil != obj && fals != obj; }
if (method.getArity().isFixed()) { if (method.getArity().getValue() <= 3) { Binder b = Binder.from(site.type()); if (!nc.hasContext()) { b.drop(0); b.insert(site.type().parameterCount() - 1, Block.NULL_BLOCK); } else if (!nc.hasBlock() && block) { b.drop(site.type().parameterCount() - 2, 1); if (b.type().parameterCount() == nc.getNativeSignature().length) { mh = b .cast(nc.getNativeReturn(), nc.getNativeSignature()) .invokeStaticQuiet(MethodHandles.lookup(), nc.getNativeTarget(), nc.getNativeName()); if (b.type().parameterCount() == nc.getNativeSignature().length + 1) { .permute(PERMUTES[arity]) .cast(MethodType.methodType(nc.getNativeReturn(), nc.getNativeTarget(), nc.getNativeSignature())) .invokeVirtualQuiet(MethodHandles.lookup(), nc.getNativeName()); .insertParameterTypes(2, RubyModule.class, String.class) .insertParameterTypes(0, DynamicMethod.class); mh = Binder.from(site.type()) .insert(2, selfClass, site.name) .insert(0, method) .cast(type2)
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 IRubyObject searchConst(MutableCallSite site, String constName, ThreadContext context, StaticScope staticScope) throws Throwable { Ruby runtime = context.runtime; SwitchPoint switchPoint = (SwitchPoint)runtime.getConstantInvalidator(constName).getData(); IRubyObject value = staticScope.getConstant(constName); if (value == null) { return staticScope.getModule().callMethod(context, "const_missing", runtime.fastNewSymbol(constName)); } // bind constant until invalidated MethodHandle target = Binder.from(site.type()) .drop(0, 2) .constant(value); MethodHandle fallback = Binder.from(site.type()) .insert(0, site, constName) .invokeStatic(MethodHandles.lookup(), Bootstrap.class, "searchConst"); site.setTarget(switchPoint.guardWithTest(target, fallback)); return value; }
: ((DefaultMethod) method).getSignature(); MethodHandle[] guards = new MethodHandle[signature.getParameterCount()]; Arrays.fill(guards, 0, guards.length, Binder.from(boolean.class, IRubyObject.class).drop(0, 1).constant(true)); methodType(boolean.class, CodegenUtils.params(boolean.class, signature.getParameterCount()))); isTrue = Binder.from(boolean.class, CodegenUtils.params(IRubyObject.class, signature.getParameterCount())) .filter(0, guards) .invoke(isTrue); return Binder.from(site.type().changeReturnType(boolean.class)) .drop(0, 3) .invoke(isTrue);
public IRubyObject lexicalSearchConst(ThreadContext context, StaticScope scope) { Ruby runtime = context.runtime; IRubyObject constant = scope.getConstantDefined(name); if (constant == null) { constant = UndefinedValue.UNDEFINED; } SwitchPoint switchPoint = (SwitchPoint) runtime.getConstantInvalidator(name).getData(); // bind constant until invalidated MethodHandle target = Binder.from(type()) .drop(0, 2) .constant(constant); MethodHandle fallback = Binder.from(type()) .insert(0, this) .invokeVirtualQuiet(Bootstrap.LOOKUP, "lexicalSearchConst"); setTarget(switchPoint.guardWithTest(target, fallback)); if (Options.INVOKEDYNAMIC_LOG_CONSTANTS.load()) { LOG.info(name + "\tretrieved and cached from scope (lexicalSearchConst) " + scope.getIRScope());// + " added to PIC" + extractSourceInfo(site)); } return constant; }
int index = accessor.getIndex(); mh = Binder.from(type()) .cast(type().changeParameterType(2, RubyStruct.class)) .permute(2) .append(index) .invokeVirtual(LOOKUP, "get"); int index = mutator.getIndex(); mh = Binder.from(type()) .cast(type().changeParameterType(2, RubyStruct.class)) .permute(2, 3) .append(index) .invokeVirtual(LOOKUP, "set");
private MethodHandle SMFC() { if (_SMFC != null) return _SMFC; return _SMFC = Binder.from(type()) .insert(0, this) .invokeVirtualQuiet(Bootstrap.LOOKUP, "searchModuleForConst"); }
public MethodHandle possiblyDebugGuard(Entry entry, int position, MethodHandle input) throws NoSuchMethodException, IllegalAccessException { if (!debug) { return input; } MethodHandle debugMh = MethodHandles.lookup() .findStatic(LinkPlan.class, "debugGuard", MethodType.methodType(boolean.class, LinkPlan.class, LinkPlan.Entry.class, int.class, MethodHandle.class, Object[].class)); debugMh = Binder.from(input.type()) .convert(input.type().erase()) .collect(0, Object[].class) .insert(0, input) .insert(0, position) .insert(0, entry) .insert(0, this) .invoke(debugMh); return debugMh; }
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); }
private void bind(Ruby runtime, RubyModule module, IRubyObject constant, MethodHandle cachingFallback) { MethodHandle target = Binder.from(type()) .drop(0, 2) .constant(constant); // Get appropriate fallback given state of site MethodHandle fallback = getFallback(module, cachingFallback); // Test that module is same as before target = guardWithTest(module.getIdTest(), target, fallback); // Global invalidation SwitchPoint switchPoint = (SwitchPoint) runtime.getConstantInvalidator(name).getData(); target = switchPoint.guardWithTest(target, fallback); setTarget(target); }
public static CallSite bootstrap(MethodHandles.Lookup lookup, String name, MethodType type, int unwrap) throws Throwable { YieldSite site = new YieldSite(type, unwrap == 1 ? true : false); MethodHandle handle; switch (name) { case "yield": case "yieldSpecific": handle = Binder.from(type) .prepend(YieldSite.class, site) .invokeVirtual(lookup, name); break; case "yieldValues": handle = Binder.from(type) .collect(2, IRubyObject[].class) .prepend(YieldSite.class, site) .invokeVirtual(lookup, name); break; default: throw new RuntimeException("invalid yield type: " + name); } site.setTarget(handle); return site; }