From aa9b0c47baa6fc0593068667acf22bfe65663065 Mon Sep 17 00:00:00 2001 From: Jan de Mooij Date: Fri, 11 Jan 2019 09:15:41 +0000 Subject: [PATCH] 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 --HG-- extra : moz-landing-system : lando --- js/src/jit/BaselineCompiler.cpp | 2 +- js/src/jit/VMFunctions.cpp | 30 ------------------------- js/src/jit/VMFunctions.h | 3 --- js/src/vm/EnvironmentObject.cpp | 37 ++++++++++++++++++++++++++++--- js/src/vm/EnvironmentObject.h | 7 +++--- js/src/vm/Stack.cpp | 39 +++++++++------------------------ 6 files changed, 48 insertions(+), 70 deletions(-) diff --git a/js/src/jit/BaselineCompiler.cpp b/js/src/jit/BaselineCompiler.cpp index 4cfb189329fe..7ded43555916 100644 --- a/js/src/jit/BaselineCompiler.cpp +++ b/js/src/jit/BaselineCompiler.cpp @@ -819,7 +819,7 @@ typedef bool (*CheckGlobalOrEvalDeclarationConflictsFn)(JSContext*, HandleScript); static const VMFunction CheckGlobalOrEvalDeclarationConflictsInfo = FunctionInfo( - jit::CheckGlobalOrEvalDeclarationConflicts, + js::CheckGlobalOrEvalDeclarationConflicts, "CheckGlobalOrEvalDeclarationConflicts"); typedef bool (*InitFunctionEnvironmentObjectsFn)(JSContext*, BaselineFrame*); diff --git a/js/src/jit/VMFunctions.cpp b/js/src/jit/VMFunctions.cpp index 93b9f3f08cd1..51c2f68de18e 100644 --- a/js/src/jit/VMFunctions.cpp +++ b/js/src/jit/VMFunctions.cpp @@ -901,36 +901,6 @@ bool GeneratorThrowOrReturn(JSContext* cx, BaselineFrame* frame, 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() || - !script->enclosingScope()->as().hasParameterExprs())); - if (!CheckEvalDeclarationConflicts(cx, script, envChain, varObj)) { - return false; - } - } - } else { - Rooted lexicalEnv( - cx, &NearestEnclosingExtensibleLexicalEnvironment(envChain)); - if (!CheckGlobalDeclarationConflicts(cx, script, lexicalEnv, varObj)) { - return false; - } - } - - return true; -} - bool GlobalNameConflictsCheckFromIon(JSContext* cx, HandleScript script) { Rooted globalLexical( cx, &cx->global()->lexicalEnvironment()); diff --git a/js/src/jit/VMFunctions.h b/js/src/jit/VMFunctions.h index 00a770ff2b03..e3554e767749 100644 --- a/js/src/jit/VMFunctions.h +++ b/js/src/jit/VMFunctions.h @@ -1031,9 +1031,6 @@ MOZ_MUST_USE bool GeneratorThrowOrReturn(JSContext* cx, BaselineFrame* frame, 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); diff --git a/js/src/vm/EnvironmentObject.cpp b/js/src/vm/EnvironmentObject.cpp index 47b2d3817599..6cc412cbb064 100644 --- a/js/src/vm/EnvironmentObject.cpp +++ b/js/src/vm/EnvironmentObject.cpp @@ -3670,9 +3670,9 @@ static bool CheckVarNameConflictsInEnv(JSContext* cx, HandleScript script, 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().hasBindings()) { return true; } @@ -3710,6 +3710,37 @@ bool js::CheckEvalDeclarationConflicts(JSContext* cx, HandleScript script, 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() || + !script->enclosingScope()->as().hasParameterExprs())); + if (!CheckEvalDeclarationConflicts(cx, script, envChain, varObj)) { + return false; + } + } + } else { + Rooted 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()); diff --git a/js/src/vm/EnvironmentObject.h b/js/src/vm/EnvironmentObject.h index 6f8901fcf4a6..510d277c884e 100644 --- a/js/src/vm/EnvironmentObject.h +++ b/js/src/vm/EnvironmentObject.h @@ -1172,10 +1172,9 @@ MOZ_MUST_USE bool CheckGlobalDeclarationConflicts( JSContext* cx, HandleScript script, Handle 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); diff --git a/js/src/vm/Stack.cpp b/js/src/vm/Stack.cpp index 192f1d948bf9..4f33b48733ca 100644 --- a/js/src/vm/Stack.cpp +++ b/js/src/vm/Stack.cpp @@ -198,34 +198,14 @@ bool InterpreterFrame::prologue(JSContext* cx) { 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 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; } @@ -236,11 +216,12 @@ bool InterpreterFrame::prologue(JSContext* cx) { 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;