зеркало из https://github.com/mozilla/gecko-dev.git
In the interpreter loop comparision operations are represented by separated optimized do_cmp.
This commit is contained in:
Родитель
10f3c4233e
Коммит
f9804a0ac7
|
@ -498,16 +498,16 @@ public class Interpreter
|
||||||
stackChange(1);
|
stackChange(1);
|
||||||
iCodeTop = generateICode(first, iCodeTop);
|
iCodeTop = generateICode(first, iCodeTop);
|
||||||
iCodeTop = addToken(Token.SHEQ, iCodeTop);
|
iCodeTop = addToken(Token.SHEQ, iCodeTop);
|
||||||
itsStackDepth--;
|
stackChange(-1);
|
||||||
Node.Target target = new Node.Target();
|
Node.Target target = new Node.Target();
|
||||||
thisCase.addChildAfter(target, first);
|
thisCase.addChildAfter(target, first);
|
||||||
// If true, Icode_IFEQ_POP will jump and remove case value
|
// If true, Icode_IFEQ_POP will jump and remove case value
|
||||||
// from stack
|
// from stack
|
||||||
iCodeTop = addGoto(target, Icode_IFEQ_POP, iCodeTop);
|
iCodeTop = addGoto(target, Icode_IFEQ_POP, iCodeTop);
|
||||||
itsStackDepth--;
|
stackChange(-1);
|
||||||
}
|
}
|
||||||
iCodeTop = addToken(Token.POP, iCodeTop);
|
iCodeTop = addToken(Token.POP, iCodeTop);
|
||||||
itsStackDepth--;
|
stackChange(-1);
|
||||||
|
|
||||||
Node defaultNode = (Node) switchNode.getProp(Node.DEFAULT_PROP);
|
Node defaultNode = (Node) switchNode.getProp(Node.DEFAULT_PROP);
|
||||||
if (defaultNode != null) {
|
if (defaultNode != null) {
|
||||||
|
@ -755,13 +755,13 @@ public class Interpreter
|
||||||
iCodeTop = addIcode(Icode_DUP2, iCodeTop);
|
iCodeTop = addIcode(Icode_DUP2, iCodeTop);
|
||||||
stackChange(2);
|
stackChange(2);
|
||||||
iCodeTop = addToken(Token.GETELEM, iCodeTop);
|
iCodeTop = addToken(Token.GETELEM, iCodeTop);
|
||||||
itsStackDepth--;
|
stackChange(-1);
|
||||||
// Compensate for the following USE_STACK
|
// Compensate for the following USE_STACK
|
||||||
itsStackDepth--;
|
stackChange(-1);
|
||||||
}
|
}
|
||||||
iCodeTop = generateICode(child, iCodeTop);
|
iCodeTop = generateICode(child, iCodeTop);
|
||||||
iCodeTop = addToken(Token.SETELEM, iCodeTop);
|
iCodeTop = addToken(Token.SETELEM, iCodeTop);
|
||||||
itsStackDepth -= 2;
|
stackChange(-2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Token.SETNAME :
|
case Token.SETNAME :
|
||||||
|
@ -2178,66 +2178,12 @@ public class Interpreter
|
||||||
int sourceLine = getShort(iCode, pc);
|
int sourceLine = getShort(iCode, pc);
|
||||||
throw new JavaScriptException(value, idata.itsSourceFile, sourceLine);
|
throw new JavaScriptException(value, idata.itsSourceFile, sourceLine);
|
||||||
}
|
}
|
||||||
case Token.GE : {
|
case Token.GE :
|
||||||
--stackTop;
|
case Token.LE :
|
||||||
Object rhs = stack[stackTop + 1];
|
case Token.GT :
|
||||||
Object lhs = stack[stackTop];
|
case Token.LT :
|
||||||
boolean valBln;
|
stackTop = do_cmp(stack, sDbl, stackTop, op);
|
||||||
if (rhs == DBL_MRK || lhs == DBL_MRK) {
|
|
||||||
double rDbl = stack_double(stack, sDbl, stackTop + 1);
|
|
||||||
double lDbl = stack_double(stack, sDbl, stackTop);
|
|
||||||
valBln = (rDbl <= lDbl);
|
|
||||||
} else {
|
|
||||||
valBln = ScriptRuntime.cmp_LE(rhs, lhs);
|
|
||||||
}
|
|
||||||
stack[stackTop] = valBln ? Boolean.TRUE : Boolean.FALSE;
|
|
||||||
continue Loop;
|
continue Loop;
|
||||||
}
|
|
||||||
case Token.LE : {
|
|
||||||
--stackTop;
|
|
||||||
Object rhs = stack[stackTop + 1];
|
|
||||||
Object lhs = stack[stackTop];
|
|
||||||
boolean valBln;
|
|
||||||
if (rhs == DBL_MRK || lhs == DBL_MRK) {
|
|
||||||
double rDbl = stack_double(stack, sDbl, stackTop + 1);
|
|
||||||
double lDbl = stack_double(stack, sDbl, stackTop);
|
|
||||||
valBln = (lDbl <= rDbl);
|
|
||||||
} else {
|
|
||||||
valBln = ScriptRuntime.cmp_LE(lhs, rhs);
|
|
||||||
}
|
|
||||||
stack[stackTop] = valBln ? Boolean.TRUE : Boolean.FALSE;
|
|
||||||
continue Loop;
|
|
||||||
}
|
|
||||||
case Token.GT : {
|
|
||||||
--stackTop;
|
|
||||||
Object rhs = stack[stackTop + 1];
|
|
||||||
Object lhs = stack[stackTop];
|
|
||||||
boolean valBln;
|
|
||||||
if (rhs == DBL_MRK || lhs == DBL_MRK) {
|
|
||||||
double rDbl = stack_double(stack, sDbl, stackTop + 1);
|
|
||||||
double lDbl = stack_double(stack, sDbl, stackTop);
|
|
||||||
valBln = (rDbl < lDbl);
|
|
||||||
} else {
|
|
||||||
valBln = ScriptRuntime.cmp_LT(rhs, lhs);
|
|
||||||
}
|
|
||||||
stack[stackTop] = valBln ? Boolean.TRUE : Boolean.FALSE;
|
|
||||||
continue Loop;
|
|
||||||
}
|
|
||||||
case Token.LT : {
|
|
||||||
--stackTop;
|
|
||||||
Object rhs = stack[stackTop + 1];
|
|
||||||
Object lhs = stack[stackTop];
|
|
||||||
boolean valBln;
|
|
||||||
if (rhs == DBL_MRK || lhs == DBL_MRK) {
|
|
||||||
double rDbl = stack_double(stack, sDbl, stackTop + 1);
|
|
||||||
double lDbl = stack_double(stack, sDbl, stackTop);
|
|
||||||
valBln = (lDbl < rDbl);
|
|
||||||
} else {
|
|
||||||
valBln = ScriptRuntime.cmp_LT(lhs, rhs);
|
|
||||||
}
|
|
||||||
stack[stackTop] = valBln ? Boolean.TRUE : Boolean.FALSE;
|
|
||||||
continue Loop;
|
|
||||||
}
|
|
||||||
case Token.IN : {
|
case Token.IN : {
|
||||||
Object rhs = stack[stackTop];
|
Object rhs = stack[stackTop];
|
||||||
if (rhs == DBL_MRK) rhs = doubleWrap(sDbl[stackTop]);
|
if (rhs == DBL_MRK) rhs = doubleWrap(sDbl[stackTop]);
|
||||||
|
@ -2258,59 +2204,33 @@ public class Interpreter
|
||||||
stack[stackTop] = valBln ? Boolean.TRUE : Boolean.FALSE;
|
stack[stackTop] = valBln ? Boolean.TRUE : Boolean.FALSE;
|
||||||
continue Loop;
|
continue Loop;
|
||||||
}
|
}
|
||||||
case Token.EQ : {
|
case Token.EQ :
|
||||||
--stackTop;
|
case Token.NE :
|
||||||
boolean valBln = do_eq(stack, sDbl, stackTop);
|
stackTop = do_eq(stack, sDbl, stackTop, op);
|
||||||
stack[stackTop] = valBln ? Boolean.TRUE : Boolean.FALSE;
|
|
||||||
continue Loop;
|
continue Loop;
|
||||||
}
|
case Token.SHEQ :
|
||||||
case Token.NE : {
|
case Token.SHNE :
|
||||||
--stackTop;
|
stackTop = do_sheq(stack, sDbl, stackTop, op);
|
||||||
boolean valBln = !do_eq(stack, sDbl, stackTop);
|
|
||||||
stack[stackTop] = valBln ? Boolean.TRUE : Boolean.FALSE;
|
|
||||||
continue Loop;
|
continue Loop;
|
||||||
}
|
case Token.IFNE :
|
||||||
case Token.SHEQ : {
|
if (stack_boolean(stack, sDbl, stackTop--)) {
|
||||||
--stackTop;
|
|
||||||
boolean valBln = do_sheq(stack, sDbl, stackTop);
|
|
||||||
stack[stackTop] = valBln ? Boolean.TRUE : Boolean.FALSE;
|
|
||||||
continue Loop;
|
|
||||||
}
|
|
||||||
case Token.SHNE : {
|
|
||||||
--stackTop;
|
|
||||||
boolean valBln = !do_sheq(stack, sDbl, stackTop);
|
|
||||||
stack[stackTop] = valBln ? Boolean.TRUE : Boolean.FALSE;
|
|
||||||
continue Loop;
|
|
||||||
}
|
|
||||||
case Token.IFNE : {
|
|
||||||
boolean valBln = stack_boolean(stack, sDbl, stackTop);
|
|
||||||
--stackTop;
|
|
||||||
if (valBln) {
|
|
||||||
pc += 2;
|
pc += 2;
|
||||||
continue Loop;
|
continue Loop;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
case Token.IFEQ :
|
||||||
case Token.IFEQ : {
|
if (!stack_boolean(stack, sDbl, stackTop--)) {
|
||||||
boolean valBln = stack_boolean(stack, sDbl, stackTop);
|
|
||||||
--stackTop;
|
|
||||||
if (!valBln) {
|
|
||||||
pc += 2;
|
pc += 2;
|
||||||
continue Loop;
|
continue Loop;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
case Icode_IFEQ_POP :
|
||||||
case Icode_IFEQ_POP : {
|
if (!stack_boolean(stack, sDbl, stackTop--)) {
|
||||||
boolean valBln = stack_boolean(stack, sDbl, stackTop);
|
|
||||||
--stackTop;
|
|
||||||
if (!valBln) {
|
|
||||||
pc += 2;
|
pc += 2;
|
||||||
continue Loop;
|
continue Loop;
|
||||||
}
|
}
|
||||||
stack[stackTop] = null;
|
stack[stackTop--] = null;
|
||||||
--stackTop;
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case Token.GOTO :
|
case Token.GOTO :
|
||||||
break;
|
break;
|
||||||
case Icode_GOSUB :
|
case Icode_GOSUB :
|
||||||
|
@ -2435,18 +2355,6 @@ public class Interpreter
|
||||||
sDbl[stackTop] = ScriptRuntime.toUint32(lDbl) >>> rIntValue;
|
sDbl[stackTop] = ScriptRuntime.toUint32(lDbl) >>> rIntValue;
|
||||||
continue Loop;
|
continue Loop;
|
||||||
}
|
}
|
||||||
case Token.ADD :
|
|
||||||
--stackTop;
|
|
||||||
do_add(stack, sDbl, stackTop);
|
|
||||||
continue Loop;
|
|
||||||
case Token.SUB : {
|
|
||||||
double rDbl = stack_double(stack, sDbl, stackTop);
|
|
||||||
--stackTop;
|
|
||||||
double lDbl = stack_double(stack, sDbl, stackTop);
|
|
||||||
stack[stackTop] = DBL_MRK;
|
|
||||||
sDbl[stackTop] = lDbl - rDbl;
|
|
||||||
continue Loop;
|
|
||||||
}
|
|
||||||
case Token.NEG : {
|
case Token.NEG : {
|
||||||
double rDbl = stack_double(stack, sDbl, stackTop);
|
double rDbl = stack_double(stack, sDbl, stackTop);
|
||||||
stack[stackTop] = DBL_MRK;
|
stack[stackTop] = DBL_MRK;
|
||||||
|
@ -2459,6 +2367,17 @@ public class Interpreter
|
||||||
sDbl[stackTop] = rDbl;
|
sDbl[stackTop] = rDbl;
|
||||||
continue Loop;
|
continue Loop;
|
||||||
}
|
}
|
||||||
|
case Token.ADD :
|
||||||
|
stackTop = do_add(stack, sDbl, stackTop);
|
||||||
|
continue Loop;
|
||||||
|
case Token.SUB : {
|
||||||
|
double rDbl = stack_double(stack, sDbl, stackTop);
|
||||||
|
--stackTop;
|
||||||
|
double lDbl = stack_double(stack, sDbl, stackTop);
|
||||||
|
stack[stackTop] = DBL_MRK;
|
||||||
|
sDbl[stackTop] = lDbl - rDbl;
|
||||||
|
continue Loop;
|
||||||
|
}
|
||||||
case Token.MUL : {
|
case Token.MUL : {
|
||||||
double rDbl = stack_double(stack, sDbl, stackTop);
|
double rDbl = stack_double(stack, sDbl, stackTop);
|
||||||
--stackTop;
|
--stackTop;
|
||||||
|
@ -2484,11 +2403,10 @@ public class Interpreter
|
||||||
sDbl[stackTop] = lDbl % rDbl;
|
sDbl[stackTop] = lDbl % rDbl;
|
||||||
continue Loop;
|
continue Loop;
|
||||||
}
|
}
|
||||||
case Token.NOT : {
|
case Token.NOT :
|
||||||
stack[stackTop] = stack_boolean(stack, sDbl, stackTop)
|
stack[stackTop] = stack_boolean(stack, sDbl, stackTop)
|
||||||
? Boolean.FALSE : Boolean.TRUE;
|
? Boolean.FALSE : Boolean.TRUE;
|
||||||
continue Loop;
|
continue Loop;
|
||||||
}
|
|
||||||
case Token.BINDNAME :
|
case Token.BINDNAME :
|
||||||
stack[++stackTop] = ScriptRuntime.bind(scope, stringReg);
|
stack[++stackTop] = ScriptRuntime.bind(scope, stringReg);
|
||||||
continue Loop;
|
continue Loop;
|
||||||
|
@ -2525,12 +2443,10 @@ public class Interpreter
|
||||||
continue Loop;
|
continue Loop;
|
||||||
}
|
}
|
||||||
case Token.GETELEM :
|
case Token.GETELEM :
|
||||||
do_getElem(cx, stack, sDbl, stackTop, scope);
|
stackTop = do_getElem(stack, sDbl, stackTop, cx, scope);
|
||||||
--stackTop;
|
|
||||||
continue Loop;
|
continue Loop;
|
||||||
case Token.SETELEM :
|
case Token.SETELEM :
|
||||||
do_setElem(cx, stack, sDbl, stackTop, scope);
|
stackTop = do_setElem(stack, sDbl, stackTop, cx, scope);
|
||||||
stackTop -= 2;
|
|
||||||
continue Loop;
|
continue Loop;
|
||||||
case Icode_PROPINC :
|
case Icode_PROPINC :
|
||||||
case Icode_PROPDEC : {
|
case Icode_PROPDEC : {
|
||||||
|
@ -2834,34 +2750,11 @@ public class Interpreter
|
||||||
continue Loop;
|
continue Loop;
|
||||||
}
|
}
|
||||||
case Icode_GETPROTO :
|
case Icode_GETPROTO :
|
||||||
case Icode_GETSCOPEPARENT : {
|
case Icode_GETSCOPEPARENT :
|
||||||
Object lhs = stack[stackTop];
|
|
||||||
if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop]);
|
|
||||||
Object val;
|
|
||||||
if (op == Icode_GETPROTO) {
|
|
||||||
val = ScriptRuntime.getProto(lhs, scope);
|
|
||||||
} else {
|
|
||||||
val = ScriptRuntime.getParent(lhs, scope);
|
|
||||||
}
|
|
||||||
stack[stackTop] = val;
|
|
||||||
continue Loop;
|
|
||||||
}
|
|
||||||
case Icode_SETPROTO :
|
case Icode_SETPROTO :
|
||||||
case Icode_SETPARENT : {
|
case Icode_SETPARENT :
|
||||||
Object rhs = stack[stackTop];
|
stackTop = do_specialProp(stack, sDbl, stackTop, op, scope);
|
||||||
if (rhs == DBL_MRK) rhs = doubleWrap(sDbl[stackTop]);
|
|
||||||
--stackTop;
|
|
||||||
Object lhs = stack[stackTop];
|
|
||||||
if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop]);
|
|
||||||
Object val;
|
|
||||||
if (op == Icode_SETPROTO) {
|
|
||||||
val = ScriptRuntime.setProto(lhs, rhs, scope);
|
|
||||||
} else {
|
|
||||||
val = ScriptRuntime.setParent(lhs, rhs, scope);
|
|
||||||
}
|
|
||||||
stack[stackTop] = val;
|
|
||||||
continue Loop;
|
continue Loop;
|
||||||
}
|
|
||||||
case Icode_SCOPE :
|
case Icode_SCOPE :
|
||||||
stack[++stackTop] = scope;
|
stack[++stackTop] = scope;
|
||||||
continue Loop;
|
continue Loop;
|
||||||
|
@ -3078,34 +2971,39 @@ public class Interpreter
|
||||||
int i)
|
int i)
|
||||||
{
|
{
|
||||||
Object x = stack[i];
|
Object x = stack[i];
|
||||||
if (x == DBL_MRK) {
|
if (x == Boolean.TRUE) {
|
||||||
|
return true;
|
||||||
|
} else if (x == Boolean.FALSE) {
|
||||||
|
return false;
|
||||||
|
} else if (x == DBL_MRK) {
|
||||||
double d = stackDbl[i];
|
double d = stackDbl[i];
|
||||||
return d == d && d != 0.0;
|
return d == d && d != 0.0;
|
||||||
} else if (x instanceof Boolean) {
|
|
||||||
return ((Boolean)x).booleanValue();
|
|
||||||
} else if (x == null || x == Undefined.instance) {
|
} else if (x == null || x == Undefined.instance) {
|
||||||
return false;
|
return false;
|
||||||
} else if (x instanceof Number) {
|
} else if (x instanceof Number) {
|
||||||
double d = ((Number)x).doubleValue();
|
double d = ((Number)x).doubleValue();
|
||||||
return (d == d && d != 0.0);
|
return (d == d && d != 0.0);
|
||||||
|
} else if (x instanceof Boolean) {
|
||||||
|
return ((Boolean)x).booleanValue();
|
||||||
} else {
|
} else {
|
||||||
return ScriptRuntime.toBoolean(x);
|
return ScriptRuntime.toBoolean(x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void do_add(Object[] stack, double[] stackDbl, int stackTop)
|
private static int do_add(Object[] stack, double[] sDbl, int stackTop)
|
||||||
{
|
{
|
||||||
|
--stackTop;
|
||||||
Object rhs = stack[stackTop + 1];
|
Object rhs = stack[stackTop + 1];
|
||||||
Object lhs = stack[stackTop];
|
Object lhs = stack[stackTop];
|
||||||
if (rhs == DBL_MRK) {
|
if (rhs == DBL_MRK) {
|
||||||
double rDbl = stackDbl[stackTop + 1];
|
double rDbl = sDbl[stackTop + 1];
|
||||||
if (lhs == DBL_MRK) {
|
if (lhs == DBL_MRK) {
|
||||||
stackDbl[stackTop] += rDbl;
|
sDbl[stackTop] += rDbl;
|
||||||
} else {
|
} else {
|
||||||
do_add(lhs, rDbl, stack, stackDbl, stackTop, true);
|
do_add(lhs, rDbl, stack, sDbl, stackTop, true);
|
||||||
}
|
}
|
||||||
} else if (lhs == DBL_MRK) {
|
} else if (lhs == DBL_MRK) {
|
||||||
do_add(rhs, stackDbl[stackTop], stack, stackDbl, stackTop, false);
|
do_add(rhs, sDbl[stackTop], stack, sDbl, stackTop, false);
|
||||||
} else {
|
} else {
|
||||||
if (lhs instanceof Scriptable)
|
if (lhs instanceof Scriptable)
|
||||||
lhs = ((Scriptable) lhs).getDefaultValue(null);
|
lhs = ((Scriptable) lhs).getDefaultValue(null);
|
||||||
|
@ -3125,9 +3023,10 @@ public class Interpreter
|
||||||
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] = DBL_MRK;
|
||||||
stackDbl[stackTop] = lDbl + rDbl;
|
sDbl[stackTop] = lDbl + rDbl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return stackTop;
|
||||||
}
|
}
|
||||||
|
|
||||||
// x + y when x is Number
|
// x + y when x is Number
|
||||||
|
@ -3159,71 +3058,142 @@ public class Interpreter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean do_eq(Object[] stack, double[] stackDbl,
|
private static int do_cmp(Object[] stack, double[] sDbl, int stackTop,
|
||||||
int stackTop)
|
int op)
|
||||||
{
|
{
|
||||||
|
--stackTop;
|
||||||
|
Object rhs = stack[stackTop + 1];
|
||||||
|
Object lhs = stack[stackTop];
|
||||||
|
boolean result;
|
||||||
|
object_compare:
|
||||||
|
{
|
||||||
|
number_compare:
|
||||||
|
{
|
||||||
|
double rDbl, lDbl;
|
||||||
|
if (rhs == DBL_MRK) {
|
||||||
|
rDbl = sDbl[stackTop + 1];
|
||||||
|
lDbl = stack_double(stack, sDbl, stackTop);
|
||||||
|
} else if (lhs == DBL_MRK) {
|
||||||
|
rDbl = ScriptRuntime.toNumber(rhs);
|
||||||
|
lDbl = sDbl[stackTop];
|
||||||
|
} else {
|
||||||
|
break number_compare;
|
||||||
|
}
|
||||||
|
switch (op) {
|
||||||
|
case Token.GE:
|
||||||
|
result = (lDbl >= rDbl);
|
||||||
|
break object_compare;
|
||||||
|
case Token.LE:
|
||||||
|
result = (lDbl <= rDbl);
|
||||||
|
break object_compare;
|
||||||
|
case Token.GT:
|
||||||
|
result = (lDbl > rDbl);
|
||||||
|
break object_compare;
|
||||||
|
case Token.LT:
|
||||||
|
result = (lDbl < rDbl);
|
||||||
|
break object_compare;
|
||||||
|
default:
|
||||||
|
throw Kit.codeBug();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch (op) {
|
||||||
|
case Token.GE:
|
||||||
|
result = ScriptRuntime.cmp_LE(rhs, lhs);
|
||||||
|
break;
|
||||||
|
case Token.LE:
|
||||||
|
result = ScriptRuntime.cmp_LE(lhs, rhs);
|
||||||
|
break;
|
||||||
|
case Token.GT:
|
||||||
|
result = ScriptRuntime.cmp_LT(rhs, lhs);
|
||||||
|
break;
|
||||||
|
case Token.LT:
|
||||||
|
result = ScriptRuntime.cmp_LT(lhs, rhs);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw Kit.codeBug();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stack[stackTop] = result ? Boolean.TRUE : Boolean.FALSE;
|
||||||
|
return stackTop;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int do_eq(Object[] stack, double[] sDbl, int stackTop,
|
||||||
|
int op)
|
||||||
|
{
|
||||||
|
--stackTop;
|
||||||
boolean result;
|
boolean result;
|
||||||
Object rhs = stack[stackTop + 1];
|
Object rhs = stack[stackTop + 1];
|
||||||
Object lhs = stack[stackTop];
|
Object lhs = stack[stackTop];
|
||||||
if (rhs == DBL_MRK) {
|
if (rhs == DBL_MRK) {
|
||||||
if (lhs == DBL_MRK) {
|
if (lhs == DBL_MRK) {
|
||||||
result = (stackDbl[stackTop] == stackDbl[stackTop + 1]);
|
result = (sDbl[stackTop] == sDbl[stackTop + 1]);
|
||||||
} else {
|
} else {
|
||||||
result = ScriptRuntime.eqNumber(stackDbl[stackTop + 1], lhs);
|
result = ScriptRuntime.eqNumber(sDbl[stackTop + 1], lhs);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (lhs == DBL_MRK) {
|
if (lhs == DBL_MRK) {
|
||||||
result = ScriptRuntime.eqNumber(stackDbl[stackTop], rhs);
|
result = ScriptRuntime.eqNumber(sDbl[stackTop], rhs);
|
||||||
} else {
|
} else {
|
||||||
result = ScriptRuntime.eq(lhs, rhs);
|
result = ScriptRuntime.eq(lhs, rhs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
result ^= (op == Token.NE);
|
||||||
|
stack[stackTop] = (result) ? Boolean.TRUE : Boolean.FALSE;
|
||||||
|
return stackTop;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean do_sheq(Object[] stack, double[] stackDbl,
|
private static int do_sheq(Object[] stack, double[] sDbl, int stackTop,
|
||||||
int stackTop)
|
int op)
|
||||||
{
|
{
|
||||||
|
--stackTop;
|
||||||
Object rhs = stack[stackTop + 1];
|
Object rhs = stack[stackTop + 1];
|
||||||
Object lhs = stack[stackTop];
|
Object lhs = stack[stackTop];
|
||||||
double rdbl, ldbl;
|
boolean result;
|
||||||
if (rhs == DBL_MRK) {
|
double_compare: {
|
||||||
rdbl = stackDbl[stackTop + 1];
|
double rdbl, ldbl;
|
||||||
if (lhs == DBL_MRK) {
|
|
||||||
ldbl = stackDbl[stackTop];
|
|
||||||
} else if (lhs instanceof Number) {
|
|
||||||
ldbl = ((Number)lhs).doubleValue();
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (lhs == DBL_MRK) {
|
|
||||||
ldbl = stackDbl[stackTop];
|
|
||||||
if (rhs == DBL_MRK) {
|
if (rhs == DBL_MRK) {
|
||||||
rdbl = stackDbl[stackTop + 1];
|
rdbl = sDbl[stackTop + 1];
|
||||||
} else if (rhs instanceof Number) {
|
if (lhs == DBL_MRK) {
|
||||||
rdbl = ((Number)rhs).doubleValue();
|
ldbl = sDbl[stackTop];
|
||||||
|
} else if (lhs instanceof Number) {
|
||||||
|
ldbl = ((Number)lhs).doubleValue();
|
||||||
|
} else {
|
||||||
|
result = false;
|
||||||
|
break double_compare;
|
||||||
|
}
|
||||||
|
} else if (lhs == DBL_MRK) {
|
||||||
|
ldbl = sDbl[stackTop];
|
||||||
|
if (rhs == DBL_MRK) {
|
||||||
|
rdbl = sDbl[stackTop + 1];
|
||||||
|
} else if (rhs instanceof Number) {
|
||||||
|
rdbl = ((Number)rhs).doubleValue();
|
||||||
|
} else {
|
||||||
|
result = false;
|
||||||
|
break double_compare;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return false;
|
result = ScriptRuntime.shallowEq(lhs, rhs);
|
||||||
|
break double_compare;
|
||||||
}
|
}
|
||||||
} else {
|
result = ldbl == rdbl;
|
||||||
return ScriptRuntime.shallowEq(lhs, rhs);
|
|
||||||
}
|
}
|
||||||
return ldbl == rdbl;
|
result ^= (op == Token.SHNE);
|
||||||
|
stack[stackTop] = (result) ? Boolean.TRUE : Boolean.FALSE;
|
||||||
|
return stackTop;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void do_getElem(Context cx,
|
private static int do_getElem(Object[] stack, double[] sDbl, int stackTop,
|
||||||
Object[] stack, double[] stackDbl,
|
Context cx, Scriptable scope)
|
||||||
int stackTop, Scriptable scope)
|
|
||||||
{
|
{
|
||||||
Object lhs = stack[stackTop - 1];
|
Object lhs = stack[stackTop - 1];
|
||||||
if (lhs == DBL_MRK) lhs = doubleWrap(stackDbl[stackTop - 1]);
|
if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop - 1]);
|
||||||
|
|
||||||
Object result;
|
Object result;
|
||||||
Object id = stack[stackTop];
|
Object id = stack[stackTop];
|
||||||
if (id != DBL_MRK) {
|
if (id != DBL_MRK) {
|
||||||
result = ScriptRuntime.getElem(lhs, id, scope);
|
result = ScriptRuntime.getElem(lhs, id, scope);
|
||||||
} else {
|
} else {
|
||||||
double val = stackDbl[stackTop];
|
double val = sDbl[stackTop];
|
||||||
if (lhs == null || lhs == Undefined.instance) {
|
if (lhs == null || lhs == Undefined.instance) {
|
||||||
throw ScriptRuntime.undefReadError(
|
throw ScriptRuntime.undefReadError(
|
||||||
lhs, ScriptRuntime.toString(val));
|
lhs, ScriptRuntime.toString(val));
|
||||||
|
@ -3239,24 +3209,25 @@ public class Interpreter
|
||||||
result = ScriptRuntime.getStrIdElem(obj, s);
|
result = ScriptRuntime.getStrIdElem(obj, s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stack[stackTop - 1] = result;
|
--stackTop;
|
||||||
|
stack[stackTop] = result;
|
||||||
|
return stackTop;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void do_setElem(Context cx,
|
private static int do_setElem(Object[] stack, double[] sDbl, int stackTop,
|
||||||
Object[] stack, double[] stackDbl,
|
Context cx, Scriptable scope)
|
||||||
int stackTop, Scriptable scope)
|
|
||||||
{
|
{
|
||||||
Object rhs = stack[stackTop];
|
Object rhs = stack[stackTop];
|
||||||
if (rhs == DBL_MRK) rhs = doubleWrap(stackDbl[stackTop]);
|
if (rhs == DBL_MRK) rhs = doubleWrap(sDbl[stackTop]);
|
||||||
Object lhs = stack[stackTop - 2];
|
Object lhs = stack[stackTop - 2];
|
||||||
if (lhs == DBL_MRK) lhs = doubleWrap(stackDbl[stackTop - 2]);
|
if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop - 2]);
|
||||||
|
|
||||||
Object result;
|
Object result;
|
||||||
Object id = stack[stackTop - 1];
|
Object id = stack[stackTop - 1];
|
||||||
if (id != DBL_MRK) {
|
if (id != DBL_MRK) {
|
||||||
result = ScriptRuntime.setElem(lhs, id, rhs, scope);
|
result = ScriptRuntime.setElem(lhs, id, rhs, scope);
|
||||||
} else {
|
} else {
|
||||||
double val = stackDbl[stackTop - 1];
|
double val = sDbl[stackTop - 1];
|
||||||
if (lhs == null || lhs == Undefined.instance) {
|
if (lhs == null || lhs == Undefined.instance) {
|
||||||
throw ScriptRuntime.undefWriteError(
|
throw ScriptRuntime.undefWriteError(
|
||||||
lhs, ScriptRuntime.toString(val), rhs);
|
lhs, ScriptRuntime.toString(val), rhs);
|
||||||
|
@ -3272,7 +3243,9 @@ public class Interpreter
|
||||||
result = ScriptRuntime.setStrIdElem(obj, s, rhs, scope);
|
result = ScriptRuntime.setStrIdElem(obj, s, rhs, scope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stack[stackTop - 2] = result;
|
stackTop -= 2;
|
||||||
|
stack[stackTop] = result;
|
||||||
|
return stackTop;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int do_nameAndThis(Object[] stack, int stackTop,
|
private static int do_nameAndThis(Object[] stack, int stackTop,
|
||||||
|
@ -3300,6 +3273,36 @@ public class Interpreter
|
||||||
return stackTop;
|
return stackTop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int do_specialProp(Object[] stack, double[] sDbl,
|
||||||
|
int stackTop, int op, Scriptable scope)
|
||||||
|
{
|
||||||
|
Object val;
|
||||||
|
Object top = stack[stackTop];
|
||||||
|
if (top == DBL_MRK) top = doubleWrap(sDbl[stackTop]);
|
||||||
|
switch (op) {
|
||||||
|
default: throw Kit.codeBug();
|
||||||
|
case Icode_GETPROTO:
|
||||||
|
val = ScriptRuntime.getProto(top, scope);
|
||||||
|
break;
|
||||||
|
case Icode_GETSCOPEPARENT:
|
||||||
|
val = ScriptRuntime.getParent(top, scope);
|
||||||
|
break;
|
||||||
|
case Icode_SETPROTO:
|
||||||
|
case Icode_SETPARENT:
|
||||||
|
--stackTop;
|
||||||
|
Object snd = stack[stackTop];
|
||||||
|
if (snd == DBL_MRK) snd = doubleWrap(sDbl[stackTop]);
|
||||||
|
if (op == Icode_SETPROTO) {
|
||||||
|
val = ScriptRuntime.setProto(snd, top, scope);
|
||||||
|
} else {
|
||||||
|
val = ScriptRuntime.setParent(snd, top, scope);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
stack[stackTop] = val;
|
||||||
|
return stackTop;
|
||||||
|
}
|
||||||
|
|
||||||
private static Object[] getArgsArray(Object[] stack, double[] sDbl,
|
private static Object[] getArgsArray(Object[] stack, double[] sDbl,
|
||||||
int shift, int count)
|
int shift, int count)
|
||||||
{
|
{
|
||||||
|
|
Загрузка…
Ссылка в новой задаче