⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gen.java

📁 GJC(Generic Java Compiler)编译器
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
                    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 + -