示例#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();
    }
  }
示例#2
0
  static int getCompOperator(ASTree expr) throws CompileError {
    if (expr instanceof Expr) {
      Expr bexpr = (Expr) expr;
      int token = bexpr.getOperator();
      if (token == '!') return '!';
      else if ((bexpr instanceof BinExpr)
          && token != OROR
          && token != ANDAND
          && token != '&'
          && token != '|') return EQ; // ==, !=, ...
      else return token;
    }

    return ' '; // others
  }
示例#3
0
  protected void atAssignExpr(AssignExpr expr, boolean doDup) throws CompileError {
    // =, %=, &=, *=, /=, +=, -=, ^=, |=, <<=, >>=, >>>=
    int op = expr.getOperator();
    ASTree left = expr.oprand1();
    ASTree right = expr.oprand2();
    if (left instanceof Variable)
      atVariableAssign(expr, op, (Variable) left, ((Variable) left).getDeclarator(), right, doDup);
    else {
      if (left instanceof Expr) {
        Expr e = (Expr) left;
        if (e.getOperator() == ARRAY) {
          atArrayAssign(expr, op, (Expr) left, right, doDup);
          return;
        }
      }

      atFieldAssign(expr, op, left, right, doDup);
    }
  }
示例#4
0
  public void atStmnt(Stmnt st) throws CompileError {
    if (st == null) return; // empty

    int op = st.getOperator();
    if (op == EXPR) {
      ASTree expr = st.getLeft();
      doTypeCheck(expr);
      if (expr instanceof AssignExpr) atAssignExpr((AssignExpr) expr, false);
      else if (isPlusPlusExpr(expr)) {
        Expr e = (Expr) expr;
        atPlusPlus(e.getOperator(), e.oprand1(), e, false);
      } else {
        expr.accept(this);
        if (is2word(exprType, arrayDim)) bytecode.addOpcode(POP2);
        else if (exprType != VOID) bytecode.addOpcode(POP);
      }
    } else if (op == DECL || op == BLOCK) {
      ASTList list = st;
      while (list != null) {
        ASTree h = list.head();
        list = list.tail();
        if (h != null) h.accept(this);
      }
    } else if (op == IF) atIfStmnt(st);
    else if (op == WHILE || op == DO) atWhileStmnt(st, op == WHILE);
    else if (op == FOR) atForStmnt(st);
    else if (op == BREAK || op == CONTINUE) atBreakStmnt(st, op == BREAK);
    else if (op == TokenId.RETURN) atReturnStmnt(st);
    else if (op == THROW) atThrowStmnt(st);
    else if (op == TRY) atTryStmnt(st);
    else if (op == SWITCH) atSwitchStmnt(st);
    else if (op == SYNCHRONIZED) atSyncStmnt(st);
    else {
      // LABEL, SWITCH label stament might be null?.
      hasReturned = false;
      throw new CompileError("sorry, not supported statement: TokenId " + op);
    }
  }
示例#5
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);
    }
  }