private void injectCode(MethodInfo methodInfo) throws IOException {
    if (methodInfo.getCode() == null) {
      return;
    }

    InterceptorConstants interceptorConstants =
        getOrInsertInterceptorConstants(methodInfo.getInterceptorClass());

    fixupSignature(methodInfo.getSignature());

    Map<String, Integer> wrapperMethods =
        getOrInsertPrimitiveWrapperMethods(methodInfo.getSignature());

    ByteArrayOutputStream codeToInject = new ByteArrayOutputStream();
    InstructionsFacility instructionsFacility =
        new InstructionsFacility(
            new DataOutputStream(codeToInject),
            methodInfo.getSignature(),
            interceptorConstants,
            wrapperMethods);

    instructionsFacility.generateInterceptorInstantiationCode();

    instructionsFacility.generateInterceptorMethodParametersCode(getObjectClassIndex());

    instructionsFacility.generateObjectArrayFillingCode();

    instructionsFacility.generateInterceptorInvocationCode(
        interceptorConstants.getInterceptorMethod());

    Code code = methodInfo.getCode();

    int originalStackSize = code.getMaxStack();
    code.setMaxStack(Math.max(originalStackSize, instructionsFacility.getStackSizeNeeded()));

    code.setInjected(codeToInject.toByteArray());
    code.refresh();
  }
  public void generate(ClassEmitter ce, Context context, List methods) {
    for (Iterator it = methods.iterator(); it.hasNext(); ) {
      MethodInfo method = (MethodInfo) it.next();
      Signature impl = context.getImplSignature(method);
      ce.declare_field(Constants.PRIVATE_FINAL_STATIC, impl.getName(), METHOD, null);

      CodeEmitter e = context.beginMethod(ce, method);
      Block handler = e.begin_block();
      context.emitCallback(e, context.getIndex(method));
      e.load_this();
      e.getfield(impl.getName());
      e.create_arg_array();
      e.invoke_interface(INVOCATION_HANDLER, INVOKE);
      e.unbox(method.getSignature().getReturnType());
      e.return_value();
      handler.end();
      EmitUtils.wrap_undeclared_throwable(
          e, handler, method.getExceptionTypes(), UNDECLARED_THROWABLE_EXCEPTION);
      e.end_method();
    }
  }
Exemple #3
0
 private void generateSet(final Class target, final Method[] setters) {
     // setPropertyValues
     CodeEmitter e = begin_method(Constants.ACC_PUBLIC, SET_PROPERTY_VALUES, null);
     if (setters.length > 0) {
         Local index = e.make_local(Type.INT_TYPE);
         e.push(0);
         e.store_local(index);
         e.load_arg(0);
         e.checkcast(Type.getType(target));
         e.load_arg(1);
         Block handler = e.begin_block();
         int lastIndex = 0;
         for (int i = 0; i < setters.length; i++) {
             if (setters[i] != null) {
                 MethodInfo setter = ReflectUtils.getMethodInfo(setters[i]);
                 int diff = i - lastIndex;
                 if (diff > 0) {
                     e.iinc(index, diff);
                     lastIndex = i;
                 }
                 e.dup2();
                 e.aaload(i);
                 e.unbox(setter.getSignature().getArgumentTypes()[0]);
                 e.invoke(setter);
             }
         }
         handler.end();
         e.return_value();
         e.catch_exception(handler, Constants.TYPE_THROWABLE);
         e.new_instance(BULK_BEAN_EXCEPTION);
         e.dup_x1();
         e.swap();
         e.load_local(index);
         e.invoke_constructor(BULK_BEAN_EXCEPTION, CSTRUCT_EXCEPTION);
         e.athrow();
     } else {
         e.return_value();
     }
     e.end_method();
 }
Exemple #4
0
 private void generateGet(final Class target, final Method[] getters) {
     CodeEmitter e = begin_method(Constants.ACC_PUBLIC, GET_PROPERTY_VALUES, null);
     if (getters.length >= 0) {
         e.load_arg(0);
         e.checkcast(Type.getType(target));
         Local bean = e.make_local();
         e.store_local(bean);
         for (int i = 0; i < getters.length; i++) {
             if (getters[i] != null) {
                 MethodInfo getter = ReflectUtils.getMethodInfo(getters[i]);
                 e.load_arg(1);
                 e.push(i);
                 e.load_local(bean);
                 e.invoke(getter);
                 e.box(getter.getSignature().getReturnType());
                 e.aastore();
             }
         }
     }
     e.return_value();
     e.end_method();
 }
 public static boolean isConstructor(final MethodInfo method) {
   return method.getSignature().getName().equals(Constants.CONSTRUCTOR_NAME);
 }
    public void generateClass(ClassVisitor v) throws NoSuchMethodException {
      Method proxy = ReflectUtils.findInterfaceMethod(iface);
      final Method method = targetClass.getMethod(methodName, proxy.getParameterTypes());
      if (!proxy.getReturnType().isAssignableFrom(method.getReturnType())) {
        throw new IllegalArgumentException("incompatible return types");
      }

      MethodInfo methodInfo = ReflectUtils.getMethodInfo(method);

      boolean isStatic = TypeUtils.isStatic(methodInfo.getModifiers());
      if ((target == null) ^ isStatic) {
        throw new IllegalArgumentException(
            "Static method " + (isStatic ? "not " : "") + "expected");
      }

      ClassEmitter ce = new ClassEmitter(v);
      CodeEmitter e;
      ce.begin_class(
          Constants.V1_2,
          Constants.ACC_PUBLIC,
          getClassName(),
          METHOD_DELEGATE,
          new Type[] {Type.getType(iface)},
          Constants.SOURCE_FILE);
      ce.declare_field(Constants.PRIVATE_FINAL_STATIC, "eqMethod", Constants.TYPE_STRING, null);
      EmitUtils.null_constructor(ce);

      // generate proxied method
      MethodInfo proxied = ReflectUtils.getMethodInfo(iface.getDeclaredMethods()[0]);
      int modifiers = Constants.ACC_PUBLIC;
      if ((proxied.getModifiers() & Constants.ACC_VARARGS) == Constants.ACC_VARARGS) {
        modifiers |= Constants.ACC_VARARGS;
      }
      e = EmitUtils.begin_method(ce, proxied, modifiers);
      e.load_this();
      e.super_getfield("target", Constants.TYPE_OBJECT);
      e.checkcast(methodInfo.getClassInfo().getType());
      e.load_args();
      e.invoke(methodInfo);
      e.return_value();
      e.end_method();

      // newInstance
      e = ce.begin_method(Constants.ACC_PUBLIC, NEW_INSTANCE, null);
      e.new_instance_this();
      e.dup();
      e.dup2();
      e.invoke_constructor_this();
      e.getfield("eqMethod");
      e.super_putfield("eqMethod", Constants.TYPE_STRING);
      e.load_arg(0);
      e.super_putfield("target", Constants.TYPE_OBJECT);
      e.return_value();
      e.end_method();

      // static initializer
      e = ce.begin_static();
      e.push(methodInfo.getSignature().toString());
      e.putfield("eqMethod");
      e.return_value();
      e.end_method();

      ce.end_class();
    }