Пример #1
0
  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);
  }
Пример #4
0
 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;
  }
Пример #7
0
  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();
  }