Beispiel #1
0
 @Override
 public void overrideMethod(ClassMethod method, Method superclassMethod) {
   CodeAttribute ca = method.getCodeAttribute();
   if (method.getName().equals("_getProxyInvocationDispatcher")) {
     ca.aload(0);
     ca.getfield(getClassName(), INVOCATION_DISPATCHER_FIELD, InvocationDispatcher.class);
     ca.returnInstruction();
   } else if (method.getName().equals("_setProxyInvocationDispatcher")) {
     ca.aload(0);
     ca.aload(1);
     ca.putfield(getClassName(), INVOCATION_DISPATCHER_FIELD, InvocationDispatcher.class);
     ca.returnInstruction();
   } else {
     throw new RuntimeException("Unkown method on interface " + ProxyInstance.class);
   }
 }
Beispiel #2
0
 // we simply want to load the corresponding identifier
 // and then forward it to the dispatcher
 @Override
 public void overrideMethod(ClassMethod method, Method superclassMethod) {
   CodeAttribute ca = method.getCodeAttribute();
   // first we need to check the constructed field
   ca.aload(0);
   ca.getfield(getClassName(), CONSTRUCTED_GUARD, "Z");
   // if the object has not been constructed yet invoke the superclass version of the method
   BranchEnd end = ca.ifne();
   ca.aload(0);
   ca.loadMethodParameters();
   ca.invokespecial(getSuperClassName(), method.getName(), method.getDescriptor());
   ca.returnInstruction();
   // normal invocation path begins here
   ca.branchEnd(end);
   ca.aload(0);
   ca.getfield(getClassName(), INVOCATION_DISPATCHER_FIELD, InvocationDispatcher.class);
   // now we have the dispatcher on the stack, we need to build an invocation
   ca.newInstruction(Invocation.class.getName());
   ca.dup();
   // the constructor we are using is Invocation(final Class<?> declaringClass, final
   // MethodIdentifier
   // methodIdentifier, final Object... args)
   ca.loadClass(getClassName());
   loadMethodIdentifier(superclassMethod, method);
   // now we need to stick the parameters into an array, boxing if nessesary
   String[] params = method.getParameters();
   ca.iconst(params.length);
   ca.anewarray("java/lang/Object");
   int loadPosition = 1;
   for (int i = 0; i < params.length; ++i) {
     ca.dup();
     ca.iconst(i);
     String type = params[i];
     if (type.length() == 1) { // primitive
       char typeChar = type.charAt(0);
       switch (typeChar) {
         case 'I':
           ca.iload(loadPosition);
           Boxing.boxInt(ca);
           break;
         case 'S':
           ca.iload(loadPosition);
           Boxing.boxShort(ca);
           break;
         case 'B':
           ca.iload(loadPosition);
           Boxing.boxByte(ca);
           break;
         case 'Z':
           ca.iload(loadPosition);
           Boxing.boxBoolean(ca);
           break;
         case 'C':
           ca.iload(loadPosition);
           Boxing.boxChar(ca);
           break;
         case 'D':
           ca.dload(loadPosition);
           Boxing.boxDouble(ca);
           loadPosition++;
           break;
         case 'J':
           ca.lload(loadPosition);
           Boxing.boxLong(ca);
           loadPosition++;
           break;
         case 'F':
           ca.fload(loadPosition);
           Boxing.boxFloat(ca);
           break;
         default:
           throw new RuntimeException("Unkown primitive type descriptor: " + typeChar);
       }
     } else {
       ca.aload(loadPosition);
     }
     ca.aastore();
     loadPosition++;
   }
   ca.invokespecial(
       Invocation.class.getName(),
       "<init>",
       "(Ljava/lang/Class;Lorg/jboss/invocation/MethodIdentifier;[Ljava/lang/Object;)V");
   // now we have the invocation on top of the stack, with the dispatcher below it
   ca.invokeinterface(
       InvocationDispatcher.class.getName(),
       "dispatch",
       "(Lorg/jboss/invocation/Invocation;)Lorg/jboss/invocation/InvocationReply;");
   ca.invokevirtual(InvocationReply.class.getName(), "getReply", "()Ljava/lang/Object;");
   if (superclassMethod.getReturnType() != void.class) {
     if (superclassMethod.getReturnType().isPrimitive()) {
       Boxing.unbox(ca, method.getReturnType());
     } else {
       ca.checkcast(superclassMethod.getReturnType().getName());
     }
   }
   ca.returnInstruction();
 }