1. Using UniqueTag.DOUBLE_MARK in interpreter instaed of Object instance to mark double values on stack for better debug printouts.

2. In parse tree use Node instances, not Node.Target to denote target nodes as later just leads to code bloat without safty benefits.
This commit is contained in:
igor%mir2.org 2004-09-15 13:51:19 +00:00
parent 4f61cba96e
commit bef182034b
5 changed files with 111 additions and 99 deletions

View File

@ -141,7 +141,7 @@ final class IRFactory
Node.Jump switchNode = (Node.Jump)switchBlock.getFirstChild(); Node.Jump switchNode = (Node.Jump)switchBlock.getFirstChild();
if (switchNode.getType() != Token.SWITCH) throw Kit.codeBug(); if (switchNode.getType() != Token.SWITCH) throw Kit.codeBug();
Node.Target gotoTarget = new Node.Target(); Node gotoTarget = Node.newTarget();
if (caseExpression != null) { if (caseExpression != null) {
Node.Jump caseNode = new Node.Jump(Token.CASE, caseExpression); Node.Jump caseNode = new Node.Jump(Token.CASE, caseExpression);
caseNode.target = gotoTarget; caseNode.target = gotoTarget;
@ -159,12 +159,12 @@ final class IRFactory
Node.Jump switchNode = (Node.Jump)switchBlock.getFirstChild(); Node.Jump switchNode = (Node.Jump)switchBlock.getFirstChild();
if (switchNode.getType() != Token.SWITCH) throw Kit.codeBug(); if (switchNode.getType() != Token.SWITCH) throw Kit.codeBug();
Node.Target switchBreakTarget = new Node.Target(); Node switchBreakTarget = Node.newTarget();
// switchNode.target is only used by NodeTransformer // switchNode.target is only used by NodeTransformer
// to detect switch end // to detect switch end
switchNode.target = switchBreakTarget; switchNode.target = switchBreakTarget;
Node.Target defaultTarget = switchNode.getDefault(); Node defaultTarget = switchNode.getDefault();
if (defaultTarget == null) { if (defaultTarget == null) {
defaultTarget = switchBreakTarget; defaultTarget = switchBreakTarget;
} }
@ -337,7 +337,7 @@ final class IRFactory
// node. And in the LABEL node, so breaks get the // node. And in the LABEL node, so breaks get the
// right target. // right target.
Node.Target breakTarget = new Node.Target(); Node breakTarget = Node.newTarget();
Node block = new Node(Token.BLOCK, label, statement, breakTarget); Node block = new Node(Token.BLOCK, label, statement, breakTarget);
label.target = breakTarget; label.target = breakTarget;
@ -499,14 +499,14 @@ final class IRFactory
private Node createLoop(Node.Jump loop, int loopType, Node body, Node cond, private Node createLoop(Node.Jump loop, int loopType, Node body, Node cond,
Node init, Node incr) Node init, Node incr)
{ {
Node.Target bodyTarget = new Node.Target(); Node bodyTarget = Node.newTarget();
Node.Target condTarget = new Node.Target(); Node condTarget = Node.newTarget();
if (loopType == LOOP_FOR && cond.getType() == Token.EMPTY) { if (loopType == LOOP_FOR && cond.getType() == Token.EMPTY) {
cond = new Node(Token.TRUE); cond = new Node(Token.TRUE);
} }
Node.Jump IFEQ = new Node.Jump(Token.IFEQ, cond); Node.Jump IFEQ = new Node.Jump(Token.IFEQ, cond);
IFEQ.target = bodyTarget; IFEQ.target = bodyTarget;
Node.Target breakTarget = new Node.Target(); Node breakTarget = Node.newTarget();
loop.addChildToBack(bodyTarget); loop.addChildToBack(bodyTarget);
loop.addChildrenToBack(body); loop.addChildrenToBack(body);
@ -519,7 +519,7 @@ final class IRFactory
loop.addChildToBack(breakTarget); loop.addChildToBack(breakTarget);
loop.target = breakTarget; loop.target = breakTarget;
Node.Target continueTarget = condTarget; Node continueTarget = condTarget;
if (loopType == LOOP_WHILE || loopType == LOOP_FOR) { if (loopType == LOOP_WHILE || loopType == LOOP_FOR) {
// Just add a GOTO to the condition in the do..while // Just add a GOTO to the condition in the do..while
@ -532,7 +532,7 @@ final class IRFactory
} }
loop.addChildToFront(init); loop.addChildToFront(init);
} }
Node.Target incrTarget = new Node.Target(); Node incrTarget = Node.newTarget();
loop.addChildAfter(incrTarget, body); loop.addChildAfter(incrTarget, body);
if (incr.getType() != Token.EMPTY) { if (incr.getType() != Token.EMPTY) {
incr = new Node(Token.EXPR_VOID, incr); incr = new Node(Token.EXPR_VOID, incr);
@ -647,11 +647,11 @@ final class IRFactory
if (hasCatch) { if (hasCatch) {
// jump around catch code // jump around catch code
Node.Target endCatch = new Node.Target(); Node endCatch = Node.newTarget();
pn.addChildToBack(makeJump(Token.GOTO, endCatch)); pn.addChildToBack(makeJump(Token.GOTO, endCatch));
// make a TARGET for the catch that the tcf node knows about // make a TARGET for the catch that the tcf node knows about
Node.Target catchTarget = new Node.Target(); Node catchTarget = Node.newTarget();
pn.target = catchTarget; pn.target = catchTarget;
// mark it // mark it
pn.addChildToBack(catchTarget); pn.addChildToBack(catchTarget);
@ -766,14 +766,14 @@ final class IRFactory
} }
if (hasFinally) { if (hasFinally) {
Node.Target finallyTarget = new Node.Target(); Node finallyTarget = Node.newTarget();
pn.setFinally(finallyTarget); pn.setFinally(finallyTarget);
// add jsr finally to the try block // add jsr finally to the try block
pn.addChildToBack(makeJump(Token.JSR, finallyTarget)); pn.addChildToBack(makeJump(Token.JSR, finallyTarget));
// jump around finally code // jump around finally code
Node.Target finallyEnd = new Node.Target(); Node finallyEnd = Node.newTarget();
pn.addChildToBack(makeJump(Token.GOTO, finallyEnd)); pn.addChildToBack(makeJump(Token.GOTO, finallyEnd));
pn.addChildToBack(finallyTarget); pn.addChildToBack(finallyTarget);
@ -890,7 +890,7 @@ final class IRFactory
} }
Node result = new Node(Token.BLOCK, lineno); Node result = new Node(Token.BLOCK, lineno);
Node.Target ifNotTarget = new Node.Target(); Node ifNotTarget = Node.newTarget();
Node.Jump IFNE = new Node.Jump(Token.IFNE, cond); Node.Jump IFNE = new Node.Jump(Token.IFNE, cond);
IFNE.target = ifNotTarget; IFNE.target = ifNotTarget;
@ -898,7 +898,7 @@ final class IRFactory
result.addChildrenToBack(ifTrue); result.addChildrenToBack(ifTrue);
if (ifFalse != null) { if (ifFalse != null) {
Node.Target endTarget = new Node.Target(); Node endTarget = Node.newTarget();
result.addChildToBack(makeJump(Token.GOTO, endTarget)); result.addChildToBack(makeJump(Token.GOTO, endTarget));
result.addChildToBack(ifNotTarget); result.addChildToBack(ifNotTarget);
result.addChildrenToBack(ifFalse); result.addChildrenToBack(ifFalse);
@ -1327,7 +1327,7 @@ final class IRFactory
return result; return result;
} }
private Node.Jump makeJump(int type, Node.Target target) private Node.Jump makeJump(int type, Node target)
{ {
Node.Jump n = new Node.Jump(type); Node.Jump n = new Node.Jump(type);
n.target = target; n.target = target;

View File

@ -200,8 +200,6 @@ public class Interpreter
// ECF_ or Expression Context Flags constants: for now only TAIL is available // ECF_ or Expression Context Flags constants: for now only TAIL is available
private static final int ECF_TAIL = 1 << 0; private static final int ECF_TAIL = 1 << 0;
private static final Object DBL_MRK = new Object();
/** /**
* Class to hold data corresponding to one interpreted call stack frame. * Class to hold data corresponding to one interpreted call stack frame.
*/ */
@ -216,7 +214,7 @@ public class Interpreter
// stack[0 <= i < localShift]: arguments and local variables // stack[0 <= i < localShift]: arguments and local variables
// stack[localShift <= i <= emptyStackTop]: used for local temporaries // stack[localShift <= i <= emptyStackTop]: used for local temporaries
// stack[emptyStackTop < i < stack.length]: stack data // stack[emptyStackTop < i < stack.length]: stack data
// sDbl[i]: if stack[i] is DBL_MRK, sDbl[i] holds the number value // sDbl[i]: if stack[i] is UniqueTag.DOUBLE_MARK, sDbl[i] holds the number value
Object[] stack; Object[] stack;
double[] sDbl; double[] sDbl;
@ -632,13 +630,13 @@ public class Interpreter
break; break;
case Token.TARGET: case Token.TARGET:
markTargetLabel((Node.Target)node); markTargetLabel(node);
break; break;
case Token.IFEQ : case Token.IFEQ :
case Token.IFNE : case Token.IFNE :
{ {
Node.Target target = ((Node.Jump)node).target; Node target = ((Node.Jump)node).target;
visitExpression(child, 0); visitExpression(child, 0);
addGoto(target, type); addGoto(target, type);
stackChange(-1); stackChange(-1);
@ -647,14 +645,14 @@ public class Interpreter
case Token.GOTO: case Token.GOTO:
{ {
Node.Target target = ((Node.Jump)node).target; Node target = ((Node.Jump)node).target;
addGoto(target, type); addGoto(target, type);
} }
break; break;
case Token.JSR: case Token.JSR:
{ {
Node.Target target = ((Node.Jump)node).target; Node target = ((Node.Jump)node).target;
addGoto(target, Icode_GOSUB); addGoto(target, Icode_GOSUB);
} }
break; break;
@ -696,7 +694,7 @@ public class Interpreter
child = child.getNext(); child = child.getNext();
} }
Node.Target catchTarget = tryNode.target; Node catchTarget = tryNode.target;
if (catchTarget != null) { if (catchTarget != null) {
int catchStartPC int catchStartPC
= itsLabelTable[getTargetLabel(catchTarget)]; = itsLabelTable[getTargetLabel(catchTarget)];
@ -704,7 +702,7 @@ public class Interpreter
tryStart, catchStartPC, catchStartPC, tryStart, catchStartPC, catchStartPC,
false, exceptionObjectLocal, scopeLocal); false, exceptionObjectLocal, scopeLocal);
} }
Node.Target finallyTarget = tryNode.getFinally(); Node finallyTarget = tryNode.getFinally();
if (finallyTarget != null) { if (finallyTarget != null) {
int finallyStartPC int finallyStartPC
= itsLabelTable[getTargetLabel(finallyTarget)]; = itsLabelTable[getTargetLabel(finallyTarget)];
@ -1359,9 +1357,9 @@ public class Interpreter
return localBlock.getExistingIntProp(Node.LOCAL_PROP); return localBlock.getExistingIntProp(Node.LOCAL_PROP);
} }
private int getTargetLabel(Node.Target target) private int getTargetLabel(Node target)
{ {
int label = target.labelId; int label = target.labelId();
if (label != -1) { if (label != -1) {
return label; return label;
} }
@ -1378,11 +1376,11 @@ public class Interpreter
itsLabelTableTop = label + 1; itsLabelTableTop = label + 1;
itsLabelTable[label] = -1; itsLabelTable[label] = -1;
target.labelId = label; target.labelId(label);
return label; return label;
} }
private void markTargetLabel(Node.Target target) private void markTargetLabel(Node target)
{ {
int label = getTargetLabel(target); int label = getTargetLabel(target);
if (itsLabelTable[label] != -1) { if (itsLabelTable[label] != -1) {
@ -1392,7 +1390,7 @@ public class Interpreter
itsLabelTable[label] = itsICodeTop; itsLabelTable[label] = itsICodeTop;
} }
private void addGoto(Node.Target target, int gotoOp) private void addGoto(Node target, int gotoOp)
{ {
int label = getTargetLabel(target); int label = getTargetLabel(target);
if (!(label < itsLabelTableTop)) Kit.codeBug(); if (!(label < itsLabelTableTop)) Kit.codeBug();
@ -2093,7 +2091,7 @@ public class Interpreter
private static Object interpret(Context cx, CallFrame frame) private static Object interpret(Context cx, CallFrame frame)
{ {
final Object DBL_MRK = Interpreter.DBL_MRK; final Object DBL_MRK = UniqueTag.DOUBLE_MARK;
final Scriptable undefined = Undefined.instance; final Scriptable undefined = Undefined.instance;
final boolean instructionCounting = (cx.instructionThreshold != 0); final boolean instructionCounting = (cx.instructionThreshold != 0);
@ -3364,7 +3362,7 @@ switch (op) {
} else { } else {
Object result; Object result;
result = frame.result; result = frame.result;
if (result == DBL_MRK) { if (result == UniqueTag.DOUBLE_MARK) {
result = ScriptRuntime.wrapNumber(frame.resultDbl); result = ScriptRuntime.wrapNumber(frame.resultDbl);
} }
frame.debuggerFrame.onExit(cx, false, result); frame.debuggerFrame.onExit(cx, false, result);
@ -3403,7 +3401,7 @@ switch (op) {
{ {
Object x = frame.stack[i]; Object x = frame.stack[i];
double value; double value;
if (x == DBL_MRK) { if (x == UniqueTag.DOUBLE_MARK) {
value = frame.sDbl[i]; value = frame.sDbl[i];
} else { } else {
value = ScriptRuntime.toNumber(x); value = ScriptRuntime.toNumber(x);
@ -3414,7 +3412,11 @@ switch (op) {
private static double stack_double(CallFrame frame, int i) private static double stack_double(CallFrame frame, int i)
{ {
Object x = frame.stack[i]; Object x = frame.stack[i];
return (x != DBL_MRK) ? ScriptRuntime.toNumber(x) : frame.sDbl[i]; if (x != UniqueTag.DOUBLE_MARK) {
return ScriptRuntime.toNumber(x);
} else {
return frame.sDbl[i];
}
} }
private static boolean stack_boolean(CallFrame frame, int i) private static boolean stack_boolean(CallFrame frame, int i)
@ -3424,7 +3426,7 @@ switch (op) {
return true; return true;
} else if (x == Boolean.FALSE) { } else if (x == Boolean.FALSE) {
return false; return false;
} else if (x == DBL_MRK) { } else if (x == UniqueTag.DOUBLE_MARK) {
double d = frame.sDbl[i]; double d = frame.sDbl[i];
return d == d && d != 0.0; return d == d && d != 0.0;
} else if (x == null || x == Undefined.instance) { } else if (x == null || x == Undefined.instance) {
@ -3446,15 +3448,15 @@ switch (op) {
Object lhs = stack[stackTop]; Object lhs = stack[stackTop];
double d; double d;
boolean leftRightOrder; boolean leftRightOrder;
if (rhs == DBL_MRK) { if (rhs == UniqueTag.DOUBLE_MARK) {
d = sDbl[stackTop + 1]; d = sDbl[stackTop + 1];
if (lhs == DBL_MRK) { if (lhs == UniqueTag.DOUBLE_MARK) {
sDbl[stackTop] += d; sDbl[stackTop] += d;
return; return;
} }
leftRightOrder = true; leftRightOrder = true;
// fallthrough to object + number code // fallthrough to object + number code
} else if (lhs == DBL_MRK) { } else if (lhs == UniqueTag.DOUBLE_MARK) {
d = sDbl[stackTop]; d = sDbl[stackTop];
lhs = rhs; lhs = rhs;
leftRightOrder = false; leftRightOrder = false;
@ -3475,7 +3477,7 @@ switch (op) {
? ((Number)lhs).doubleValue() : ScriptRuntime.toNumber(lhs); ? ((Number)lhs).doubleValue() : ScriptRuntime.toNumber(lhs);
double rDbl = (rhs instanceof Number) double rDbl = (rhs instanceof Number)
? ((Number)rhs).doubleValue() : ScriptRuntime.toNumber(rhs); ? ((Number)rhs).doubleValue() : ScriptRuntime.toNumber(rhs);
stack[stackTop] = DBL_MRK; stack[stackTop] = UniqueTag.DOUBLE_MARK;
sDbl[stackTop] = lDbl + rDbl; sDbl[stackTop] = lDbl + rDbl;
} }
return; return;
@ -3501,7 +3503,7 @@ switch (op) {
} else { } else {
double lDbl = (lhs instanceof Number) double lDbl = (lhs instanceof Number)
? ((Number)lhs).doubleValue() : ScriptRuntime.toNumber(lhs); ? ((Number)lhs).doubleValue() : ScriptRuntime.toNumber(lhs);
stack[stackTop] = DBL_MRK; stack[stackTop] = UniqueTag.DOUBLE_MARK;
sDbl[stackTop] = lDbl + d; sDbl[stackTop] = lDbl + d;
} }
} }
@ -3516,10 +3518,10 @@ switch (op) {
number_compare: number_compare:
{ {
double rDbl, lDbl; double rDbl, lDbl;
if (rhs == DBL_MRK) { if (rhs == UniqueTag.DOUBLE_MARK) {
rDbl = frame.sDbl[i + 1]; rDbl = frame.sDbl[i + 1];
lDbl = stack_double(frame, i); lDbl = stack_double(frame, i);
} else if (lhs == DBL_MRK) { } else if (lhs == UniqueTag.DOUBLE_MARK) {
rDbl = ScriptRuntime.toNumber(rhs); rDbl = ScriptRuntime.toNumber(rhs);
lDbl = frame.sDbl[i]; lDbl = frame.sDbl[i];
} else { } else {
@ -3567,14 +3569,14 @@ switch (op) {
boolean result; boolean result;
Object rhs = frame.stack[i + 1]; Object rhs = frame.stack[i + 1];
Object lhs = frame.stack[i]; Object lhs = frame.stack[i];
if (rhs == DBL_MRK) { if (rhs == UniqueTag.DOUBLE_MARK) {
if (lhs == DBL_MRK) { if (lhs == UniqueTag.DOUBLE_MARK) {
result = (frame.sDbl[i] == frame.sDbl[i + 1]); result = (frame.sDbl[i] == frame.sDbl[i + 1]);
} else { } else {
result = ScriptRuntime.eqNumber(frame.sDbl[i + 1], lhs); result = ScriptRuntime.eqNumber(frame.sDbl[i + 1], lhs);
} }
} else { } else {
if (lhs == DBL_MRK) { if (lhs == UniqueTag.DOUBLE_MARK) {
result = ScriptRuntime.eqNumber(frame.sDbl[i], rhs); result = ScriptRuntime.eqNumber(frame.sDbl[i], rhs);
} else { } else {
result = ScriptRuntime.eq(lhs, rhs); result = ScriptRuntime.eq(lhs, rhs);
@ -3591,9 +3593,9 @@ switch (op) {
boolean result; boolean result;
double_compare: { double_compare: {
double rdbl, ldbl; double rdbl, ldbl;
if (rhs == DBL_MRK) { if (rhs == UniqueTag.DOUBLE_MARK) {
rdbl = frame.sDbl[i + 1]; rdbl = frame.sDbl[i + 1];
if (lhs == DBL_MRK) { if (lhs == UniqueTag.DOUBLE_MARK) {
ldbl = frame.sDbl[i]; ldbl = frame.sDbl[i];
} else if (lhs instanceof Number) { } else if (lhs instanceof Number) {
ldbl = ((Number)lhs).doubleValue(); ldbl = ((Number)lhs).doubleValue();
@ -3601,9 +3603,9 @@ switch (op) {
result = false; result = false;
break double_compare; break double_compare;
} }
} else if (lhs == DBL_MRK) { } else if (lhs == UniqueTag.DOUBLE_MARK) {
ldbl = frame.sDbl[i]; ldbl = frame.sDbl[i];
if (rhs == DBL_MRK) { if (rhs == UniqueTag.DOUBLE_MARK) {
rdbl = frame.sDbl[i + 1]; rdbl = frame.sDbl[i + 1];
} else if (rhs instanceof Number) { } else if (rhs instanceof Number) {
rdbl = ((Number)rhs).doubleValue(); rdbl = ((Number)rhs).doubleValue();
@ -3624,11 +3626,12 @@ switch (op) {
private static void do_getElem(CallFrame frame, int i, Context cx) private static void do_getElem(CallFrame frame, int i, Context cx)
{ {
Object lhs = frame.stack[i]; Object lhs = frame.stack[i];
if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(frame.sDbl[i]); if (lhs == UniqueTag.DOUBLE_MARK) {
lhs = ScriptRuntime.wrapNumber(frame.sDbl[i]);
}
Object result; Object result;
Object id = frame.stack[i + 1]; Object id = frame.stack[i + 1];
if (id != DBL_MRK) { if (id != UniqueTag.DOUBLE_MARK) {
result = ScriptRuntime.getObjectElem(lhs, id, cx, frame.scope); result = ScriptRuntime.getObjectElem(lhs, id, cx, frame.scope);
} else { } else {
double val = frame.sDbl[i + 1]; double val = frame.sDbl[i + 1];
@ -3653,13 +3656,16 @@ switch (op) {
private static void do_setElem(CallFrame frame, int i, Context cx) private static void do_setElem(CallFrame frame, int i, Context cx)
{ {
Object rhs = frame.stack[i + 2]; Object rhs = frame.stack[i + 2];
if (rhs == DBL_MRK) rhs = ScriptRuntime.wrapNumber(frame.sDbl[i + 2]); if (rhs == UniqueTag.DOUBLE_MARK) {
rhs = ScriptRuntime.wrapNumber(frame.sDbl[i + 2]);
}
Object lhs = frame.stack[i]; Object lhs = frame.stack[i];
if (lhs == DBL_MRK) lhs = ScriptRuntime.wrapNumber(frame.sDbl[i]); if (lhs == UniqueTag.DOUBLE_MARK) {
lhs = ScriptRuntime.wrapNumber(frame.sDbl[i]);
}
Object result; Object result;
Object id = frame.stack[i + 1]; Object id = frame.stack[i + 1];
if (id != DBL_MRK) { if (id != UniqueTag.DOUBLE_MARK) {
result = ScriptRuntime.setObjectElem(lhs, id, rhs, cx, frame.scope); result = ScriptRuntime.setObjectElem(lhs, id, rhs, cx, frame.scope);
} else { } else {
double val = frame.sDbl[i + 1]; double val = frame.sDbl[i + 1];
@ -3690,7 +3696,9 @@ switch (op) {
Object[] args = new Object[count]; Object[] args = new Object[count];
for (int i = 0; i != count; ++i, ++shift) { for (int i = 0; i != count; ++i, ++shift) {
Object val = stack[shift]; Object val = stack[shift];
if (val == DBL_MRK) val = ScriptRuntime.wrapNumber(sDbl[shift]); if (val == UniqueTag.DOUBLE_MARK) {
val = ScriptRuntime.wrapNumber(sDbl[shift]);
}
args[i] = val; args[i] = val;
} }
return args; return args;

View File

@ -74,7 +74,8 @@ public class Node
OBJECT_IDS_PROP = 13, // array of properties for object literal OBJECT_IDS_PROP = 13, // array of properties for object literal
INCRDECR_PROP = 14, // pre or post type of increment/decerement INCRDECR_PROP = 14, // pre or post type of increment/decerement
CATCH_SCOPE_PROP = 15, // Index of catch scope block in catch CATCH_SCOPE_PROP = 15, // Index of catch scope block in catch
LAST_PROP = 15; LABEL_ID_PROP = 16, // Label id: code generation uses it
LAST_PROP = 16;
// values of ISNUMBER_PROP to specify // values of ISNUMBER_PROP to specify
// which of the children are Number types // which of the children are Number types
@ -149,30 +150,30 @@ public class Node
this.jumpNode = jumpStatement; this.jumpNode = jumpStatement;
} }
public final Target getDefault() public final Node getDefault()
{ {
if (!(type == Token.SWITCH)) Kit.codeBug(); if (!(type == Token.SWITCH)) Kit.codeBug();
return target2; return target2;
} }
public final void setDefault(Target defaultTarget) public final void setDefault(Node defaultTarget)
{ {
if (!(type == Token.SWITCH)) Kit.codeBug(); if (!(type == Token.SWITCH)) Kit.codeBug();
if (defaultTarget == null) Kit.codeBug(); if (defaultTarget.type != Token.TARGET) Kit.codeBug();
if (target2 != null) Kit.codeBug(); //only once if (target2 != null) Kit.codeBug(); //only once
target2 = defaultTarget; target2 = defaultTarget;
} }
public final Target getFinally() public final Node getFinally()
{ {
if (!(type == Token.TRY)) Kit.codeBug(); if (!(type == Token.TRY)) Kit.codeBug();
return target2; return target2;
} }
public final void setFinally(Target finallyTarget) public final void setFinally(Node finallyTarget)
{ {
if (!(type == Token.TRY)) Kit.codeBug(); if (!(type == Token.TRY)) Kit.codeBug();
if (finallyTarget == null) Kit.codeBug(); if (finallyTarget.type != Token.TARGET) Kit.codeBug();
if (target2 != null) Kit.codeBug(); //only once if (target2 != null) Kit.codeBug(); //only once
target2 = finallyTarget; target2 = finallyTarget;
} }
@ -191,35 +192,25 @@ public class Node
jumpNode = loop; jumpNode = loop;
} }
public final Target getContinue() public final Node getContinue()
{ {
if (type != Token.LOOP) Kit.codeBug(); if (type != Token.LOOP) Kit.codeBug();
return target2; return target2;
} }
public final void setContinue(Target continueTarget) public final void setContinue(Node continueTarget)
{ {
if (type != Token.LOOP) Kit.codeBug(); if (type != Token.LOOP) Kit.codeBug();
if (continueTarget == null) Kit.codeBug(); if (continueTarget.type != Token.TARGET) Kit.codeBug();
if (target2 != null) Kit.codeBug(); //only once if (target2 != null) Kit.codeBug(); //only once
target2 = continueTarget; target2 = continueTarget;
} }
public Target target; public Node target;
private Target target2; private Node target2;
private Jump jumpNode; private Jump jumpNode;
} }
public static class Target extends Node
{
public Target()
{
super(Token.TARGET);
}
public int labelId = -1;
}
private static class PropListItem private static class PropListItem
{ {
PropListItem next; PropListItem next;
@ -453,6 +444,7 @@ public class Node
case OBJECT_IDS_PROP: return "object_ids_prop"; case OBJECT_IDS_PROP: return "object_ids_prop";
case INCRDECR_PROP: return "incrdecr_prop"; case INCRDECR_PROP: return "incrdecr_prop";
case CATCH_SCOPE_PROP: return "catch_scope_prop"; case CATCH_SCOPE_PROP: return "catch_scope_prop";
case LABEL_ID_PROP: return "label_id_prop";
default: Kit.codeBug(); default: Kit.codeBug();
} }
@ -560,6 +552,23 @@ public class Node
((StringNode)this).str = s; ((StringNode)this).str = s;
} }
public static Node newTarget()
{
return new Node(Token.TARGET);
}
public final int labelId()
{
if (type != Token.TARGET) Kit.codeBug();
return getIntProp(LABEL_ID_PROP, -1);
}
public void labelId(int labelId)
{
if (type != Token.TARGET) Kit.codeBug();
putIntProp(LABEL_ID_PROP, labelId);
}
public String toString() { public String toString() {
if (Token.printTrees) { if (Token.printTrees) {
StringBuffer sb = new StringBuffer(Token.name(type)); StringBuffer sb = new StringBuffer(Token.name(type));
@ -591,7 +600,7 @@ public class Node
sb.append(']'); sb.append(']');
} else if (type == Token.TRY) { } else if (type == Token.TRY) {
Node catchNode = jump.target; Node catchNode = jump.target;
Node.Target finallyTarget = jump.getFinally(); Node finallyTarget = jump.getFinally();
if (catchNode != null) { if (catchNode != null) {
sb.append(" [catch: "); sb.append(" [catch: ");
sb.append(catchNode); sb.append(catchNode);
@ -618,13 +627,6 @@ public class Node
sb.append(jump.target); sb.append(jump.target);
sb.append(']'); sb.append(']');
} }
} else if (this instanceof Target) {
Target target = (Target)this;
sb.append(' ');
sb.append(hashCode());
sb.append(" [labelId: ");
sb.append(target.labelId);
sb.append(']');
} else if (type == Token.NUMBER) { } else if (type == Token.NUMBER) {
sb.append(' '); sb.append(' ');
sb.append(getDouble()); sb.append(getDouble());

View File

@ -149,7 +149,7 @@ public class NodeTransformer
Node unwind; Node unwind;
if (elemtype == Token.TRY) { if (elemtype == Token.TRY) {
Node.Jump jsrnode = new Node.Jump(Token.JSR); Node.Jump jsrnode = new Node.Jump(Token.JSR);
Node.Target jsrtarget = ((Node.Jump)n).getFinally(); Node jsrtarget = ((Node.Jump)n).getFinally();
jsrnode.target = jsrtarget; jsrnode.target = jsrtarget;
unwind = jsrnode; unwind = jsrnode;
} else { } else {

View File

@ -1608,7 +1608,7 @@ class BodyCodegen
case Token.TARGET: case Token.TARGET:
{ {
int label = getTargetLabel((Node.Target)node); int label = getTargetLabel(node);
cfw.markLabel(label); cfw.markLabel(label);
} }
break; break;
@ -2342,17 +2342,19 @@ class BodyCodegen
+")V"); +")V");
} }
private int getTargetLabel(Node.Target target) private int getTargetLabel(Node target)
{ {
if (target.labelId == -1) { int labelId = target.labelId();
target.labelId = cfw.acquireLabel(); if (labelId == -1) {
labelId = cfw.acquireLabel();
target.labelId(labelId);
} }
return target.labelId; return labelId;
} }
private void visitGOTO(Node.Jump node, int type, Node child) private void visitGOTO(Node.Jump node, int type, Node child)
{ {
Node.Target target = node.target; Node target = node.target;
if (type == Token.IFEQ || type == Token.IFNE) { if (type == Token.IFEQ || type == Token.IFNE) {
if (child == null) throw Codegen.badTree(); if (child == null) throw Codegen.badTree();
int targetLabel = getTargetLabel(target); int targetLabel = getTargetLabel(target);
@ -2911,8 +2913,8 @@ Else pass the JS object in the aReg and 0.0 in the dReg.
child = child.getNext(); child = child.getNext();
} }
Node.Target catchTarget = node.target; Node catchTarget = node.target;
Node.Target finallyTarget = node.getFinally(); Node finallyTarget = node.getFinally();
// control flow skips the handlers // control flow skips the handlers
int realEnd = cfw.acquireLabel(); int realEnd = cfw.acquireLabel();
@ -2923,7 +2925,7 @@ Else pass the JS object in the aReg and 0.0 in the dReg.
// catch area. // catch area.
if (catchTarget != null) { if (catchTarget != null) {
// get the label to goto // get the label to goto
int catchLabel = catchTarget.labelId; int catchLabel = catchTarget.labelId();
generateCatchBlock(JAVASCRIPT_EXCEPTION, savedVariableObject, generateCatchBlock(JAVASCRIPT_EXCEPTION, savedVariableObject,
catchLabel, startLabel, exceptionLocal); catchLabel, startLabel, exceptionLocal);
@ -2954,7 +2956,7 @@ Else pass the JS object in the aReg and 0.0 in the dReg.
cfw.addAStore(variableObjectLocal); cfw.addAStore(variableObjectLocal);
// get the label to JSR to // get the label to JSR to
int finallyLabel = finallyTarget.labelId; int finallyLabel = finallyTarget.labelId();
cfw.add(ByteCode.JSR, finallyLabel); cfw.add(ByteCode.JSR, finallyLabel);
// rethrow // rethrow
@ -3853,7 +3855,7 @@ Else pass the JS object in the aReg and 0.0 in the dReg.
cfw.markLabel(beyond); cfw.markLabel(beyond);
} }
private void addGoto(Node.Target target, int jumpcode) private void addGoto(Node target, int jumpcode)
{ {
int targetLabel = getTargetLabel(target); int targetLabel = getTargetLabel(target);
cfw.add(jumpcode, targetLabel); cfw.add(jumpcode, targetLabel);