Bug 1456416 - Make EagerGetter/EagerSetter create their scope earlier;r?arai,efaust draft
authorDavid Teller <dteller@mozilla.com>
Tue, 24 Apr 2018 11:24:23 +0200
changeset 787103 2ec378ab7f02c2068326fab372982bff53337ca1
parent 787102 7aea198713b2c166e651ca1049c867da160bc7f4
push id107642
push userdteller@mozilla.com
push dateTue, 24 Apr 2018 09:26:40 +0000
reviewersarai, efaust
bugs1456416
milestone61.0a1
Bug 1456416 - Make EagerGetter/EagerSetter create their scope earlier;r?arai,efaust MozReview-Commit-ID: 79spaZ9O8MY
js/src/frontend/BinSource-auto.cpp
js/src/frontend/BinSource.webidl_
js/src/frontend/BinSource.yaml
--- a/js/src/frontend/BinSource-auto.cpp
+++ b/js/src/frontend/BinSource-auto.cpp
@@ -13,18 +13,16 @@
 #include "mozilla/Casting.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/Move.h"
 #include "mozilla/PodOperations.h"
 #include "mozilla/Vector.h"
 
 #include "frontend/BinSource-macros.h"
 #include "frontend/BinSource.h"
-#include "frontend/BinSource-macros.h"
-#include "frontend/BinSource.h"
 #include "frontend/BinTokenReaderTester.h"
 #include "frontend/FullParseHandler.h"
 #include "frontend/Parser.h"
 #include "frontend/SharedContext.h"
 
 #include "vm/RegExpObject.h"
 
 #include "frontend/ParseContext-inl.h"
@@ -4170,19 +4168,19 @@ BinASTParser<Tok>::parseInterfaceEagerAr
     return raiseError("FIXME: Not implemented yet (EagerArrowExpression)");
 }
 
 
 /*
  interface EagerFunctionDeclaration : Node {
     bool isAsync;
     bool isGenerator;
+    BindingIdentifier name;
     AssertedParameterScope? parameterScope;
     AssertedVarScope? bodyScope;
-    BindingIdentifier name;
     FormalParameters params;
     FunctionBody body;
  }
 */
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseEagerFunctionDeclaration()
 {
     BinKind kind;
@@ -4201,31 +4199,36 @@ BinASTParser<Tok>::parseEagerFunctionDec
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceEagerFunctionDeclaration(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::EagerFunctionDeclaration);
     CheckRecursionLimit(cx_);
 
 
 #if defined(DEBUG)
-    const BinField expected_fields[7] = { BinField::IsAsync, BinField::IsGenerator, BinField::ParameterScope, BinField::BodyScope, BinField::Name, BinField::Params, BinField::Body };
+    const BinField expected_fields[7] = { BinField::IsAsync, BinField::IsGenerator, BinField::Name, BinField::ParameterScope, BinField::BodyScope, BinField::Params, BinField::Body };
     MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
 #endif // defined(DEBUG)
 
     const auto syntax = FunctionSyntaxKind::Statement;
 
 
     BINJS_MOZ_TRY_DECL(isAsync, tokenizer_->readBool());
 
 
 
 
     BINJS_MOZ_TRY_DECL(isGenerator, tokenizer_->readBool());
 
 
+
+
+    BINJS_MOZ_TRY_DECL(name, parseBindingIdentifier());
+
+
     BINJS_MOZ_TRY_DECL(funbox, buildFunctionBox(
         isGenerator ? GeneratorKind::Generator
                     : GeneratorKind::NotGenerator,
         isAsync ? FunctionAsyncKind::AsyncFunction
                 : FunctionAsyncKind::SyncFunction,
         syntax));
 
     // Push a new ParseContext. It will be used to parse `scope`, the arguments, the function.
@@ -4242,21 +4245,16 @@ BinASTParser<Tok>::parseInterfaceEagerFu
 
 
 
     MOZ_TRY(parseOptionalAssertedVarScope());
 
 
 
 
-    BINJS_MOZ_TRY_DECL(name, parseBindingIdentifier());
-
-
-
-
     BINJS_MOZ_TRY_DECL(params, parseFormalParameters());
 
 
 
 
     BINJS_MOZ_TRY_DECL(body, parseFunctionBody());
 
 
@@ -4266,19 +4264,19 @@ BinASTParser<Tok>::parseInterfaceEagerFu
     return result;
 }
 
 
 /*
  interface EagerFunctionExpression : Node {
     bool isAsync;
     bool isGenerator;
+    BindingIdentifier? name;
     AssertedParameterScope? parameterScope;
     AssertedVarScope? bodyScope;
-    BindingIdentifier? name;
     FormalParameters params;
     FunctionBody body;
  }
 */
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseEagerFunctionExpression()
 {
     BinKind kind;
@@ -4297,31 +4295,36 @@ BinASTParser<Tok>::parseEagerFunctionExp
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceEagerFunctionExpression(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::EagerFunctionExpression);
     CheckRecursionLimit(cx_);
 
 
 #if defined(DEBUG)
-    const BinField expected_fields[7] = { BinField::IsAsync, BinField::IsGenerator, BinField::ParameterScope, BinField::BodyScope, BinField::Name, BinField::Params, BinField::Body };
+    const BinField expected_fields[7] = { BinField::IsAsync, BinField::IsGenerator, BinField::Name, BinField::ParameterScope, BinField::BodyScope, BinField::Params, BinField::Body };
     MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
 #endif // defined(DEBUG)
 
     const auto syntax = FunctionSyntaxKind::Expression;
 
 
     BINJS_MOZ_TRY_DECL(isAsync, tokenizer_->readBool());
 
 
 
 
     BINJS_MOZ_TRY_DECL(isGenerator, tokenizer_->readBool());
 
 
+
+
+    BINJS_MOZ_TRY_DECL(name, parseOptionalBindingIdentifier());
+
+
     BINJS_MOZ_TRY_DECL(funbox, buildFunctionBox(
         isGenerator ? GeneratorKind::Generator
                     : GeneratorKind::NotGenerator,
         isAsync ? FunctionAsyncKind::AsyncFunction
                 : FunctionAsyncKind::SyncFunction,
         syntax));
 
     // Push a new ParseContext. It will be used to parse `scope`, the arguments, the function.
@@ -4338,21 +4341,16 @@ BinASTParser<Tok>::parseInterfaceEagerFu
 
 
 
     MOZ_TRY(parseOptionalAssertedVarScope());
 
 
 
 
-    BINJS_MOZ_TRY_DECL(name, parseOptionalBindingIdentifier());
-
-
-
-
     BINJS_MOZ_TRY_DECL(params, parseFormalParameters());
 
 
 
 
     BINJS_MOZ_TRY_DECL(body, parseFunctionBody());
 
 
@@ -4360,18 +4358,18 @@ BinASTParser<Tok>::parseInterfaceEagerFu
     BINJS_TRY_VAR(body, factory_.newLexicalScope(*lexicalScopeData, body));
     BINJS_MOZ_TRY_DECL(result, buildFunction(start, kind, name, params, body, funbox));
     return result;
 }
 
 
 /*
  interface EagerGetter : Node {
+    PropertyName name;
     AssertedVarScope? bodyScope;
-    PropertyName name;
     FunctionBody body;
  }
 */
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseEagerGetter()
 {
     BinKind kind;
     BinFields fields(cx_);
@@ -4389,62 +4387,62 @@ BinASTParser<Tok>::parseEagerGetter()
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceEagerGetter(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::EagerGetter);
     CheckRecursionLimit(cx_);
 
 
 #if defined(DEBUG)
-    const BinField expected_fields[3] = { BinField::BodyScope, BinField::Name, BinField::Body };
+    const BinField expected_fields[3] = { BinField::Name, BinField::BodyScope, BinField::Body };
     MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
 #endif // defined(DEBUG)
 
 
-
-
-    MOZ_TRY(parseOptionalAssertedVarScope());
-
-
-
-
-    BINJS_MOZ_TRY_DECL(name, parsePropertyName());
-
-
     BINJS_MOZ_TRY_DECL(funbox, buildFunctionBox(
         GeneratorKind::NotGenerator,
         FunctionAsyncKind::SyncFunction,
         FunctionSyntaxKind::Getter));
 
     // Push a new ParseContext. It will be used to parse `scope`, the arguments, the function.
     BinParseContext funpc(cx_, this, funbox, /* newDirectives = */ nullptr);
     BINJS_TRY(funpc.init());
     parseContext_->functionScope().useAsVarScope(parseContext_);
     MOZ_ASSERT(parseContext_->isFunctionBox());
 
     ParseContext::Scope lexicalScope(cx_, parseContext_, usedNames_);
     BINJS_TRY(lexicalScope.init(parseContext_));
 
+    BINJS_MOZ_TRY_DECL(name, parsePropertyName());
+
+
+
+
+    MOZ_TRY(parseOptionalAssertedVarScope());
+
+
+
+
     BINJS_MOZ_TRY_DECL(body, parseFunctionBody());
 
 
     ParseNode* params = new_<ListNode>(ParseNodeKind::ParamsBody, tokenizer_->pos(start));
     BINJS_MOZ_TRY_DECL(method, buildFunction(start, kind, name, params, body, funbox));
     BINJS_TRY_DECL(result, factory_.newObjectMethodOrPropertyDefinition(name, method, AccessorType::Getter));
     return result;
 }
 
 
 /*
  interface EagerMethod : Node {
     bool isAsync;
     bool isGenerator;
+    PropertyName name;
     AssertedParameterScope? parameterScope;
     AssertedVarScope? bodyScope;
-    PropertyName name;
     FormalParameters params;
     FunctionBody body;
  }
 */
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseEagerMethod()
 {
     BinKind kind;
@@ -4463,31 +4461,36 @@ BinASTParser<Tok>::parseEagerMethod()
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceEagerMethod(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::EagerMethod);
     CheckRecursionLimit(cx_);
 
 
 #if defined(DEBUG)
-    const BinField expected_fields[7] = { BinField::IsAsync, BinField::IsGenerator, BinField::ParameterScope, BinField::BodyScope, BinField::Name, BinField::Params, BinField::Body };
+    const BinField expected_fields[7] = { BinField::IsAsync, BinField::IsGenerator, BinField::Name, BinField::ParameterScope, BinField::BodyScope, BinField::Params, BinField::Body };
     MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
 #endif // defined(DEBUG)
 
     const auto syntax = FunctionSyntaxKind::Method;
 
 
     BINJS_MOZ_TRY_DECL(isAsync, tokenizer_->readBool());
 
 
 
 
     BINJS_MOZ_TRY_DECL(isGenerator, tokenizer_->readBool());
 
 
+
+
+    BINJS_MOZ_TRY_DECL(name, parsePropertyName());
+
+
     BINJS_MOZ_TRY_DECL(funbox, buildFunctionBox(
         isGenerator ? GeneratorKind::Generator
                     : GeneratorKind::NotGenerator,
         isAsync ? FunctionAsyncKind::AsyncFunction
                 : FunctionAsyncKind::SyncFunction,
         syntax));
 
     // Push a new ParseContext. It will be used to parse `scope`, the arguments, the function.
@@ -4504,40 +4507,35 @@ BinASTParser<Tok>::parseInterfaceEagerMe
 
 
 
     MOZ_TRY(parseOptionalAssertedVarScope());
 
 
 
 
-    BINJS_MOZ_TRY_DECL(name, parsePropertyName());
-
-
-
-
     BINJS_MOZ_TRY_DECL(params, parseFormalParameters());
 
 
 
 
     BINJS_MOZ_TRY_DECL(body, parseFunctionBody());
 
 
     BINJS_MOZ_TRY_DECL(method, buildFunction(start, kind, name, params, body, funbox));
     BINJS_TRY_DECL(result, factory_.newObjectMethodOrPropertyDefinition(name, method, AccessorType::None));
     return result;
 }
 
 
 /*
  interface EagerSetter : Node {
+    PropertyName name;
     AssertedParameterScope? parameterScope;
     AssertedVarScope? bodyScope;
-    PropertyName name;
     Parameter param;
     FunctionBody body;
  }
 */
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseEagerSetter()
 {
     BinKind kind;
@@ -4556,55 +4554,55 @@ BinASTParser<Tok>::parseEagerSetter()
 template<typename Tok> JS::Result<ParseNode*>
 BinASTParser<Tok>::parseInterfaceEagerSetter(const size_t start, const BinKind kind, const BinFields& fields)
 {
     MOZ_ASSERT(kind == BinKind::EagerSetter);
     CheckRecursionLimit(cx_);
 
 
 #if defined(DEBUG)
-    const BinField expected_fields[5] = { BinField::ParameterScope, BinField::BodyScope, BinField::Name, BinField::Param, BinField::Body };
+    const BinField expected_fields[5] = { BinField::Name, BinField::ParameterScope, BinField::BodyScope, BinField::Param, BinField::Body };
     MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
 #endif // defined(DEBUG)
 
 
-
-
-    MOZ_TRY(parseOptionalAssertedParameterScope());
-
-
-
-
-    MOZ_TRY(parseOptionalAssertedVarScope());
-
-
-
-
-    BINJS_MOZ_TRY_DECL(name, parsePropertyName());
-
-
-
-
-    BINJS_MOZ_TRY_DECL(param, parseParameter());
-
-
     BINJS_MOZ_TRY_DECL(funbox, buildFunctionBox(
         GeneratorKind::NotGenerator,
         FunctionAsyncKind::SyncFunction,
         FunctionSyntaxKind::Setter));
 
     // Push a new ParseContext. It will be used to parse `scope`, the arguments, the function.
     BinParseContext funpc(cx_, this, funbox, /* newDirectives = */ nullptr);
     BINJS_TRY(funpc.init());
     parseContext_->functionScope().useAsVarScope(parseContext_);
     MOZ_ASSERT(parseContext_->isFunctionBox());
 
     ParseContext::Scope lexicalScope(cx_, parseContext_, usedNames_);
     BINJS_TRY(lexicalScope.init(parseContext_));
 
+    BINJS_MOZ_TRY_DECL(name, parsePropertyName());
+
+
+
+
+    MOZ_TRY(parseOptionalAssertedParameterScope());
+
+
+
+
+    MOZ_TRY(parseOptionalAssertedVarScope());
+
+
+
+
+    BINJS_MOZ_TRY_DECL(param, parseParameter());
+
+
+
+
     BINJS_MOZ_TRY_DECL(body, parseFunctionBody());
 
 
     ParseNode* params = new_<ListNode>(ParseNodeKind::ParamsBody, param->pn_pos);
     factory_.addList(params, param);
     BINJS_MOZ_TRY_DECL(method, buildFunction(start, kind, name, params, body, funbox));
     BINJS_TRY_DECL(result, factory_.newObjectMethodOrPropertyDefinition(name, method, AccessorType::Setter));
     return result;
--- a/js/src/frontend/BinSource.webidl_
+++ b/js/src/frontend/BinSource.webidl_
@@ -423,44 +423,44 @@ interface ExportLocalSpecifier : Node {
 // `MethodDefinition :: PropertyName ( UniqueFormalParameters ) { FunctionBody }`,
 // `GeneratorMethod :: * PropertyName ( UniqueFormalParameters ) { GeneratorBody }`,
 // `AsyncMethod :: async PropertyName ( UniqueFormalParameters ) { AsyncFunctionBody }`
 interface EagerMethod : Node {
   // True for `AsyncMethod`, false otherwise.
   attribute boolean isAsync;
   // True for `GeneratorMethod`, false otherwise.
   attribute boolean isGenerator;
+  attribute PropertyName name;
   attribute AssertedParameterScope? parameterScope;
   attribute AssertedVarScope? bodyScope;
-  attribute PropertyName name;
   // The `UniqueFormalParameters`.
   attribute FormalParameters params;
   attribute FunctionBody body;
 };
 
 [Skippable] interface SkippableMethod : Node {
   attribute EagerMethod skipped;
 };
 
 // `get PropertyName ( ) { FunctionBody }`
 interface EagerGetter : Node {
+  attribute PropertyName name;
   attribute AssertedVarScope? bodyScope;
-  attribute PropertyName name;
   attribute FunctionBody body;
 };
 
 [Skippable] interface SkippableGetter : Node {
   attribute EagerGetter skipped;
 };
 
 // `set PropertyName ( PropertySetParameterList ) { FunctionBody }`
 interface EagerSetter : Node {
+  attribute PropertyName name;
   attribute AssertedParameterScope? parameterScope;
   attribute AssertedVarScope? bodyScope;
-  attribute PropertyName name;
   // The `PropertySetParameterList`.
   attribute Parameter param;
   attribute FunctionBody body;
 };
 
 [Skippable] interface SkippableSetter : Node {
   attribute EagerSetter skipped;
 };
@@ -600,19 +600,19 @@ interface ConditionalExpression : Node {
 };
 
 // `FunctionExpression`,
 // `GeneratorExpression`,
 // `AsyncFunctionExpression`,
 interface EagerFunctionExpression : Node {
   attribute boolean isAsync;
   attribute boolean isGenerator;
+  attribute BindingIdentifier? name;
   attribute AssertedParameterScope? parameterScope;
   attribute AssertedVarScope? bodyScope;
-  attribute BindingIdentifier? name;
   attribute FormalParameters params;
   attribute FunctionBody body;
 };
 
 [Skippable] interface SkippableFunctionExpression : Node {
   attribute EagerFunctionExpression skipped;
 };
 
@@ -852,19 +852,19 @@ interface FunctionBody : Node {
 
 
 // `FunctionDeclaration`,
 // `GeneratorDeclaration`,
 // `AsyncFunctionDeclaration`
 interface EagerFunctionDeclaration : Node {
   attribute boolean isAsync;
   attribute boolean isGenerator;
+  attribute BindingIdentifier name;
   attribute AssertedParameterScope? parameterScope;
   attribute AssertedVarScope? bodyScope;
-  attribute BindingIdentifier name;
   attribute FormalParameters params;
   attribute FunctionBody body;
 };
 
 [Skippable] interface SkippableFunctionDeclaration : Node {
   attribute EagerFunctionDeclaration skipped;
 };
 
@@ -900,9 +900,9 @@ interface TemplateElement : Node {
 interface VariableDeclaration : Node {
   attribute VariableDeclarationKind kind;
   [NonEmpty] attribute FrozenArray<VariableDeclarator> declarators;
 };
 
 interface VariableDeclarator : Node {
   attribute Binding binding;
   attribute Expression? init;
-};
\ No newline at end of file
+};
--- a/js/src/frontend/BinSource.yaml
+++ b/js/src/frontend/BinSource.yaml
@@ -554,17 +554,17 @@ EagerFunctionExpression:
                 BINJS_TRY(lexicalScope.init(parseContext_));
     build: |
         BINJS_TRY_DECL(lexicalScopeData, NewLexicalScopeData(cx_, lexicalScope, alloc_, parseContext_));
         BINJS_TRY_VAR(body, factory_.newLexicalScope(*lexicalScopeData, body));
         BINJS_MOZ_TRY_DECL(result, buildFunction(start, kind, name, params, body, funbox));
 
 EagerGetter:
     fields:
-        body:
+        name:
             before: |
                 BINJS_MOZ_TRY_DECL(funbox, buildFunctionBox(
                     GeneratorKind::NotGenerator,
                     FunctionAsyncKind::SyncFunction,
                     FunctionSyntaxKind::Getter));
 
                 // Push a new ParseContext. It will be used to parse `scope`, the arguments, the function.
                 BinParseContext funpc(cx_, this, funbox, /* newDirectives = */ nullptr);
@@ -584,17 +584,17 @@ EagerMethod:
         const auto syntax = FunctionSyntaxKind::Method;
     inherits: EagerFunctionExpression
     build: |
         BINJS_MOZ_TRY_DECL(method, buildFunction(start, kind, name, params, body, funbox));
         BINJS_TRY_DECL(result, factory_.newObjectMethodOrPropertyDefinition(name, method, AccessorType::None));
 
 EagerSetter:
     fields:
-        body:
+        name:
             before: |
                 BINJS_MOZ_TRY_DECL(funbox, buildFunctionBox(
                     GeneratorKind::NotGenerator,
                     FunctionAsyncKind::SyncFunction,
                     FunctionSyntaxKind::Setter));
 
                 // Push a new ParseContext. It will be used to parse `scope`, the arguments, the function.
                 BinParseContext funpc(cx_, this, funbox, /* newDirectives = */ nullptr);