private void analyze(Class<?> cls, boolean topLevel) { if (!Modifier.isPublic(cls.getModifiers())) { return; } Lookup lookup = MethodHandles.lookup(); if (topLevel) { this.constructor = new DynamicConstructor(getCoercionMatrix()); Constructor<?>[] constructors = cls.getConstructors(); for (int i = 0; i < constructors.length; ++i) { try { this.constructor.addConstructorHandle(lookup.unreflectConstructor(constructors[i])); } catch (IllegalAccessException e) { } } } Method[] methods = getTargetClass().getMethods(); for (int i = 0; i < methods.length; ++i) { int modifiers = methods[i].getModifiers(); if (Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers)) { analyzeMethod(methods[i]); } } Field[] fields = getTargetClass().getFields(); for (int i = 0; i < fields.length; ++i) { int modifiers = fields[i].getModifiers(); if (Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers)) { analyzeField(fields[i]); } } if (cls.getSuperclass() != null) { analyze(cls.getSuperclass(), false); } Class<?>[] interfaces = cls.getInterfaces(); for (int i = 0; i < interfaces.length; ++i) { analyze(interfaces[i], false); } Class<?>[] innerClasses = cls.getDeclaredClasses(); for (int i = 0; i < innerClasses.length; ++i) { int modifiers = innerClasses[i].getModifiers(); if (Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers)) { this.propertyReaders.put( innerClasses[i].getSimpleName(), MethodHandles.constant(Class.class, innerClasses[i])); } } }
private static boolean lookupsEqual(Lookup l1, Lookup l2) { if (l1 == l2) { return true; } if (l1.lookupClass() != l2.lookupClass()) { return false; } return l1.lookupModes() == l2.lookupModes(); }
// warning ! stolen code ahead ! (http://code.google.com/p/jsr292-cookbook) public static CallSite myBSM(Lookup lookup, String name, MethodType type, Class<?> staticType) throws ReflectiveOperationException { MethodHandle target = lookup.findStatic(staticType, name, type); HashMap<String, HashMap<Object, Object>> cacheTable = cacheTables.get(staticType); String selector = name + type.toMethodDescriptorString(); HashMap<Object, Object> cache = cacheTable.get(selector); if (cache == null) { cache = new HashMap<Object, Object>(); cacheTable.put(selector, cache); } MethodHandle identity = MethodHandles.identity(type.returnType()); identity = identity.asType(identity.type().changeParameterType(0, Object.class)); identity = MethodHandles.dropArguments(identity, 1, type.parameterType(0)); MethodHandle update = UPDATE.bindTo(cache); update = update.asType(type.insertParameterTypes(0, type.returnType())); MethodHandle fallback = MethodHandles.foldArguments(update, target); fallback = MethodHandles.dropArguments(fallback, 0, Object.class); MethodHandle combiner = MethodHandles.guardWithTest(NOT_NULL, identity, fallback); MethodHandle cacheQuerier = MAP_GET.bindTo(cache); cacheQuerier = cacheQuerier.asType(MethodType.methodType(Object.class, type.parameterType(0))); MethodHandle memoize = MethodHandles.foldArguments(combiner, cacheQuerier); return new ConstantCallSite(memoize); }
private static MethodHandle findStatic( Lookup lookup, Class target, String name, MethodType type) { try { return lookup.findStatic(target, name, type); } catch (Exception e) { throw new RuntimeException(e); } }
static { Lookup lookup = MethodHandles.lookup(); try { NOT_NULL = lookup.findStatic( SpeedRecurenceWithIndyUsingBigInteger.class, "notNull", MethodType.methodType(boolean.class, Object.class)); MAP_GET = lookup.findVirtual( HashMap.class, "get", MethodType.methodType(Object.class, Object.class)); UPDATE = lookup.findStatic( SpeedRecurenceWithIndyUsingBigInteger.class, "update", MethodType.methodType(Object.class, HashMap.class, Object.class, Object.class)); } catch (ReflectiveOperationException e) { throw (AssertionError) new AssertionError().initCause(e); } }
public void giveLookup(Lookup lookup) { final Class<?> caller = PMLSecurityManager.getStackClass(3); final Class<?> lookedup = lookup.lookupClass(); if (!caller.equals(lookedup)) throw new IllegalStateException(); final String name = caller.getName(); if (!this.aboutClass.equals(name)) throw new IllegalStateException(); if (this.myLookup != null) throw new IllegalStateException(); this.myLookup = lookup; this.self = caller; }
public static CallSite ivar(Lookup lookup, String name, MethodType type) throws Throwable { String[] names = name.split(":"); String operation = names[0]; String varName = names[1]; VariableSite site = new VariableSite(type, varName, "noname", 0); MethodHandle handle; handle = lookup.findStatic( Bootstrap.class, operation, type.insertParameterTypes(0, VariableSite.class)); handle = handle.bindTo(site); site.setTarget(handle.asType(site.type())); return site; }
private static Map<QName, MethodHandle> createInvokerMap( final Class<? extends NotificationListener> key) { final Builder<QName, MethodHandle> ret = ImmutableMap.<QName, MethodHandle>builder(); for (final Method method : key.getMethods()) { if (BindingReflections.isNotificationCallback(method)) { final Class<?> notification = method.getParameterTypes()[0]; final QName name = BindingReflections.findQName(notification); MethodHandle handle; try { handle = LOOKUP .unreflect(method) .asType( MethodType.methodType( void.class, NotificationListener.class, DataContainer.class)); ret.put(name, handle); } catch (final IllegalAccessException e) { throw new IllegalStateException("Can not access public method.", e); } } } return ret.build(); }