зеркало из https://github.com/mozilla/pjs.git
Fix left operand of for/in loop control evaluation order bug (299641, r=mrbkap).
This commit is contained in:
Родитель
a99673a4c7
Коммит
e9a2b70fb2
|
@ -2140,7 +2140,7 @@ static JSBool
|
|||
EmitElemOp(JSContext *cx, JSParseNode *pn, JSOp op, JSCodeGenerator *cg)
|
||||
{
|
||||
ptrdiff_t top;
|
||||
JSParseNode *left, *right, *next;
|
||||
JSParseNode *left, *right, *next, temp;
|
||||
jsint slot;
|
||||
|
||||
top = CG_OFFSET(cg);
|
||||
|
@ -2192,9 +2192,22 @@ EmitElemOp(JSContext *cx, JSParseNode *pn, JSOp op, JSCodeGenerator *cg)
|
|||
next = next->pn_next;
|
||||
}
|
||||
} else {
|
||||
JS_ASSERT(pn->pn_arity == PN_BINARY);
|
||||
left = pn->pn_left;
|
||||
right = pn->pn_right;
|
||||
if (pn->pn_arity == PN_NAME) {
|
||||
/*
|
||||
* Set left and right so pn appears to be a TOK_LB node, instead
|
||||
* of a TOK_DOT node (see the TOK_FOR/IN case in js_EmitTree).
|
||||
*/
|
||||
left = pn->pn_expr;
|
||||
right = &temp;
|
||||
right->pn_type = TOK_STRING;
|
||||
right->pn_arity = PN_NULLARY;
|
||||
right->pn_op = JSOP_STRING;
|
||||
right->pn_atom = pn->pn_atom;
|
||||
} else {
|
||||
JS_ASSERT(pn->pn_arity == PN_BINARY);
|
||||
left = pn->pn_left;
|
||||
right = pn->pn_right;
|
||||
}
|
||||
|
||||
/* Try to optimize arguments[0] (e.g.) into JSOP_ARGSUB<0>. */
|
||||
if (op == JSOP_GETELEM &&
|
||||
|
@ -3118,6 +3131,8 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
|
|||
js_PushStatement(&cg->treeContext, &stmtInfo, STMT_FOR_LOOP, top);
|
||||
|
||||
if (pn2->pn_type == TOK_IN) {
|
||||
JSBool emitIFEQ;
|
||||
|
||||
/* Set stmtInfo type for later testing. */
|
||||
stmtInfo.type = STMT_FOR_IN_LOOP;
|
||||
noteIndex = -1;
|
||||
|
@ -3166,6 +3181,7 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
|
|||
#endif
|
||||
|
||||
/* Compile a JSOP_FOR* bytecode based on the left hand side. */
|
||||
emitIFEQ = JS_TRUE;
|
||||
switch (pn3->pn_type) {
|
||||
case TOK_VAR:
|
||||
pn3 = pn3->pn_head;
|
||||
|
@ -3203,9 +3219,17 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
|
|||
break;
|
||||
|
||||
case TOK_DOT:
|
||||
if (!EmitPropOp(cx, pn3, JSOP_FORPROP, cg))
|
||||
useful = JS_TRUE;
|
||||
if (!CheckSideEffects(cx, &cg->treeContext, pn3->pn_expr,
|
||||
&useful)) {
|
||||
return JS_FALSE;
|
||||
break;
|
||||
}
|
||||
if (!useful) {
|
||||
if (!EmitPropOp(cx, pn3, JSOP_FORPROP, cg))
|
||||
return JS_FALSE;
|
||||
break;
|
||||
}
|
||||
/* FALL THROUGH */
|
||||
|
||||
case TOK_LB:
|
||||
/*
|
||||
|
@ -3214,6 +3238,7 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
|
|||
* expression (e.g., for (x[i++] in {}) should not bind x[i]
|
||||
* or increment i at all).
|
||||
*/
|
||||
emitIFEQ = JS_FALSE;
|
||||
if (!js_Emit1(cx, cg, JSOP_FORELEM))
|
||||
return JS_FALSE;
|
||||
|
||||
|
@ -3240,7 +3265,7 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
|
|||
JS_ASSERT(0);
|
||||
}
|
||||
|
||||
if (pn3->pn_type != TOK_LB) {
|
||||
if (emitIFEQ) {
|
||||
/* Annotate so the decompiler can find the loop-closing jump. */
|
||||
noteIndex = js_NewSrcNote(cx, cg, SRC_WHILE);
|
||||
if (noteIndex < 0)
|
||||
|
|
Загрузка…
Ссылка в новой задаче