Ejemplo n.º 1
0
  public void atExpr(Expr expr) throws CompileError {
    // array access, member access,
    // (unary) +, (unary) -, ++, --, !, ~

    int token = expr.getOperator();
    ASTree oprand = expr.oprand1();
    if (token == '.') {
      String member = ((Symbol) expr.oprand2()).get();
      if (member.equals("class")) atClassObject(expr); // .class
      else atFieldRead(expr);
    } else if (token == MEMBER) { // field read
      /* MEMBER ('#') is an extension by Javassist.
       * The compiler internally uses # for compiling .class
       * expressions such as "int.class".
       */
      atFieldRead(expr);
    } else if (token == ARRAY) atArrayRead(oprand, expr.oprand2());
    else if (token == PLUSPLUS || token == MINUSMINUS) atPlusPlus(token, oprand, expr, true);
    else if (token == '!') {
      if (!booleanExpr(false, expr)) {
        bytecode.addIndex(7);
        bytecode.addIconst(1);
        bytecode.addOpcode(Opcode.GOTO);
        bytecode.addIndex(4);
      }

      bytecode.addIconst(0);
    } else if (token == CALL) // method call
    fatal();
    else {
      expr.oprand1().accept(this);
      int type = typePrecedence(exprType);
      if (arrayDim > 0) badType(expr);

      if (token == '-') {
        if (type == P_DOUBLE) bytecode.addOpcode(DNEG);
        else if (type == P_FLOAT) bytecode.addOpcode(FNEG);
        else if (type == P_LONG) bytecode.addOpcode(LNEG);
        else if (type == P_INT) {
          bytecode.addOpcode(INEG);
          exprType = INT; // type may be BYTE, ...
        } else badType(expr);
      } else if (token == '~') {
        if (type == P_INT) {
          bytecode.addIconst(-1);
          bytecode.addOpcode(IXOR);
          exprType = INT; // type may be BYTE. ...
        } else if (type == P_LONG) {
          bytecode.addLconst(-1);
          bytecode.addOpcode(LXOR);
        } else badType(expr);

      } else if (token == '+') {
        if (type == P_OTHER) badType(expr);

        // do nothing. ignore.
      } else fatal();
    }
  }
Ejemplo n.º 2
0
  public void atArrayPlusPlus(int token, boolean isPost, Expr expr, boolean doDup)
      throws CompileError {
    arrayAccess(expr.oprand1(), expr.oprand2());
    int t = exprType;
    int dim = arrayDim;
    if (dim > 0) badType(expr);

    bytecode.addOpcode(DUP2);
    bytecode.addOpcode(getArrayReadOp(t, arrayDim));
    int dup_code = is2word(t, dim) ? DUP2_X2 : DUP_X2;
    atPlusPlusCore(dup_code, doDup, token, isPost, expr);
    bytecode.addOpcode(getArrayWriteOp(t, dim));
  }
Ejemplo n.º 3
0
  protected void atPlusPlusCore(int dup_code, boolean doDup, int token, boolean isPost, Expr expr)
      throws CompileError {
    int t = exprType;

    if (doDup && isPost) bytecode.addOpcode(dup_code);

    if (t == INT || t == BYTE || t == CHAR || t == SHORT) {
      bytecode.addIconst(1);
      bytecode.addOpcode(token == PLUSPLUS ? IADD : ISUB);
      exprType = INT;
    } else if (t == LONG) {
      bytecode.addLconst((long) 1);
      bytecode.addOpcode(token == PLUSPLUS ? LADD : LSUB);
    } else if (t == FLOAT) {
      bytecode.addFconst(1.0f);
      bytecode.addOpcode(token == PLUSPLUS ? FADD : FSUB);
    } else if (t == DOUBLE) {
      bytecode.addDconst(1.0);
      bytecode.addOpcode(token == PLUSPLUS ? DADD : DSUB);
    } else badType(expr);

    if (doDup && !isPost) bytecode.addOpcode(dup_code);
  }
Ejemplo n.º 4
0
  private void atPlusPlus(int token, ASTree oprand, Expr expr, boolean doDup) throws CompileError {
    boolean isPost = oprand == null; // ++i or i++?
    if (isPost) oprand = expr.oprand2();

    if (oprand instanceof Variable) {
      Declarator d = ((Variable) oprand).getDeclarator();
      int t = exprType = d.getType();
      arrayDim = d.getArrayDim();
      int var = getLocalVar(d);
      if (arrayDim > 0) badType(expr);

      if (t == DOUBLE) {
        bytecode.addDload(var);
        if (doDup && isPost) bytecode.addOpcode(DUP2);

        bytecode.addDconst(1.0);
        bytecode.addOpcode(token == PLUSPLUS ? DADD : DSUB);
        if (doDup && !isPost) bytecode.addOpcode(DUP2);

        bytecode.addDstore(var);
      } else if (t == LONG) {
        bytecode.addLload(var);
        if (doDup && isPost) bytecode.addOpcode(DUP2);

        bytecode.addLconst((long) 1);
        bytecode.addOpcode(token == PLUSPLUS ? LADD : LSUB);
        if (doDup && !isPost) bytecode.addOpcode(DUP2);

        bytecode.addLstore(var);
      } else if (t == FLOAT) {
        bytecode.addFload(var);
        if (doDup && isPost) bytecode.addOpcode(DUP);

        bytecode.addFconst(1.0f);
        bytecode.addOpcode(token == PLUSPLUS ? FADD : FSUB);
        if (doDup && !isPost) bytecode.addOpcode(DUP);

        bytecode.addFstore(var);
      } else if (t == BYTE || t == CHAR || t == SHORT || t == INT) {
        if (doDup && isPost) bytecode.addIload(var);

        int delta = token == PLUSPLUS ? 1 : -1;
        if (var > 0xff) {
          bytecode.addOpcode(WIDE);
          bytecode.addOpcode(IINC);
          bytecode.addIndex(var);
          bytecode.addIndex(delta);
        } else {
          bytecode.addOpcode(IINC);
          bytecode.add(var);
          bytecode.add(delta);
        }

        if (doDup && !isPost) bytecode.addIload(var);
      } else badType(expr);
    } else {
      if (oprand instanceof Expr) {
        Expr e = (Expr) oprand;
        if (e.getOperator() == ARRAY) {
          atArrayPlusPlus(token, isPost, e, doDup);
          return;
        }
      }

      atFieldPlusPlus(token, isPost, oprand, expr, doDup);
    }
  }