mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 686381 - JSOP_AND/JSOP_OR should always leave the value on the stack. r=dvander
This commit is contained in:
parent
4be8796dfe
commit
e3dfcb5651
@ -6488,21 +6488,22 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
case PNK_OR:
|
||||
case PNK_AND:
|
||||
/*
|
||||
* JSOP_OR converts the operand on the stack to boolean, and if true,
|
||||
* leaves the original operand value on the stack and jumps; otherwise
|
||||
* it pops and falls into the next bytecode, which evaluates the right
|
||||
* operand. The jump goes around the right operand evaluation.
|
||||
* JSOP_OR converts the operand on the stack to boolean, leaves the original
|
||||
* value on the stack and jumps if true; otherwise it falls into the next
|
||||
* bytecode, which pops the left operand and then evaluates the right operand.
|
||||
* The jump goes around the right operand evaluation.
|
||||
*
|
||||
* JSOP_AND converts the operand on the stack to boolean, and if false,
|
||||
* leaves the original operand value on the stack and jumps; otherwise
|
||||
* it pops and falls into the right operand's bytecode.
|
||||
* JSOP_AND converts the operand on the stack to boolean and jumps if false;
|
||||
* otherwise it falls into the right operand's bytecode.
|
||||
*/
|
||||
if (pn->isArity(PN_BINARY)) {
|
||||
if (!EmitTree(cx, bce, pn->pn_left))
|
||||
return JS_FALSE;
|
||||
top = EmitJump(cx, bce, JSOP_BACKPATCH_POP, 0);
|
||||
top = EmitJump(cx, bce, JSOP_BACKPATCH, 0);
|
||||
if (top < 0)
|
||||
return JS_FALSE;
|
||||
if (Emit1(cx, bce, JSOP_POP) < 0)
|
||||
return JS_FALSE;
|
||||
if (!EmitTree(cx, bce, pn->pn_right))
|
||||
return JS_FALSE;
|
||||
off = bce->offset();
|
||||
@ -6517,18 +6518,22 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
pn2 = pn->pn_head;
|
||||
if (!EmitTree(cx, bce, pn2))
|
||||
return JS_FALSE;
|
||||
top = EmitJump(cx, bce, JSOP_BACKPATCH_POP, 0);
|
||||
top = EmitJump(cx, bce, JSOP_BACKPATCH, 0);
|
||||
if (top < 0)
|
||||
return JS_FALSE;
|
||||
if (Emit1(cx, bce, JSOP_POP) < 0)
|
||||
return JS_FALSE;
|
||||
|
||||
/* Emit nodes between the head and the tail. */
|
||||
jmp = top;
|
||||
while ((pn2 = pn2->pn_next)->pn_next) {
|
||||
if (!EmitTree(cx, bce, pn2))
|
||||
return JS_FALSE;
|
||||
off = EmitJump(cx, bce, JSOP_BACKPATCH_POP, 0);
|
||||
off = EmitJump(cx, bce, JSOP_BACKPATCH, 0);
|
||||
if (off < 0)
|
||||
return JS_FALSE;
|
||||
if (Emit1(cx, bce, JSOP_POP) < 0)
|
||||
return JS_FALSE;
|
||||
if (!SetBackPatchDelta(cx, bce, bce->code(jmp), off - jmp))
|
||||
return JS_FALSE;
|
||||
jmp = off;
|
||||
|
@ -568,18 +568,6 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
|
||||
unsigned newStackDepth = stackDepth;
|
||||
|
||||
switch (op) {
|
||||
case JSOP_OR:
|
||||
case JSOP_AND:
|
||||
case JSOP_ORX:
|
||||
case JSOP_ANDX:
|
||||
/*
|
||||
* OR/AND instructions push the operation result when branching.
|
||||
* We accounted for this in GetDefCount, so subtract the pushed value
|
||||
* for the fallthrough case.
|
||||
*/
|
||||
stackDepth--;
|
||||
break;
|
||||
|
||||
case JSOP_CASE:
|
||||
case JSOP_CASEX:
|
||||
/* Case instructions do not push the lvalue back when branching. */
|
||||
|
@ -1332,7 +1332,7 @@ js::FindUpvarFrame(JSContext *cx, uintN targetLevel)
|
||||
#define POP_COPY_TO(v) v = *--regs.sp
|
||||
#define POP_RETURN_VALUE() regs.fp()->setReturnValue(*--regs.sp)
|
||||
|
||||
#define POP_BOOLEAN(cx, vp, b) \
|
||||
#define VALUE_TO_BOOLEAN(cx, vp, b) \
|
||||
JS_BEGIN_MACRO \
|
||||
vp = ®s.sp[-1]; \
|
||||
if (vp->isNull()) { \
|
||||
@ -1342,9 +1342,10 @@ js::FindUpvarFrame(JSContext *cx, uintN targetLevel)
|
||||
} else { \
|
||||
b = !!js_ValueToBoolean(*vp); \
|
||||
} \
|
||||
regs.sp--; \
|
||||
JS_END_MACRO
|
||||
|
||||
#define POP_BOOLEAN(cx, vp, b) do { VALUE_TO_BOOLEAN(cx, vp, b); regs.sp--; } while(0)
|
||||
|
||||
#define VALUE_TO_OBJECT(cx, vp, obj) \
|
||||
JS_BEGIN_MACRO \
|
||||
if ((vp)->isObject()) { \
|
||||
@ -2326,11 +2327,10 @@ END_CASE(JSOP_IFNE)
|
||||
BEGIN_CASE(JSOP_OR)
|
||||
{
|
||||
bool cond;
|
||||
Value *vp;
|
||||
POP_BOOLEAN(cx, vp, cond);
|
||||
Value *_;
|
||||
VALUE_TO_BOOLEAN(cx, _, cond);
|
||||
if (cond == true) {
|
||||
len = GET_JUMP_OFFSET(regs.pc);
|
||||
PUSH_COPY(*vp);
|
||||
DO_NEXT_OP(len);
|
||||
}
|
||||
}
|
||||
@ -2339,11 +2339,10 @@ END_CASE(JSOP_OR)
|
||||
BEGIN_CASE(JSOP_AND)
|
||||
{
|
||||
bool cond;
|
||||
Value *vp;
|
||||
POP_BOOLEAN(cx, vp, cond);
|
||||
Value *_;
|
||||
VALUE_TO_BOOLEAN(cx, _, cond);
|
||||
if (cond == false) {
|
||||
len = GET_JUMP_OFFSET(regs.pc);
|
||||
PUSH_COPY(*vp);
|
||||
DO_NEXT_OP(len);
|
||||
}
|
||||
}
|
||||
@ -2386,11 +2385,10 @@ END_CASE(JSOP_IFNEX)
|
||||
BEGIN_CASE(JSOP_ORX)
|
||||
{
|
||||
bool cond;
|
||||
Value *vp;
|
||||
POP_BOOLEAN(cx, vp, cond);
|
||||
Value *_;
|
||||
VALUE_TO_BOOLEAN(cx, _, cond);
|
||||
if (cond == true) {
|
||||
len = GET_JUMPX_OFFSET(regs.pc);
|
||||
PUSH_COPY(*vp);
|
||||
DO_NEXT_OP(len);
|
||||
}
|
||||
}
|
||||
@ -2399,11 +2397,10 @@ END_CASE(JSOP_ORX)
|
||||
BEGIN_CASE(JSOP_ANDX)
|
||||
{
|
||||
bool cond;
|
||||
Value *vp;
|
||||
POP_BOOLEAN(cx, vp, cond);
|
||||
Value *_;
|
||||
VALUE_TO_BOOLEAN(cx, _, cond);
|
||||
if (cond == JS_FALSE) {
|
||||
len = GET_JUMPX_OFFSET(regs.pc);
|
||||
PUSH_COPY(*vp);
|
||||
DO_NEXT_OP(len);
|
||||
}
|
||||
}
|
||||
|
@ -3475,6 +3475,8 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
|
||||
return NULL;
|
||||
done = pc + GetJumpOffset(pc, pc);
|
||||
pc += len;
|
||||
JS_ASSERT(*pc == JSOP_POP);
|
||||
pc += JSOP_POP_LENGTH;
|
||||
len = done - pc;
|
||||
if (!Decompile(ss, pc, len)) {
|
||||
cx->free_((char *)lval);
|
||||
|
@ -187,8 +187,8 @@ OPDEF(JSOP_NULL, 64, js_null_str, js_null_str, 1, 0, 1, 19, JOF_BYTE)
|
||||
OPDEF(JSOP_THIS, 65, js_this_str, js_this_str, 1, 0, 1, 19, JOF_BYTE)
|
||||
OPDEF(JSOP_FALSE, 66, js_false_str, js_false_str, 1, 0, 1, 19, JOF_BYTE)
|
||||
OPDEF(JSOP_TRUE, 67, js_true_str, js_true_str, 1, 0, 1, 19, JOF_BYTE)
|
||||
OPDEF(JSOP_OR, 68, "or", NULL, 3, 1, 0, 5, JOF_JUMP|JOF_DETECTING|JOF_LEFTASSOC)
|
||||
OPDEF(JSOP_AND, 69, "and", NULL, 3, 1, 0, 6, JOF_JUMP|JOF_DETECTING|JOF_LEFTASSOC)
|
||||
OPDEF(JSOP_OR, 68, "or", NULL, 3, 1, 1, 5, JOF_JUMP|JOF_DETECTING|JOF_LEFTASSOC)
|
||||
OPDEF(JSOP_AND, 69, "and", NULL, 3, 1, 1, 6, JOF_JUMP|JOF_DETECTING|JOF_LEFTASSOC)
|
||||
|
||||
/* The switch bytecodes have variable length. */
|
||||
OPDEF(JSOP_TABLESWITCH, 70, "tableswitch", NULL, -1, 1, 0, 0, JOF_TABLESWITCH|JOF_DETECTING|JOF_PARENHEAD)
|
||||
@ -384,8 +384,8 @@ OPDEF(JSOP_DEFLOCALFUN, 138,"deflocalfun",NULL, 5, 0, 0, 0, JOF_SLOTOB
|
||||
OPDEF(JSOP_GOTOX, 139,"gotox", NULL, 5, 0, 0, 0, JOF_JUMPX)
|
||||
OPDEF(JSOP_IFEQX, 140,"ifeqx", NULL, 5, 1, 0, 4, JOF_JUMPX|JOF_DETECTING)
|
||||
OPDEF(JSOP_IFNEX, 141,"ifnex", NULL, 5, 1, 0, 0, JOF_JUMPX|JOF_PARENHEAD)
|
||||
OPDEF(JSOP_ORX, 142,"orx", NULL, 5, 1, 0, 5, JOF_JUMPX|JOF_DETECTING)
|
||||
OPDEF(JSOP_ANDX, 143,"andx", NULL, 5, 1, 0, 6, JOF_JUMPX|JOF_DETECTING)
|
||||
OPDEF(JSOP_ORX, 142,"orx", NULL, 5, 1, 1, 5, JOF_JUMPX|JOF_DETECTING)
|
||||
OPDEF(JSOP_ANDX, 143,"andx", NULL, 5, 1, 1, 6, JOF_JUMPX|JOF_DETECTING)
|
||||
OPDEF(JSOP_GOSUBX, 144,"gosubx", NULL, 5, 0, 0, 0, JOF_JUMPX)
|
||||
OPDEF(JSOP_CASEX, 145,"casex", NULL, 5, 2, 1, 0, JOF_JUMPX)
|
||||
OPDEF(JSOP_DEFAULTX, 146,"defaultx", NULL, 5, 1, 0, 0, JOF_JUMPX)
|
||||
|
@ -225,7 +225,7 @@ JS_XDRFindClassById(JSXDRState *xdr, uint32 id);
|
||||
* before deserialization of bytecode. If the saved version does not match
|
||||
* the current version, abort deserialization and invalidate the file.
|
||||
*/
|
||||
#define JSXDR_BYTECODE_VERSION (0xb973c0de - 97)
|
||||
#define JSXDR_BYTECODE_VERSION (0xb973c0de - 98)
|
||||
|
||||
/*
|
||||
* Library-private functions.
|
||||
|
Loading…
Reference in New Issue
Block a user