?? gen.java
字號:
void gen() { genLast(); assert ((Gen.GenContext) syncEnv.info).gaps.length() % 2 == 0; ((Gen.GenContext) syncEnv.info).gaps.append( new Integer(code.curPc())); } void genLast() { lockVar.load(); code.emitop(monitorexit); } }; ((Gen.GenContext) syncEnv.info).gaps = new ListBuffer(); genTry(tree.body, Catch.emptyList, syncEnv); code.endScopes(limit); } public void visitTry(final Try tree) { final Env tryEnv = env.dup(tree, new GenContext()); final Env oldEnv = env; final boolean useJsrLocally = jsrlimit <= 0 || jsrlimit < 100 && estimateCodeComplexity(tree.finalizer) > jsrlimit; ((Gen.GenContext) tryEnv.info).finalize = new GenFinalizer() { void gen() { if (useJsrLocally) { if (tree.finalizer != null) { ((Gen.GenContext) tryEnv.info).cont = new Chain(code.emitJump(jsr), code.stacksize + 1, ((Gen.GenContext) tryEnv.info).cont, varDebugInfo ? code.defined.dup() : null); } assert ((Gen.GenContext) tryEnv.info).gaps.length() % 2 == 0; ((Gen.GenContext) tryEnv.info).gaps.append( new Integer(code.curPc())); } else { assert ((Gen.GenContext) tryEnv.info).gaps.length() % 2 == 0; ((Gen.GenContext) tryEnv.info).gaps.append( new Integer(code.curPc())); genLast(); } } void genLast() { if (tree.finalizer != null) genStat(tree.finalizer, oldEnv, CRT_BLOCK); } boolean hasFinalizer() { return tree.finalizer != null; } }; ((Gen.GenContext) tryEnv.info).gaps = new ListBuffer(); genTry(tree.body, tree.catchers, tryEnv); } /** * Generate code for a try or synchronized statement * @param body The body of the try or synchronized statement. * @param catchers The lis of catch clauses. * @param env the environment current for the body. */ void genTry(Tree body, List catchers, Env env) { int limit = code.nextreg; int startpc = code.curPc(); Bits definedTry = varDebugInfo ? code.defined.dup() : null; genStat(body, env, CRT_BLOCK); int endpc = code.curPc(); boolean hasFinalizer = ((Gen.GenContext) env.info).finalize != null && ((Gen.GenContext) env.info).finalize.hasFinalizer(); if (startpc == endpc) { if (hasFinalizer) { code.statBegin(TreeInfo.finalizerPos(env.tree)); code.markStatBegin(); ((Gen.GenContext) env.info).finalize.genLast(); } } else { List gaps = ((Gen.GenContext) env.info).gaps.toList(); code.statBegin(TreeInfo.endPos(body)); genFinalizer(env); code.statBegin(TreeInfo.endPos(env.tree)); Chain exitChain = code.branch(goto_); endFinalizerGap(env); for (List l = catchers; l.nonEmpty(); l = l.tail) { code.entryPoint(1); code.setDefined(definedTry); genCatch((Tree.Catch) l.head, env, startpc, endpc, gaps); genFinalizer(env); if (hasFinalizer || l.tail.nonEmpty()) { code.statBegin(TreeInfo.endPos(env.tree)); exitChain = code.mergeChains(exitChain, code.branch(goto_)); } endFinalizerGap(env); } if (hasFinalizer) { code.newRegSegment(); int catchallpc = code.entryPoint(1); code.setDefined(definedTry); int startseg = startpc; while (((Gen.GenContext) env.info).gaps.nonEmpty()) { int endseg = ((Integer)((Gen.GenContext) env.info).gaps.next()). intValue(); registerCatch(body.pos, startseg, endseg, catchallpc, 0); startseg = ((Integer)((Gen.GenContext) env.info).gaps.next()). intValue(); } code.statBegin(TreeInfo.finalizerPos(env.tree)); code.markStatBegin(); Item excVar = makeTemp(syms.throwableType); excVar.store(); genFinalizer(env); excVar.load(); registerCatch(body.pos, startseg, ((Integer)((Gen.GenContext) env.info).gaps.next()). intValue(), catchallpc, 0); code.emitop(athrow); code.markDead(); if (((Gen.GenContext) env.info).cont != null) { code.resolve(((Gen.GenContext) env.info).cont); code.statBegin(TreeInfo.finalizerPos(env.tree)); code.markStatBegin(); LocalItem retVar = makeTemp(syms.throwableType); retVar.store(); ((Gen.GenContext) env.info).finalize.genLast(); code.emitop1w(ret, retVar.reg); code.markDead(); } } code.resolve(exitChain); code.endScopes(limit); } } /** * Generate code for a catch clause. * @param tree The catch clause. * @param env The environment current in the enclosing try. * @param startpc Start pc of try-block. * @param endpc End pc of try-block. */ void genCatch(Catch tree, Env env, int startpc, int endpc, List gaps) { if (startpc != endpc) { int catchType = makeRef(tree.pos, tree.param.type); while (gaps.nonEmpty()) { int end = ((Integer) gaps.head).intValue(); registerCatch(tree.pos, startpc, end, code.curPc(), catchType); gaps = gaps.tail; startpc = ((Integer) gaps.head).intValue(); gaps = gaps.tail; } if (startpc < endpc) registerCatch(tree.pos, startpc, endpc, code.curPc(), catchType); VarSymbol exparam = tree.param.sym; code.statBegin(tree.pos); code.markStatBegin(); int limit = code.nextreg; int exlocal = code.newLocal(exparam); items.makeLocalItem(exparam).store(); code.setDefined(exlocal); code.statBegin(TreeInfo.firstStatPos(tree.body)); genStat(tree.body, env, CRT_BLOCK); code.endScopes(limit); code.statBegin(TreeInfo.endPos(tree.body)); } } /** * Register a catch clause in the "Exceptions" code-atttribute. */ void registerCatch(int pos, int startpc, int endpc, int handler_pc, int catch_type) { if (startpc != endpc) { char startpc1 = (char) startpc; char endpc1 = (char) endpc; char handler_pc1 = (char) handler_pc; if (startpc1 == startpc && endpc1 == endpc && handler_pc1 == handler_pc) { code.addCatch(startpc1, endpc1, handler_pc1, (char) catch_type); } else { log.error(pos, "limit.code.too.large.for.try.stmt"); nerrs++; } } } /** * Very roughly estimate the number of instructions needed for * the given tree. */ int estimateCodeComplexity(Tree tree) { if (tree == null) return 0; class ComplexityScanner extends TreeScanner { ComplexityScanner() { super(); } int complexity = 0; public void scan(Tree tree) { if (complexity > jsrlimit) return; super.scan(tree); } public void visitClassDef(ClassDef tree) { } public void visitDoLoop(DoLoop tree) { super.visitDoLoop(tree); complexity++; } public void visitWhileLoop(WhileLoop tree) { super.visitWhileLoop(tree); complexity++; } public void visitForLoop(ForLoop tree) { super.visitForLoop(tree); complexity++; } public void visitSwitch(Switch tree) { super.visitSwitch(tree); complexity += 5; } public void visitCase(Case tree) { super.visitCase(tree); complexity++; } public void visitSynchronized(Synchronized tree) { super.visitSynchronized(tree); complexity += 6; } public void visitTry(Try tree) { super.visitTry(tree); if (tree.finalizer != null) complexity += 6; } public void visitCatch(Catch tree) { super.visitCatch(tree); complexity += 2; } public void visitConditional(Conditional tree) { super.visitConditional(tree); complexity += 2; } public void visitIf(If tree) { super.visitIf(tree); complexity += 2; } public void visitBreak(Break tree) { super.visitBreak(tree); complexity += 1; } public void visitContinue(Continue tree) { super.visitContinue(tree); complexity += 1; } public void visitReturn(Return tree) { super.visitReturn(tree); complexity += 1; } public void visitThrow(Throw tree) { super.visitThrow(tree); complexity += 1; } public void visitAssert(Assert tree) { super.visitAssert(tree); complexity += 5; } public void visitApply(Apply tree) { super.visitApply(tree); complexity += 2; } public void visitNewClass(NewClass tree) { scan(tree.encl); scan(tree.args); complexity += 2; } public void visitNewArray(NewArray tree) { super.visitNewArray(tree); complexity += 5; } public void visitAssign(Assign tree) { super.visitAssign(tree); complexity += 1; } public void visitAssignop(Assignop tree) { super.visitAssignop(tree); complexity += 2; } public void visitUnary(Unary tree) { complexity += 1; if (tree.type.constValue == null) super.visitUnary(tree); } public void visitBinary(Binary tree) { complexity += 1; if (tree.type.constValue == null) super.visitBinary(tree); } public void visitTypeTest(TypeTest tree) { super.visitTypeTest(tree); complexity += 1; } public void visitIndexed(Indexed tree) { super.visitIndexed(tree); complexity += 1; } public void visitSelect(Select tree) { super.visitSelect(tree); if (tree.sym.kind == VAR) complexity += 1; } public void visitIdent(Ident tree) { if (tree.sym.kind == VAR) { complexity += 1; if (tree.type.constValue == null && tree.sym.owner.kind == TYP) complexity += 1; } } public void visitLiteral(Literal tree) { complexity += 1; } public void visitTree(Tree tree) { } } ComplexityScanner scanner = new ComplexityScanner(); tree.accept(scanner); return scanner.complexity; }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -