Skip let binding not in scope (in let head, e.g.) and find any shadowed binding (496532, r=mrbkap).
authorBrendan Eich <brendan@mozilla.org>
Fri, 05 Jun 2009 13:55:51 -0700
changeset 25909 3b76e2b5482b6a93d0eefecc764e5e9217fb6dcc
parent 25908 7e440eed8c443acc564c052d24dd27da6232fb55
child 25910 2d0f0efc8f142f6af11a2a1d5690241a05408ee9
push id1664
push userrsayre@mozilla.com
push dateMon, 08 Jun 2009 17:47:56 +0000
reviewersmrbkap
bugs496532
milestone1.9.1pre
Skip let binding not in scope (in let head, e.g.) and find any shadowed binding (496532, r=mrbkap).
js/src/jsparse.cpp
--- a/js/src/jsparse.cpp
+++ b/js/src/jsparse.cpp
@@ -8067,18 +8067,30 @@ PrimaryExpr(JSContext *cx, JSTokenStream
             JSStmtInfo *stmt = js_LexicalLookup(tc, pn->pn_atom, NULL);
             if (!stmt || stmt->type != STMT_WITH) {
                 JSDefinition *dn;
 
                 JSAtomListElement *ale = tc->decls.lookup(pn->pn_atom);
                 if (ale) {
                     dn = ALE_DEFN(ale);
 #if JS_HAS_BLOCK_SCOPE
-                    if (dn->isLet() && !BlockIdInScope(dn->pn_blockid, tc))
-                        ale = NULL;
+                    /*
+                     * Skip out-of-scope let bindings along an ALE list or hash
+                     * chain. These can happen due to |let (x = x) x| block and
+                     * expression bindings, where the x on the right of = comes
+                     * from an outer scope. See bug 496532.
+                     */
+                    while (dn->isLet() && !BlockIdInScope(dn->pn_blockid, tc)) {
+                        do {
+                            ale = ALE_NEXT(ale);
+                        } while (ale && ALE_ATOM(ale) != pn->pn_atom);
+                        if (!ale)
+                            break;
+                        dn = ALE_DEFN(ale);
+                    }
 #endif
                 }
 
                 if (ale) {
                     dn = ALE_DEFN(ale);
                 } else {
                     ale = tc->lexdeps.lookup(pn->pn_atom);
                     if (ale) {