Backed out changeset 70eb46335a2c (bug 1499448) on request by jorendorff
authorCoroiu Cristina <ccoroiu@mozilla.com>
Sat, 02 Mar 2019 02:59:56 +0200
changeset 519939 c6197e7ad760cac9d691482130fa8ea72e7fd8de
parent 519938 45b70e8a557b8e179ab87a66ade201eed0257196
child 519940 0b61149893f94fcc65fe6535c55f6ef6240741db
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1499448
milestone67.0a1
backs out70eb46335a2ca23516774624f7ce1cbe34de56ea
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
Backed out changeset 70eb46335a2c (bug 1499448) on request by jorendorff
js/src/frontend/BytecodeEmitter.cpp
js/src/frontend/Parser.cpp
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -2455,17 +2455,29 @@ bool BytecodeEmitter::emitInitializeInst
   FieldInitializers fieldInfo = this->fieldInitializers_;
   MOZ_ASSERT(fieldInfo.valid);
   size_t numFields = fieldInfo.numFieldInitializers;
 
   if (numFields == 0) {
     return true;
   }
 
-  if (!emitGetName(cx->names().dotInitializers)) {
+  PropOpEmitter poe(this, PropOpEmitter::Kind::Get,
+                    PropOpEmitter::ObjKind::Other);
+  if (!poe.prepareForObj()) {
+    return false;
+  }
+
+  // This is guaranteed to run after super(), so we don't need TDZ checks.
+  if (!emitGetName(cx->names().dotThis)) {
+    //              [stack] THIS
+    return false;
+  }
+
+  if (!poe.emitGet(cx->names().dotInitializers)) {
     //              [stack] ARRAY
     return false;
   }
 
   for (size_t fieldIndex = 0; fieldIndex < numFields; fieldIndex++) {
     if (fieldIndex < numFields - 1) {
       // We DUP to keep the array around (it is consumed in the bytecode below)
       // for next iterations of this loop, except for the last iteration, which
@@ -8003,50 +8015,59 @@ bool BytecodeEmitter::emitPropertyList(L
     }
   }
 
   if (numFields > 0) {
     // .initializers is a variable that stores an array of lambdas containing
     // code (the initializer) for each field. Upon an object's construction,
     // these lambdas will be called, defining the values.
 
-    NameOpEmitter noe(this, cx->names().dotInitializers,
-                      NameOpEmitter::Kind::Initialize);
-    if (!noe.prepareForRhs()) {
+    PropOpEmitter poe(this, PropOpEmitter::Kind::SimpleAssignment,
+                      PropOpEmitter::ObjKind::Other);
+    if (!poe.prepareForObj()) {
+      return false;
+    }
+
+    if (!emit1(JSOP_DUP)) {
+      //            [stack] CTOR? OBJ OBJ
+      return false;
+    }
+
+    if (!poe.prepareForRhs()) {
       return false;
     }
 
     if (!emitUint32Operand(JSOP_NEWARRAY, numFields)) {
-      //            [stack] CTOR? OBJ ARRAY
+      //            [stack] CTOR? OBJ OBJ ARRAY
       return false;
     }
 
     size_t curFieldIndex = 0;
     for (ParseNode* propdef : obj->contents()) {
       if (propdef->is<ClassField>()) {
         FunctionNode* initializer = &propdef->as<ClassField>().initializer();
         if (initializer == nullptr) {
           continue;
         }
 
         if (!emitTree(initializer)) {
-          //        [stack] CTOR? OBJ ARRAY LAMBDA
+          //        [stack] CTOR? OBJ OBJ ARRAY LAMBDA
           return false;
         }
 
         if (!emitUint32Operand(JSOP_INITELEM_ARRAY, curFieldIndex)) {
-          //        [stack] CTOR? OBJ ARRAY
+          //        [stack] CTOR? OBJ OBJ ARRAY
           return false;
         }
 
         curFieldIndex++;
       }
     }
 
-    if (!noe.emitAssignment()) {
+    if (!poe.emitAssignment(cx->names().dotInitializers)) {
       //            [stack] CTOR? OBJ ARRAY
       return false;
     }
 
     if (!emit1(JSOP_POP)) {
       //            [stack] CTOR? OBJ
       return false;
     }
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -1824,24 +1824,16 @@ GeneralParser<ParseHandler, Unit>::funct
                                                 FunctionSyntaxKind kind,
                                                 FunctionBodyType type) {
   MOZ_ASSERT(pc_->isFunctionBox());
 
 #ifdef DEBUG
   uint32_t startYieldOffset = pc_->lastYieldOffset;
 #endif
 
-  if (kind == FunctionSyntaxKind::ClassConstructor) {
-    // Don't do DerivedClassConstructor here, that gets marked after super()
-    // calls.
-    if (!noteUsedName(cx_->names().dotInitializers)) {
-      return null();
-    }
-  }
-
   Node body;
   if (type == StatementListBody) {
     bool inheritedStrict = pc_->sc()->strict();
     body = statementList(yieldHandling);
     if (!body) {
       return null();
     }
 
@@ -6782,20 +6774,22 @@ GeneralParser<ParseHandler, Unit>::class
   ParseContext::ClassStatement classStmt(pc_);
 
   RootedAtom propAtom(cx_);
 
   // A named class creates a new lexical scope with a const binding of the
   // class name for the "inner name".
   Maybe<ParseContext::Statement> innerScopeStmt;
   Maybe<ParseContext::Scope> innerScope;
-  innerScopeStmt.emplace(pc_, StatementKind::Block);
-  innerScope.emplace(this);
-  if (!innerScope->init(pc_)) {
-    return null();
+  if (className) {
+    innerScopeStmt.emplace(pc_, StatementKind::Block);
+    innerScope.emplace(this);
+    if (!innerScope->init(pc_)) {
+      return null();
+    }
   }
 
   // Because the binding definitions keep track of their blockId, we need to
   // create at least the inner binding later. Keep track of the name's position
   // in order to provide it for the nodes created later.
   TokenPos namePos = pos();
 
   Node classHeritage = null();
@@ -7024,45 +7018,40 @@ GeneralParser<ParseHandler, Unit>::class
       // Field initializers can be retrieved if the class and constructor are
       // being compiled at the same time, but we need to stash the field
       // information if the constructor is being compiled lazily.
       FieldInitializers fieldInfo(numFieldsWithInitializers);
       ctorbox->function()->lazyScript()->setFieldInitializers(fieldInfo);
     }
   }
 
-  NameNodeType innerName;
   Node nameNode = null();
+  Node membersOrBlock = classMembers;
   if (className) {
     // The inner name is immutable.
     if (!noteDeclaredName(className, DeclarationKind::Const, namePos)) {
       return null();
     }
 
-    innerName = newName(className, namePos);
+    NameNodeType innerName = newName(className, namePos);
     if (!innerName) {
       return null();
     }
-  }
-
-  if (!noteDeclaredName(cx_->names().dotInitializers, DeclarationKind::Const,
-                        namePos)) {
-    return null();
-  }
-
-  Node classBlock = finishLexicalScope(*innerScope, classMembers);
-  if (!classBlock) {
-    return null();
-  }
-
-  // Pop the inner scope.
-  innerScope.reset();
-  innerScopeStmt.reset();
-
-  if (className) {
+
+    Node classBlock = finishLexicalScope(*innerScope, classMembers);
+    if (!classBlock) {
+      return null();
+    }
+
+    membersOrBlock = classBlock;
+
+    // Pop the inner scope.
+    innerScope.reset();
+    innerScopeStmt.reset();
+
     NameNodeType outerName = null();
     if (classContext == ClassStatement) {
       // The outer name is mutable.
       if (!noteDeclaredName(className, DeclarationKind::Class, namePos)) {
         return null();
       }
 
       outerName = newName(className, namePos);
@@ -7074,17 +7063,17 @@ GeneralParser<ParseHandler, Unit>::class
     nameNode = handler_.newClassNames(outerName, innerName, namePos);
     if (!nameNode) {
       return null();
     }
   }
 
   MOZ_ALWAYS_TRUE(setLocalStrictMode(savedStrictness));
 
-  return handler_.newClass(nameNode, classHeritage, classBlock,
+  return handler_.newClass(nameNode, classHeritage, membersOrBlock,
                            TokenPos(classStartOffset, classEndOffset));
 }
 
 template <class ParseHandler, typename Unit>
 typename ParseHandler::FunctionNodeType
 GeneralParser<ParseHandler, Unit>::synthesizeConstructor(
     HandleAtom className, uint32_t classNameOffset) {
   FunctionSyntaxKind functionSyntaxKind = FunctionSyntaxKind::ClassConstructor;
@@ -7138,20 +7127,16 @@ GeneralParser<ParseHandler, Unit>::synth
     return null();
   }
 
   auto stmtList = handler_.newStatementList(synthesizedBodyPos);
   if (!stmtList) {
     return null();
   }
 
-  if (!noteUsedName(cx_->names().dotInitializers)) {
-    return null();
-  }
-
   if (!noteUsedName(cx_->names().dotThis)) {
     return null();
   }
 
   bool canSkipLazyClosedOverBindings = handler_.canSkipLazyClosedOverBindings();
   if (!pc_->declareFunctionThis(usedNames_, canSkipLazyClosedOverBindings)) {
     return null();
   }