[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:
parent
1952f92838
commit
83fd98abe9
@ -1808,9 +1808,8 @@ Variable* Scope::NonLocal(const AstRawString* name, VariableMode mode) {
|
|||||||
// static
|
// static
|
||||||
template <Scope::ScopeLookupMode mode>
|
template <Scope::ScopeLookupMode mode>
|
||||||
Variable* Scope::Lookup(VariableProxy* proxy, Scope* scope,
|
Variable* Scope::Lookup(VariableProxy* proxy, Scope* scope,
|
||||||
Scope* outer_scope_end, bool force_context_allocation) {
|
Scope* outer_scope_end, Scope* entry_point,
|
||||||
Scope* entry_point = scope;
|
bool force_context_allocation) {
|
||||||
|
|
||||||
if (mode == kDeserializedScope) {
|
if (mode == kDeserializedScope) {
|
||||||
Variable* var = entry_point->variables_.Lookup(proxy->raw_name());
|
Variable* var = entry_point->variables_.Lookup(proxy->raw_name());
|
||||||
if (var != nullptr) return var;
|
if (var != nullptr) return var;
|
||||||
@ -1850,12 +1849,12 @@ Variable* Scope::Lookup(VariableProxy* proxy, Scope* scope,
|
|||||||
|
|
||||||
DCHECK(!scope->is_script_scope());
|
DCHECK(!scope->is_script_scope());
|
||||||
if (V8_UNLIKELY(scope->is_with_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);
|
force_context_allocation);
|
||||||
}
|
}
|
||||||
if (V8_UNLIKELY(scope->is_declaration_scope() &&
|
if (V8_UNLIKELY(scope->is_declaration_scope() &&
|
||||||
scope->AsDeclarationScope()->calls_sloppy_eval())) {
|
scope->AsDeclarationScope()->calls_sloppy_eval())) {
|
||||||
return LookupSloppyEval(proxy, scope, outer_scope_end,
|
return LookupSloppyEval(proxy, scope, outer_scope_end, entry_point,
|
||||||
force_context_allocation);
|
force_context_allocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1863,7 +1862,7 @@ Variable* Scope::Lookup(VariableProxy* proxy, Scope* scope,
|
|||||||
scope = scope->outer_scope_;
|
scope = scope->outer_scope_;
|
||||||
// TODO(verwaest): Separate through AnalyzePartially.
|
// TODO(verwaest): Separate through AnalyzePartially.
|
||||||
if (mode == kParsedScope && !scope->scope_info_.is_null()) {
|
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>(
|
template Variable* Scope::Lookup<Scope::kParsedScope>(
|
||||||
VariableProxy* proxy, Scope* scope, Scope* outer_scope_end,
|
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>(
|
template Variable* Scope::Lookup<Scope::kDeserializedScope>(
|
||||||
VariableProxy* proxy, Scope* scope, Scope* outer_scope_end,
|
VariableProxy* proxy, Scope* scope, Scope* outer_scope_end,
|
||||||
bool force_context_allocation);
|
Scope* entry_point, bool force_context_allocation);
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
bool CanBeShadowed(Scope* scope, Variable* var) {
|
bool CanBeShadowed(Scope* scope, Variable* var) {
|
||||||
@ -1906,16 +1905,16 @@ bool CanBeShadowed(Scope* scope, Variable* var) {
|
|||||||
}; // namespace
|
}; // namespace
|
||||||
|
|
||||||
Variable* Scope::LookupWith(VariableProxy* proxy, Scope* scope,
|
Variable* Scope::LookupWith(VariableProxy* proxy, Scope* scope,
|
||||||
Scope* outer_scope_end,
|
Scope* outer_scope_end, Scope* entry_point,
|
||||||
bool force_context_allocation) {
|
bool force_context_allocation) {
|
||||||
DCHECK(scope->is_with_scope());
|
DCHECK(scope->is_with_scope());
|
||||||
|
|
||||||
Variable* var =
|
Variable* var =
|
||||||
scope->outer_scope_->scope_info_.is_null()
|
scope->outer_scope_->scope_info_.is_null()
|
||||||
? Lookup<kParsedScope>(proxy, scope->outer_scope_, outer_scope_end,
|
? Lookup<kParsedScope>(proxy, scope->outer_scope_, outer_scope_end,
|
||||||
force_context_allocation)
|
nullptr, force_context_allocation)
|
||||||
: Lookup<kDeserializedScope>(proxy, scope->outer_scope_,
|
: Lookup<kDeserializedScope>(proxy, scope->outer_scope_,
|
||||||
outer_scope_end);
|
outer_scope_end, entry_point);
|
||||||
|
|
||||||
if (!CanBeShadowed(scope, var)) return var;
|
if (!CanBeShadowed(scope, var)) return var;
|
||||||
|
|
||||||
@ -1931,21 +1930,26 @@ Variable* Scope::LookupWith(VariableProxy* proxy, Scope* scope,
|
|||||||
var->ForceContextAllocation();
|
var->ForceContextAllocation();
|
||||||
if (proxy->is_assigned()) var->set_maybe_assigned();
|
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,
|
Variable* Scope::LookupSloppyEval(VariableProxy* proxy, Scope* scope,
|
||||||
Scope* outer_scope_end,
|
Scope* outer_scope_end, Scope* entry_point,
|
||||||
bool force_context_allocation) {
|
bool force_context_allocation) {
|
||||||
DCHECK(scope->is_declaration_scope() &&
|
DCHECK(scope->is_declaration_scope() &&
|
||||||
scope->AsDeclarationScope()->calls_sloppy_eval());
|
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 =
|
Variable* var =
|
||||||
scope->outer_scope_->scope_info_.is_null()
|
scope->outer_scope_->scope_info_.is_null()
|
||||||
? Lookup<kParsedScope>(proxy, scope->outer_scope_, outer_scope_end,
|
? Lookup<kParsedScope>(proxy, scope->outer_scope_, outer_scope_end,
|
||||||
force_context_allocation)
|
nullptr, force_context_allocation)
|
||||||
: Lookup<kDeserializedScope>(proxy, scope->outer_scope_,
|
: Lookup<kDeserializedScope>(proxy, scope->outer_scope_,
|
||||||
outer_scope_end);
|
outer_scope_end, entry);
|
||||||
if (!CanBeShadowed(scope, var)) return var;
|
if (!CanBeShadowed(scope, var)) return var;
|
||||||
|
|
||||||
// A variable binding may have been found in an outer scope, but the current
|
// 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
|
// here (this excludes block and catch scopes), and variable lookups at
|
||||||
// script scope are always dynamic.
|
// script scope are always dynamic.
|
||||||
if (var->IsGlobalObjectProperty()) {
|
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;
|
if (var->is_dynamic()) return var;
|
||||||
|
|
||||||
Variable* invalidated = 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);
|
var->set_local_if_not_shadowed(invalidated);
|
||||||
|
|
||||||
return var;
|
return var;
|
||||||
|
@ -615,13 +615,13 @@ class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
|
|||||||
// calling context of 'eval'.
|
// calling context of 'eval'.
|
||||||
template <ScopeLookupMode mode>
|
template <ScopeLookupMode mode>
|
||||||
static Variable* Lookup(VariableProxy* proxy, Scope* scope,
|
static Variable* Lookup(VariableProxy* proxy, Scope* scope,
|
||||||
Scope* outer_scope_end,
|
Scope* outer_scope_end, Scope* entry_point = nullptr,
|
||||||
bool force_context_allocation = false);
|
bool force_context_allocation = false);
|
||||||
static Variable* LookupWith(VariableProxy* proxy, Scope* scope,
|
static Variable* LookupWith(VariableProxy* proxy, Scope* scope,
|
||||||
Scope* outer_scope_end,
|
Scope* outer_scope_end, Scope* entry_point,
|
||||||
bool force_context_allocation);
|
bool force_context_allocation);
|
||||||
static Variable* LookupSloppyEval(VariableProxy* proxy, Scope* scope,
|
static Variable* LookupSloppyEval(VariableProxy* proxy, Scope* scope,
|
||||||
Scope* outer_scope_end,
|
Scope* outer_scope_end, Scope* entry_point,
|
||||||
bool force_context_allocation);
|
bool force_context_allocation);
|
||||||
void ResolveTo(ParseInfo* info, VariableProxy* proxy, Variable* var);
|
void ResolveTo(ParseInfo* info, VariableProxy* proxy, Variable* var);
|
||||||
V8_WARN_UNUSED_RESULT bool ResolveVariable(ParseInfo* info,
|
V8_WARN_UNUSED_RESULT bool ResolveVariable(ParseInfo* info,
|
||||||
|
Loading…
Reference in New Issue
Block a user