Bug 1552022 - Pass through arguments in synthesized constructors for derived classes. r=jorendorff
authorAshley Hauck <khyperia@mozilla.com>
Thu, 16 May 2019 20:54:39 +0000
changeset 474235 3944c733e4179698371ea69f9c462dbc7ed226da
parent 474234 1256739720ca8dca77a035c72d8e62977d90a990
child 474236 507d95016ed26c189386369dac28bd49c5fb3a7d
push id113144
push usershindli@mozilla.com
push dateFri, 17 May 2019 16:44:55 +0000
treeherdermozilla-inbound@f4c4b796f845 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjorendorff
bugs1552022
milestone68.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 1552022 - Pass through arguments in synthesized constructors for derived classes. r=jorendorff Differential Revision: https://phabricator.services.mozilla.com/D31507
js/src/frontend/Parser.cpp
js/src/jit-test/tests/fields/bug1552022.js
js/src/vm/CommonPropertyNames.h
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -7177,19 +7177,32 @@ GeneralParser<ParseHandler, Unit>::synth
   TokenPos synthesizedBodyPos = TokenPos(classNameOffset, classNameOffset + 1);
   // Create a ListNode for the parameters + body (there are no parameters).
   ListNodeType argsbody =
       handler_.newList(ParseNodeKind::ParamsBody, synthesizedBodyPos);
   if (!argsbody) {
     return null();
   }
   handler_.setFunctionFormalParametersAndBody(funNode, argsbody);
-  funbox->function()->setArgCount(0);
   setFunctionStartAtCurrentToken(funbox);
 
+  if (hasHeritage == HasHeritage::Yes) {
+    // Synthesize the equivalent to `function f(...args)`
+    funbox->setHasRest();
+    if (!notePositionalFormalParameter(funNode, cx_->names().args,
+                                       synthesizedBodyPos.begin,
+                                       /* disallowDuplicateParams = */ false,
+                                       /* duplicatedParam = */ nullptr)) {
+      return null();
+    }
+    funbox->function()->setArgCount(1);
+  } else {
+    funbox->function()->setArgCount(0);
+  }
+
   pc_->functionScope().useAsVarScope(pc_);
 
   auto stmtList = handler_.newStatementList(synthesizedBodyPos);
   if (!stmtList) {
     return null();
   }
 
   if (!noteUsedName(cx_->names().dotThis)) {
@@ -7223,17 +7236,33 @@ GeneralParser<ParseHandler, Unit>::synth
       return null();
     }
 
     ListNodeType arguments = handler_.newArguments(synthesizedBodyPos);
     if (!arguments) {
       return null();
     }
 
-    CallNodeType superCall = handler_.newSuperCall(superBase, arguments, false);
+    NameNodeType argsNameNode = newName(cx_->names().args, synthesizedBodyPos);
+    if (!argsNameNode) {
+      return null();
+    }
+    if (!noteUsedName(cx_->names().args)) {
+      return null();
+    }
+
+    UnaryNodeType spreadArgs =
+        handler_.newSpread(synthesizedBodyPos.begin, argsNameNode);
+    if (!spreadArgs) {
+      return null();
+    }
+    handler_.addList(arguments, spreadArgs);
+
+    CallNodeType superCall =
+        handler_.newSuperCall(superBase, arguments, /* isSpread = */ true);
     if (!superCall) {
       return null();
     }
 
     BinaryNodeType setThis = handler_.newSetThis(thisName, superCall);
     if (!setThis) {
       return null();
     }
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/fields/bug1552022.js
@@ -0,0 +1,24 @@
+// |jit-test| --enable-experimental-fields
+
+load(libdir + "eqArrayHelper.js");
+
+let expected = [];
+class B {
+    constructor(...args) {
+        assertEqArray(expected, args);
+    }
+}
+
+class C extends B {
+    asdf = 2;
+}
+
+expected = [];
+new C();
+expected = [1];
+new C(1);
+expected = [1, 2];
+new C(1, 2);
+
+if (typeof reportCompare === "function")
+  reportCompare(true, true);
--- a/js/src/vm/CommonPropertyNames.h
+++ b/js/src/vm/CommonPropertyNames.h
@@ -12,16 +12,17 @@
 #include "js/ProtoKey.h"
 
 #define FOR_EACH_COMMON_PROPERTYNAME(MACRO)                                    \
   MACRO(add, add, "add")                                                       \
   MACRO(allowContentIter, allowContentIter, "allowContentIter")                \
   MACRO(anonymous, anonymous, "anonymous")                                     \
   MACRO(Any, Any, "Any")                                                       \
   MACRO(apply, apply, "apply")                                                 \
+  MACRO(args, args, "args")                                                    \
   MACRO(arguments, arguments, "arguments")                                     \
   MACRO(ArrayBufferSpecies, ArrayBufferSpecies, "ArrayBufferSpecies")          \
   MACRO(ArrayIterator, ArrayIterator, "Array Iterator")                        \
   MACRO(ArrayIteratorNext, ArrayIteratorNext, "ArrayIteratorNext")             \
   MACRO(ArraySort, ArraySort, "ArraySort")                                     \
   MACRO(ArraySpecies, ArraySpecies, "ArraySpecies")                            \
   MACRO(ArraySpeciesCreate, ArraySpeciesCreate, "ArraySpeciesCreate")          \
   MACRO(ArrayToLocaleString, ArrayToLocaleString, "ArrayToLocaleString")       \