src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java
branchdatagramsocketimpl-branch
changeset 58678 9cf78a70fa4f
parent 54894 382101e97784
child 58679 9c3209ff7550
equal deleted inserted replaced
58677:13588c901957 58678:9cf78a70fa4f
   164 
   164 
   165     boolean inCondSwitchExpression;
   165     boolean inCondSwitchExpression;
   166     Chain switchExpressionTrueChain;
   166     Chain switchExpressionTrueChain;
   167     Chain switchExpressionFalseChain;
   167     Chain switchExpressionFalseChain;
   168     List<LocalItem> stackBeforeSwitchExpression;
   168     List<LocalItem> stackBeforeSwitchExpression;
       
   169     LocalItem switchResult;
   169 
   170 
   170     /** Generate code to load an integer constant.
   171     /** Generate code to load an integer constant.
   171      *  @param n     The integer to be loaded.
   172      *  @param n     The integer to be loaded.
   172      */
   173      */
   173     void loadIntConst(int n) {
   174     void loadIntConst(int n) {
  1188         result = items.makeStackItem(pt);
  1189         result = items.makeStackItem(pt);
  1189     }
  1190     }
  1190 
  1191 
  1191     private void doHandleSwitchExpression(JCSwitchExpression tree) {
  1192     private void doHandleSwitchExpression(JCSwitchExpression tree) {
  1192         List<LocalItem> prevStackBeforeSwitchExpression = stackBeforeSwitchExpression;
  1193         List<LocalItem> prevStackBeforeSwitchExpression = stackBeforeSwitchExpression;
       
  1194         LocalItem prevSwitchResult = switchResult;
  1193         int limit = code.nextreg;
  1195         int limit = code.nextreg;
  1194         try {
  1196         try {
  1195             stackBeforeSwitchExpression = List.nil();
  1197             stackBeforeSwitchExpression = List.nil();
       
  1198             switchResult = null;
  1196             if (hasTry(tree)) {
  1199             if (hasTry(tree)) {
  1197                 //if the switch expression contains try-catch, the catch handlers need to have
  1200                 //if the switch expression contains try-catch, the catch handlers need to have
  1198                 //an empty stack. So stash whole stack to local variables, and restore it before
  1201                 //an empty stack. So stash whole stack to local variables, and restore it before
  1199                 //breaks:
  1202                 //breaks:
  1200                 while (code.state.stacksize > 0) {
  1203                 while (code.state.stacksize > 0) {
  1209                                                   this.env.enclMethod.sym);
  1212                                                   this.env.enclMethod.sym);
  1210                     LocalItem item = items.new LocalItem(type, code.newLocal(var));
  1213                     LocalItem item = items.new LocalItem(type, code.newLocal(var));
  1211                     stackBeforeSwitchExpression = stackBeforeSwitchExpression.prepend(item);
  1214                     stackBeforeSwitchExpression = stackBeforeSwitchExpression.prepend(item);
  1212                     item.store();
  1215                     item.store();
  1213                 }
  1216                 }
       
  1217                 switchResult = makeTemp(tree.type);
  1214             }
  1218             }
  1215             int prevLetExprStart = code.setLetExprStackPos(code.state.stacksize);
  1219             int prevLetExprStart = code.setLetExprStackPos(code.state.stacksize);
  1216             try {
  1220             try {
  1217                 handleSwitch(tree, tree.selector, tree.cases);
  1221                 handleSwitch(tree, tree.selector, tree.cases);
  1218             } finally {
  1222             } finally {
  1219                 code.setLetExprStackPos(prevLetExprStart);
  1223                 code.setLetExprStackPos(prevLetExprStart);
  1220             }
  1224             }
  1221         } finally {
  1225         } finally {
  1222             stackBeforeSwitchExpression = prevStackBeforeSwitchExpression;
  1226             stackBeforeSwitchExpression = prevStackBeforeSwitchExpression;
       
  1227             switchResult = prevSwitchResult;
  1223             code.endScopes(limit);
  1228             code.endScopes(limit);
  1224         }
  1229         }
  1225     }
  1230     }
  1226     //where:
  1231     //where:
  1227         private boolean hasTry(JCSwitchExpression tree) {
  1232         private boolean hasTry(JCSwitchExpression tree) {
  1715         Assert.check(code.isStatementStart());
  1720         Assert.check(code.isStatementStart());
  1716     }
  1721     }
  1717 
  1722 
  1718     public void visitBreak(JCBreak tree) {
  1723     public void visitBreak(JCBreak tree) {
  1719         Assert.check(code.isStatementStart());
  1724         Assert.check(code.isStatementStart());
       
  1725         final Env<GenContext> targetEnv = unwindBreak(tree.target);
       
  1726         targetEnv.info.addExit(code.branch(goto_));
       
  1727         endFinalizerGaps(env, targetEnv);
       
  1728     }
       
  1729 
       
  1730     public void visitYield(JCYield tree) {
       
  1731         Assert.check(code.isStatementStart());
  1720         final Env<GenContext> targetEnv;
  1732         final Env<GenContext> targetEnv;
  1721         if (tree.isValueBreak()) {
  1733         if (inCondSwitchExpression) {
  1722             //restore stack as it was before the switch expression:
  1734             CondItem value = genCond(tree.value, CRT_FLOW_TARGET);
  1723             for (LocalItem li : stackBeforeSwitchExpression) {
  1735             Chain falseJumps = value.jumpFalse();
  1724                 li.load();
  1736 
  1725             }
  1737             code.resolve(value.trueJumps);
  1726             if (inCondSwitchExpression) {
  1738             Env<GenContext> localEnv = unwindBreak(tree.target);
  1727                 CondItem value = genCond(tree.value, CRT_FLOW_TARGET);
  1739             reloadStackBeforeSwitchExpr();
  1728                 Chain falseJumps = value.jumpFalse();
  1740             Chain trueJumps = code.branch(goto_);
  1729                 targetEnv = unwindBreak(tree);
  1741 
  1730                 code.resolve(value.trueJumps);
  1742             endFinalizerGaps(env, localEnv);
  1731                 Chain trueJumps = code.branch(goto_);
  1743 
  1732                 if (switchExpressionTrueChain == null) {
  1744             code.resolve(falseJumps);
  1733                     switchExpressionTrueChain = trueJumps;
  1745             targetEnv = unwindBreak(tree.target);
  1734                 } else {
  1746             reloadStackBeforeSwitchExpr();
  1735                     switchExpressionTrueChain =
  1747             falseJumps = code.branch(goto_);
  1736                             Code.mergeChains(switchExpressionTrueChain, trueJumps);
  1748 
  1737                 }
  1749             if (switchExpressionTrueChain == null) {
  1738                 if (switchExpressionFalseChain == null) {
  1750                 switchExpressionTrueChain = trueJumps;
  1739                     switchExpressionFalseChain = falseJumps;
       
  1740                 } else {
       
  1741                     switchExpressionFalseChain =
       
  1742                             Code.mergeChains(switchExpressionFalseChain, falseJumps);
       
  1743                 }
       
  1744             } else {
  1751             } else {
  1745                 genExpr(tree.value, pt).load();
  1752                 switchExpressionTrueChain =
       
  1753                         Code.mergeChains(switchExpressionTrueChain, trueJumps);
       
  1754             }
       
  1755             if (switchExpressionFalseChain == null) {
       
  1756                 switchExpressionFalseChain = falseJumps;
       
  1757             } else {
       
  1758                 switchExpressionFalseChain =
       
  1759                         Code.mergeChains(switchExpressionFalseChain, falseJumps);
       
  1760             }
       
  1761         } else {
       
  1762             genExpr(tree.value, pt).load();
       
  1763             if (switchResult != null)
       
  1764                 switchResult.store();
       
  1765 
       
  1766             targetEnv = unwindBreak(tree.target);
       
  1767 
       
  1768             if (code.isAlive()) {
       
  1769                 reloadStackBeforeSwitchExpr();
       
  1770                 if (switchResult != null)
       
  1771                     switchResult.load();
       
  1772 
  1746                 code.state.forceStackTop(tree.target.type);
  1773                 code.state.forceStackTop(tree.target.type);
  1747                 targetEnv = unwindBreak(tree);
       
  1748                 targetEnv.info.addExit(code.branch(goto_));
  1774                 targetEnv.info.addExit(code.branch(goto_));
  1749             }
  1775                 code.markDead();
  1750         } else {
  1776             }
  1751             targetEnv = unwindBreak(tree);
       
  1752             targetEnv.info.addExit(code.branch(goto_));
       
  1753         }
  1777         }
  1754         endFinalizerGaps(env, targetEnv);
  1778         endFinalizerGaps(env, targetEnv);
  1755     }
  1779     }
  1756     //where:
  1780     //where:
  1757         private Env<GenContext> unwindBreak(JCBreak tree) {
  1781         /** As side-effect, might mark code as dead disabling any further emission.
       
  1782          */
       
  1783         private Env<GenContext> unwindBreak(JCTree target) {
  1758             int tmpPos = code.pendingStatPos;
  1784             int tmpPos = code.pendingStatPos;
  1759             Env<GenContext> targetEnv = unwind(tree.target, env);
  1785             Env<GenContext> targetEnv = unwind(target, env);
  1760             code.pendingStatPos = tmpPos;
  1786             code.pendingStatPos = tmpPos;
  1761             return targetEnv;
  1787             return targetEnv;
       
  1788         }
       
  1789 
       
  1790         private void reloadStackBeforeSwitchExpr() {
       
  1791             for (LocalItem li : stackBeforeSwitchExpression)
       
  1792                 li.load();
  1762         }
  1793         }
  1763 
  1794 
  1764     public void visitContinue(JCContinue tree) {
  1795     public void visitContinue(JCContinue tree) {
  1765         int tmpPos = code.pendingStatPos;
  1796         int tmpPos = code.pendingStatPos;
  1766         Env<GenContext> targetEnv = unwind(tree.target, env);
  1797         Env<GenContext> targetEnv = unwind(tree.target, env);