[parser] Track the correct entry-point for with/sloppy eval

This way we'll always only use the variables_ map of the first ScopeInfo-backed
Scope in the Scope chain.

Change-Id: I9187f7ef0b300b3ee36184d6dddd37242786c19a
Reviewed-on: https://chromium-review.googlesource.com/c/1340284
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57579}
This commit is contained in:
Toon Verwaest 2018-11-16 15:52:53 +01:00 committed by Commit Bot
parent 1952f92838
commit 83fd98abe9
2 changed files with 28 additions and 20 deletions

View File

@ -1808,9 +1808,8 @@ Variable* Scope::NonLocal(const AstRawString* name, VariableMode mode) {
// static
template <Scope::ScopeLookupMode mode>
Variable* Scope::Lookup(VariableProxy* proxy, Scope* scope,
Scope* outer_scope_end, bool force_context_allocation) {
Scope* entry_point = scope;
Scope* outer_scope_end, Scope* entry_point,
bool force_context_allocation) {
if (mode == kDeserializedScope) {
Variable* var = entry_point->variables_.Lookup(proxy->raw_name());
if (var != nullptr) return var;
@ -1850,12 +1849,12 @@ Variable* Scope::Lookup(VariableProxy* proxy, Scope* scope,
DCHECK(!scope->is_script_scope());
if (V8_UNLIKELY(scope->is_with_scope())) {
return LookupWith(proxy, scope, outer_scope_end,
return LookupWith(proxy, scope, outer_scope_end, entry_point,
force_context_allocation);
}
if (V8_UNLIKELY(scope->is_declaration_scope() &&
scope->AsDeclarationScope()->calls_sloppy_eval())) {
return LookupSloppyEval(proxy, scope, outer_scope_end,
return LookupSloppyEval(proxy, scope, outer_scope_end, entry_point,
force_context_allocation);
}
@ -1863,7 +1862,7 @@ Variable* Scope::Lookup(VariableProxy* proxy, Scope* scope,
scope = scope->outer_scope_;
// TODO(verwaest): Separate through AnalyzePartially.
if (mode == kParsedScope && !scope->scope_info_.is_null()) {
return Lookup<kDeserializedScope>(proxy, scope, outer_scope_end);
return Lookup<kDeserializedScope>(proxy, scope, outer_scope_end, scope);
}
}
@ -1883,10 +1882,10 @@ Variable* Scope::Lookup(VariableProxy* proxy, Scope* scope,
template Variable* Scope::Lookup<Scope::kParsedScope>(
VariableProxy* proxy, Scope* scope, Scope* outer_scope_end,
bool force_context_allocation);
Scope* entry_point, bool force_context_allocation);
template Variable* Scope::Lookup<Scope::kDeserializedScope>(
VariableProxy* proxy, Scope* scope, Scope* outer_scope_end,
bool force_context_allocation);
Scope* entry_point, bool force_context_allocation);
namespace {
bool CanBeShadowed(Scope* scope, Variable* var) {
@ -1906,16 +1905,16 @@ bool CanBeShadowed(Scope* scope, Variable* var) {
}; // namespace
Variable* Scope::LookupWith(VariableProxy* proxy, Scope* scope,
Scope* outer_scope_end,
Scope* outer_scope_end, Scope* entry_point,
bool force_context_allocation) {
DCHECK(scope->is_with_scope());
Variable* var =
scope->outer_scope_->scope_info_.is_null()
? Lookup<kParsedScope>(proxy, scope->outer_scope_, outer_scope_end,
force_context_allocation)
nullptr, force_context_allocation)
: Lookup<kDeserializedScope>(proxy, scope->outer_scope_,
outer_scope_end);
outer_scope_end, entry_point);
if (!CanBeShadowed(scope, var)) return var;
@ -1931,21 +1930,26 @@ Variable* Scope::LookupWith(VariableProxy* proxy, Scope* scope,
var->ForceContextAllocation();
if (proxy->is_assigned()) var->set_maybe_assigned();
}
return scope->NonLocal(proxy->raw_name(), VariableMode::kDynamic);
if (entry_point != nullptr) entry_point->variables_.Remove(var);
Scope* target = entry_point == nullptr ? scope : entry_point;
return target->NonLocal(proxy->raw_name(), VariableMode::kDynamic);
}
Variable* Scope::LookupSloppyEval(VariableProxy* proxy, Scope* scope,
Scope* outer_scope_end,
Scope* outer_scope_end, Scope* entry_point,
bool force_context_allocation) {
DCHECK(scope->is_declaration_scope() &&
scope->AsDeclarationScope()->calls_sloppy_eval());
// If we're compiling eval, it's possible that the outer scope is the first
// ScopeInfo-backed scope.
Scope* entry = entry_point == nullptr ? scope->outer_scope_ : entry_point;
Variable* var =
scope->outer_scope_->scope_info_.is_null()
? Lookup<kParsedScope>(proxy, scope->outer_scope_, outer_scope_end,
force_context_allocation)
nullptr, force_context_allocation)
: Lookup<kDeserializedScope>(proxy, scope->outer_scope_,
outer_scope_end);
outer_scope_end, entry);
if (!CanBeShadowed(scope, var)) return var;
// A variable binding may have been found in an outer scope, but the current
@ -1956,13 +1960,17 @@ Variable* Scope::LookupSloppyEval(VariableProxy* proxy, Scope* scope,
// here (this excludes block and catch scopes), and variable lookups at
// script scope are always dynamic.
if (var->IsGlobalObjectProperty()) {
return scope->NonLocal(proxy->raw_name(), VariableMode::kDynamicGlobal);
Scope* target = entry_point == nullptr ? scope : entry_point;
return target->NonLocal(proxy->raw_name(), VariableMode::kDynamicGlobal);
}
if (var->is_dynamic()) return var;
Variable* invalidated = var;
var = scope->NonLocal(proxy->raw_name(), VariableMode::kDynamicLocal);
if (entry_point != nullptr) entry_point->variables_.Remove(invalidated);
Scope* target = entry_point == nullptr ? scope : entry_point;
var = target->NonLocal(proxy->raw_name(), VariableMode::kDynamicLocal);
var->set_local_if_not_shadowed(invalidated);
return var;

View File

@ -615,13 +615,13 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
// calling context of 'eval'.
template <ScopeLookupMode mode>
static Variable* Lookup(VariableProxy* proxy, Scope* scope,
Scope* outer_scope_end,
Scope* outer_scope_end, Scope* entry_point = nullptr,
bool force_context_allocation = false);
static Variable* LookupWith(VariableProxy* proxy, Scope* scope,
Scope* outer_scope_end,
Scope* outer_scope_end, Scope* entry_point,
bool force_context_allocation);
static Variable* LookupSloppyEval(VariableProxy* proxy, Scope* scope,
Scope* outer_scope_end,
Scope* outer_scope_end, Scope* entry_point,
bool force_context_allocation);
void ResolveTo(ParseInfo* info, VariableProxy* proxy, Variable* var);
V8_WARN_UNUSED_RESULT bool ResolveVariable(ParseInfo* info,