/** * Terminate this binder by looking up the named static method on the * given target type. Perform the actual method lookup using the given * Lookup object. * * @param lookup the Lookup to use for handle lookups * @param target the type on which to find the static method * @param name the name of the target static method * @return a SmartHandle with this binder's starting signature, bound * to the target method * @throws NoSuchMethodException if the named method with current signature's types does not exist * @throws IllegalAccessException if the named method is not accessible to the given Lookup */ public SmartHandle invokeStatic(Lookup lookup, Class<?> target, String name) throws NoSuchMethodException, IllegalAccessException { return new SmartHandle(start, binder.invokeStatic(lookup, target, name)); }
.insert(0, site.name) .invokeStatic(MethodHandles.lookup(), Bootstrap.class, "invokeSelfSimple"); .from(site.type().changeReturnType(boolean.class)) .insert(0, new Class[]{RubyClass.class}, selfClass) .invokeStatic(MethodHandles.lookup(), Bootstrap.class, "testType"); mh = MethodHandles.guardWithTest(test, mh, fallback); mh = switchPoint.guardWithTest(mh, fallback);
.insert(0, site.name) .invokeStatic(MethodHandles.lookup(), Bootstrap.class, "invokeSelfSimple"); .from(site.type().changeReturnType(boolean.class)) .insert(0, new Class[]{RubyClass.class}, selfClass) .invokeStatic(MethodHandles.lookup(), Bootstrap.class, "testType"); mh = MethodHandles.guardWithTest(test, mh, fallback); mh = switchPoint.guardWithTest(mh, fallback);
/** * Apply the chain of transforms and bind them to a static method specified * using the end signature plus the given class and name. The method will * be retrieved using the given Lookup and must match the end signature * exactly. * * If the final handle's type does not exactly match the initial type for * this Binder, an additional cast will be attempted. * * This version is "quiet" in that it throws an unchecked InvalidTransformException * if the target method does not exist or is inaccessible. * * @param lookup the MethodHandles.Lookup to use to look up the method * @param target the class in which to find the method * @param name the name of the method to invoke * @return the full handle chain, bound to the given method */ public MethodHandle invokeStaticQuiet(MethodHandles.Lookup lookup, Class<?> target, String name) { try { return invokeStatic(lookup, target, name); } catch (IllegalAccessException | NoSuchMethodException e) { throw new InvalidTransformException(e); } }
public static CallSite contextFieldBootstrap(Lookup lookup, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException { MutableCallSite site = new MutableCallSite(type); if (name.equals("nil")) { site.setTarget(Binder.from(type).insert(0, site).invokeStatic(lookup, InvokeDynamicSupport.class, "loadNil")); } else if (name.equals("runtime")) { site.setTarget(Binder.from(type).insert(0, site).invokeStatic(lookup, InvokeDynamicSupport.class, "loadRuntime")); } return site; }
public static CallSite contextFieldBootstrap(Lookup lookup, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException { MutableCallSite site = new MutableCallSite(type); if (name.equals("nil")) { site.setTarget(Binder.from(type).insert(0, site).invokeStatic(lookup, InvokeDynamicSupport.class, "loadNil")); } else if (name.equals("runtime")) { site.setTarget(Binder.from(type).insert(0, site).invokeStatic(lookup, InvokeDynamicSupport.class, "loadRuntime")); } return site; }
public static IRubyObject inheritanceSearchConst(MutableCallSite site, String constName, ThreadContext context, IRubyObject cmVal) throws Throwable { Ruby runtime = context.runtime; RubyModule module; if (cmVal instanceof RubyModule) { module = (RubyModule) cmVal; } else { throw runtime.newTypeError(cmVal + " is not a type/class"); } SwitchPoint switchPoint = (SwitchPoint)runtime.getConstantInvalidator(constName).getData(); IRubyObject value = module.getConstantFromNoConstMissing(constName, false); if (value == null) { return (IRubyObject)UndefinedValue.UNDEFINED; } // 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, "inheritanceSearchConst"); site.setTarget(switchPoint.guardWithTest(target, fallback)); return value; }
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; }
public static IRubyObject inheritanceSearchConst(MutableCallSite site, String constName, ThreadContext context, IRubyObject cmVal) throws Throwable { Ruby runtime = context.runtime; RubyModule module; if (cmVal instanceof RubyModule) { module = (RubyModule) cmVal; } else { throw runtime.newTypeError(cmVal + " is not a type/class"); } SwitchPoint switchPoint = (SwitchPoint)runtime.getConstantInvalidator(constName).getData(); IRubyObject value = module.getConstantFromNoConstMissing(constName, false); if (value == null) { return (IRubyObject)UndefinedValue.UNDEFINED; } // 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, "inheritanceSearchConst"); site.setTarget(switchPoint.guardWithTest(target, fallback)); return value; }
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; }