public WSTryStmtClassGen(AbstractWSClassGen parent, Try tryStmt) { super( parent, parent, WSUtil.getExceptionFrameClassName(parent.getClassName()), parent.xts.TryFrame(), tryStmt.tryBlock()); this.tryStmt = tryStmt; // Never need PC value in fact // if(WSOptimizeConfig.OPT_PC_FIELD == 0){ // addPCField(); // } }
@Override protected void genMethods() throws SemanticException { CodeBlockSynth fastBodySynth = fastMSynth.getMethodBodySynth(compilerPos); CodeBlockSynth resumeBodySynth = resumeMSynth.getMethodBodySynth(compilerPos); CodeBlockSynth backBodySynth = backMSynth.getMethodBodySynth(compilerPos); AbstractWSClassGen childFrameGen = genChildFrame(xts.RegularFrame(), codeBlock, WSUtil.getBlockFrameClassName(getClassName())); List<Stmt> stmts = wsynth.genInvocateFrameStmts(1, classSynth, fastMSynth, childFrameGen); // now add codes to three path; // FIXME: just a simple try. Not correct // Some style // try { child frame call } // catch { original code but replace the local var access with field access} // finally {still replace the local var access with field access} // // fast path & resume path Block tryBlockFast = xnf.Block(tryStmt.tryBlock().position(), stmts); Block tryBlockResume = xnf.Block(tryStmt.tryBlock().position(), wsynth.genRethrowStmt(resumeMSynth)); Try tryFast = tryStmt.tryBlock(tryBlockFast); Try tryResume = tryStmt.tryBlock(tryBlockResume); List<Catch> catchBlocksFast = new ArrayList<Catch>(); List<Catch> catchBlocksResume = new ArrayList<Catch>(); Name formalName = xct.getNewVarName(); Formal fa = synth.createFormal(compilerPos, xts.Abort(), formalName, Flags.NONE); Stmt ea = xnf.Throw( compilerPos, xnf.Local(compilerPos, xnf.Id(compilerPos, formalName)) .localInstance(fa.localDef().asInstance()) .type(xts.Abort())); Catch ca = xnf.Catch(compilerPos, fa, xnf.Block(compilerPos, ea)); catchBlocksFast.add(ca); catchBlocksResume.add(ca); for (Catch c : tryStmt.catchBlocks()) { // note there is only one local var, the exception int pc = 1; // No need the pc; TransCodes catchBody = transNormalStmt(c.body(), pc, Collections.singleton(c.formal().name().id())); catchBlocksFast.add(c.body(WSUtil.stmtToBlock(xnf, catchBody.getFastStmts().get(0)))); catchBlocksResume.add(c.body(WSUtil.stmtToBlock(xnf, catchBody.getResumeStmts().get(0)))); } tryFast = tryFast.catchBlocks(catchBlocksFast); tryResume = tryResume.catchBlocks(catchBlocksResume); if (tryStmt.finallyBlock() != null) { int pc = 1; TransCodes finalBody = transNormalStmt(tryStmt.finallyBlock(), pc, Collections.EMPTY_SET); tryFast.finallyBlock(WSUtil.stmtToBlock(xnf, finalBody.getFastStmts().get(0))); tryResume.finallyBlock(WSUtil.stmtToBlock(xnf, finalBody.getResumeStmts().get(0))); } fastBodySynth.addStmt(tryFast); resumeBodySynth.addStmt(tryResume); }