src/share/classes/com/sun/tools/javac/jvm/Gen.java
Print this page
*** 431,441 ****
* @param target The tree representing the structure that's aborted
* @param env The environment current at the non-local exit.
*/
boolean hasFinally(JCTree target, Env<GenContext> env) {
while (env.tree != target) {
! if (env.tree.getTag() == JCTree.TRY && env.info.finalize.hasFinalizer())
return true;
env = env.next;
}
return false;
}
--- 431,441 ----
* @param target The tree representing the structure that's aborted
* @param env The environment current at the non-local exit.
*/
boolean hasFinally(JCTree target, Env<GenContext> env) {
while (env.tree != target) {
! if (env.tree.getTag() == JCTree.Tag.TRY && env.info.finalize.hasFinalizer())
return true;
env = env.next;
}
return false;
}
*** 458,478 ****
// - clinitCode for class initializers
// - methodDefs for method definitions
for (List<JCTree> l = defs; l.nonEmpty(); l = l.tail) {
JCTree def = l.head;
switch (def.getTag()) {
! case JCTree.BLOCK:
JCBlock block = (JCBlock)def;
if ((block.flags & STATIC) != 0)
clinitCode.append(block);
else
initCode.append(block);
break;
! case JCTree.METHODDEF:
methodDefs.append(def);
break;
! case JCTree.VARDEF:
JCVariableDecl vdef = (JCVariableDecl) def;
VarSymbol sym = vdef.sym;
checkDimension(vdef.pos(), sym.type);
if (vdef.init != null) {
if ((sym.flags() & STATIC) == 0) {
--- 458,478 ----
// - clinitCode for class initializers
// - methodDefs for method definitions
for (List<JCTree> l = defs; l.nonEmpty(); l = l.tail) {
JCTree def = l.head;
switch (def.getTag()) {
! case BLOCK:
JCBlock block = (JCBlock)def;
if ((block.flags & STATIC) != 0)
clinitCode.append(block);
else
initCode.append(block);
break;
! case METHODDEF:
methodDefs.append(def);
break;
! case VARDEF:
JCVariableDecl vdef = (JCVariableDecl) def;
VarSymbol sym = vdef.sym;
checkDimension(vdef.pos(), sym.type);
if (vdef.init != null) {
if ((sym.flags() & STATIC) == 0) {
*** 705,725 ****
genStat(tree, env);
return;
}
int startpc = code.curPc();
genStat(tree, env);
! if (tree.getTag() == JCTree.BLOCK) crtFlags |= CRT_BLOCK;
code.crt.put(tree, crtFlags, startpc, code.curPc());
}
/** Derived visitor method: generate code for a statement.
*/
public void genStat(JCTree tree, Env<GenContext> env) {
if (code.isAlive()) {
code.statBegin(tree.pos);
genDef(tree, env);
! } else if (env.info.isSwitch && tree.getTag() == JCTree.VARDEF) {
// variables whose declarations are in a switch
// can be used even if the decl is unreachable.
code.newLocal(((JCVariableDecl) tree).sym);
}
}
--- 705,725 ----
genStat(tree, env);
return;
}
int startpc = code.curPc();
genStat(tree, env);
! if (tree.getTag() == JCTree.Tag.BLOCK) crtFlags |= CRT_BLOCK;
code.crt.put(tree, crtFlags, startpc, code.curPc());
}
/** Derived visitor method: generate code for a statement.
*/
public void genStat(JCTree tree, Env<GenContext> env) {
if (code.isAlive()) {
code.statBegin(tree.pos);
genDef(tree, env);
! } else if (env.info.isSwitch && tree.getTag() == JCTree.Tag.VARDEF) {
// variables whose declarations are in a switch
// can be used even if the decl is unreachable.
code.newLocal(((JCVariableDecl) tree).sym);
}
}
*** 782,792 ****
* should contain a proper tree to generate
* CharacterRangeTable branches for them.
*/
public CondItem genCond(JCTree _tree, boolean markBranches) {
JCTree inner_tree = TreeInfo.skipParens(_tree);
! if (inner_tree.getTag() == JCTree.CONDEXPR) {
JCConditional tree = (JCConditional)inner_tree;
CondItem cond = genCond(tree.cond, CRT_FLOW_CONTROLLER);
if (cond.isTrue()) {
code.resolve(cond.trueJumps);
CondItem result = genCond(tree.truepart, CRT_FLOW_TARGET);
--- 782,792 ----
* should contain a proper tree to generate
* CharacterRangeTable branches for them.
*/
public CondItem genCond(JCTree _tree, boolean markBranches) {
JCTree inner_tree = TreeInfo.skipParens(_tree);
! if (inner_tree.getTag() == JCTree.Tag.CONDEXPR) {
JCConditional tree = (JCConditional)inner_tree;
CondItem cond = genCond(tree.cond, CRT_FLOW_CONTROLLER);
if (cond.isTrue()) {
code.resolve(cond.trueJumps);
CondItem result = genCond(tree.truepart, CRT_FLOW_TARGET);
*** 1031,1041 ****
public void visitBlock(JCBlock tree) {
int limit = code.nextreg;
Env<GenContext> localEnv = env.dup(tree, new GenContext());
genStats(tree.stats, localEnv);
// End the scope of all block-local variables in variable info.
! if (env.tree.getTag() != JCTree.METHODDEF) {
code.statBegin(tree.endpos);
code.endScopes(limit);
code.pendingStatPos = Position.NOPOS;
}
}
--- 1031,1041 ----
public void visitBlock(JCBlock tree) {
int limit = code.nextreg;
Env<GenContext> localEnv = env.dup(tree, new GenContext());
genStats(tree.stats, localEnv);
// End the scope of all block-local variables in variable info.
! if (env.tree.getTag() != JCTree.Tag.METHODDEF) {
code.statBegin(tree.endpos);
code.endScopes(limit);
code.pendingStatPos = Position.NOPOS;
}
}
*** 1626,1640 ****
public void visitExec(JCExpressionStatement tree) {
// Optimize x++ to ++x and x-- to --x.
JCExpression e = tree.expr;
switch (e.getTag()) {
! case JCTree.POSTINC:
! ((JCUnary) e).setTag(JCTree.PREINC);
break;
! case JCTree.POSTDEC:
! ((JCUnary) e).setTag(JCTree.PREDEC);
break;
}
genExpr(tree.expr, tree.expr.type).drop();
}
--- 1626,1640 ----
public void visitExec(JCExpressionStatement tree) {
// Optimize x++ to ++x and x-- to --x.
JCExpression e = tree.expr;
switch (e.getTag()) {
! case POSTINC:
! ((JCUnary) e).setTag(JCTree.Tag.PREINC);
break;
! case POSTDEC:
! ((JCUnary) e).setTag(JCTree.Tag.PREDEC);
break;
}
genExpr(tree.expr, tree.expr.type).drop();
}
*** 1817,1833 ****
l = genExpr(tree.lhs, tree.lhs.type);
// If we have an increment of -32768 to +32767 of a local
// int variable we can use an incr instruction instead of
// proceeding further.
! if ((tree.getTag() == JCTree.PLUS_ASG || tree.getTag() == JCTree.MINUS_ASG) &&
l instanceof LocalItem &&
tree.lhs.type.tag <= INT &&
tree.rhs.type.tag <= INT &&
tree.rhs.type.constValue() != null) {
int ival = ((Number) tree.rhs.type.constValue()).intValue();
! if (tree.getTag() == JCTree.MINUS_ASG) ival = -ival;
((LocalItem)l).incr(ival);
result = l;
return;
}
// Otherwise, duplicate expression, load one copy
--- 1817,1833 ----
l = genExpr(tree.lhs, tree.lhs.type);
// If we have an increment of -32768 to +32767 of a local
// int variable we can use an incr instruction instead of
// proceeding further.
! if ((tree.getTag() == JCTree.Tag.PLUS_ASG || tree.getTag() == JCTree.Tag.MINUS_ASG) &&
l instanceof LocalItem &&
tree.lhs.type.tag <= INT &&
tree.rhs.type.tag <= INT &&
tree.rhs.type.constValue() != null) {
int ival = ((Number) tree.rhs.type.constValue()).intValue();
! if (tree.getTag() == JCTree.Tag.MINUS_ASG) ival = -ival;
((LocalItem)l).incr(ival);
result = l;
return;
}
// Otherwise, duplicate expression, load one copy
*** 1839,1871 ****
result = items.makeAssignItem(l);
}
public void visitUnary(JCUnary tree) {
OperatorSymbol operator = (OperatorSymbol)tree.operator;
! if (tree.getTag() == JCTree.NOT) {
CondItem od = genCond(tree.arg, false);
result = od.negate();
} else {
Item od = genExpr(tree.arg, operator.type.getParameterTypes().head);
switch (tree.getTag()) {
! case JCTree.POS:
result = od.load();
break;
! case JCTree.NEG:
result = od.load();
code.emitop0(operator.opcode);
break;
! case JCTree.COMPL:
result = od.load();
emitMinusOne(od.typecode);
code.emitop0(operator.opcode);
break;
! case JCTree.PREINC: case JCTree.PREDEC:
od.duplicate();
if (od instanceof LocalItem &&
(operator.opcode == iadd || operator.opcode == isub)) {
! ((LocalItem)od).incr(tree.getTag() == JCTree.PREINC ? 1 : -1);
result = od;
} else {
od.load();
code.emitop0(one(od.typecode));
code.emitop0(operator.opcode);
--- 1839,1871 ----
result = items.makeAssignItem(l);
}
public void visitUnary(JCUnary tree) {
OperatorSymbol operator = (OperatorSymbol)tree.operator;
! if (tree.getTag() == JCTree.Tag.NOT) {
CondItem od = genCond(tree.arg, false);
result = od.negate();
} else {
Item od = genExpr(tree.arg, operator.type.getParameterTypes().head);
switch (tree.getTag()) {
! case POS:
result = od.load();
break;
! case NEG:
result = od.load();
code.emitop0(operator.opcode);
break;
! case COMPL:
result = od.load();
emitMinusOne(od.typecode);
code.emitop0(operator.opcode);
break;
! case PREINC: case PREDEC:
od.duplicate();
if (od instanceof LocalItem &&
(operator.opcode == iadd || operator.opcode == isub)) {
! ((LocalItem)od).incr(tree.getTag() == JCTree.Tag.PREINC ? 1 : -1);
result = od;
} else {
od.load();
code.emitop0(one(od.typecode));
code.emitop0(operator.opcode);
*** 1875,1890 ****
Code.truncate(od.typecode) == INTcode)
code.emitop0(int2byte + od.typecode - BYTEcode);
result = items.makeAssignItem(od);
}
break;
! case JCTree.POSTINC: case JCTree.POSTDEC:
od.duplicate();
if (od instanceof LocalItem &&
(operator.opcode == iadd || operator.opcode == isub)) {
Item res = od.load();
! ((LocalItem)od).incr(tree.getTag() == JCTree.POSTINC ? 1 : -1);
result = res;
} else {
Item res = od.load();
od.stash(od.typecode);
code.emitop0(one(od.typecode));
--- 1875,1890 ----
Code.truncate(od.typecode) == INTcode)
code.emitop0(int2byte + od.typecode - BYTEcode);
result = items.makeAssignItem(od);
}
break;
! case POSTINC: case POSTDEC:
od.duplicate();
if (od instanceof LocalItem &&
(operator.opcode == iadd || operator.opcode == isub)) {
Item res = od.load();
! ((LocalItem)od).incr(tree.getTag() == JCTree.Tag.POSTINC ? 1 : -1);
result = res;
} else {
Item res = od.load();
od.stash(od.typecode);
code.emitop0(one(od.typecode));
*** 1896,1906 ****
code.emitop0(int2byte + od.typecode - BYTEcode);
od.store();
result = res;
}
break;
! case JCTree.NULLCHK:
result = od.load();
code.emitop0(dup);
genNullCheck(tree.pos());
break;
default:
--- 1896,1906 ----
code.emitop0(int2byte + od.typecode - BYTEcode);
od.store();
result = res;
}
break;
! case NULLCHK:
result = od.load();
code.emitop0(dup);
genNullCheck(tree.pos());
break;
default:
*** 1924,1934 ****
// Append all strings to buffer.
appendStrings(tree);
// Convert buffer to string.
bufferToString(tree.pos());
result = items.makeStackItem(syms.stringType);
! } else if (tree.getTag() == JCTree.AND) {
CondItem lcond = genCond(tree.lhs, CRT_FLOW_CONTROLLER);
if (!lcond.isFalse()) {
Chain falseJumps = lcond.jumpFalse();
code.resolve(lcond.trueJumps);
CondItem rcond = genCond(tree.rhs, CRT_FLOW_TARGET);
--- 1924,1934 ----
// Append all strings to buffer.
appendStrings(tree);
// Convert buffer to string.
bufferToString(tree.pos());
result = items.makeStackItem(syms.stringType);
! } else if (tree.getTag() == JCTree.Tag.AND) {
CondItem lcond = genCond(tree.lhs, CRT_FLOW_CONTROLLER);
if (!lcond.isFalse()) {
Chain falseJumps = lcond.jumpFalse();
code.resolve(lcond.trueJumps);
CondItem rcond = genCond(tree.rhs, CRT_FLOW_TARGET);
*** 1938,1948 ****
Code.mergeChains(falseJumps,
rcond.falseJumps));
} else {
result = lcond;
}
! } else if (tree.getTag() == JCTree.OR) {
CondItem lcond = genCond(tree.lhs, CRT_FLOW_CONTROLLER);
if (!lcond.isTrue()) {
Chain trueJumps = lcond.jumpTrue();
code.resolve(lcond.falseJumps);
CondItem rcond = genCond(tree.rhs, CRT_FLOW_TARGET);
--- 1938,1948 ----
Code.mergeChains(falseJumps,
rcond.falseJumps));
} else {
result = lcond;
}
! } else if (tree.getTag() == JCTree.Tag.OR) {
CondItem lcond = genCond(tree.lhs, CRT_FLOW_CONTROLLER);
if (!lcond.isTrue()) {
Chain trueJumps = lcond.jumpTrue();
code.resolve(lcond.falseJumps);
CondItem rcond = genCond(tree.rhs, CRT_FLOW_TARGET);
*** 1995,2005 ****
/** Add all strings in tree to string buffer.
*/
void appendStrings(JCTree tree) {
tree = TreeInfo.skipParens(tree);
! if (tree.getTag() == JCTree.PLUS && tree.type.constValue() == null) {
JCBinary op = (JCBinary) tree;
if (op.operator.kind == MTH &&
((OperatorSymbol) op.operator).opcode == string_add) {
appendStrings(op.lhs);
appendStrings(op.rhs);
--- 1995,2005 ----
/** Add all strings in tree to string buffer.
*/
void appendStrings(JCTree tree) {
tree = TreeInfo.skipParens(tree);
! if (tree.getTag() == JCTree.Tag.PLUS && tree.type.constValue() == null) {
JCBinary op = (JCBinary) tree;
if (op.operator.kind == MTH &&
((OperatorSymbol) op.operator).opcode == string_add) {
appendStrings(op.lhs);
appendStrings(op.rhs);
*** 2238,2248 ****
nerrs++;
}
if (nerrs != 0) {
// if errors, discard code
for (List<JCTree> l = cdef.defs; l.nonEmpty(); l = l.tail) {
! if (l.head.getTag() == JCTree.METHODDEF)
((JCMethodDecl) l.head).sym.code = null;
}
}
cdef.defs = List.nil(); // discard trees
return nerrs == 0;
--- 2238,2248 ----
nerrs++;
}
if (nerrs != 0) {
// if errors, discard code
for (List<JCTree> l = cdef.defs; l.nonEmpty(); l = l.tail) {
! if (l.head.getTag() == JCTree.Tag.METHODDEF)
((JCMethodDecl) l.head).sym.code = null;
}
}
cdef.defs = List.nil(); // discard trees
return nerrs == 0;