Bug 1494930 - Part 4: Respect strictness directives. (r=arai)
☠☠ backed out by 63ea63571271 ☠ ☠
authorEric Faust <efausbmo@gmail.com>
Mon, 01 Oct 2018 20:41:48 -0700
changeset 494874 275f7949148be2d20a45653e44a0bf4b4ae09a44
parent 494873 8544285b414588d834cd9147ed06ba02a2a60a03
child 494875 8f2f2bcd57d2d65a5f4412a9c8867a0296a5b271
push id9984
push userffxbld-merge
push dateMon, 15 Oct 2018 21:07:35 +0000
treeherdermozilla-beta@183d27ea8570 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersarai
bugs1494930
milestone64.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 1494930 - Part 4: Respect strictness directives. (r=arai)
js/src/frontend/BinSource-auto.cpp
js/src/frontend/BinSource.cpp
js/src/frontend/BinSource.h
js/src/frontend/BinSource.yaml
--- a/js/src/frontend/BinSource-auto.cpp
+++ b/js/src/frontend/BinSource-auto.cpp
@@ -4631,16 +4631,18 @@ BinASTParser<Tok>::parseInterfaceEagerFu
         isGenerator ? GeneratorKind::Generator
                     : GeneratorKind::NotGenerator,
         isAsync ? FunctionAsyncKind::AsyncFunction
                 : FunctionAsyncKind::SyncFunction,
         syntax,
         (syntax != FunctionSyntaxKind::Setter &&
          syntax != FunctionSyntaxKind::Getter) ? name : nullptr));
 
+    forceStrictIfNecessary(funbox, directives);
+
     // 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_));
@@ -4710,16 +4712,18 @@ BinASTParser<Tok>::parseInterfaceEagerFu
         isGenerator ? GeneratorKind::Generator
                     : GeneratorKind::NotGenerator,
         isAsync ? FunctionAsyncKind::AsyncFunction
                 : FunctionAsyncKind::SyncFunction,
         syntax,
         (syntax != FunctionSyntaxKind::Setter &&
          syntax != FunctionSyntaxKind::Getter) ? name : nullptr));
 
+    forceStrictIfNecessary(funbox, directives);
+
     // 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_));
@@ -4784,16 +4788,18 @@ BinASTParser<Tok>::parseInterfaceEagerGe
         isGenerator ? GeneratorKind::Generator
                     : GeneratorKind::NotGenerator,
         isAsync ? FunctionAsyncKind::AsyncFunction
                 : FunctionAsyncKind::SyncFunction,
         syntax,
         (syntax != FunctionSyntaxKind::Setter &&
          syntax != FunctionSyntaxKind::Getter) ? name : nullptr));
 
+    forceStrictIfNecessary(funbox, directives);
+
     // 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_));
@@ -4863,16 +4869,18 @@ BinASTParser<Tok>::parseInterfaceEagerMe
         isGenerator ? GeneratorKind::Generator
                     : GeneratorKind::NotGenerator,
         isAsync ? FunctionAsyncKind::AsyncFunction
                 : FunctionAsyncKind::SyncFunction,
         syntax,
         (syntax != FunctionSyntaxKind::Setter &&
          syntax != FunctionSyntaxKind::Getter) ? name : nullptr));
 
+    forceStrictIfNecessary(funbox, directives);
+
     // 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_));
@@ -4938,16 +4946,18 @@ BinASTParser<Tok>::parseInterfaceEagerSe
         isGenerator ? GeneratorKind::Generator
                     : GeneratorKind::NotGenerator,
         isAsync ? FunctionAsyncKind::AsyncFunction
                 : FunctionAsyncKind::SyncFunction,
         syntax,
         (syntax != FunctionSyntaxKind::Setter &&
          syntax != FunctionSyntaxKind::Getter) ? name : nullptr));
 
+    forceStrictIfNecessary(funbox, directives);
+
     // 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_));
--- a/js/src/frontend/BinSource.cpp
+++ b/js/src/frontend/BinSource.cpp
@@ -149,16 +149,28 @@ BinASTParser<Tok>::parseAux(GlobalShared
     if (!bindings) {
         return cx_->alreadyReportedError();
     }
     globalsc->bindings = *bindings;
 
     return result; // Magic conversion to Ok.
 }
 
+template<typename Tok> void
+BinASTParser<Tok>::forceStrictIfNecessary(FunctionBox* funbox, ListNode* directives)
+{
+    JSAtom* useStrict = cx_->names().useStrict;
+
+    for (const ParseNode* directive : directives->contents()) {
+        if (directive->as<NameNode>().atom() == useStrict) {
+            funbox->strictScript = true;
+            break;
+        }
+    }
+}
 
 template<typename Tok> JS::Result<FunctionBox*>
 BinASTParser<Tok>::buildFunctionBox(GeneratorKind generatorKind,
     FunctionAsyncKind functionAsyncKind,
     FunctionSyntaxKind syntax,
     ParseNode* name)
 {
     RootedAtom atom(cx_);
--- a/js/src/frontend/BinSource.h
+++ b/js/src/frontend/BinSource.h
@@ -208,16 +208,20 @@ class BinASTParser : public BinASTParser
     // As a convenience, a helper that checks the body, parameter, and recursive binding scopes.
     MOZ_MUST_USE JS::Result<Ok> checkFunctionClosedVars();
 
     // --- Utilities.
 
     MOZ_MUST_USE JS::Result<ParseNode*> appendDirectivesToBody(ListNode* body,
         ListNode* directives);
 
+    // Optionally force a strict context without restarting the parse when we see a strict
+    // directive.
+    void forceStrictIfNecessary(FunctionBox* funbox, ListNode* directives);
+
   private: // Implement ErrorReporter
     const JS::ReadOnlyCompileOptions& options_;
 
     const JS::ReadOnlyCompileOptions& options() const override {
         return this->options_;
     }
 
   public:
--- a/js/src/frontend/BinSource.yaml
+++ b/js/src/frontend/BinSource.yaml
@@ -697,16 +697,18 @@ EagerFunctionExpression:
                     isGenerator ? GeneratorKind::Generator
                                 : GeneratorKind::NotGenerator,
                     isAsync ? FunctionAsyncKind::AsyncFunction
                             : FunctionAsyncKind::SyncFunction,
                     syntax,
                     (syntax != FunctionSyntaxKind::Setter &&
                      syntax != FunctionSyntaxKind::Getter) ? name : nullptr));
 
+                forceStrictIfNecessary(funbox, directives);
+
                 // 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_));