Exemple #1
0
  private void atIfStmnt(Stmnt st) throws CompileError {
    ASTree expr = st.head();
    Stmnt thenp = (Stmnt) st.tail().head();
    Stmnt elsep = (Stmnt) st.tail().tail().head();
    if (compileBooleanExpr(false, expr)) {
      hasReturned = false;
      if (elsep != null) elsep.accept(this);

      return;
    }

    int pc = bytecode.currentPc();
    int pc2 = 0;
    bytecode.addIndex(0); // correct later

    hasReturned = false;
    if (thenp != null) thenp.accept(this);

    boolean thenHasReturned = hasReturned;
    hasReturned = false;

    if (elsep != null && !thenHasReturned) {
      bytecode.addOpcode(Opcode.GOTO);
      pc2 = bytecode.currentPc();
      bytecode.addIndex(0);
    }

    bytecode.write16bit(pc, bytecode.currentPc() - pc + 1);
    if (elsep != null) {
      elsep.accept(this);
      if (!thenHasReturned) bytecode.write16bit(pc2, bytecode.currentPc() - pc2 + 1);

      hasReturned = thenHasReturned && hasReturned;
    }
  }
Exemple #2
0
  private void atWhileStmnt(Stmnt st, boolean notDo) throws CompileError {
    ArrayList prevBreakList = breakList;
    ArrayList prevContList = continueList;
    breakList = new ArrayList();
    continueList = new ArrayList();

    ASTree expr = st.head();
    Stmnt body = (Stmnt) st.tail();

    int pc = 0;
    if (notDo) {
      bytecode.addOpcode(Opcode.GOTO);
      pc = bytecode.currentPc();
      bytecode.addIndex(0);
    }

    int pc2 = bytecode.currentPc();
    if (body != null) body.accept(this);

    int pc3 = bytecode.currentPc();
    if (notDo) bytecode.write16bit(pc, pc3 - pc + 1);

    boolean alwaysBranch = compileBooleanExpr(true, expr);
    if (alwaysBranch) {
      bytecode.addOpcode(Opcode.GOTO);
      alwaysBranch = breakList.size() == 0;
    }

    bytecode.addIndex(pc2 - bytecode.currentPc() + 1);
    patchGoto(breakList, bytecode.currentPc());
    patchGoto(continueList, pc3);
    continueList = prevContList;
    breakList = prevBreakList;
    hasReturned = alwaysBranch;
  }
Exemple #3
0
  private void atForStmnt(Stmnt st) throws CompileError {
    ArrayList prevBreakList = breakList;
    ArrayList prevContList = continueList;
    breakList = new ArrayList();
    continueList = new ArrayList();

    Stmnt init = (Stmnt) st.head();
    ASTList p = st.tail();
    ASTree expr = p.head();
    p = p.tail();
    Stmnt update = (Stmnt) p.head();
    Stmnt body = (Stmnt) p.tail();

    if (init != null) init.accept(this);

    int pc = bytecode.currentPc();
    int pc2 = 0;
    if (expr != null) {
      if (compileBooleanExpr(false, expr)) {
        // in case of "for (...; false; ...)"
        continueList = prevContList;
        breakList = prevBreakList;
        hasReturned = false;
        return;
      }

      pc2 = bytecode.currentPc();
      bytecode.addIndex(0);
    }

    if (body != null) body.accept(this);

    int pc3 = bytecode.currentPc();
    if (update != null) update.accept(this);

    bytecode.addOpcode(Opcode.GOTO);
    bytecode.addIndex(pc - bytecode.currentPc() + 1);

    int pc4 = bytecode.currentPc();
    if (expr != null) bytecode.write16bit(pc2, pc4 - pc2 + 1);

    patchGoto(breakList, pc4);
    patchGoto(continueList, pc3);
    continueList = prevContList;
    breakList = prevBreakList;
    hasReturned = false;
  }
Exemple #4
0
  /** @param isCons true if super() must be called. false if the method is a class initializer. */
  public void atMethodBody(Stmnt s, boolean isCons, boolean isVoid) throws CompileError {
    if (s == null) return;

    if (isCons && needsSuperCall(s)) insertDefaultSuperCall();

    hasReturned = false;
    s.accept(this);
    if (!hasReturned)
      if (isVoid) {
        bytecode.addOpcode(Opcode.RETURN);
        hasReturned = true;
      } else throw new CompileError("no return statement");
  }
Exemple #5
0
  private void atSyncStmnt(Stmnt st) throws CompileError {
    int nbreaks = getListSize(breakList);
    int ncontinues = getListSize(continueList);

    compileExpr(st.head());
    if (exprType != CLASS && arrayDim == 0)
      throw new CompileError("bad type expr for synchronized block");

    Bytecode bc = bytecode;
    final int var = bc.getMaxLocals();
    bc.incMaxLocals(1);
    bc.addOpcode(DUP);
    bc.addAstore(var);
    bc.addOpcode(MONITORENTER);

    ReturnHook rh =
        new ReturnHook(this) {
          protected boolean doit(Bytecode b, int opcode) {
            b.addAload(var);
            b.addOpcode(MONITOREXIT);
            return false;
          }
        };

    int pc = bc.currentPc();
    Stmnt body = (Stmnt) st.tail();
    if (body != null) body.accept(this);

    int pc2 = bc.currentPc();
    int pc3 = 0;
    if (!hasReturned) {
      rh.doit(bc, 0); // the 2nd arg is ignored.
      bc.addOpcode(Opcode.GOTO);
      pc3 = bc.currentPc();
      bc.addIndex(0);
    }

    if (pc < pc2) { // if the body is not empty
      int pc4 = bc.currentPc();
      rh.doit(bc, 0); // the 2nd arg is ignored.
      bc.addOpcode(ATHROW);
      bc.addExceptionHandler(pc, pc2, pc4, 0);
    }

    if (!hasReturned) bc.write16bit(pc3, bc.currentPc() - pc3 + 1);

    rh.remove(this);

    if (getListSize(breakList) != nbreaks || getListSize(continueList) != ncontinues)
      throw new CompileError("sorry, cannot break/continue in synchronized block");
  }