Bug 1511891 part 8 - Move CheckGlobalOrEvalDeclarationConflicts to EnvironmentObject.cpp and call it also in the interpreter. r=tcampbell
authorJan de Mooij <jdemooij@mozilla.com>
Fri, 11 Jan 2019 09:15:41 +0000
changeset 453462 4e1a2cc33577009e6ff6149b0231e5c55f0e7289
parent 453461 0df13a6c64be51a71425190e082e977795ad7242
child 453463 d7c3229eb734731f76d35191a283dc3e07cabf62
push id35357
push usernerli@mozilla.com
push dateFri, 11 Jan 2019 21:54:07 +0000
treeherdermozilla-central@0ce024c91511 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstcampbell
bugs1511891
milestone66.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 1511891 part 8 - Move CheckGlobalOrEvalDeclarationConflicts to EnvironmentObject.cpp and call it also in the interpreter. r=tcampbell Differential Revision: https://phabricator.services.mozilla.com/D13706
js/src/jit/BaselineCompiler.cpp
js/src/jit/VMFunctions.cpp
js/src/jit/VMFunctions.h
js/src/vm/EnvironmentObject.cpp
js/src/vm/EnvironmentObject.h
js/src/vm/Stack.cpp
--- a/js/src/jit/BaselineCompiler.cpp
+++ b/js/src/jit/BaselineCompiler.cpp
@@ -814,17 +814,17 @@ bool BaselineCompiler::emitDebugPrologue
   return true;
 }
 
 typedef bool (*CheckGlobalOrEvalDeclarationConflictsFn)(JSContext*,
                                                         HandleObject,
                                                         HandleScript);
 static const VMFunction CheckGlobalOrEvalDeclarationConflictsInfo =
     FunctionInfo<CheckGlobalOrEvalDeclarationConflictsFn>(
-        jit::CheckGlobalOrEvalDeclarationConflicts,
+        js::CheckGlobalOrEvalDeclarationConflicts,
         "CheckGlobalOrEvalDeclarationConflicts");
 
 typedef bool (*InitFunctionEnvironmentObjectsFn)(JSContext*, BaselineFrame*);
 static const VMFunction InitFunctionEnvironmentObjectsInfo =
     FunctionInfo<InitFunctionEnvironmentObjectsFn>(
         jit::InitFunctionEnvironmentObjects, "InitFunctionEnvironmentObjects");
 
 bool BaselineCompiler::initEnvironmentChain() {
--- a/js/src/jit/VMFunctions.cpp
+++ b/js/src/jit/VMFunctions.cpp
@@ -896,46 +896,16 @@ bool GeneratorThrowOrReturn(JSContext* c
     resumeKind = GeneratorObject::RETURN;
   }
 
   MOZ_ALWAYS_FALSE(
       js::GeneratorThrowOrReturn(cx, frame, genObj, arg, resumeKind));
   return false;
 }
 
-bool CheckGlobalOrEvalDeclarationConflicts(JSContext* cx, HandleObject envChain,
-                                           HandleScript script) {
-  RootedObject varObj(cx, &GetVariablesObject(envChain));
-
-  if (script->isForEval()) {
-    // Strict eval and eval in parameter default expressions have their
-    // own call objects.
-    //
-    // Non-strict eval may introduce 'var' bindings that conflict with
-    // lexical bindings in an enclosing lexical scope.
-    if (!script->bodyScope()->hasEnvironment()) {
-      MOZ_ASSERT(
-          !script->strict() &&
-          (!script->enclosingScope()->is<FunctionScope>() ||
-           !script->enclosingScope()->as<FunctionScope>().hasParameterExprs()));
-      if (!CheckEvalDeclarationConflicts(cx, script, envChain, varObj)) {
-        return false;
-      }
-    }
-  } else {
-    Rooted<LexicalEnvironmentObject*> lexicalEnv(
-        cx, &NearestEnclosingExtensibleLexicalEnvironment(envChain));
-    if (!CheckGlobalDeclarationConflicts(cx, script, lexicalEnv, varObj)) {
-      return false;
-    }
-  }
-
-  return true;
-}
-
 bool GlobalNameConflictsCheckFromIon(JSContext* cx, HandleScript script) {
   Rooted<LexicalEnvironmentObject*> globalLexical(
       cx, &cx->global()->lexicalEnvironment());
   return CheckGlobalDeclarationConflicts(cx, script, globalLexical,
                                          cx->global());
 }
 
 bool InitFunctionEnvironmentObjects(JSContext* cx, BaselineFrame* frame) {
--- a/js/src/jit/VMFunctions.h
+++ b/js/src/jit/VMFunctions.h
@@ -1026,19 +1026,16 @@ MOZ_MUST_USE bool InterpretResume(JSCont
 MOZ_MUST_USE bool DebugAfterYield(JSContext* cx, BaselineFrame* frame,
                                   jsbytecode* pc, bool* mustReturn);
 MOZ_MUST_USE bool GeneratorThrowOrReturn(JSContext* cx, BaselineFrame* frame,
                                          Handle<GeneratorObject*> genObj,
                                          HandleValue arg, uint32_t resumeKind);
 
 MOZ_MUST_USE bool GlobalNameConflictsCheckFromIon(JSContext* cx,
                                                   HandleScript script);
-MOZ_MUST_USE bool CheckGlobalOrEvalDeclarationConflicts(JSContext* cx,
-                                                        HandleObject envChain,
-                                                        HandleScript script);
 MOZ_MUST_USE bool InitFunctionEnvironmentObjects(JSContext* cx,
                                                  BaselineFrame* frame);
 
 MOZ_MUST_USE bool NewArgumentsObject(JSContext* cx, BaselineFrame* frame,
                                      MutableHandleValue res);
 
 JSObject* CopyLexicalEnvironmentObject(JSContext* cx, HandleObject env,
                                        bool copySlots);
--- a/js/src/vm/EnvironmentObject.cpp
+++ b/js/src/vm/EnvironmentObject.cpp
@@ -3665,19 +3665,19 @@ static bool CheckVarNameConflictsInEnv(J
     if (!CheckVarNameConflict(cx, env, name)) {
       return false;
     }
   }
 
   return true;
 }
 
-bool js::CheckEvalDeclarationConflicts(JSContext* cx, HandleScript script,
-                                       HandleObject scopeChain,
-                                       HandleObject varObj) {
+static bool CheckEvalDeclarationConflicts(JSContext* cx, HandleScript script,
+                                          HandleObject scopeChain,
+                                          HandleObject varObj) {
   if (!script->bodyScope()->as<EvalScope>().hasBindings()) {
     return true;
   }
 
   RootedObject obj(cx, scopeChain);
 
   // ES 18.2.1.3.
 
@@ -3705,16 +3705,47 @@ bool js::CheckEvalDeclarationConflicts(J
         return false;
       }
     }
   }
 
   return true;
 }
 
+bool js::CheckGlobalOrEvalDeclarationConflicts(JSContext* cx,
+                                               HandleObject envChain,
+                                               HandleScript script) {
+  RootedObject varObj(cx, &GetVariablesObject(envChain));
+
+  if (script->isForEval()) {
+    // Strict eval and eval in parameter default expressions have their
+    // own call objects.
+    //
+    // Non-strict eval may introduce 'var' bindings that conflict with
+    // lexical bindings in an enclosing lexical scope.
+    if (!script->bodyScope()->hasEnvironment()) {
+      MOZ_ASSERT(
+          !script->strict() &&
+          (!script->enclosingScope()->is<FunctionScope>() ||
+           !script->enclosingScope()->as<FunctionScope>().hasParameterExprs()));
+      if (!CheckEvalDeclarationConflicts(cx, script, envChain, varObj)) {
+        return false;
+      }
+    }
+  } else {
+    Rooted<LexicalEnvironmentObject*> lexicalEnv(
+        cx, &NearestEnclosingExtensibleLexicalEnvironment(envChain));
+    if (!CheckGlobalDeclarationConflicts(cx, script, lexicalEnv, varObj)) {
+      return false;
+    }
+  }
+
+  return true;
+}
+
 bool js::InitFunctionEnvironmentObjects(JSContext* cx, AbstractFramePtr frame) {
   MOZ_ASSERT(frame.isFunctionFrame());
   MOZ_ASSERT(frame.callee()->needsSomeEnvironmentObject());
 
   RootedFunction callee(cx, frame.callee());
 
   // Named lambdas may have an environment that holds itself for recursion.
   if (callee->needsNamedLambdaEnvironment()) {
--- a/js/src/vm/EnvironmentObject.h
+++ b/js/src/vm/EnvironmentObject.h
@@ -1167,20 +1167,19 @@ MOZ_MUST_USE bool CheckCanDeclareGlobalB
 MOZ_MUST_USE bool CheckLexicalNameConflict(
     JSContext* cx, Handle<LexicalEnvironmentObject*> lexicalEnv,
     HandleObject varObj, HandlePropertyName name);
 
 MOZ_MUST_USE bool CheckGlobalDeclarationConflicts(
     JSContext* cx, HandleScript script,
     Handle<LexicalEnvironmentObject*> lexicalEnv, HandleObject varObj);
 
-MOZ_MUST_USE bool CheckEvalDeclarationConflicts(JSContext* cx,
-                                                HandleScript script,
-                                                HandleObject envChain,
-                                                HandleObject varObj);
+MOZ_MUST_USE bool CheckGlobalOrEvalDeclarationConflicts(JSContext* cx,
+                                                        HandleObject envChain,
+                                                        HandleScript script);
 
 MOZ_MUST_USE bool InitFunctionEnvironmentObjects(JSContext* cx,
                                                  AbstractFramePtr frame);
 
 MOZ_MUST_USE bool PushVarEnvironmentObject(JSContext* cx, HandleScope scope,
                                            AbstractFramePtr frame);
 
 MOZ_MUST_USE bool GetFrameEnvironmentAndScope(JSContext* cx,
--- a/js/src/vm/Stack.cpp
+++ b/js/src/vm/Stack.cpp
@@ -193,59 +193,40 @@ bool InterpreterFrame::initFunctionEnvir
 }
 
 bool InterpreterFrame::prologue(JSContext* cx) {
   RootedScript script(cx, this->script());
 
   MOZ_ASSERT(cx->interpreterRegs().pc == script->code());
   MOZ_ASSERT(cx->realm() == script->realm());
 
-  if (isEvalFrame()) {
-    if (!script->bodyScope()->hasEnvironment()) {
-      MOZ_ASSERT(!script->strict());
-      // Non-strict eval may introduce var bindings that conflict with
-      // lexical bindings in an enclosing lexical scope.
-      RootedObject varObjRoot(cx, &varObj());
-      if (!CheckEvalDeclarationConflicts(cx, script, environmentChain(),
-                                         varObjRoot)) {
-        return false;
-      }
-    }
-    return probes::EnterScript(cx, script, nullptr, this);
-  }
-
-  if (isGlobalFrame()) {
-    Rooted<LexicalEnvironmentObject*> lexicalEnv(cx);
-    RootedObject varObjRoot(cx);
-    if (script->hasNonSyntacticScope()) {
-      lexicalEnv = &extensibleLexicalEnvironment();
-      varObjRoot = &varObj();
-    } else {
-      lexicalEnv = &cx->global()->lexicalEnvironment();
-      varObjRoot = cx->global();
-    }
-    if (!CheckGlobalDeclarationConflicts(cx, script, lexicalEnv, varObjRoot)) {
-      // Treat this as a script entry, for consistency with Ion.
-      if (script->trackRecordReplayProgress()) {
-        mozilla::recordreplay::AdvanceExecutionProgressCounter();
+  if (isEvalFrame() || isGlobalFrame()) {
+    HandleObject env = environmentChain();
+    if (!CheckGlobalOrEvalDeclarationConflicts(cx, env, script)) {
+      if (isGlobalFrame()) {
+        // Treat this as a script entry, for consistency with Ion.
+        if (script->trackRecordReplayProgress()) {
+          mozilla::recordreplay::AdvanceExecutionProgressCounter();
+        }
       }
       return false;
     }
     return probes::EnterScript(cx, script, nullptr, this);
   }
 
   if (isModuleFrame()) {
     return probes::EnterScript(cx, script, nullptr, this);
   }
 
+  MOZ_ASSERT(isFunctionFrame());
+
   // At this point, we've yet to push any environments. Check that they
   // match the enclosing scope.
   AssertScopeMatchesEnvironment(script->enclosingScope(), environmentChain());
 
-  MOZ_ASSERT(isFunctionFrame());
   if (callee().needsFunctionEnvironmentObjects() &&
       !initFunctionEnvironmentObjects(cx)) {
     return false;
   }
 
   MOZ_ASSERT_IF(isConstructing(),
                 thisArgument().isObject() ||
                     thisArgument().isMagic(JS_UNINITIALIZED_LEXICAL));