Fix left operand of for/in loop control evaluation order bug (299641, r=mrbkap).

This commit is contained in:
brendan%mozilla.org 2005-07-14 00:44:27 +00:00
Родитель a99673a4c7
Коммит e9a2b70fb2
1 изменённых файлов: 32 добавлений и 7 удалений

Просмотреть файл

@ -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)