Bug 1462286 - Fix handling of spread operator when exporting destructuring object bindings r=jorendorff
authorJon Coppeard <jcoppeard@mozilla.com>
Thu, 14 Jun 2018 14:58:45 -0700
changeset 422635 c2c5734903b2a97acacecad7366e0f63cab19e12
parent 422634 9f47539cf72c76dc447a3581783e2ff46668e092
child 422636 abb03136bfaffb0e34565e1bbbf001db9bccc9df
push id34140
push useraciure@mozilla.com
push dateFri, 15 Jun 2018 09:49:23 +0000
treeherdermozilla-central@0b5495dc100d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjorendorff
bugs1462286
milestone62.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 1462286 - Fix handling of spread operator when exporting destructuring object bindings r=jorendorff
js/src/builtin/ModuleObject.cpp
js/src/frontend/Parser.cpp
js/src/jit-test/tests/modules/bug-1462286.js
--- a/js/src/builtin/ModuleObject.cpp
+++ b/js/src/builtin/ModuleObject.cpp
@@ -1485,24 +1485,31 @@ bool
 ModuleBuilder::processExportObjectBinding(frontend::ParseNode* pn)
 {
     MOZ_ASSERT(pn->isKind(ParseNodeKind::Object));
     MOZ_ASSERT(pn->isArity(PN_LIST));
 
     for (ParseNode* node = pn->pn_head; node; node = node->pn_next) {
         MOZ_ASSERT(node->isKind(ParseNodeKind::MutateProto) ||
                    node->isKind(ParseNodeKind::Colon) ||
-                   node->isKind(ParseNodeKind::Shorthand));
+                   node->isKind(ParseNodeKind::Shorthand) ||
+                   node->isKind(ParseNodeKind::Spread));
 
-        ParseNode* target = node->isKind(ParseNodeKind::MutateProto)
-            ? node->pn_kid
-            : node->pn_right;
+        ParseNode* target;
+        if (node->isKind(ParseNodeKind::Spread)) {
+            target = node->pn_kid;
+        } else {
+            if (node->isKind(ParseNodeKind::MutateProto))
+                target = node->pn_kid;
+            else
+                target = node->pn_right;
 
-        if (target->isKind(ParseNodeKind::Assign))
-            target = target->pn_left;
+            if (target->isKind(ParseNodeKind::Assign))
+                target = target->pn_left;
+        }
 
         if (!processExportBinding(target))
             return false;
     }
 
     return true;
 }
 
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -5434,24 +5434,31 @@ bool
 Parser<FullParseHandler, CharT>::checkExportedNamesForObjectBinding(ParseNode* pn)
 {
     MOZ_ASSERT(pn->isKind(ParseNodeKind::Object));
     MOZ_ASSERT(pn->isArity(PN_LIST));
 
     for (ParseNode* node = pn->pn_head; node; node = node->pn_next) {
         MOZ_ASSERT(node->isKind(ParseNodeKind::MutateProto) ||
                    node->isKind(ParseNodeKind::Colon) ||
-                   node->isKind(ParseNodeKind::Shorthand));
-
-        ParseNode* target = node->isKind(ParseNodeKind::MutateProto)
-            ? node->pn_kid
-            : node->pn_right;
-
-        if (target->isKind(ParseNodeKind::Assign))
-            target = target->pn_left;
+                   node->isKind(ParseNodeKind::Shorthand) ||
+                   node->isKind(ParseNodeKind::Spread));
+
+        ParseNode* target;
+        if (node->isKind(ParseNodeKind::Spread)) {
+            target = node->pn_kid;
+        } else {
+            if (node->isKind(ParseNodeKind::MutateProto))
+                target = node->pn_kid;
+            else
+                target = node->pn_right;
+
+            if (target->isKind(ParseNodeKind::Assign))
+                target = target->pn_left;
+        }
 
         if (!checkExportedNamesForDeclaration(target))
             return false;
     }
 
     return true;
 }
 
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/modules/bug-1462286.js
@@ -0,0 +1,10 @@
+load(libdir + "dummyModuleResolveHook.js");
+
+let a = moduleRepo['a'] = parseModule(`
+  export var { ... get } = { x: "foo" };
+`);
+
+let m = parseModule("import { get } from 'a'; export { get };");
+m.declarationInstantiation();
+m.evaluation()
+assertEq(getModuleEnvironmentValue(m, "get").x, "foo");