Пример #1
0
  public void atVariable(Variable v) throws CompileError {
    Declarator d = v.getDeclarator();
    exprType = d.getType();
    arrayDim = d.getArrayDim();
    className = d.getClassName();
    int var = getLocalVar(d);

    if (arrayDim > 0) bytecode.addAload(var);
    else
      switch (exprType) {
        case CLASS:
          bytecode.addAload(var);
          break;
        case LONG:
          bytecode.addLload(var);
          break;
        case FLOAT:
          bytecode.addFload(var);
          break;
        case DOUBLE:
          bytecode.addDload(var);
          break;
        default: // BOOLEAN, BYTE, CHAR, SHORT, INT
          bytecode.addIload(var);
          break;
      }
  }
Пример #2
0
 private Bytecode createAbstractMethodCode(ClassFile file, MethodInformation method)
     throws NotFoundException {
   if ((delegateField != null) && (!Modifier.isPrivate(delegateField.getModifiers()))) {
     // Call the corresponding method directly on the delegate
     Bytecode b = new Bytecode(file.getConstPool());
     int localVariables = MethodUtils.calculateMaxLocals(method.getMethod());
     b.setMaxLocals(localVariables);
     // load the delegate field
     b.addAload(0);
     b.addGetfield(
         file.getName(),
         delegateField.getName(),
         DescriptorUtils.classToStringRepresentation(delegateField.getType()));
     // load the parameters
     BytecodeUtils.loadParameters(b, method.getDescriptor());
     // invoke the delegate method
     b.addInvokeinterface(
         delegateField.getType().getName(),
         method.getName(),
         method.getDescriptor(),
         localVariables);
     // return the value if applicable
     BytecodeUtils.addReturnInstruction(b, method.getReturnType());
     return b;
   } else {
     if (!Modifier.isPrivate(method.getMethod().getModifiers())) {
       // if it is a parameter injection point we need to initalize the
       // injection point then handle the method with the method handler
       return createAbstractMethodHandler(file, method);
     } else {
       // if the delegate is private we need to use the method handler
       return createInterceptorBody(file, method);
     }
   }
 }
Пример #3
0
  public void atKeyword(Keyword k) throws CompileError {
    arrayDim = 0;
    int token = k.get();
    switch (token) {
      case TRUE:
        bytecode.addIconst(1);
        exprType = BOOLEAN;
        break;
      case FALSE:
        bytecode.addIconst(0);
        exprType = BOOLEAN;
        break;
      case NULL:
        bytecode.addOpcode(ACONST_NULL);
        exprType = NULL;
        break;
      case THIS:
      case SUPER:
        if (inStaticMethod)
          throw new CompileError("not-available: " + (token == THIS ? "this" : "super"));

        bytecode.addAload(0);
        exprType = CLASS;
        if (token == THIS) className = getThisName();
        else className = getSuperName();
        break;
      default:
        fatal();
    }
  }
Пример #4
0
  /**
   * Creates a public setter method. The setter method assigns the value of the first parameter to
   * the specified field in the class to which this method is added. The created method is not
   * static even if the field is static. You may not change it to be static by <code>setModifiers()
   * </code> in <code>CtBehavior</code>.
   *
   * @param methodName the name of the setter
   * @param field the field accessed.
   */
  public static CtMethod setter(String methodName, CtField field) throws CannotCompileException {
    FieldInfo finfo = field.getFieldInfo2();
    String fieldType = finfo.getDescriptor();
    String desc = "(" + fieldType + ")V";
    ConstPool cp = finfo.getConstPool();
    MethodInfo minfo = new MethodInfo(cp, methodName, desc);
    minfo.setAccessFlags(AccessFlag.PUBLIC);

    Bytecode code = new Bytecode(cp, 3, 3);
    try {
      String fieldName = finfo.getName();
      if ((finfo.getAccessFlags() & AccessFlag.STATIC) == 0) {
        code.addAload(0);
        code.addLoad(1, field.getType());
        code.addPutfield(Bytecode.THIS, fieldName, fieldType);
      } else {
        code.addLoad(1, field.getType());
        code.addPutstatic(Bytecode.THIS, fieldName, fieldType);
      }

      code.addReturn(null);
    } catch (NotFoundException e) {
      throw new CannotCompileException(e);
    }

    minfo.setCodeAttribute(code.toCodeAttribute());
    return new CtMethod(minfo, field.getDeclaringClass());
  }
Пример #5
0
  /**
   * When creates the delegate initializer code when the delegate is injected into a method.
   *
   * <p>super initializer method is called first, and then _initMH is called
   *
   * @param file
   * @param intializerMethodInfo
   * @param delegateParameterPosition
   * @return
   */
  private Bytecode createDelegateInitializerCode(
      ClassFile file, MethodInformation intializerMethodInfo, int delegateParameterPosition) {
    Bytecode b = new Bytecode(file.getConstPool());
    // we need to push all the pareters on the stack to call the corresponding
    // superclass arguments
    b.addAload(0); // load this
    int localVariables = 1;
    int actualDelegateParamterPosition = 0;
    for (int i = 0; i < intializerMethodInfo.getMethod().getParameterTypes().length; ++i) {
      if (i == delegateParameterPosition) {
        // figure out the actual position of the delegate in the local
        // variables
        actualDelegateParamterPosition = localVariables;
      }
      Class<?> type = intializerMethodInfo.getMethod().getParameterTypes()[i];
      BytecodeUtils.addLoadInstruction(
          b, DescriptorUtils.classToStringRepresentation(type), localVariables);
      if (type == long.class || type == double.class) {
        localVariables = localVariables + 2;
      } else {
        localVariables++;
      }
    }
    b.addInvokespecial(
        file.getSuperclass(), intializerMethodInfo.getName(), intializerMethodInfo.getDescriptor());
    // if this method returns a value it is now sitting on top of the stack
    // we will leave it there are return it later

    // now we need to call _initMH
    b.addAload(0); // load this
    b.addAload(actualDelegateParamterPosition); // load the delegate
    b.addInvokevirtual(file.getName(), "_initMH", "(Ljava/lang/Object;)V");
    // return the object from the top of the stack that we got from calling
    // the superclass method earlier
    BytecodeUtils.addReturnInstruction(b, intializerMethodInfo.getReturnType());
    b.setMaxLocals(localVariables);
    return b;
  }
 /**
  * Client proxies are equal to other client proxies for the same bean.
  *
  * <p>The corresponding java code: <code>
  * return other instanceof MyProxyClassType.class
  * </code>
  */
 @Override
 protected MethodInfo generateEqualsMethod(ClassFile proxyClassType) {
   MethodInfo method =
       new MethodInfo(proxyClassType.getConstPool(), "equals", "(Ljava/lang/Object;)Z");
   method.setAccessFlags(AccessFlag.PUBLIC);
   Bytecode b = new Bytecode(proxyClassType.getConstPool());
   b.addAload(1);
   b.addInstanceof(proxyClassType.getName());
   b.add(Opcode.IRETURN);
   b.setMaxLocals(2);
   b.setMaxStack(1);
   method.setCodeAttribute(b.toCodeAttribute());
   return method;
 }
  @Override
  public boolean transform(
      ClassLoader loader,
      String className,
      Class<?> classBeingRedefined,
      ProtectionDomain protectionDomain,
      ClassFile file)
      throws IllegalClassFormatException, BadBytecode {

    /**
     * Hack up the proxy factory so it stores the proxy ClassFile. We need this to regenerate
     * proxies.
     */
    if (file.getName().equals("org.jboss.weld.bean.proxy.ProxyFactory")) {
      for (final MethodInfo method : (List<MethodInfo>) file.getMethods()) {
        if (method.getName().equals("createProxyClass")) {
          final MethodInvokationManipulator methodInvokationManipulator =
              new MethodInvokationManipulator();
          methodInvokationManipulator.replaceVirtualMethodInvokationWithStatic(
              ClassLoader.class.getName(),
              WeldProxyClassLoadingDelegate.class.getName(),
              "loadClass",
              "(Ljava/lang/String;)Ljava/lang/Class;",
              "(Ljava/lang/ClassLoader;Ljava/lang/String;)Ljava/lang/Class;",
              loader);
          methodInvokationManipulator.replaceVirtualMethodInvokationWithStatic(
              "org.jboss.weld.util.bytecode.ClassFileUtils",
              WeldProxyClassLoadingDelegate.class.getName(),
              "toClass",
              "(Ljavassist/bytecode/ClassFile;Ljava/lang/ClassLoader;Ljava/security/ProtectionDomain;)Ljava/lang/Class;",
              "(Ljavassist/bytecode/ClassFile;Ljava/lang/ClassLoader;Ljava/security/ProtectionDomain;)Ljava/lang/Class;",
              loader);
          HashSet<MethodInfo> modifiedMethods = new HashSet<MethodInfo>();
          methodInvokationManipulator.transformClass(file, loader, true, modifiedMethods);
          for (MethodInfo m : modifiedMethods) {
            m.rebuildStackMap(ClassPool.getDefault());
          }
          return true;
        } else if (method.getName().equals("<init>")) {

          Integer beanArgument = null;
          int count = 0;
          for (final String paramType :
              DescriptorUtils.descriptorStringToParameterArray(method.getDescriptor())) {
            if (paramType.equals("javax/enterprise/inject/spi/Bean")) {
              beanArgument = count;
              break;
            } else if (paramType.equals("D") || paramType.equals("J")) {
              count += 2;
            } else {
              count++;
            }
          }
          if (beanArgument == null) {
            log.error(
                "Constructor org.jboss.weld.bean.proxy.ProxyFactory.<init>"
                    + method.getDescriptor()
                    + " does not have a bean parameter, proxies produced by this factory will not be reloadable");
            continue;
          }

          // similar to other tracked instances
          // but we need a strong ref
          Bytecode code = new Bytecode(file.getConstPool());
          code.addAload(0);
          code.addAload(beanArgument);
          code.addInvokestatic(
              WeldClassChangeAware.class.getName(),
              "addProxyFactory",
              "(Lorg/jboss/weld/bean/proxy/ProxyFactory;)V");
          CodeIterator it = method.getCodeAttribute().iterator();
          it.skipConstructor();
          it.insert(code.get());
        }
      }
    }
    return false;
  }
  /** Add a method to a class that simply delegates to the parent implementation of the method */
  public static void addDelegatingMethod(ClassFile file, MethodData mData)
      throws BadBytecode, DuplicateMemberException {
    MethodInfo m =
        new MethodInfo(file.getConstPool(), mData.getMethodName(), mData.getDescriptor());
    m.setAccessFlags(mData.getAccessFlags());
    Bytecode code = new Bytecode(file.getConstPool());

    String[] params = DescriptorUtils.descriptorStringToParameterArray(mData.getDescriptor());
    code.add(Opcode.ALOAD_0); // push this
    int count = 1; // zero is the this pointer
    int maxLocals = 1;
    for (String p : params) {
      // int char short boolean byte
      if (p.equals("I") || p.equals("C") || p.equals("S") || p.equals("Z") || p.equals("B")) {
        // push integer 0
        code.addIload(count);
        maxLocals++;
      }
      // long
      else if (p.equals("J")) {
        code.addLload(count);
        maxLocals += 2;
        count++;
      }
      // double
      else if (p.equals("D")) {
        code.addDload(count);
        maxLocals += 2;
        count++;
      }
      // float
      else if (p.equals("F")) {
        code.addFload(count);
        maxLocals++;
      }
      // arrays and reference types
      else {
        code.addAload(count);
        maxLocals++;
      }
      count++;
    }
    code.addInvokespecial(file.getSuperclass(), mData.getMethodName(), mData.getDescriptor());
    String p = DescriptorUtils.getReturnTypeInJvmFormat(mData.getDescriptor());
    // int char short boolean byte
    if (p.equals("I") || p.equals("C") || p.equals("S") || p.equals("Z") || p.equals("B")) {
      code.add(Opcode.IRETURN);
    }
    // long
    else if (p.equals("J")) {
      code.add(Opcode.LRETURN);
    }
    // double
    else if (p.equals("D")) {
      code.add(Opcode.DRETURN);
    }
    // float
    else if (p.equals("F")) {
      code.add(Opcode.FRETURN);
    }
    // void
    else if (p.equals("V")) {
      code.add(Opcode.RETURN);
    }
    // arrays and reference types
    else {
      code.add(Opcode.ARETURN);
    }
    CodeAttribute ca = code.toCodeAttribute();
    ca.computeMaxStack();
    ca.setMaxLocals(maxLocals);
    m.setCodeAttribute(ca);
    file.addMethod(m);
  }