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

📄 flow.java

📁 java编译器gjc源码 java编译环境
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
            } else {
                initsCond = inits.dup();
                initsCond.inclRange(firstadr, nextadr);
                uninitsCond = uninits.dup();
                uninitsCond.inclRange(firstadr, nextadr);
                alive = true;
            }
            scanStat(tree.body);
            alive |= resolveContinues(tree);
            scan(tree.step);
            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 != null &&
                !tree.cond.type.isTrue();
        nextadr = nextadrPrev;
    }

    public void visitLabelled(Labelled tree) {
        ListBuffer prevPendingExits = pendingExits;
        pendingExits = new ListBuffer();
        scanStat(tree.body);
        alive |= resolveBreaks(tree, prevPendingExits);
    }

    public void visitSwitch(Switch tree) {
        ListBuffer prevPendingExits = pendingExits;
        pendingExits = new ListBuffer();
        int nextadrPrev = nextadr;
        scanExpr(tree.selector);
        Bits initsSwitch = inits;
        Bits uninitsSwitch = uninits.dup();
        boolean hasDefault = false;
        for (List l = tree.cases; l.nonEmpty(); l = l.tail) {
            alive = true;
            inits = initsSwitch.dup();
            uninits = uninits.andSet(uninitsSwitch);
            Case c = (Tree.Case) l.head;
            if (c.pat == null)
                hasDefault = true;
            else
                scanExpr(c.pat);
            scanStats(c.stats);
            addVars(c.stats, initsSwitch, uninitsSwitch);
            if (!loopPassTwo && switchCheck && alive && c.stats.nonEmpty() &&
                    l.tail.nonEmpty())
                log.warning(((Tree.Case) l.tail.head).pos, "possible.fall-through.into.case");
        }
        if (!hasDefault) {
            inits.andSet(initsSwitch);
            alive = true;
        }
        alive |= resolveBreaks(tree, prevPendingExits);
        nextadr = nextadrPrev;
    }

    /**
      * Add any variables defined in stats to inits and uninits.
      */
    private static void addVars(List stats, Bits inits, Bits uninits) {
        for (; stats.nonEmpty(); stats = stats.tail) {
            Tree stat = (Tree) stats.head;
            if (stat.tag == Tree.VARDEF) {
                int adr = ((VarDef) stat).sym.adr;
                inits.excl(adr);
                uninits.incl(adr);
            }
        }
    }

    public void visitTry(Try tree) {
        List caughtPrev = caught;
        List thrownPrev = thrown;
        thrown = Type.emptyList;
        for (List l = tree.catchers; l.nonEmpty(); l = l.tail)
            caught = chk.incl(((Tree.Catch) l.head).param.type, caught);
        Bits uninitsTryPrev = uninitsTry;
        ListBuffer prevPendingExits = pendingExits;
        pendingExits = new ListBuffer();
        Bits initsTry = inits.dup();
        uninitsTry = uninits.dup();
        scanStat(tree.body);
        List thrownInTry = thrown;
        thrown = thrownPrev;
        caught = caughtPrev;
        boolean aliveEnd = alive;
        uninitsTry.andSet(uninits);
        Bits initsEnd = inits;
        Bits uninitsEnd = uninits;
        int nextadrCatch = nextadr;
        List caughtInTry = Type.emptyList;
        for (List l = tree.catchers; l.nonEmpty(); l = l.tail) {
            alive = true;
            VarDef param = ((Tree.Catch) l.head).param;
            Type exc = param.type;
            if (chk.subset(exc, caughtInTry)) {
                log.error(((Tree.Catch) l.head).pos, "except.already.caught",
                        exc.toJava());
            } else if (!chk.isUnchecked(((Tree.Catch) l.head).pos, exc) &&
                    exc != syms.throwableType && exc != syms.exceptionType &&
                    !chk.intersects(exc, thrownInTry)) {
                log.error(((Tree.Catch) l.head).pos, "except.never.thrown.in.try",
                        exc.toJava());
            }
            caughtInTry = chk.incl(exc, caughtInTry);
            inits = initsTry.dup();
            uninits = uninitsTry.dup();
            scan(param);
            inits.incl(param.sym.adr);
            uninits.excl(param.sym.adr);
            scanStat(((Tree.Catch) l.head).body);
            initsEnd.andSet(inits);
            uninitsEnd.andSet(uninits);
            nextadr = nextadrCatch;
            aliveEnd |= alive;
        }
        if (tree.finalizer != null) {
            List savedThrown = thrown;
            thrown = Type.emptyList;
            inits = initsTry.dup();
            uninits = uninitsTry.dup();
            ListBuffer exits = pendingExits;
            pendingExits = prevPendingExits;
            alive = true;
            scanStat(tree.finalizer);
            if (!alive) {
                thrown = chk.union(thrown, thrownPrev);
                if (!loopPassTwo)
                    log.warning(TreeInfo.endPos(tree.finalizer), "finally.cannot.complete");
            } else {
                thrown = chk.union(thrown, chk.diff(thrownInTry, caughtInTry));
                thrown = chk.union(thrown, savedThrown);
                uninits.andSet(uninitsEnd);
                while (exits.nonEmpty()) {
                    PendingExit exit = (Flow.PendingExit) exits.next();
                    if (exit.inits != null) {
                        exit.inits.orSet(inits);
                        exit.uninits.andSet(uninits);
                    }
                    pendingExits.append(exit);
                }
                inits.orSet(initsEnd);
                alive = aliveEnd;
            }
        } else {
            thrown = chk.union(thrown, chk.diff(thrownInTry, caughtInTry));
            inits = initsEnd;
            uninits = uninitsEnd;
            alive = aliveEnd;
            ListBuffer exits = pendingExits;
            pendingExits = prevPendingExits;
            while (exits.nonEmpty())
                pendingExits.append(exits.next());
        }
        uninitsTry.andSet(uninitsTryPrev).andSet(uninits);
    }

    public void visitConditional(Conditional tree) {
        scanCond(tree.cond);
        Bits initsBeforeElse = initsWhenFalse;
        Bits uninitsBeforeElse = uninitsWhenFalse;
        inits = initsWhenTrue;
        uninits = uninitsWhenTrue;
        if (tree.truepart.type.tag == BOOLEAN && tree.falsepart.type.tag == BOOLEAN) {
            scanCond(tree.truepart);
            Bits initsAfterThenWhenTrue = initsWhenTrue.dup();
            Bits initsAfterThenWhenFalse = initsWhenFalse.dup();
            Bits uninitsAfterThenWhenTrue = uninitsWhenTrue.dup();
            Bits uninitsAfterThenWhenFalse = uninitsWhenFalse.dup();
            inits = initsBeforeElse;
            uninits = uninitsBeforeElse;
            scanCond(tree.falsepart);
            initsWhenTrue.andSet(initsAfterThenWhenTrue);
            initsWhenFalse.andSet(initsAfterThenWhenFalse);
            uninitsWhenTrue.andSet(uninitsAfterThenWhenTrue);
            uninitsWhenFalse.andSet(uninitsAfterThenWhenFalse);
        } else {
            scanExpr(tree.truepart);
            Bits initsAfterThen = inits.dup();
            Bits uninitsAfterThen = uninits.dup();
            inits = initsBeforeElse;
            uninits = uninitsBeforeElse;
            scanExpr(tree.falsepart);
            inits.andSet(initsAfterThen);
            uninits.andSet(uninitsAfterThen);
        }
    }

    public void visitIf(If tree) {
        scanCond(tree.cond);
        Bits initsBeforeElse = initsWhenFalse;
        Bits uninitsBeforeElse = uninitsWhenFalse;
        inits = initsWhenTrue;
        uninits = uninitsWhenTrue;
        scanStat(tree.thenpart);
        if (tree.elsepart != null) {
            boolean aliveAfterThen = alive;
            alive = true;
            Bits initsAfterThen = inits.dup();
            Bits uninitsAfterThen = uninits.dup();
            inits = initsBeforeElse;
            uninits = uninitsBeforeElse;
            scanStat(tree.elsepart);
            inits.andSet(initsAfterThen);
            uninits.andSet(uninitsAfterThen);
            alive = alive | aliveAfterThen;
        } else {
            inits.andSet(initsBeforeElse);
            uninits.andSet(uninitsBeforeElse);
            alive = true;
        }
    }

    public void visitBreak(Break tree) {
        recordExit(tree);
    }

    public void visitContinue(Continue tree) {
        recordExit(tree);
    }

    public void visitReturn(Return tree) {
        scanExpr(tree.expr);
        recordExit(tree);
    }

    public void visitThrow(Throw tree) {
        scanExpr(tree.expr);
        markThrown(tree, tree.expr.type);
        markDead();
    }

    public void visitApply(Apply tree) {
        scanExpr(tree.meth);
        scanExprs(tree.args);
        for (List l = tree.meth.type.thrown(); l.nonEmpty(); l = l.tail)
            markThrown(tree, (Type) l.head);
    }

    public void visitNewClass(NewClass tree) {
        scanExpr(tree.encl);
        scanExprs(tree.args);
        for (List l = tree.constructor.type.thrown(); l.nonEmpty(); l = l.tail)
            markThrown(tree, (Type) l.head);
        scan(tree.def);
    }

    public void visitNewArray(NewArray tree) {
        scanExprs(tree.dims);
        scanExprs(tree.elems);
    }

    public void visitAssert(Assert tree) {
        Bits initsExit = inits.dup();
        Bits uninitsExit = uninits.dup();
        scanCond(tree.cond);
        uninitsExit.andSet(uninitsWhenTrue);
        if (tree.detail != null) {
            inits = initsWhenFalse;
            uninits = uninitsWhenFalse;
            scanExpr(tree.detail);
        }
        inits = initsExit;
        uninits = uninitsExit;
    }

    public void visitAssign(Assign tree) {
        Tree lhs = TreeInfo.skipParens(tree.lhs);
        if (!(lhs instanceof Ident))
            scanExpr(lhs);
        scanExpr(tree.rhs);
        letInit(lhs);
    }

    public void visitAssignop(Assignop tree) {
        scanExpr(tree.lhs);
        scanExpr(tree.rhs);
        letInit(tree.lhs);
    }

    public void visitUnary(Unary tree) {
        switch (tree.tag) {
        case Tree.NOT:
            scanCond(tree.arg);
            Bits t = initsWhenFalse;
            initsWhenFalse = initsWhenTrue;
            initsWhenTrue = t;
            t = uninitsWhenFalse;
            uninitsWhenFalse = uninitsWhenTrue;
            uninitsWhenTrue = t;
            break;

        case Tree.PREINC:

        case Tree.POSTINC:

        case Tree.PREDEC:

        case Tree.POSTDEC:
            scanExpr(tree.arg);
            letInit(tree.arg);
            break;

        default:
            scanExpr(tree.arg);

        }
    }

    public void visitBinary(Binary tree) {
        switch (tree.tag) {
        case Tree.AND:
            scanCond(tree.lhs);
            Bits initsWhenFalseLeft = initsWhenFalse;
            Bits uninitsWhenFalseLeft = uninitsWhenFalse;
            inits = initsWhenTrue;
            uninits = uninitsWhenTrue;
            scanCond(tree.rhs);
            initsWhenFalse.andSet(initsWhenFalseLeft);
            uninitsWhenFalse.andSet(uninitsWhenFalseLeft);
            break;

        case Tree.OR:
            scanCond(tree.lhs);
            Bits initsWhenTrueLeft = initsWhenTrue;
            Bits uninitsWhenTrueLeft = uninitsWhenTrue;
            inits = initsWhenFalse;
            uninits = uninitsWhenFalse;
            scanCond(tree.rhs);
            initsWhenTrue.andSet(initsWhenTrueLeft);
            uninitsWhenTrue.andSet(uninitsWhenTrueLeft);
            break;

        default:
            scanExpr(tree.lhs);
            scanExpr(tree.rhs);

        }
    }

    public void visitIdent(Ident tree) {
        if (tree.sym.kind == VAR)
            checkInit(tree.pos, (VarSymbol) tree.sym);
    }

    /**
      * Perform definite assignment/unassignment analysis on a tree.
      */
    public void analyzeTree(Tree tree, TreeMaker make) {
        try {
            this.make = make;
            inits = new Bits();
            uninits = new Bits();
            uninitsTry = new Bits();
            initsWhenTrue = initsWhenFalse = uninitsWhenTrue = uninitsWhenFalse =
                    null;
            if (vars == null)
                vars = new VarSymbol[32];
            else
                for (int i = 0; i < vars.length; i++)
                    vars[i] = null;
            firstadr = 0;
            nextadr = 0;
            pendingExits = new ListBuffer();
            alive = true;
            this.thrown = this.caught = null;
            this.classDef = null;
            scan(tree);
        }
        finally { inits = uninits = uninitsTry = null;
                  initsWhenTrue = initsWhenFalse = uninitsWhenTrue =
                          uninitsWhenFalse = null;
              if (vars != null)
                  for (int i = 0; i < vars.length; i++)
                          vars[i] = null;
                          firstadr = 0;
                          nextadr = 0;
                          pendingExits = null;
                          this.make = null;
                          this.thrown = this.caught = null;
                          this.classDef = null;
                        } }
}

⌨️ 快捷键说明

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