Bug 1529439 - Share variable redeclaration code between regular parser and BinAST parser. r=Yoric
authorTooru Fujisawa <arai_a@mac.com>
Sun, 24 Feb 2019 03:35:19 +0000
changeset 518665 abcf203b0474
parent 518664 6bbc695865c6
child 518666 cfdb566ecbb8
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)
reviewersYoric
bugs1529439
milestone67.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 1529439 - Share variable redeclaration code between regular parser and BinAST parser. r=Yoric Shared the part to redeclare vars as body-level functions. Differential Revision: https://phabricator.services.mozilla.com/D20778
js/src/frontend/BinASTParserPerTokenizer.cpp
js/src/frontend/ParseContext-inl.h
js/src/frontend/ParseContext.cpp
--- a/js/src/frontend/BinASTParserPerTokenizer.cpp
+++ b/js/src/frontend/BinASTParserPerTokenizer.cpp
@@ -229,22 +229,19 @@ JS::Result<FunctionBox*> BinASTParserPer
 
   if (pc_ && syntax == FunctionSyntaxKind::Statement) {
     auto ptr = pc_->varScope().lookupDeclaredName(atom);
     if (!ptr) {
       return raiseError(
           "FunctionDeclaration without corresponding AssertedDeclaredName.");
     }
 
-    // FIXME: Should be merged with ParseContext::tryDeclareVarHelper
-    //        (bug 1499044).
     DeclarationKind declaredKind = ptr->value()->kind();
     if (DeclarationKindIsVar(declaredKind)) {
-      MOZ_ASSERT(declaredKind != DeclarationKind::VarForAnnexBLexicalFunction);
-      ptr->value()->alterKind(DeclarationKind::BodyLevelFunction);
+      RedeclareVar(ptr, DeclarationKind::BodyLevelFunction);
     }
   }
 
   // Allocate the function before walking down the tree.
   RootedFunction fun(cx_);
   BINJS_TRY_VAR(fun, !pc_ ? lazyScript_->functionNonDelazifying()
                           : AllocNewFunction(cx_, atom, syntax, generatorKind,
                                              functionAsyncKind, nullptr));
--- a/js/src/frontend/ParseContext-inl.h
+++ b/js/src/frontend/ParseContext-inl.h
@@ -132,12 +132,46 @@ ParseContext::checkContinueStatement(Pro
         return Ok();
       }
 
       stmt = stmt->enclosing();
     }
   }
 }
 
+template <typename DeclaredNamePtrT>
+inline void RedeclareVar(DeclaredNamePtrT ptr, DeclarationKind kind) {
+#ifdef DEBUG
+  DeclarationKind declaredKind = ptr->value()->kind();
+  MOZ_ASSERT(DeclarationKindIsVar(declaredKind));
+#endif
+
+  // Any vars that are redeclared as body-level functions must
+  // be recorded as body-level functions.
+  //
+  // In the case of global and eval scripts, GlobalDeclaration-
+  // Instantiation [1] and EvalDeclarationInstantiation [2]
+  // check for the declarability of global var and function
+  // bindings via CanDeclareVar [3] and CanDeclareGlobal-
+  // Function [4]. CanDeclareGlobalFunction is strictly more
+  // restrictive than CanDeclareGlobalVar, so record the more
+  // restrictive kind. These semantics are implemented in
+  // CheckCanDeclareGlobalBinding.
+  //
+  // VarForAnnexBLexicalFunction declarations are declared when
+  // the var scope exits. It is not possible for a var to be
+  // previously declared as VarForAnnexBLexicalFunction and
+  // checked for redeclaration.
+  //
+  // [1] ES 15.1.11
+  // [2] ES 18.2.1.3
+  // [3] ES 8.1.1.4.15
+  // [4] ES 8.1.1.4.16
+  if (kind == DeclarationKind::BodyLevelFunction) {
+    MOZ_ASSERT(declaredKind != DeclarationKind::VarForAnnexBLexicalFunction);
+    ptr->value()->alterKind(kind);
+  }
+}
+
 }  // namespace frontend
 }  // namespace js
 
 #endif  // frontend_ParseContext_inl_h
--- a/js/src/frontend/ParseContext.cpp
+++ b/js/src/frontend/ParseContext.cpp
@@ -412,42 +412,18 @@ bool ParseContext::tryDeclareVarHelper(H
   //   { var x; var x; }
   //   { { let x; } var x; }
 
   for (ParseContext::Scope* scope = innermostScope();
        scope != varScope().enclosing(); scope = scope->enclosing()) {
     if (AddDeclaredNamePtr p = scope->lookupDeclaredNameForAdd(name)) {
       DeclarationKind declaredKind = p->value()->kind();
       if (DeclarationKindIsVar(declaredKind)) {
-        // Any vars that are redeclared as body-level functions must
-        // be recorded as body-level functions.
-        //
-        // In the case of global and eval scripts, GlobalDeclaration-
-        // Instantiation [1] and EvalDeclarationInstantiation [2]
-        // check for the declarability of global var and function
-        // bindings via CanDeclareVar [3] and CanDeclareGlobal-
-        // Function [4]. CanDeclareGlobalFunction is strictly more
-        // restrictive than CanDeclareGlobalVar, so record the more
-        // restrictive kind. These semantics are implemented in
-        // CheckCanDeclareGlobalBinding.
-        //
-        // VarForAnnexBLexicalFunction declarations are declared when
-        // the var scope exits. It is not possible for a var to be
-        // previously declared as VarForAnnexBLexicalFunction and
-        // checked for redeclaration.
-        //
-        // [1] ES 15.1.11
-        // [2] ES 18.2.1.3
-        // [3] ES 8.1.1.4.15
-        // [4] ES 8.1.1.4.16
-        if (dryRunOption == NotDryRun &&
-            kind == DeclarationKind::BodyLevelFunction) {
-          MOZ_ASSERT(declaredKind !=
-                     DeclarationKind::VarForAnnexBLexicalFunction);
-          p->value()->alterKind(kind);
+        if (dryRunOption == NotDryRun) {
+          RedeclareVar(p, kind);
         }
       } else if (!DeclarationKindIsParameter(declaredKind)) {
         // Annex B.3.5 allows redeclaring simple (non-destructured)
         // catch parameters with var declarations.
         bool annexB35Allowance =
             declaredKind == DeclarationKind::SimpleCatchParameter;
 
         // Annex B.3.3 allows redeclaring functions in the same block.