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 536118 3944c733e4179698371ea69f9c462dbc7ed226da
parent 536117 1256739720ca8dca77a035c72d8e62977d90a990
child 536119 507d95016ed26c189386369dac28bd49c5fb3a7d
push id2082
push userffxbld-merge
push dateMon, 01 Jul 2019 08:34:18 +0000
treeherdermozilla-release@2fb19d0466d2 [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")       \