private MethodHandle makeGetMethodHandle() { try { if (Modifier.isStatic(field.getModifiers())) { MethodHandle getter = MethodHandles.publicLookup().findStaticGetter(field.getDeclaringClass(), field.getName(), field.getType()); return MethodHandles.dropArguments(getter.asType(MethodType.methodType(Object.class)), 0, Object.class); } else { MethodHandle getter = MethodHandles.publicLookup().findGetter(field.getDeclaringClass(), field.getName(), field.getType()); return getter.asType(MethodType.methodType(Object.class, Object.class)); } } catch (NoSuchFieldException | IllegalAccessException e) { throw new IllegalStateException(e); } }
private MethodHandle makeGetMethodHandle() { try { if (Modifier.isStatic(field.getModifiers())) { MethodHandle getter = MethodHandles.publicLookup().findStaticGetter(field.getDeclaringClass(), field.getName(), field.getType()); return MethodHandles.dropArguments(getter.asType(MethodType.methodType(Object.class)), 0, Object.class); } else { MethodHandle getter = MethodHandles.publicLookup().findGetter(field.getDeclaringClass(), field.getName(), field.getType()); return getter.asType(MethodType.methodType(Object.class, Object.class)); } } catch (NoSuchFieldException | IllegalAccessException e) { throw new IllegalStateException(e); } }
public static <T, U> MethodHandle field( Class<T> parentClass, Class<U> fieldClass, String name) { try { return LOOKUP.findGetter( parentClass, name, fieldClass); } catch (NoSuchFieldException | IllegalAccessException e) { throw new Error(e); } }
MethodHandles.publicLookup(); fh = lookup.findGetter(mc, name, jType);
klass.getVariableTableManager().getVariableAccessorForVar( name, LOOKUP.findGetter(cna.cls, "var" + offset, Object.class), LOOKUP.findSetter(cna.cls, "var" + offset, Object.class)); offset++;
int offset = ((FieldVariableAccessor)accessor).getOffset(); Class cls = REIFIED_OBJECT_CLASSES[offset]; getValue = lookup().findGetter(cls, "var" + offset, Object.class); getValue = explicitCastArguments(getValue, methodType(Object.class, IRubyObject.class)); } else {
int offset = ((FieldVariableAccessor)accessor).getOffset(); Class cls = REIFIED_OBJECT_CLASSES[offset]; getValue = lookup().findGetter(cls, "var" + offset, Object.class); getValue = explicitCastArguments(getValue, methodType(Object.class, IRubyObject.class)); } else {
klass.getVariableTableManager().getVariableAccessorForVar( name, LOOKUP.findGetter(cna.cls, "var" + offset, Object.class), LOOKUP.findSetter(cna.cls, "var" + offset, Object.class)); offset++;
mhsb = new ConstantCallSite(lookup.findSetter(Container.class, "b", Integer.TYPE)); mhsc = new ConstantCallSite(lookup.findSetter(Container.class, "c", Short.TYPE)); mhga = new ConstantCallSite(lookup.findGetter(Container.class, "a", Long.TYPE)); mhgb = new ConstantCallSite(lookup.findGetter(Container.class, "b", Integer.TYPE)); mhgc = new ConstantCallSite(lookup.findGetter(Container.class, "c", Short.TYPE)); } catch (Exception ex) {
/** * Performs a {@link java.lang.invoke.MethodHandles.Lookup#findGetter(Class, String, Class)}, converting any * encountered {@link IllegalAccessException} into an {@link IllegalAccessError} and {@link NoSuchFieldException} * into a {@link NoSuchFieldError}. * * @param refc the class declaring the field * @param name the name of the field * @param type the type of the field * @return the unreflected field getter handle. * @throws IllegalAccessError if the field is inaccessible. * @throws NoSuchFieldError if the field does not exist. */ public MethodHandle findGetter(Class<?>refc, String name, Class<?> type) { try { return lookup.findGetter(refc, name, type); } catch(IllegalAccessException e) { final IllegalAccessError ee = new IllegalAccessError("Failed to access getter for field " + refc.getName() + "." + name + " of type " + type.getName()); ee.initCause(e); throw ee; } catch(NoSuchFieldException e) { final NoSuchFieldError ee = new NoSuchFieldError("Failed to find getter for field " + refc.getName() + "." + name + " of type " + type.getName()); ee.initCause(e); throw ee; } }
/** * Performs a {@link java.lang.invoke.MethodHandles.Lookup#findGetter(Class, String, Class)}, converting any * encountered {@link IllegalAccessException} into an {@link IllegalAccessError} and {@link NoSuchFieldException} * into a {@link NoSuchFieldError}. * * @param refc the class declaring the field * @param name the name of the field * @param type the type of the field * @return the unreflected field getter handle. * @throws IllegalAccessError if the field is inaccessible. * @throws NoSuchFieldError if the field does not exist. */ public MethodHandle findGetter(final Class<?>refc, final String name, final Class<?> type) { try { return lookup.findGetter(refc, name, type); } catch(final IllegalAccessException e) { final IllegalAccessError ee = new IllegalAccessError("Failed to access getter for field " + refc.getName() + "." + name + " of type " + type.getName()); ee.initCause(e); throw ee; } catch(final NoSuchFieldException e) { final NoSuchFieldError ee = new NoSuchFieldError("Failed to find getter for field " + refc.getName() + "." + name + " of type " + type.getName()); ee.initCause(e); throw ee; } }
/** * Apply the chain of transforms and bind them to an object field retrieval specified * using the end signature plus the given class and name. The field must * match the end signature's return value and the end signature must take * the target class or a subclass as its only argument. * * If the final handle's type does not exactly match the initial type for * this Binder, an additional cast will be attempted. * * @param lookup the MethodHandles.Lookup to use to look up the field * @param name the field's name * @return the full handle chain, bound to the given field access * @throws java.lang.NoSuchFieldException if the field does not exist * @throws java.lang.IllegalAccessException if the field is not accessible * @throws java.lang.NoSuchFieldException if the field does not exist * @throws java.lang.IllegalAccessException if the field is not accessible */ public MethodHandle getField(MethodHandles.Lookup lookup, String name) throws NoSuchFieldException, IllegalAccessException { return invoke(lookup.findGetter(type().parameterType(0), name, type().returnType())); }
@Override protected MethodHandle findAccess(Class receiverClass) throws NoSuchFieldException, IllegalAccessException { return lookup.findGetter(receiverClass, selector, getFieldType(receiverClass)); } }
public static <T, U> MethodHandle field( Class<T> parentClass, Class<U> fieldClass, String name) { try { return LOOKUP.findGetter( parentClass, name, fieldClass); } catch (NoSuchFieldException | IllegalAccessException e) { throw new Error(e); } }
@Override public CallSite getField(Lookup caller, String fieldName, Class<?> fieldType, Class<?> owner) throws ReflectiveOperationException { try { return new ConstantCallSite(caller.findGetter(owner, fieldName, fieldType)); } catch (ReflectiveOperationException e) { return null; } }
@Test public void testFieldTypeChange() throws Throwable { A a = new A(); MethodHandle getter = MethodHandles.publicLookup().findGetter(A.class, "fieldA", int.class); MethodHandle setter = MethodHandles.publicLookup().findSetter(A.class, "fieldA", int.class); a.fieldA = 3; assertEquals(3, getter.invoke(a)); // Remove fieldA __toVersion__(3); try { getter.invoke(a); Assert.fail("Handle should have been cleared!"); } catch (NullPointerException e) { // Handle was cleared! } try { setter.invoke(a, 10); Assert.fail("Handle should have been cleared!"); } catch (NullPointerException e) { // Handle was cleared! } } }
@Test public void testFieldRemoved() throws Throwable { A a = new A(); MethodHandle getter = MethodHandles.publicLookup().findGetter(A.class, "fieldA", int.class); MethodHandle setter = MethodHandles.publicLookup().findSetter(A.class, "fieldA", int.class); a.fieldA = 3; assertEquals(3, getter.invoke(a)); // Remove fieldA __toVersion__(2); try { getter.invoke(a); Assert.fail("Handle should have been cleared!"); } catch (NullPointerException e) { // Handle was cleared! } try { setter.invoke(a, 10); Assert.fail("Handle should have been cleared!"); } catch (NullPointerException e) { // Handle was cleared! } }
@Test public void testFieldChangeOrder() throws Throwable { A a = new A(); MethodHandle getter = MethodHandles.publicLookup().findGetter(A.class, "fieldA", int.class); MethodHandle setter = MethodHandles.publicLookup().findSetter(A.class, "fieldA", int.class); a.fieldA = 3; assertEquals(3, getter.invoke(a)); // Swap fields __toVersion__(1); assertEquals(3, getter.invoke(a)); setter.invoke(a, 53); assertEquals(53, a.getFieldA()); assertEquals(53, getter.invoke(a)); }