/** * Terminate this binder by looking up the named virtual method on the * first argument's type. Perform the actual method lookup using the given * Lookup object. * * @param lookup the Lookup to use for handle lookups * @param name the name of the target virtual 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 invokeVirtual(Lookup lookup, String name) throws NoSuchMethodException, IllegalAccessException { return new SmartHandle(start, binder.invokeVirtual(lookup, name)); }
.invokeVirtual(MethodHandles.lookup(), "call");
/** * Apply the chain of transforms and bind them to a virtual 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 name the name of the method to invoke * @return the full handle chain, bound to the given method */ public MethodHandle invokeVirtualQuiet(MethodHandles.Lookup lookup, String name) { try { return invokeVirtual(lookup, name); } catch (IllegalAccessException | NoSuchMethodException e) { throw new InvalidTransformException(e); } }
.invokeVirtual(MethodHandles.lookup(), "call");
public MethodHandle getBootstrapMethodHandle() throws NoSuchMethodException, IllegalAccessException { Lookup lookup = MethodHandles.lookup(); return Binder.from(CallSite.class, Lookup.class, String.class, MethodType.class) .insert(0, this) .invokeVirtual(lookup, "bootstrap"); }
protected void addArrayCoercion(int distance, Class<?> toType, Class<?> fromType, ArrayCoercer arrayCoercer) throws IllegalAccessException, NoSuchMethodException { Lookup lookup = MethodHandles.lookup(); String coerceMethod = "coerceToObjectInternal"; if (toType.equals(boolean[].class)) { coerceMethod = "coerceToBoolean"; } else if (toType.equals(byte[].class)) { coerceMethod = "coerceToByte"; } else if (toType.equals(char[].class)) { coerceMethod = "coerceToChar"; } else if (toType.equals(double[].class)) { coerceMethod = "coerceToDouble"; } else if (toType.equals(float[].class)) { coerceMethod = "coerceToFloat"; } else if (toType.equals(int[].class)) { coerceMethod = "coerceToInt"; } else if (toType.equals(long[].class)) { coerceMethod = "coerceToLong"; } else if (toType.equals(short[].class)) { coerceMethod = "coerceToShort"; } MethodHandle filter = Binder.from(toType, Object.class) .insert(0, arrayCoercer) .invokeVirtual(lookup, coerceMethod); this.arrayCoercions.add(new ArrayCoercionEntry(distance, filter, fromType, toType, arrayCoercer)); }
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; }
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; }
.permute(2) .append(index) .invokeVirtual(LOOKUP, "get"); .permute(2, 3) .append(index) .invokeVirtual(LOOKUP, "set");
.permute(2) .append(index) .invokeVirtual(LOOKUP, "get"); .permute(2, 3) .append(index) .invokeVirtual(LOOKUP, "set");