bug 471044 - fixing upgvar detection for for-in loop. r=mrbkap
--- a/js/src/jsemit.cpp
+++ b/js/src/jsemit.cpp
@@ -1871,18 +1871,17 @@ BindNameToSlot(JSContext *cx, JSCodeGene
/*
* We can't optimize if var and closure (a local function not in a larger
* expression and not at top-level within another's body) collide.
* XXX suboptimal: keep track of colliding names and deoptimize only those
*/
if (tc->flags & TCF_FUN_CLOSURE_VS_VAR)
return JS_TRUE;
- /* Don't generate upvars on the left side of a for loop. See bug 470758. */
- if (!(tc->flags & (TCF_IN_FUNCTION | TCF_IN_FOR_INIT))) {
+ if (!(tc->flags & TCF_IN_FUNCTION)) {
JSStackFrame *caller;
caller = tc->parseContext->callerFrame;
if (caller) {
JS_ASSERT(tc->flags & TCF_COMPILE_N_GO);
JS_ASSERT(caller->script);
if (!caller->fun || caller->varobj != tc->u.scopeChain)
return JS_TRUE;
@@ -1894,16 +1893,23 @@ BindNameToSlot(JSContext *cx, JSCodeGene
* arguments object.
*/
if (PN_OP(pn) != JSOP_NAME || cg->staticDepth > JS_DISPLAY_SIZE)
goto arguments_check;
localKind = js_LookupLocal(cx, caller->fun, atom, &index);
if (localKind == JSLOCAL_NONE)
goto arguments_check;
+ /*
+ * Don't generate upvars on the left side of a for loop. See
+ * bug 470758.
+ */
+ if (tc->flags & TCF_IN_FOR_INIT)
+ goto arguments_check;
+
ATOM_LIST_SEARCH(ale, &cg->upvarList, atom);
if (!ale) {
uint32 length, *vector;
ale = js_IndexAtom(cx, atom, &cg->upvarList);
if (!ale)
return JS_FALSE;
JS_ASSERT(ALE_INDEX(ale) == cg->upvarList.count - 1);