protected final void atReturnStmnt2(ASTree result) throws CompileError { int op; if (result == null) op = Opcode.RETURN; else { compileExpr(result); if (arrayDim > 0) op = ARETURN; else { int type = exprType; if (type == DOUBLE) op = DRETURN; else if (type == FLOAT) op = FRETURN; else if (type == LONG) op = LRETURN; else if (isRefType(type)) op = ARETURN; else op = IRETURN; } } for (ReturnHook har = returnHooks; har != null; har = har.next) if (har.doit(bytecode, op)) { hasReturned = true; return; } bytecode.addOpcode(op); hasReturned = true; }
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"); }