Bug 1496332 - Properly handle { __proto__: foo } in BinAST. (r=arai)
authorEric Faust <efausbmo@gmail.com>
Mon, 15 Oct 2018 17:17:58 -0400
changeset 489585 4ba3494b8b7637420f6b01eaf5f1199227798915
parent 489584 f7d0546ee3cecaef21bf86e44717d84632d61580
child 489586 0855e7bda81620c0c3029b14cece477261f3e08f
push id247
push userfmarier@mozilla.com
push dateSat, 27 Oct 2018 01:06:44 +0000
reviewersarai
bugs1496332
milestone64.0a1
Bug 1496332 - Properly handle { __proto__: foo } in BinAST. (r=arai)
js/src/frontend/BinSource-auto.cpp
js/src/frontend/BinSource.cpp
js/src/frontend/BinSource.yaml
--- a/js/src/frontend/BinSource-auto.cpp
+++ b/js/src/frontend/BinSource-auto.cpp
@@ -3127,17 +3127,22 @@ BinASTParser<Tok>::parseInterfaceDataPro
     BINJS_MOZ_TRY_DECL(name, parsePropertyName());
 
     BINJS_MOZ_TRY_DECL(expression, parseExpression());
 
     if (!factory_.isUsableAsObjectPropertyName(name)) {
         return raiseError("DataProperty key kind");
     }
 
-    BINJS_TRY_DECL(result, factory_.newObjectMethodOrPropertyDefinition(name, expression, AccessorType::None));
+    ParseNode* result;
+    if (name->template is<NameNode>() && name->template as<NameNode>().atom() == cx_->names().proto) {
+        BINJS_TRY_VAR(result, factory_.newUnary(ParseNodeKind::MutateProto, start, expression));
+    } else {
+        BINJS_TRY_VAR(result, factory_.newObjectMethodOrPropertyDefinition(name, expression, AccessorType::None));
+    }
     return result;
 }
 
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceDebuggerStatement(const size_t start, const BinKind kind, const BinFields& fields)
 {
     return raiseError("FIXME: Not implemented yet in this preview release (DebuggerStatement)");
 }
--- a/js/src/frontend/BinSource.cpp
+++ b/js/src/frontend/BinSource.cpp
@@ -230,18 +230,20 @@ template<typename Tok> JS::Result<Functi
 BinASTParser<Tok>::buildFunctionBox(GeneratorKind generatorKind,
     FunctionAsyncKind functionAsyncKind,
     FunctionSyntaxKind syntax,
     ParseNode* name)
 {
     MOZ_ASSERT_IF(!parseContext_, lazyScript_);
 
     RootedAtom atom(cx_);
-    if (name) {
-        atom = name->name();
+
+    // Name might be any of {Identifier,ComputedPropertyName,LiteralPropertyName}
+    if (name && name->is<NameNode>()) {
+        atom = name->as<NameNode>().atom();
     }
 
     if (parseContext_ && syntax == FunctionSyntaxKind::Statement) {
         auto ptr = parseContext_->varScope().lookupDeclaredName(atom);
         if (!ptr) {
             return raiseError("FunctionDeclaration without corresponding AssertedDeclaredName.");
         }
 
@@ -346,17 +348,35 @@ BinASTParser<Tok>::buildFunction(const s
             funbox->declaredArguments = true;
             funbox->usesArguments = true;
 
             funbox->setArgumentsHasLocalBinding();
             funbox->setDefinitelyNeedsArgsObj();
         }
     }
 
-    // Check all our bindings after maybe adding function This.
+    if (funbox->needsDotGeneratorName()) {
+        ParseContext::Scope& funScope = parseContext_->functionScope();
+        HandlePropertyName dotGenerator = cx_->names().dotGenerator;
+        ParseContext::Scope::AddDeclaredNamePtr p = funScope.lookupDeclaredNameForAdd(dotGenerator);
+        if (!p) {
+            BINJS_TRY(funScope.addDeclaredName(parseContext_, p, dotGenerator, DeclarationKind::Var,
+                                               DeclaredNameInfo::npos));
+        }
+
+        BINJS_TRY(usedNames_.noteUse(cx_, dotGenerator, parseContext_->scriptId(),
+                                     parseContext_->innermostScope()->id()));
+
+        BINJS_TRY_DECL(dotGen, factory_.newName(dotGenerator,
+                                                tokenizer_->pos(tokenizer_->offset()), cx_));
+
+        BINJS_TRY(factory_.prependInitialYield(&body->as<ListNode>(), dotGen));
+    }
+
+    // Check all our bindings after maybe adding function metavars.
     MOZ_TRY(checkFunctionClosedVars());
 
     BINJS_TRY_DECL(bindings,
              NewFunctionScopeData(cx_, parseContext_->functionScope(),
                                   /* hasParameterExprs = */ false, alloc_, parseContext_));
 
     funbox->functionScopeBindings().set(*bindings);
 
--- a/js/src/frontend/BinSource.yaml
+++ b/js/src/frontend/BinSource.yaml
@@ -617,17 +617,22 @@ ContinueStatement:
         BINJS_TRY_DECL(result, factory_.newContinueStatement(label ? label->asPropertyName() : nullptr, tokenizer_->pos(start)));
 
 DataProperty:
     build: |
         if (!factory_.isUsableAsObjectPropertyName(name)) {
             return raiseError("DataProperty key kind");
         }
 
-        BINJS_TRY_DECL(result, factory_.newObjectMethodOrPropertyDefinition(name, expression, AccessorType::None));
+        ParseNode* result;
+        if (name->template is<NameNode>() && name->template as<NameNode>().atom() == cx_->names().proto) {
+            BINJS_TRY_VAR(result, factory_.newUnary(ParseNodeKind::MutateProto, start, expression));
+        } else {
+            BINJS_TRY_VAR(result, factory_.newObjectMethodOrPropertyDefinition(name, expression, AccessorType::None));
+        }
 
 Directive:
     build: |
         TokenPos pos = tokenizer_->pos(start);
         BINJS_TRY_DECL(result, factory_.newStringLiteral(rawValue, pos));
 
 DoWhileStatement:
     init: