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

📄 flow.java

📁 java编译器gjc源码 java编译环境
💻 JAVA
📖 第 1 页 / 共 3 页
字号:

    /**
      * Resolve all breaks of this statement.
      */
    boolean resolveBreaks(Tree tree, ListBuffer oldPendingExits) {
        boolean result = false;
        List exits = pendingExits.toList();
        pendingExits = oldPendingExits;
        for (; exits.nonEmpty(); exits = exits.tail) {
            PendingExit exit = (Flow.PendingExit) exits.head;
            if (exit.tree.tag == Tree.BREAK && ((Break) exit.tree).target == tree) {
                inits.andSet(exit.inits);
                uninits.andSet(exit.uninits);
                result = true;
            } else {
                pendingExits.append(exit);
            }
        }
        return result;
    }

    /**
      * Resolve all continues of this statement.
      */
    boolean resolveContinues(Tree tree) {
        boolean result = false;
        List exits = pendingExits.toList();
        pendingExits = new ListBuffer();
        for (; exits.nonEmpty(); exits = exits.tail) {
            PendingExit exit = (Flow.PendingExit) exits.head;
            if (exit.tree.tag == Tree.CONTINUE &&
                    ((Continue) exit.tree).target == tree) {
                inits.andSet(exit.inits);
                uninits.andSet(exit.uninits);
                result = true;
            } else {
                pendingExits.append(exit);
            }
        }
        return result;
    }

    /**
      * Record that statement is unreachable.
      */
    void markDead() {
        inits.inclRange(firstadr, nextadr);
        uninits.inclRange(firstadr, nextadr);
        alive = false;
    }

    /**
      * Split (duplicate) inits/uninits into WhenTrue/WhenFalse sets
      */
    void split() {
        initsWhenFalse = inits.dup();
        uninitsWhenFalse = uninits.dup();
        initsWhenTrue = inits;
        uninitsWhenTrue = uninits;
        inits = uninits = null;
    }

    /**
      * Merge (intersect) inits/uninits from WhenTrue/WhenFalse sets.
      */
    void merge() {
        inits = initsWhenFalse.andSet(initsWhenTrue);
        uninits = uninitsWhenFalse.andSet(uninitsWhenTrue);
    }

    /**
      * Analyze a definition.
      */
    void scanDef(Tree tree) {
        scanStat(tree);
        if (tree != null && tree.tag == Tree.BLOCK && !alive) {
            log.error(tree.pos, "initializer.must.be.able.to.complete.normally");
        }
    }

    /**
      * Analyze a statement. Check that statement is reachable.
      */
    void scanStat(Tree tree) {
        if (!alive && tree != null) {
            log.error(tree.pos, "unreachable.stmt");
            if (tree.tag != Tree.SKIP)
                alive = true;
        }
        scan(tree);
    }

    /**
      * Analyze list of statements.
      */
    void scanStats(List trees) {
        if (trees != null)
            for (List l = trees; l.nonEmpty(); l = l.tail)
                scanStat((Tree) l.head);
    }

    /**
      * Analyze an expression. Make sure to set (un)inits rather than
      *	(un)initsWhenTrue(WhenFalse) on exit.
      */
    void scanExpr(Tree tree) {
        if (tree != null) {
            scan(tree);
            if (inits == null)
                merge();
        }
    }

    /**
      * Analyze a list of expressions.
      */
    void scanExprs(List trees) {
        if (trees != null)
            for (List l = trees; l.nonEmpty(); l = l.tail)
                scanExpr((Tree) l.head);
    }

    /**
      * Analyze a condition. Make sure to set (un)initsWhenTrue(WhenFalse)
      *	rather than (un)inits on exit.
      */
    void scanCond(Tree tree) {
        if (tree.type.isFalse()) {
            if (inits == null)
                merge();
            initsWhenTrue = inits.dup();
            initsWhenTrue.inclRange(firstadr, nextadr);
            uninitsWhenTrue = uninits.dup();
            uninitsWhenTrue.inclRange(firstadr, nextadr);
            initsWhenFalse = inits;
            uninitsWhenFalse = uninits;
        } else if (tree.type.isTrue()) {
            if (inits == null)
                merge();
            initsWhenFalse = inits.dup();
            initsWhenFalse.inclRange(firstadr, nextadr);
            uninitsWhenFalse = uninits.dup();
            uninitsWhenFalse.inclRange(firstadr, nextadr);
            initsWhenTrue = inits;
            uninitsWhenTrue = uninits;
        } else {
            scan(tree);
            if (inits != null)
                split();
        }
        inits = uninits = null;
    }

    public void visitClassDef(ClassDef tree) {
        if (tree.sym == null)
            return;
        ClassDef classDefPrev = classDef;
        List thrownPrev = thrown;
        List caughtPrev = caught;
        boolean alivePrev = alive;
        int firstadrPrev = firstadr;
        int nextadrPrev = nextadr;
        ListBuffer pendingExitsPrev = pendingExits;
        pendingExits = new ListBuffer();
        if (tree.name != names.empty) {
            caught = Type.emptyList;
            firstadr = nextadr;
        }
        classDef = tree;
        thrown = Type.emptyList;
        try {
            for (List l = tree.defs; l.nonEmpty(); l = l.tail) {
                if (((Tree) l.head).tag == Tree.VARDEF) {
                    VarDef def = (VarDef) l.head;
                    if ((def.flags & STATIC) != 0) {
                        VarSymbol sym = def.sym;
                        if (trackable(sym))
                            newVar(sym);
                    }
                }
            }
            for (List l = tree.defs; l.nonEmpty(); l = l.tail) {
                if (((Tree) l.head).tag != Tree.METHODDEF &&
                        (TreeInfo.flags((Tree) l.head) & STATIC) != 0) {
                    scanDef((Tree) l.head);
                    errorUncaught();
                }
            }
            if (tree.name != names.empty) {
                boolean firstConstructor = true;
                for (List l = tree.defs; l.nonEmpty(); l = l.tail) {
                    if (TreeInfo.isInitialConstructor((Tree) l.head)) {
                        List mthrown = ((MethodDef) l.head).sym.type.thrown();
                        if (firstConstructor) {
                            caught = mthrown;
                            firstConstructor = false;
                        } else {
                            caught = chk.intersect(mthrown, caught);
                        }
                    }
                }
            }
            for (List l = tree.defs; l.nonEmpty(); l = l.tail) {
                if (((Tree) l.head).tag == Tree.VARDEF) {
                    VarDef def = (VarDef) l.head;
                    if ((def.flags & STATIC) == 0) {
                        VarSymbol sym = def.sym;
                        if (trackable(sym))
                            newVar(sym);
                    }
                }
            }
            for (List l = tree.defs; l.nonEmpty(); l = l.tail) {
                if (((Tree) l.head).tag != Tree.METHODDEF &&
                        (TreeInfo.flags((Tree) l.head) & STATIC) == 0) {
                    scanDef((Tree) l.head);
                    errorUncaught();
                }
            }
            for (List l = tree.defs; l.nonEmpty(); l = l.tail) {
                if (((Tree) l.head).tag == Tree.METHODDEF) {
                    scan((Tree) l.head);
                    errorUncaught();
                }
            }
            if (tree.name == names.empty) {
                for (List l = tree.defs; l.nonEmpty(); l = l.tail) {
                    if (TreeInfo.isInitialConstructor((Tree) l.head)) {
                        MethodDef mdef = (MethodDef) l.head;
                        mdef.thrown = make.Types(thrown);
                        ((MethodType) mdef.sym.type).thrown = thrown;
                    }
                }
                thrown = chk.union(thrown, thrownPrev);
            } else {
                thrown = thrownPrev;
            }
        }
        finally { pendingExits = pendingExitsPrev;
                  alive = alivePrev;
                  nextadr = nextadrPrev;
                  firstadr = firstadrPrev;
                  caught = caughtPrev;
                  classDef = classDefPrev;
                } }

    public void visitMethodDef(MethodDef tree) {
        if (tree.body == null)
            return;
        List caughtPrev = caught;
        List mthrown = tree.sym.type.thrown();
        Bits initsPrev = inits.dup();
        Bits uninitsPrev = uninits.dup();
        int nextadrPrev = nextadr;
        int firstadrPrev = firstadr;
        assert pendingExits.isEmpty();
        try {
            boolean isInitialConstructor = TreeInfo.isInitialConstructor(tree);
            if (!isInitialConstructor)
                firstadr = nextadr;
            for (List l = tree.params; l.nonEmpty(); l = l.tail) {
                VarDef def = (Tree.VarDef) l.head;
                scan(def);
                inits.incl(def.sym.adr);
                uninits.excl(def.sym.adr);
            }
            if (isInitialConstructor)
                caught = chk.union(caught, mthrown);
            else if ((tree.sym.flags() & (BLOCK | STATIC)) != BLOCK)
                caught = mthrown;
            alive = true;
            scanStat(tree.body);
            int endPos = TreeInfo.endPos(tree.body);
            if (alive && tree.sym.type.restype().tag != VOID)
                log.error(endPos, "missing.ret.stmt");
            if (isInitialConstructor) {
                for (int i = firstadr; i < nextadr; i++)
                    if (vars[i].owner == classDef.sym)
                        checkInit(endPos, vars[i]);
            }
            List exits = pendingExits.toList();
            pendingExits = new ListBuffer();
            while (exits.nonEmpty()) {
                PendingExit exit = (Flow.PendingExit) exits.head;
                exits = exits.tail;
                if (exit.thrown == null) {
                    assert exit.tree.tag == Tree.RETURN;
                    if (isInitialConstructor) {
                        inits = exit.inits;
                        for (int i = firstadr; i < nextadr; i++)
                            checkInit(exit.tree.pos, vars[i]);
                    }
                } else {
                    pendingExits.append(exit);
                }
            }
        }
        finally { inits = initsPrev;
                  uninits = uninitsPrev;
                  nextadr = nextadrPrev;
                  firstadr = firstadrPrev;
                  caught = caughtPrev;
                } }

    public void visitVarDef(VarDef tree) {
        boolean track = trackable(tree.sym);
        if (track && tree.sym.owner.kind == MTH)
            newVar(tree.sym);
        if (tree.init != null) {
            scanExpr(tree.init);
            if (track)
                letInit(tree.pos, tree.sym);
        }
    }

    public void visitBlock(Block tree) {
        int nextadrPrev = nextadr;
        scanStats(tree.stats);
        nextadr = nextadrPrev;
    }

    public void visitDoLoop(DoLoop tree) {
        ListBuffer prevPendingExits = pendingExits;
        boolean prevLoopPassTwo = loopPassTwo;
        do {
            pendingExits = new ListBuffer();
            Bits uninitsEntry = uninits.dup();
            scanStat(tree.body);
            alive |= resolveContinues(tree);
            scanCond(tree.cond);
            if (log.nerrors != 0 || loopPassTwo ||
                    uninitsEntry.diffSet(uninitsWhenTrue).nextBit(firstadr) == -1)
                break;
            inits = initsWhenTrue;
            uninits = uninitsEntry.andSet(uninitsWhenTrue);
            loopPassTwo = true;
            alive = true;
        } while (true)
            ;
        loopPassTwo = prevLoopPassTwo;
        inits = initsWhenFalse;
        uninits = uninitsWhenFalse;
        alive = alive && !tree.cond.type.isTrue();
        alive |= resolveBreaks(tree, prevPendingExits);
    }

    public void visitWhileLoop(WhileLoop tree) {
        ListBuffer prevPendingExits = pendingExits;
        boolean prevLoopPassTwo = loopPassTwo;
        Bits initsCond;
        Bits uninitsCond;
        do {
            pendingExits = new ListBuffer();
            Bits uninitsEntry = uninits.dup();
            scanCond(tree.cond);
            initsCond = initsWhenFalse;
            uninitsCond = uninitsWhenFalse;
            inits = initsWhenTrue;
            uninits = uninitsWhenTrue;
            alive = !tree.cond.type.isFalse();
            scanStat(tree.body);
            alive |= resolveContinues(tree);
            if (log.nerrors != 0 || loopPassTwo ||
                    uninitsEntry.diffSet(uninits).nextBit(firstadr) == -1)
                break;
            uninits = uninitsEntry.andSet(uninits);
            loopPassTwo = true;
            alive = true;
        } while (true)
            ;
        loopPassTwo = prevLoopPassTwo;
        inits = initsCond;
        uninits = uninitsCond;
        alive = resolveBreaks(tree, prevPendingExits) || !tree.cond.type.isTrue();
    }

    public void visitForLoop(ForLoop tree) {
        ListBuffer prevPendingExits = pendingExits;
        boolean prevLoopPassTwo = loopPassTwo;
        int nextadrPrev = nextadr;
        scanStats(tree.init);
        Bits initsCond;
        Bits uninitsCond;
        do {
            pendingExits = new ListBuffer();
            Bits uninitsEntry = uninits.dup();
            if (tree.cond != null) {
                scanCond(tree.cond);
                initsCond = initsWhenFalse;
                uninitsCond = uninitsWhenFalse;
                inits = initsWhenTrue;
                uninits = uninitsWhenTrue;
                alive = !tree.cond.type.isFalse();

⌨️ 快捷键说明

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