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

📄 gen.java

📁 java编译器gjc源码 java编译环境
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
        do {
            while (keys[i] < pivot)
                i++;
            while (pivot < keys[j])
                j--;
            if (i <= j) {
                int temp1 = keys[i];
                keys[i] = keys[j];
                keys[j] = temp1;
                int temp2 = values[i];
                values[i] = values[j];
                values[j] = temp2;
                i++;
                j--;
            }
        } while (i <= j)
            ;
        if (lo < j)
            qsort2(keys, values, lo, j);
        if (i < hi)
            qsort2(keys, values, i, hi);
    }

    public void visitSynchronized(Synchronized tree) {
        int limit = code.nextreg;
        final Item lockVar = makeTemp(syms.objectType);
        genExpr(tree.lock, tree.lock.type).load().duplicate();
        lockVar.store();
        code.emitop(monitorenter);
        final Env syncEnv = env.dup(tree, new GenContext());
        ((Gen.GenContext) syncEnv.info).finalize = new GenFinalizer() {


                    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);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -