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
This commit is contained in:
Jan de Mooij 2019-01-11 09:15:41 +00:00
Родитель 2e86f8f057
Коммит aa9b0c47ba
6 изменённых файлов: 48 добавлений и 70 удалений

Просмотреть файл

@ -819,7 +819,7 @@ typedef bool (*CheckGlobalOrEvalDeclarationConflictsFn)(JSContext*,
HandleScript);
static const VMFunction CheckGlobalOrEvalDeclarationConflictsInfo =
FunctionInfo<CheckGlobalOrEvalDeclarationConflictsFn>(
jit::CheckGlobalOrEvalDeclarationConflicts,
js::CheckGlobalOrEvalDeclarationConflicts,
"CheckGlobalOrEvalDeclarationConflicts");
typedef bool (*InitFunctionEnvironmentObjectsFn)(JSContext*, BaselineFrame*);

Просмотреть файл

@ -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<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());

Просмотреть файл

@ -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);

Просмотреть файл

@ -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<EvalScope>().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<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());

Просмотреть файл

@ -1172,10 +1172,9 @@ 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);

Просмотреть файл

@ -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<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;
}
@ -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;