< prev index next >
src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java
Print this page
rev 52724 : imported patch 8214031
rev 52725 : [mq]: 8214031-review1
*** 23,32 ****
--- 23,34 ----
* questions.
*/
package com.sun.tools.javac.jvm;
+ import java.util.function.BiConsumer;
+
import com.sun.tools.javac.tree.TreeInfo.PosKind;
import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.code.*;
*** 159,168 ****
--- 161,174 ----
/** An object containing mappings of syntax trees to their
* ending source positions.
*/
EndPosTable endPosTable;
+ boolean inCondSwitchExpression;
+ Chain switchExpressionTrueChain;
+ Chain switchExpressionFalseChain;
+
/** Generate code to load an integer constant.
* @param n The integer to be loaded.
*/
void loadIntConst(int n) {
items.makeImmediateItem(syms.intType, n).load();
*** 717,726 ****
--- 723,768 ----
CondItem result = items.makeCondItem(second.opcode,
Code.mergeChains(trueJumps, second.trueJumps),
Code.mergeChains(falseJumps, second.falseJumps));
if (markBranches) result.tree = tree.falsepart;
return result;
+ } else if (inner_tree.hasTag(SWITCH_EXPRESSION)) {
+ boolean prevInCondSwitchExpression = inCondSwitchExpression;
+ Chain prevSwitchExpressionTrueChain = switchExpressionTrueChain;
+ Chain prevSwitchExpressionFalseChain = switchExpressionFalseChain;
+ try {
+ inCondSwitchExpression = true;
+ switchExpressionTrueChain = null;
+ switchExpressionFalseChain = null;
+ try {
+ doHandleSwitchExpression((JCSwitchExpression) inner_tree);
+ } catch (CompletionFailure ex) {
+ chk.completionError(_tree.pos(), ex);
+ code.state.stacksize = 1;
+ }
+ CondItem result = items.makeCondItem(goto_,
+ switchExpressionTrueChain,
+ switchExpressionFalseChain);
+ if (markBranches) result.tree = _tree;
+ return result;
+ } finally {
+ inCondSwitchExpression = prevInCondSwitchExpression;
+ switchExpressionTrueChain = prevSwitchExpressionTrueChain;
+ switchExpressionFalseChain = prevSwitchExpressionFalseChain;
+ }
+ } else if (inner_tree.hasTag(LETEXPR) && ((LetExpr) inner_tree).needsCond) {
+ LetExpr tree = (LetExpr) inner_tree;
+ int limit = code.nextreg;
+ int prevLetExprStart = code.setLetExprStackPos(code.state.stacksize);
+ try {
+ genStats(tree.defs, env);
+ } finally {
+ code.setLetExprStackPos(prevLetExprStart);
+ }
+ CondItem result = genCond(tree.expr, markBranches);
+ code.endScopes(limit);
+ return result;
} else {
CondItem result = genExpr(_tree, syms.booleanType).mkCond();
if (markBranches) result.tree = _tree;
return result;
}
*** 1117,1145 ****
exit.state.defined.excludeFrom(code.nextreg);
}
}
public void visitSwitch(JCSwitch tree) {
int limit = code.nextreg;
! Assert.check(!tree.selector.type.hasTag(CLASS));
int startpcCrt = genCrt ? code.curCP() : 0;
Assert.check(code.isStatementStart());
! Item sel = genExpr(tree.selector, syms.intType);
! List<JCCase> cases = tree.cases;
if (cases.isEmpty()) {
// We are seeing: switch <sel> {}
sel.load().drop();
if (genCrt)
! code.crt.put(TreeInfo.skipParens(tree.selector),
CRT_FLOW_CONTROLLER, startpcCrt, code.curCP());
} else {
// We are seeing a nonempty switch.
sel.load();
if (genCrt)
! code.crt.put(TreeInfo.skipParens(tree.selector),
CRT_FLOW_CONTROLLER, startpcCrt, code.curCP());
! Env<GenContext> switchEnv = env.dup(tree, new GenContext());
switchEnv.info.isSwitch = true;
// Compute number of labels and minimum and maximum label values.
// For each case, store its label in an array.
int lo = Integer.MAX_VALUE; // minimum label.
--- 1159,1212 ----
exit.state.defined.excludeFrom(code.nextreg);
}
}
public void visitSwitch(JCSwitch tree) {
+ handleSwitch(tree, tree.selector, tree.cases);
+ }
+
+ @Override
+ public void visitSwitchExpression(JCSwitchExpression tree) {
+ code.resolvePending();
+ boolean prevInCondSwitchExpression = inCondSwitchExpression;
+ try {
+ inCondSwitchExpression = false;
+ doHandleSwitchExpression(tree);
+ } finally {
+ inCondSwitchExpression = prevInCondSwitchExpression;
+ }
+ result = items.makeStackItem(pt);
+ }
+
+ private void doHandleSwitchExpression(JCSwitchExpression tree) {
+ int prevLetExprStart = code.setLetExprStackPos(code.state.stacksize);
+ try {
+ handleSwitch(tree, tree.selector, tree.cases);
+ } finally {
+ code.setLetExprStackPos(prevLetExprStart);
+ }
+ }
+
+ private void handleSwitch(JCTree swtch, JCExpression selector, List<JCCase> cases) {
int limit = code.nextreg;
! Assert.check(!selector.type.hasTag(CLASS));
int startpcCrt = genCrt ? code.curCP() : 0;
Assert.check(code.isStatementStart());
! Item sel = genExpr(selector, syms.intType);
if (cases.isEmpty()) {
// We are seeing: switch <sel> {}
sel.load().drop();
if (genCrt)
! code.crt.put(TreeInfo.skipParens(selector),
CRT_FLOW_CONTROLLER, startpcCrt, code.curCP());
} else {
// We are seeing a nonempty switch.
sel.load();
if (genCrt)
! code.crt.put(TreeInfo.skipParens(selector),
CRT_FLOW_CONTROLLER, startpcCrt, code.curCP());
! Env<GenContext> switchEnv = env.dup(swtch, new GenContext());
switchEnv.info.isSwitch = true;
// Compute number of labels and minimum and maximum label values.
// For each case, store its label in an array.
int lo = Integer.MAX_VALUE; // minimum label.
*** 1591,1604 ****
Assert.check(code.isStatementStart());
}
public void visitBreak(JCBreak tree) {
int tmpPos = code.pendingStatPos;
Env<GenContext> targetEnv = unwind(tree.target, env);
code.pendingStatPos = tmpPos;
! Assert.check(code.isStatementStart());
targetEnv.info.addExit(code.branch(goto_));
endFinalizerGaps(env, targetEnv);
}
public void visitContinue(JCContinue tree) {
int tmpPos = code.pendingStatPos;
--- 1658,1696 ----
Assert.check(code.isStatementStart());
}
public void visitBreak(JCBreak tree) {
int tmpPos = code.pendingStatPos;
+ Assert.check(code.isStatementStart());
Env<GenContext> targetEnv = unwind(tree.target, env);
code.pendingStatPos = tmpPos;
! if (tree.isValueBreak()) {
! if (inCondSwitchExpression) {
! CondItem value = genCond(tree.value, CRT_FLOW_TARGET);
! Chain falseJumps = value.jumpFalse();
! code.resolve(value.trueJumps);
! Chain trueJumps = code.branch(goto_);
! if (switchExpressionTrueChain == null) {
! switchExpressionTrueChain = trueJumps;
! } else {
! switchExpressionTrueChain =
! Code.mergeChains(switchExpressionTrueChain, trueJumps);
! }
! if (switchExpressionFalseChain == null) {
! switchExpressionFalseChain = falseJumps;
! } else {
! switchExpressionFalseChain =
! Code.mergeChains(switchExpressionFalseChain, falseJumps);
! }
! } else {
! genExpr(tree.value, pt).load();
! code.state.forceStackTop(tree.target.type);
targetEnv.info.addExit(code.branch(goto_));
+ }
+ } else {
+ targetEnv.info.addExit(code.branch(goto_));
+ }
endFinalizerGaps(env, targetEnv);
}
public void visitContinue(JCContinue tree) {
int tmpPos = code.pendingStatPos;
< prev index next >