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

📄 flow.java

📁 GJC(Generic Java Compiler)编译器
💻 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 + -