Bug 1368360 - Use distinct TDZCheckCache for for-of/for-in expression. r=shu
authorTed Campbell <tcampbell@mozilla.com>
Wed, 14 Jun 2017 12:58:24 -0400
changeset 412810 29d1a9af2655b665a0a1b2eacbeaecdd6fbfbd9f
parent 412809 51cae901338f24eec985f2e5aa58387c50ecb28e
child 412811 0b0175f6dd5461bced946b2213106dc18440a448
push id7566
push usermtabara@mozilla.com
push dateWed, 02 Aug 2017 08:25:16 +0000
treeherdermozilla-beta@86913f512c3c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersshu
bugs1368360
milestone56.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1368360 - Use distinct TDZCheckCache for for-of/for-in expression. r=shu MozReview-Commit-ID: 6dS4wSFf4fB
js/src/frontend/BytecodeEmitter.cpp
js/src/jit-test/tests/ion/bug1368360-1.js
js/src/jit-test/tests/ion/bug1368360-2.js
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -7234,18 +7234,20 @@ BytecodeEmitter::emitForOf(ParseNode* fo
     bool allowSelfHostedIter = false;
     if (emitterMode == BytecodeEmitter::SelfHosting &&
         forHeadExpr->isKind(PNK_CALL) &&
         forHeadExpr->pn_head->name() == cx->names().allowContentIter)
     {
         allowSelfHostedIter = true;
     }
 
-    // Evaluate the expression being iterated.
-    if (!emitTree(forHeadExpr))                           // ITERABLE
+    // Evaluate the expression being iterated. The forHeadExpr should use a
+    // distinct TDZCheckCache to evaluate since (abstractly) it runs in its own
+    // LexicalEnvironment.
+    if (!emitTreeInBranch(forHeadExpr))                   // ITERABLE
         return false;
     if (iterKind == IteratorKind::Async) {
         if (!emitAsyncIterator())                         // ITER
             return false;
     } else {
         if (!emitIterator())                              // ITER
             return false;
     }
@@ -7434,17 +7436,17 @@ BytecodeEmitter::emitForIn(ParseNode* fo
                 if (!emit1(JSOP_POP))
                     return false;
             }
         }
     }
 
     // Evaluate the expression being iterated.
     ParseNode* expr = forInHead->pn_kid3;
-    if (!emitTree(expr))                                  // EXPR
+    if (!emitTreeInBranch(expr))                          // EXPR
         return false;
 
     // Convert the value to the appropriate sort of iterator object for the
     // loop variant (for-in, for-each-in, or destructuring for-in).
     unsigned iflags = forInLoop->pn_iflags;
     MOZ_ASSERT(0 == (iflags & ~(JSITER_FOREACH | JSITER_ENUMERATE)));
     if (!emit2(JSOP_ITER, AssertedCast<uint8_t>(iflags))) // ITER
         return false;
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug1368360-1.js
@@ -0,0 +1,9 @@
+// |jit-test| error: ReferenceError
+var t = {};
+function r(y) t.y = y;
+function g() {
+    for (let [x = r(x)] of x) {}
+}
+r(0);
+r(0);
+g();
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug1368360-2.js
@@ -0,0 +1,9 @@
+// |jit-test| error: ReferenceError
+var t = {};
+function r(y) t.y = y;
+function g() {
+    for (let [x = r(x)] in x) {}
+}
+r(0);
+r(0);
+g();