diff options
Diffstat (limited to 'deps/v8/src/ast/scopes.cc')
-rw-r--r-- | deps/v8/src/ast/scopes.cc | 39 |
1 files changed, 36 insertions, 3 deletions
diff --git a/deps/v8/src/ast/scopes.cc b/deps/v8/src/ast/scopes.cc index a66e4ea93f..cd8be1caec 100644 --- a/deps/v8/src/ast/scopes.cc +++ b/deps/v8/src/ast/scopes.cc @@ -632,7 +632,8 @@ void DeclarationScope::HoistSloppyBlockFunctions(AstNodeFactory* factory) { // scope and we terminate the iteration there anyway. do { Variable* var = query_scope->LookupInScopeOrScopeInfo(name, query_scope); - if (var != nullptr && IsLexicalVariableMode(var->mode())) { + if (var != nullptr && IsLexicalVariableMode(var->mode()) && + !var->is_sloppy_block_function()) { should_hoist = false; break; } @@ -649,6 +650,19 @@ void DeclarationScope::HoistSloppyBlockFunctions(AstNodeFactory* factory) { auto declaration = factory->NewVariableDeclaration(pos); // Based on the preceding checks, it doesn't matter what we pass as // sloppy_mode_block_scope_function_redefinition. + // + // This synthesized var for Annex B functions-in-block (FiB) may be + // declared multiple times for the same var scope, such as in the case of + // shadowed functions-in-block like the following: + // + // { + // function f() {} + // { function f() {} } + // } + // + // Redeclarations for vars do not create new bindings, but the + // redeclarations' initializers are still run. That is, shadowed FiB will + // result in multiple assignments to the same synthesized var. Variable* var = DeclareVariable( declaration, name, pos, VariableMode::kVar, NORMAL_VARIABLE, Variable::DefaultInitializationFlag(VariableMode::kVar), &was_added, @@ -1263,8 +1277,9 @@ Declaration* DeclarationScope::CheckConflictingVarDeclarations( if (decl->IsVariableDeclaration() && decl->AsVariableDeclaration()->AsNested() != nullptr) { Scope* current = decl->AsVariableDeclaration()->AsNested()->scope(); - DCHECK(decl->var()->mode() == VariableMode::kVar || - decl->var()->mode() == VariableMode::kDynamic); + if (decl->var()->mode() != VariableMode::kVar && + decl->var()->mode() != VariableMode::kDynamic) + continue; // Iterate through all scopes until the declaration scope. do { // There is a conflict if there exists a non-VAR binding. @@ -1796,6 +1811,8 @@ const char* Header(ScopeType scope_type, FunctionKind function_kind, case CLASS_SCOPE: return "class"; case WITH_SCOPE: return "with"; + case SHADOW_REALM_SCOPE: + return "shadowrealm"; } UNREACHABLE(); } @@ -2058,6 +2075,15 @@ Variable* Scope::NonLocal(const AstRawString* name, VariableMode mode) { return var; } +void Scope::ForceDynamicLookup(VariableProxy* proxy) { + // At the moment this is only used for looking up private names dynamically + // in debug-evaluate from top-level scope. + DCHECK(proxy->IsPrivateName()); + DCHECK(is_script_scope() || is_module_scope() || is_eval_scope()); + Variable* dynamic = NonLocal(proxy->raw_name(), VariableMode::kDynamic); + proxy->BindTo(dynamic); +} + // static template <Scope::ScopeLookupMode mode> Variable* Scope::Lookup(VariableProxy* proxy, Scope* scope, @@ -3109,6 +3135,13 @@ void PrivateNameScopeIterator::AddUnresolvedPrivateName(VariableProxy* proxy) { // be new. DCHECK(!proxy->is_resolved()); DCHECK(proxy->IsPrivateName()); + + // Use dynamic lookup for top-level scopes in debug-evaluate. + if (Done()) { + start_scope_->ForceDynamicLookup(proxy); + return; + } + GetScope()->EnsureRareData()->unresolved_private_names.Add(proxy); // Any closure scope that contain uses of private names that skips over a // class scope due to heritage expressions need private name context chain |