LCOV - code coverage report
Current view: top level - src/ast - scopes.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 663 696 95.3 %
Date: 2019-01-20 Functions: 91 105 86.7 %

          Line data    Source code
       1             : // Copyright 2012 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/ast/scopes.h"
       6             : 
       7             : #include <set>
       8             : 
       9             : #include "src/accessors.h"
      10             : #include "src/ast/ast.h"
      11             : #include "src/base/optional.h"
      12             : #include "src/bootstrapper.h"
      13             : #include "src/counters.h"
      14             : #include "src/message-template.h"
      15             : #include "src/objects-inl.h"
      16             : #include "src/objects/module-inl.h"
      17             : #include "src/objects/scope-info.h"
      18             : #include "src/parsing/parse-info.h"
      19             : #include "src/parsing/parser.h"
      20             : #include "src/parsing/preparse-data.h"
      21             : #include "src/zone/zone-list-inl.h"
      22             : 
      23             : namespace v8 {
      24             : namespace internal {
      25             : 
      26             : // ----------------------------------------------------------------------------
      27             : // Implementation of LocalsMap
      28             : //
      29             : // Note: We are storing the handle locations as key values in the hash map.
      30             : //       When inserting a new variable via Declare(), we rely on the fact that
      31             : //       the handle location remains alive for the duration of that variable
      32             : //       use. Because a Variable holding a handle with the same location exists
      33             : //       this is ensured.
      34             : 
      35           0 : VariableMap::VariableMap(Zone* zone)
      36           0 :     : ZoneHashMap(8, ZoneAllocationPolicy(zone)) {}
      37             : 
      38    43061222 : Variable* VariableMap::Declare(Zone* zone, Scope* scope,
      39    43061222 :                                const AstRawString* name, VariableMode mode,
      40             :                                VariableKind kind,
      41             :                                InitializationFlag initialization_flag,
      42             :                                MaybeAssignedFlag maybe_assigned_flag,
      43             :                                base::ThreadedList<Variable>* variable_list) {
      44             :   // AstRawStrings are unambiguous, i.e., the same string is always represented
      45             :   // by the same AstRawString*.
      46             :   // FIXME(marja): fix the type of Lookup.
      47             :   Entry* p =
      48             :       ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->Hash(),
      49    86124015 :                                   ZoneAllocationPolicy(zone));
      50    43062793 :   if (p->value == nullptr) {
      51             :     // The variable has not been declared yet -> insert it.
      52             :     DCHECK_EQ(name, p->key);
      53             :     Variable* variable = new (zone) Variable(
      54             :         scope, name, mode, kind, initialization_flag, maybe_assigned_flag);
      55    42753631 :     if (variable_list) variable_list->Add(variable);
      56    42753631 :     p->value = variable;
      57             :   }
      58    43060671 :   return reinterpret_cast<Variable*>(p->value);
      59             : }
      60             : 
      61        4115 : void VariableMap::Remove(Variable* var) {
      62        4115 :   const AstRawString* name = var->raw_name();
      63        4115 :   ZoneHashMap::Remove(const_cast<AstRawString*>(name), name->Hash());
      64           0 : }
      65             : 
      66      908146 : void VariableMap::Add(Zone* zone, Variable* var) {
      67      908146 :   const AstRawString* name = var->raw_name();
      68             :   Entry* p =
      69             :       ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->Hash(),
      70     1816313 :                                   ZoneAllocationPolicy(zone));
      71             :   DCHECK_NULL(p->value);
      72             :   DCHECK_EQ(name, p->key);
      73      908167 :   p->value = var;
      74      908167 : }
      75             : 
      76   103167143 : Variable* VariableMap::Lookup(const AstRawString* name) {
      77   103167143 :   Entry* p = ZoneHashMap::Lookup(const_cast<AstRawString*>(name), name->Hash());
      78   103168954 :   if (p != nullptr) {
      79             :     DCHECK(reinterpret_cast<const AstRawString*>(p->key) == name);
      80             :     DCHECK_NOT_NULL(p->value);
      81    42608810 :     return reinterpret_cast<Variable*>(p->value);
      82             :   }
      83             :   return nullptr;
      84             : }
      85             : 
      86           0 : void SloppyBlockFunctionMap::Delegate::set_statement(Statement* statement) {
      87        7472 :   if (statement_ != nullptr) {
      88             :     statement_->set_statement(statement);
      89             :   }
      90           0 : }
      91             : 
      92           0 : SloppyBlockFunctionMap::SloppyBlockFunctionMap(Zone* zone)
      93       10279 :     : ZoneHashMap(8, ZoneAllocationPolicy(zone)), count_(0) {}
      94             : 
      95       23100 : void SloppyBlockFunctionMap::Declare(Zone* zone, const AstRawString* name,
      96             :                                      Scope* scope,
      97             :                                      SloppyBlockFunctionStatement* statement) {
      98       11550 :   auto* delegate = new (zone) Delegate(scope, statement, count_++);
      99             :   // AstRawStrings are unambiguous, i.e., the same string is always represented
     100             :   // by the same AstRawString*.
     101             :   Entry* p =
     102             :       ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->Hash(),
     103       23100 :                                   ZoneAllocationPolicy(zone));
     104       11550 :   delegate->set_next(static_cast<SloppyBlockFunctionMap::Delegate*>(p->value));
     105       11550 :   p->value = delegate;
     106       11550 : }
     107             : 
     108             : // ----------------------------------------------------------------------------
     109             : // Implementation of Scope
     110             : 
     111     2950633 : Scope::Scope(Zone* zone)
     112             :     : zone_(zone),
     113             :       outer_scope_(nullptr),
     114             :       variables_(zone),
     115     5901276 :       scope_type_(SCRIPT_SCOPE) {
     116             :   SetDefaults();
     117     2950643 : }
     118             : 
     119    12831899 : Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type)
     120             :     : zone_(zone),
     121             :       outer_scope_(outer_scope),
     122             :       variables_(zone),
     123    25664472 :       scope_type_(scope_type) {
     124             :   DCHECK_NE(SCRIPT_SCOPE, scope_type);
     125             :   SetDefaults();
     126             :   set_language_mode(outer_scope->language_mode());
     127    12832573 :   outer_scope_->AddInnerScope(this);
     128    12832573 : }
     129             : 
     130     2950634 : DeclarationScope::DeclarationScope(Zone* zone,
     131     2950615 :                                    AstValueFactory* ast_value_factory)
     132     2950634 :     : Scope(zone), function_kind_(kNormalFunction), params_(4, zone) {
     133             :   DCHECK_EQ(scope_type_, SCRIPT_SCOPE);
     134             :   SetDefaults();
     135             : 
     136             :   // Make sure that if we don't find the global 'this', it won't be declared as
     137             :   // a regular dynamic global by predeclaring it with the right variable kind.
     138     2950615 :   DeclareDynamicGlobal(ast_value_factory->this_string(), THIS_VARIABLE, this);
     139     2950604 : }
     140             : 
     141     6633683 : DeclarationScope::DeclarationScope(Zone* zone, Scope* outer_scope,
     142             :                                    ScopeType scope_type,
     143             :                                    FunctionKind function_kind)
     144             :     : Scope(zone, outer_scope, scope_type),
     145             :       function_kind_(function_kind),
     146     6633683 :       params_(4, zone) {
     147             :   DCHECK_NE(scope_type, SCRIPT_SCOPE);
     148             :   SetDefaults();
     149     6634233 : }
     150             : 
     151       61571 : ModuleScope::ModuleScope(DeclarationScope* script_scope,
     152      123142 :                          AstValueFactory* ast_value_factory)
     153             :     : DeclarationScope(ast_value_factory->zone(), script_scope, MODULE_SCOPE,
     154       61571 :                        kModule) {
     155             :   Zone* zone = ast_value_factory->zone();
     156       61571 :   module_descriptor_ = new (zone) ModuleDescriptor(zone);
     157             :   set_language_mode(LanguageMode::kStrict);
     158       61571 :   DeclareThis(ast_value_factory);
     159       61571 : }
     160             : 
     161        3217 : ModuleScope::ModuleScope(Isolate* isolate, Handle<ScopeInfo> scope_info,
     162        6434 :                          AstValueFactory* avfactory)
     163        3217 :     : DeclarationScope(avfactory->zone(), MODULE_SCOPE, scope_info) {
     164             :   Zone* zone = avfactory->zone();
     165        6434 :   Handle<ModuleInfo> module_info(scope_info->ModuleDescriptorInfo(), isolate);
     166             : 
     167             :   set_language_mode(LanguageMode::kStrict);
     168        3217 :   module_descriptor_ = new (zone) ModuleDescriptor(zone);
     169             : 
     170             :   // Deserialize special exports.
     171        6434 :   Handle<FixedArray> special_exports(module_info->special_exports(), isolate);
     172        3217 :   for (int i = 0, n = special_exports->length(); i < n; ++i) {
     173             :     Handle<ModuleInfoEntry> serialized_entry(
     174             :         ModuleInfoEntry::cast(special_exports->get(i)), isolate);
     175             :     module_descriptor_->AddSpecialExport(
     176             :         ModuleDescriptor::Entry::Deserialize(isolate, avfactory,
     177           0 :                                              serialized_entry),
     178           0 :         avfactory->zone());
     179             :   }
     180             : 
     181             :   // Deserialize regular exports.
     182             :   module_descriptor_->DeserializeRegularExports(isolate, avfactory,
     183        3217 :                                                 module_info);
     184             : 
     185             :   // Deserialize namespace imports.
     186             :   Handle<FixedArray> namespace_imports(module_info->namespace_imports(),
     187        6434 :                                        isolate);
     188        3512 :   for (int i = 0, n = namespace_imports->length(); i < n; ++i) {
     189             :     Handle<ModuleInfoEntry> serialized_entry(
     190             :         ModuleInfoEntry::cast(namespace_imports->get(i)), isolate);
     191             :     module_descriptor_->AddNamespaceImport(
     192             :         ModuleDescriptor::Entry::Deserialize(isolate, avfactory,
     193         295 :                                              serialized_entry),
     194         295 :         avfactory->zone());
     195             :   }
     196             : 
     197             :   // Deserialize regular imports.
     198        6434 :   Handle<FixedArray> regular_imports(module_info->regular_imports(), isolate);
     199        5698 :   for (int i = 0, n = regular_imports->length(); i < n; ++i) {
     200             :     Handle<ModuleInfoEntry> serialized_entry(
     201             :         ModuleInfoEntry::cast(regular_imports->get(i)), isolate);
     202             :     module_descriptor_->AddRegularImport(ModuleDescriptor::Entry::Deserialize(
     203        2481 :         isolate, avfactory, serialized_entry));
     204             :   }
     205        3217 : }
     206             : 
     207     1059609 : Scope::Scope(Zone* zone, ScopeType scope_type, Handle<ScopeInfo> scope_info)
     208             :     : zone_(zone),
     209             :       outer_scope_(nullptr),
     210             :       variables_(zone),
     211             :       scope_info_(scope_info),
     212     2119227 :       scope_type_(scope_type) {
     213             :   DCHECK(!scope_info.is_null());
     214             :   SetDefaults();
     215             : #ifdef DEBUG
     216             :   already_resolved_ = true;
     217             : #endif
     218     1059617 :   if (scope_info->CallsSloppyEval()) scope_calls_eval_ = true;
     219     2119237 :   set_language_mode(scope_info->language_mode());
     220     1059623 :   num_heap_slots_ = scope_info->ContextLength();
     221             :   DCHECK_LE(Context::MIN_CONTEXT_SLOTS, num_heap_slots_);
     222             :   // We don't really need to use the preparsed scope data; this is just to
     223             :   // shorten the recursion in SetMustUsePreparseData.
     224     1059619 :   must_use_preparsed_scope_data_ = true;
     225     1059619 : }
     226             : 
     227      873449 : DeclarationScope::DeclarationScope(Zone* zone, ScopeType scope_type,
     228             :                                    Handle<ScopeInfo> scope_info)
     229             :     : Scope(zone, scope_type, scope_info),
     230     1746901 :       function_kind_(scope_info->function_kind()),
     231     2620351 :       params_(0, zone) {
     232             :   DCHECK_NE(scope_type, SCRIPT_SCOPE);
     233             :   SetDefaults();
     234      873451 : }
     235             : 
     236        1853 : Scope::Scope(Zone* zone, const AstRawString* catch_variable_name,
     237             :              MaybeAssignedFlag maybe_assigned, Handle<ScopeInfo> scope_info)
     238             :     : zone_(zone),
     239             :       outer_scope_(nullptr),
     240             :       variables_(zone),
     241             :       scope_info_(scope_info),
     242        3706 :       scope_type_(CATCH_SCOPE) {
     243             :   SetDefaults();
     244             : #ifdef DEBUG
     245             :   already_resolved_ = true;
     246             : #endif
     247             :   // Cache the catch variable, even though it's also available via the
     248             :   // scope_info, as the parser expects that a catch scope always has the catch
     249             :   // variable as first and only variable.
     250             :   Variable* variable =
     251             :       Declare(zone, catch_variable_name, VariableMode::kVar, NORMAL_VARIABLE,
     252             :               kCreatedInitialized, maybe_assigned);
     253             :   AllocateHeapSlot(variable);
     254        1853 : }
     255             : 
     256           0 : void DeclarationScope::SetDefaults() {
     257    10458299 :   is_declaration_scope_ = true;
     258    10458299 :   has_simple_parameters_ = true;
     259    10458299 :   is_asm_module_ = false;
     260    10458299 :   force_eager_compilation_ = false;
     261    10458299 :   has_arguments_parameter_ = false;
     262    10458299 :   scope_uses_super_property_ = false;
     263    10458299 :   has_rest_ = false;
     264    10458299 :   sloppy_block_function_map_ = nullptr;
     265    10458299 :   receiver_ = nullptr;
     266    10458299 :   new_target_ = nullptr;
     267    10458299 :   function_ = nullptr;
     268    10458299 :   arguments_ = nullptr;
     269           0 :   rare_data_ = nullptr;
     270    10458299 :   should_eager_compile_ = false;
     271    10458299 :   was_lazily_parsed_ = false;
     272    10458299 :   is_skipped_function_ = false;
     273    10458299 :   preparse_data_builder_ = nullptr;
     274             : #ifdef DEBUG
     275             :   DeclarationScope* outer_declaration_scope =
     276             :       outer_scope_ ? outer_scope_->GetDeclarationScope() : nullptr;
     277             :   is_being_lazily_parsed_ =
     278             :       outer_declaration_scope ? outer_declaration_scope->is_being_lazily_parsed_
     279             :                               : false;
     280             : #endif
     281           0 : }
     282             : 
     283           0 : void Scope::SetDefaults() {
     284             : #ifdef DEBUG
     285             :   scope_name_ = nullptr;
     286             :   already_resolved_ = false;
     287             :   needs_migration_ = false;
     288             : #endif
     289    16844687 :   inner_scope_ = nullptr;
     290    16844687 :   sibling_ = nullptr;
     291             :   unresolved_list_.Clear();
     292             : 
     293    16844687 :   start_position_ = kNoSourcePosition;
     294    16844687 :   end_position_ = kNoSourcePosition;
     295             : 
     296    16844687 :   num_stack_slots_ = 0;
     297    16844687 :   num_heap_slots_ = Context::MIN_CONTEXT_SLOTS;
     298             : 
     299             :   set_language_mode(LanguageMode::kSloppy);
     300             : 
     301    16844687 :   scope_calls_eval_ = false;
     302    16844687 :   scope_nonlinear_ = false;
     303    16844687 :   is_hidden_ = false;
     304    16844687 :   is_debug_evaluate_scope_ = false;
     305             : 
     306    16844687 :   inner_scope_calls_eval_ = false;
     307    16844687 :   force_context_allocation_ = false;
     308    16844687 :   force_context_allocation_for_parameters_ = false;
     309             : 
     310    16844687 :   is_declaration_scope_ = false;
     311             : 
     312    16844687 :   must_use_preparsed_scope_data_ = false;
     313           0 : }
     314             : 
     315      430764 : bool Scope::HasSimpleParameters() {
     316             :   DeclarationScope* scope = GetClosureScope();
     317      585049 :   return !scope->is_function_scope() || scope->has_simple_parameters();
     318             : }
     319             : 
     320     6418558 : bool DeclarationScope::ShouldEagerCompile() const {
     321     9000233 :   return force_eager_compilation_ || should_eager_compile_;
     322             : }
     323             : 
     324      722929 : void DeclarationScope::set_should_eager_compile() {
     325     2535088 :   should_eager_compile_ = !was_lazily_parsed_;
     326      722929 : }
     327             : 
     328        6299 : void DeclarationScope::set_is_asm_module() { is_asm_module_ = true; }
     329             : 
     330     2119755 : bool Scope::IsAsmModule() const {
     331     8024472 :   return is_function_scope() && AsDeclarationScope()->is_asm_module();
     332             : }
     333             : 
     334        7164 : bool Scope::ContainsAsmModule() const {
     335        7164 :   if (IsAsmModule()) return true;
     336             : 
     337             :   // Check inner scopes recursively
     338        2819 :   for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
     339             :     // Don't check inner functions which won't be eagerly compiled.
     340        5545 :     if (!scope->is_function_scope() ||
     341             :         scope->AsDeclarationScope()->ShouldEagerCompile()) {
     342        2395 :       if (scope->ContainsAsmModule()) return true;
     343             :     }
     344             :   }
     345             : 
     346             :   return false;
     347             : }
     348             : 
     349     1011002 : Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone,
     350             :                                     ScopeInfo scope_info,
     351             :                                     DeclarationScope* script_scope,
     352             :                                     AstValueFactory* ast_value_factory,
     353             :                                     DeserializationMode deserialization_mode) {
     354             :   // Reconstruct the outer scope chain from a closure's context chain.
     355             :   Scope* current_scope = nullptr;
     356             :   Scope* innermost_scope = nullptr;
     357             :   Scope* outer_scope = nullptr;
     358     3083477 :   while (!scope_info.is_null()) {
     359     1404276 :     if (scope_info->scope_type() == WITH_SCOPE) {
     360             :       // For scope analysis, debug-evaluate is equivalent to a with scope.
     361             :       outer_scope =
     362       29454 :           new (zone) Scope(zone, WITH_SCOPE, handle(scope_info, isolate));
     363             : 
     364             :       // TODO(yangguo): Remove once debug-evaluate properly keeps track of the
     365             :       // function scope in which we are evaluating.
     366       14727 :       if (scope_info->IsDebugEvaluateScope()) {
     367             :         outer_scope->set_is_debug_evaluate_scope();
     368             :       }
     369     1389557 :     } else if (scope_info->scope_type() == SCRIPT_SCOPE) {
     370             :       // If we reach a script scope, it's the outermost scope. Install the
     371             :       // scope info of this script context onto the existing script scope to
     372             :       // avoid nesting script scopes.
     373      342826 :       if (deserialization_mode == DeserializationMode::kIncludingVariables) {
     374             :         script_scope->SetScriptScopeInfo(handle(scope_info, isolate));
     375             :       }
     376             :       DCHECK(!scope_info->HasOuterScopeInfo());
     377             :       break;
     378     1046743 :     } else if (scope_info->scope_type() == FUNCTION_SCOPE) {
     379             :       outer_scope = new (zone)
     380     1668122 :           DeclarationScope(zone, FUNCTION_SCOPE, handle(scope_info, isolate));
     381      834061 :       if (scope_info->IsAsmModule()) {
     382             :         outer_scope->AsDeclarationScope()->set_is_asm_module();
     383             :       }
     384      212679 :     } else if (scope_info->scope_type() == EVAL_SCOPE) {
     385             :       outer_scope = new (zone)
     386       52898 :           DeclarationScope(zone, EVAL_SCOPE, handle(scope_info, isolate));
     387      186226 :     } else if (scope_info->scope_type() == BLOCK_SCOPE) {
     388      181155 :       if (scope_info->is_declaration_scope()) {
     389             :         outer_scope = new (zone)
     390       19447 :             DeclarationScope(zone, BLOCK_SCOPE, handle(scope_info, isolate));
     391             :       } else {
     392             :         outer_scope =
     393      342871 :             new (zone) Scope(zone, BLOCK_SCOPE, handle(scope_info, isolate));
     394             :       }
     395        5070 :     } else if (scope_info->scope_type() == MODULE_SCOPE) {
     396             :       outer_scope = new (zone)
     397        6434 :           ModuleScope(isolate, handle(scope_info, isolate), ast_value_factory);
     398             :     } else {
     399             :       DCHECK_EQ(scope_info->scope_type(), CATCH_SCOPE);
     400             :       DCHECK_EQ(scope_info->ContextLocalCount(), 1);
     401             :       DCHECK_EQ(scope_info->ContextLocalMode(0), VariableMode::kVar);
     402             :       DCHECK_EQ(scope_info->ContextLocalInitFlag(0), kCreatedInitialized);
     403        1853 :       String name = scope_info->ContextLocalName(0);
     404             :       MaybeAssignedFlag maybe_assigned =
     405        1853 :           scope_info->ContextLocalMaybeAssignedFlag(0);
     406             :       outer_scope = new (zone)
     407             :           Scope(zone, ast_value_factory->GetString(handle(name, isolate)),
     408        5559 :                 maybe_assigned, handle(scope_info, isolate));
     409             :     }
     410     1061472 :     if (deserialization_mode == DeserializationMode::kScopesOnly) {
     411           0 :       outer_scope->scope_info_ = Handle<ScopeInfo>::null();
     412             :     }
     413     1061472 :     if (current_scope != nullptr) {
     414             :       outer_scope->AddInnerScope(current_scope);
     415             :     }
     416             :     current_scope = outer_scope;
     417     1061472 :     if (innermost_scope == nullptr) innermost_scope = current_scope;
     418     1061472 :     scope_info = scope_info->HasOuterScopeInfo() ? scope_info->OuterScopeInfo()
     419     1061471 :                                                  : ScopeInfo();
     420             :   }
     421             : 
     422     2022049 :   if (deserialization_mode == DeserializationMode::kIncludingVariables &&
     423             :       script_scope->scope_info_.is_null()) {
     424             :     Handle<ScriptContextTable> table(
     425     2004594 :         isolate->native_context()->script_context_table(), isolate);
     426      668198 :     Handle<Context> first = ScriptContextTable::GetContext(isolate, table, 0);
     427     1336396 :     Handle<ScopeInfo> scope_info(first->scope_info(), isolate);
     428             :     script_scope->SetScriptScopeInfo(scope_info);
     429             :   }
     430             : 
     431     1011025 :   if (innermost_scope == nullptr) return script_scope;
     432      839192 :   script_scope->AddInnerScope(current_scope);
     433      839192 :   return innermost_scope;
     434             : }
     435             : 
     436   143890672 : DeclarationScope* Scope::AsDeclarationScope() {
     437             :   DCHECK(is_declaration_scope());
     438   143890672 :   return static_cast<DeclarationScope*>(this);
     439             : }
     440             : 
     441           0 : const DeclarationScope* Scope::AsDeclarationScope() const {
     442             :   DCHECK(is_declaration_scope());
     443           0 :   return static_cast<const DeclarationScope*>(this);
     444             : }
     445             : 
     446       94972 : ModuleScope* Scope::AsModuleScope() {
     447             :   DCHECK(is_module_scope());
     448       94972 :   return static_cast<ModuleScope*>(this);
     449             : }
     450             : 
     451           0 : const ModuleScope* Scope::AsModuleScope() const {
     452             :   DCHECK(is_module_scope());
     453           0 :   return static_cast<const ModuleScope*>(this);
     454             : }
     455             : 
     456     2214992 : int Scope::num_parameters() const {
     457     2214992 :   return is_declaration_scope() ? AsDeclarationScope()->num_parameters() : 0;
     458             : }
     459             : 
     460       11550 : void DeclarationScope::DeclareSloppyBlockFunction(
     461             :     const AstRawString* name, Scope* scope,
     462             :     SloppyBlockFunctionStatement* statement) {
     463       11550 :   if (sloppy_block_function_map_ == nullptr) {
     464             :     sloppy_block_function_map_ =
     465             :         new (zone()->New(sizeof(SloppyBlockFunctionMap)))
     466       20558 :             SloppyBlockFunctionMap(zone());
     467             :   }
     468       11550 :   sloppy_block_function_map_->Declare(zone(), name, scope, statement);
     469       11550 : }
     470             : 
     471     4962280 : void DeclarationScope::HoistSloppyBlockFunctions(AstNodeFactory* factory) {
     472             :   DCHECK(is_sloppy(language_mode()));
     473             :   DCHECK(is_function_scope() || is_eval_scope() || is_script_scope() ||
     474             :          (is_block_scope() && outer_scope()->is_function_scope()));
     475             :   DCHECK(HasSimpleParameters() || is_block_scope() || is_being_lazily_parsed_);
     476             :   DCHECK_EQ(factory == nullptr, is_being_lazily_parsed_);
     477             : 
     478             :   SloppyBlockFunctionMap* map = sloppy_block_function_map();
     479     9872164 :   if (map == nullptr) return;
     480             : 
     481             :   // In case of complex parameters the current scope is the body scope and the
     482             :   // parameters are stored in the outer scope.
     483       10227 :   Scope* parameter_scope = HasSimpleParameters() ? this : outer_scope_;
     484             :   DCHECK(parameter_scope->is_function_scope() || is_eval_scope() ||
     485             :          is_script_scope());
     486             : 
     487             :   // The declarations need to be added in the order they were seen,
     488             :   // so accumulate declared names sorted by index.
     489             :   ZoneMap<int, const AstRawString*> names_to_declare(zone());
     490             : 
     491             :   // For each variable which is used as a function declaration in a sloppy
     492             :   // block,
     493       31548 :   for (ZoneHashMap::Entry* p = map->Start(); p != nullptr; p = map->Next(p)) {
     494       11096 :     const AstRawString* name = static_cast<AstRawString*>(p->key);
     495             : 
     496             :     // If the variable wouldn't conflict with a lexical declaration
     497             :     // or parameter,
     498             : 
     499             :     // Check if there's a conflict with a parameter.
     500             :     Variable* maybe_parameter = parameter_scope->LookupLocal(name);
     501       13492 :     if (maybe_parameter != nullptr && maybe_parameter->is_parameter()) {
     502             :       continue;
     503             :     }
     504             : 
     505             :     bool declaration_queued = false;
     506             : 
     507             :     // Write in assignments to var for each block-scoped function declaration
     508       10903 :     auto delegates = static_cast<SloppyBlockFunctionMap::Delegate*>(p->value);
     509             : 
     510             :     DeclarationScope* decl_scope = this;
     511       23174 :     while (decl_scope->is_eval_scope()) {
     512       24542 :       decl_scope = decl_scope->outer_scope()->GetDeclarationScope();
     513             :     }
     514             :     Scope* outer_scope = decl_scope->outer_scope();
     515             : 
     516       46648 :     for (SloppyBlockFunctionMap::Delegate* delegate = delegates;
     517             :          delegate != nullptr; delegate = delegate->next()) {
     518             :       // Check if there's a conflict with a lexical declaration
     519       26048 :       Scope* query_scope = delegate->scope()->outer_scope();
     520        2890 :       Variable* var = nullptr;
     521             :       bool should_hoist = true;
     522             : 
     523             :       // Note that we perform this loop for each delegate named 'name',
     524             :       // which may duplicate work if those delegates share scopes.
     525             :       // It is not sufficient to just do a Lookup on query_scope: for
     526             :       // example, that does not prevent hoisting of the function in
     527             :       // `{ let e; try {} catch (e) { function e(){} } }`
     528       14753 :       do {
     529       16161 :         var = query_scope->LookupInScopeOrScopeInfo(name);
     530       19049 :         if (var != nullptr && IsLexicalVariableMode(var->mode())) {
     531             :           should_hoist = false;
     532             :           break;
     533             :         }
     534             :         query_scope = query_scope->outer_scope();
     535             :       } while (query_scope != outer_scope);
     536             : 
     537       11293 :       if (!should_hoist) continue;
     538             : 
     539        9889 :       if (!declaration_queued) {
     540             :         declaration_queued = true;
     541        9509 :         names_to_declare.insert({delegate->index(), name});
     542             :       }
     543             : 
     544        9890 :       if (factory) {
     545             :         DCHECK(!is_being_lazily_parsed_);
     546             :         int pos = delegate->position();
     547             :         Assignment* assignment = factory->NewAssignment(
     548        7471 :             Token::ASSIGN, NewUnresolved(factory, name, pos),
     549       14943 :             delegate->scope()->NewUnresolved(factory, name, pos), pos);
     550             :         assignment->set_lookup_hoisting_mode(LookupHoistingMode::kLegacySloppy);
     551             :         Statement* statement = factory->NewExpressionStatement(assignment, pos);
     552             :         delegate->set_statement(statement);
     553             :       }
     554             :     }
     555             :   }
     556             : 
     557       10226 :   if (names_to_declare.empty()) return;
     558             : 
     559       26796 :   for (const auto& index_and_name : names_to_declare) {
     560        9507 :     const AstRawString* name = index_and_name.second;
     561        9507 :     if (factory) {
     562             :       DCHECK(!is_being_lazily_parsed_);
     563        7197 :       VariableProxy* proxy = factory->NewVariableProxy(name, NORMAL_VARIABLE);
     564             :       auto declaration = factory->NewVariableDeclaration(kNoSourcePosition);
     565             :       // Based on the preceding checks, it doesn't matter what we pass as
     566             :       // sloppy_mode_block_scope_function_redefinition.
     567        7198 :       bool ok = true;
     568             :       DeclareVariable(declaration, proxy, VariableMode::kVar, NORMAL_VARIABLE,
     569             :                       Variable::DefaultInitializationFlag(VariableMode::kVar),
     570        7198 :                       nullptr, &ok);
     571             :       DCHECK(ok);
     572             :     } else {
     573             :       DCHECK(is_being_lazily_parsed_);
     574        2310 :       Variable* var = DeclareVariableName(name, VariableMode::kVar);
     575             :       var->set_maybe_assigned();
     576             :     }
     577             :   }
     578             : }
     579             : 
     580     5436455 : bool DeclarationScope::Analyze(ParseInfo* info) {
     581             :   RuntimeCallTimerScope runtimeTimer(
     582             :       info->runtime_call_stats(),
     583             :       info->on_background_thread()
     584             :           ? RuntimeCallCounterId::kCompileBackgroundScopeAnalysis
     585     3624296 :           : RuntimeCallCounterId::kCompileScopeAnalysis);
     586             :   DCHECK_NOT_NULL(info->literal());
     587     1812159 :   DeclarationScope* scope = info->literal()->scope();
     588             : 
     589             :   base::Optional<AllowHandleDereference> allow_deref;
     590             :   if (!info->maybe_outer_scope_info().is_null()) {
     591             :     // Allow dereferences to the scope info if there is one.
     592             :     allow_deref.emplace();
     593             :   }
     594             : 
     595     2668665 :   if (scope->is_eval_scope() && is_sloppy(scope->language_mode())) {
     596      730387 :     AstNodeFactory factory(info->ast_value_factory(), info->zone());
     597      730387 :     scope->HoistSloppyBlockFunctions(&factory);
     598             :   }
     599             : 
     600             :   // We are compiling one of four cases:
     601             :   // 1) top-level code,
     602             :   // 2) a function/eval/module on the top-level
     603             :   // 3) a function/eval in a scope that was already resolved.
     604             :   DCHECK(scope->scope_type() == SCRIPT_SCOPE ||
     605             :          scope->outer_scope()->scope_type() == SCRIPT_SCOPE ||
     606             :          scope->outer_scope()->already_resolved_);
     607             : 
     608             :   // The outer scope is never lazy.
     609             :   scope->set_should_eager_compile();
     610             : 
     611     1812159 :   if (scope->must_use_preparsed_scope_data_) {
     612             :     DCHECK_EQ(scope->scope_type_, ScopeType::FUNCTION_SCOPE);
     613             :     allow_deref.emplace();
     614       36868 :     info->consumed_preparse_data()->RestoreScopeAllocationData(scope);
     615             :   }
     616             : 
     617     1812159 :   if (!scope->AllocateVariables(info)) return false;
     618             : 
     619             : #ifdef DEBUG
     620             :   if (info->is_native() ? FLAG_print_builtin_scopes : FLAG_print_scopes) {
     621             :     PrintF("Global scope:\n");
     622             :     scope->Print();
     623             :   }
     624             :   scope->CheckScopePositions();
     625             :   scope->CheckZones();
     626             : #endif
     627             : 
     628     1812015 :   return true;
     629             : }
     630             : 
     631     9007568 : void DeclarationScope::DeclareThis(AstValueFactory* ast_value_factory) {
     632             :   DCHECK(!already_resolved_);
     633             :   DCHECK(is_declaration_scope());
     634             :   DCHECK(has_this_declaration());
     635             : 
     636     4503784 :   bool derived_constructor = IsDerivedConstructor(function_kind_);
     637             :   Variable* var =
     638             :       Declare(zone(), ast_value_factory->this_string(),
     639             :               derived_constructor ? VariableMode::kConst : VariableMode::kVar,
     640             :               THIS_VARIABLE,
     641     9007568 :               derived_constructor ? kNeedsInitialization : kCreatedInitialized);
     642     4503800 :   receiver_ = var;
     643     4503800 : }
     644             : 
     645     8011992 : void DeclarationScope::DeclareArguments(AstValueFactory* ast_value_factory) {
     646             :   DCHECK(is_function_scope());
     647             :   DCHECK(!is_arrow_scope());
     648             : 
     649     8012040 :   arguments_ = LookupLocal(ast_value_factory->arguments_string());
     650     4010100 :   if (arguments_ == nullptr) {
     651             :     // Declare 'arguments' variable which exists in all non arrow functions.
     652             :     // Note that it might never be accessed, in which case it won't be
     653             :     // allocated during variable allocation.
     654             :     arguments_ = Declare(zone(), ast_value_factory->arguments_string(),
     655     8009343 :                          VariableMode::kVar);
     656        2720 :   } else if (IsLexicalVariableMode(arguments_->mode())) {
     657             :     // Check if there's lexically declared variable named arguments to avoid
     658             :     // redeclaration. See ES#sec-functiondeclarationinstantiation, step 20.
     659         582 :     arguments_ = nullptr;
     660             :   }
     661     4007403 : }
     662             : 
     663     4442208 : void DeclarationScope::DeclareDefaultFunctionVariables(
     664     6273625 :     AstValueFactory* ast_value_factory) {
     665             :   DCHECK(is_function_scope());
     666             :   DCHECK(!is_arrow_scope());
     667             : 
     668     4442208 :   DeclareThis(ast_value_factory);
     669             :   new_target_ = Declare(zone(), ast_value_factory->new_target_string(),
     670     9800161 :                         VariableMode::kConst);
     671             : 
     672    16299922 :   if (IsConciseMethod(function_kind_) || IsClassConstructor(function_kind_) ||
     673             :       IsAccessorFunction(function_kind_)) {
     674             :     EnsureRareData()->this_function =
     675             :         Declare(zone(), ast_value_factory->this_function_string(),
     676      915698 :                 VariableMode::kConst);
     677             :   }
     678     4442234 : }
     679             : 
     680      972186 : Variable* DeclarationScope::DeclareFunctionVar(const AstRawString* name,
     681             :                                                Scope* cache) {
     682             :   DCHECK(is_function_scope());
     683             :   DCHECK_NULL(function_);
     684      972186 :   if (cache == nullptr) cache = this;
     685             :   DCHECK_NULL(cache->variables_.Lookup(name));
     686     1880334 :   VariableKind kind = is_sloppy(language_mode()) ? SLOPPY_FUNCTION_NAME_VARIABLE
     687      972186 :                                                  : NORMAL_VARIABLE;
     688             :   function_ = new (zone())
     689     1944372 :       Variable(this, name, VariableMode::kConst, kind, kCreatedInitialized);
     690      972186 :   if (calls_sloppy_eval()) {
     691       64038 :     cache->NonLocal(name, VariableMode::kDynamic);
     692             :   } else {
     693      908148 :     cache->variables_.Add(zone(), function_);
     694             :   }
     695      972211 :   return function_;
     696             : }
     697             : 
     698      134450 : Variable* DeclarationScope::DeclareGeneratorObjectVar(
     699      134450 :     const AstRawString* name) {
     700             :   DCHECK(is_function_scope() || is_module_scope());
     701             :   DCHECK_NULL(generator_object_var());
     702             : 
     703             :   Variable* result = EnsureRareData()->generator_object =
     704      134449 :       NewTemporary(name, kNotAssigned);
     705             :   result->set_is_used();
     706      134450 :   return result;
     707             : }
     708             : 
     709    15466201 : Scope* Scope::FinalizeBlockScope() {
     710             :   DCHECK(is_block_scope());
     711             : #ifdef DEBUG
     712             :   DCHECK_NE(sibling_, this);
     713             : #endif
     714             : 
     715    15255560 :   if (variables_.occupancy() > 0 ||
     716       75267 :       (is_declaration_scope() && AsDeclarationScope()->calls_sloppy_eval())) {
     717             :     return this;
     718             :   }
     719             : 
     720             :   // Remove this scope from outer scope.
     721             :   outer_scope()->RemoveInnerScope(this);
     722             : 
     723             :   // Reparent inner scopes.
     724     4566929 :   if (inner_scope_ != nullptr) {
     725             :     Scope* scope = inner_scope_;
     726      548538 :     scope->outer_scope_ = outer_scope();
     727     1139825 :     while (scope->sibling_ != nullptr) {
     728             :       scope = scope->sibling_;
     729       42749 :       scope->outer_scope_ = outer_scope();
     730             :     }
     731      548538 :     scope->sibling_ = outer_scope()->inner_scope_;
     732      548538 :     outer_scope()->inner_scope_ = inner_scope_;
     733      548538 :     inner_scope_ = nullptr;
     734             :   }
     735             : 
     736             :   // Move unresolved variables
     737     4566929 :   if (!unresolved_list_.is_empty()) {
     738             :     outer_scope()->unresolved_list_.Prepend(std::move(unresolved_list_));
     739             :     unresolved_list_.Clear();
     740             :   }
     741             : 
     742     4791975 :   if (inner_scope_calls_eval_) outer_scope()->inner_scope_calls_eval_ = true;
     743             : 
     744             :   // No need to propagate scope_calls_eval_, since if it was relevant to
     745             :   // this scope we would have had to bail out at the top.
     746             :   DCHECK(!scope_calls_eval_ || !is_declaration_scope() ||
     747             :          !is_sloppy(language_mode()));
     748             : 
     749             :   // This block does not need a context.
     750     4566929 :   num_heap_slots_ = 0;
     751             : 
     752             :   // Mark scope as removed by making it its own sibling.
     753             : #ifdef DEBUG
     754             :   sibling_ = this;
     755             : #endif
     756             : 
     757     4566929 :   return nullptr;
     758             : }
     759             : 
     760           0 : void DeclarationScope::AddLocal(Variable* var) {
     761             :   DCHECK(!already_resolved_);
     762             :   // Temporaries are only placed in ClosureScopes.
     763             :   DCHECK_EQ(GetClosureScope(), this);
     764             :   locals_.Add(var);
     765           0 : }
     766             : 
     767      126136 : void Scope::Snapshot::Reparent(DeclarationScope* new_parent) {
     768             :   DCHECK(!IsCleared());
     769             :   DCHECK_EQ(new_parent, outer_scope_and_calls_eval_.GetPointer()->inner_scope_);
     770             :   DCHECK_EQ(new_parent->outer_scope_, outer_scope_and_calls_eval_.GetPointer());
     771             :   DCHECK_EQ(new_parent, new_parent->GetClosureScope());
     772             :   DCHECK_NULL(new_parent->inner_scope_);
     773             :   DCHECK(new_parent->unresolved_list_.is_empty());
     774             :   DCHECK(new_parent->locals_.is_empty());
     775      126136 :   Scope* inner_scope = new_parent->sibling_;
     776      126136 :   if (inner_scope != top_inner_scope_) {
     777        3632 :     for (; inner_scope->sibling() != top_inner_scope_;
     778             :          inner_scope = inner_scope->sibling()) {
     779           0 :       inner_scope->outer_scope_ = new_parent;
     780           0 :       if (inner_scope->inner_scope_calls_eval_) {
     781           0 :         new_parent->inner_scope_calls_eval_ = true;
     782             :       }
     783             :       DCHECK_NE(inner_scope, new_parent);
     784             :     }
     785        3632 :     inner_scope->outer_scope_ = new_parent;
     786        3632 :     if (inner_scope->inner_scope_calls_eval_) {
     787         128 :       new_parent->inner_scope_calls_eval_ = true;
     788             :     }
     789        3632 :     new_parent->inner_scope_ = new_parent->sibling_;
     790        3632 :     inner_scope->sibling_ = nullptr;
     791             :     // Reset the sibling rather than the inner_scope_ since we
     792             :     // want to keep new_parent there.
     793        3632 :     new_parent->sibling_ = top_inner_scope_;
     794             :   }
     795             : 
     796             :   Scope* outer_scope_ = outer_scope_and_calls_eval_.GetPointer();
     797             :   new_parent->unresolved_list_.MoveTail(&outer_scope_->unresolved_list_,
     798             :                                         top_unresolved_);
     799             : 
     800             :   // Move temporaries allocated for complex parameter initializers.
     801             :   DeclarationScope* outer_closure = outer_scope_->GetClosureScope();
     802             :   new_parent->locals_.MoveTail(outer_closure->locals(), top_local_);
     803      252284 :   for (Variable* local : new_parent->locals_) {
     804             :     DCHECK_EQ(VariableMode::kTemporary, local->mode());
     805             :     DCHECK_EQ(local->scope(), local->scope()->GetClosureScope());
     806             :     DCHECK_NE(local->scope(), new_parent);
     807             :     local->set_scope(new_parent);
     808             :   }
     809             :   outer_closure->locals_.Rewind(top_local_);
     810             : 
     811             :   // Move eval calls since Snapshot's creation into new_parent.
     812      126136 :   if (outer_scope_and_calls_eval_->scope_calls_eval_) {
     813         413 :     new_parent->scope_calls_eval_ = true;
     814         413 :     new_parent->inner_scope_calls_eval_ = true;
     815             :   }
     816             : 
     817             :   // We are in the arrow function case. The calls eval we may have recorded
     818             :   // is intended for the inner scope and we should simply restore the
     819             :   // original "calls eval" flag of the outer scope.
     820             :   RestoreEvalFlag();
     821             :   Clear();
     822      126136 : }
     823             : 
     824          91 : void Scope::ReplaceOuterScope(Scope* outer) {
     825             :   DCHECK_NOT_NULL(outer);
     826             :   DCHECK_NOT_NULL(outer_scope_);
     827             :   DCHECK(!already_resolved_);
     828          91 :   outer_scope_->RemoveInnerScope(this);
     829             :   outer->AddInnerScope(this);
     830             :   outer_scope_ = outer;
     831          91 : }
     832             : 
     833     5022980 : Variable* Scope::LookupInScopeInfo(const AstRawString* name, Scope* cache) {
     834             :   DCHECK(!scope_info_.is_null());
     835             :   DCHECK_NULL(cache->variables_.Lookup(name));
     836             : 
     837             :   Handle<String> name_handle = name->string();
     838             :   // The Scope is backed up by ScopeInfo. This means it cannot operate in a
     839             :   // heap-independent mode, and all strings must be internalized immediately. So
     840             :   // it's ok to get the Handle<String> here.
     841             :   bool found = false;
     842             : 
     843             :   VariableLocation location;
     844             :   int index;
     845             :   VariableMode mode;
     846             :   InitializationFlag init_flag;
     847             :   MaybeAssignedFlag maybe_assigned_flag;
     848             : 
     849             :   {
     850             :     location = VariableLocation::CONTEXT;
     851             :     index = ScopeInfo::ContextSlotIndex(scope_info_, name_handle, &mode,
     852     2511264 :                                         &init_flag, &maybe_assigned_flag);
     853     2511286 :     found = index >= 0;
     854             :   }
     855             : 
     856     4628186 :   if (!found && scope_type() == MODULE_SCOPE) {
     857             :     location = VariableLocation::MODULE;
     858             :     index = scope_info_->ModuleIndex(name_handle, &mode, &init_flag,
     859        1982 :                                      &maybe_assigned_flag);
     860        1982 :     found = index != 0;
     861             :   }
     862             : 
     863     2511286 :   if (!found) {
     864     2116470 :     index = scope_info_->FunctionContextSlotIndex(*name_handle);
     865     2116470 :     if (index < 0) return nullptr;  // Nowhere found.
     866        1040 :     Variable* var = AsDeclarationScope()->DeclareFunctionVar(name, cache);
     867             :     DCHECK_EQ(VariableMode::kConst, var->mode());
     868             :     var->AllocateTo(VariableLocation::CONTEXT, index);
     869        1040 :     return cache->variables_.Lookup(name);
     870             :   }
     871             : 
     872             :   VariableKind kind = NORMAL_VARIABLE;
     873     1184450 :   if (location == VariableLocation::CONTEXT &&
     874     1183590 :       index == scope_info_->ReceiverContextSlotIndex()) {
     875             :     kind = THIS_VARIABLE;
     876             :   }
     877             :   // TODO(marja, rossberg): Correctly declare FUNCTION, CLASS, NEW_TARGET, and
     878             :   // ARGUMENTS bindings as their corresponding VariableKind.
     879             : 
     880             :   Variable* var = cache->variables_.Declare(zone(), this, name, mode, kind,
     881      789632 :                                             init_flag, maybe_assigned_flag);
     882             :   var->AllocateTo(location, index);
     883      394817 :   return var;
     884             : }
     885             : 
     886     2904184 : Variable* DeclarationScope::DeclareParameter(const AstRawString* name,
     887             :                                              VariableMode mode,
     888             :                                              bool is_optional, bool is_rest,
     889     2904189 :                                              AstValueFactory* ast_value_factory,
     890             :                                              int position) {
     891             :   DCHECK(!already_resolved_);
     892             :   DCHECK(is_function_scope() || is_module_scope());
     893             :   DCHECK(!has_rest_);
     894             :   DCHECK(!is_optional || !is_rest);
     895             :   DCHECK(!is_being_lazily_parsed_);
     896             :   DCHECK(!was_lazily_parsed_);
     897             :   Variable* var;
     898     2904184 :   if (mode == VariableMode::kTemporary) {
     899     3117169 :     var = NewTemporary(name);
     900             :   } else {
     901             :     DCHECK_EQ(mode, VariableMode::kVar);
     902     5595399 :     var = Declare(zone(), name, mode, PARAMETER_VARIABLE);
     903             :   }
     904     2904192 :   has_rest_ = is_rest;
     905     2904192 :   var->set_initializer_position(position);
     906     2904192 :   params_.Add(var, zone());
     907     2904189 :   if (!is_rest) ++num_parameters_;
     908     2904189 :   if (name == ast_value_factory->arguments_string()) {
     909        1454 :     has_arguments_parameter_ = true;
     910             :   }
     911             :   // Params are automatically marked as used to make sure that the debugger and
     912             :   // function.arguments sees them.
     913             :   // TODO(verwaest): Reevaluate whether we always need to do this, since
     914             :   // strict-mode function.arguments does not make the arguments available.
     915     2904189 :   var->set_is_used();
     916     2904189 :   return var;
     917             : }
     918             : 
     919     3739153 : void DeclarationScope::RecordParameter(bool is_rest) {
     920             :   DCHECK(!already_resolved_);
     921             :   DCHECK(is_function_scope() || is_module_scope());
     922             :   DCHECK(is_being_lazily_parsed_);
     923             :   DCHECK(!has_rest_);
     924     3739153 :   has_rest_ = is_rest;
     925     3739153 :   if (!is_rest) ++num_parameters_;
     926     3739153 : }
     927             : 
     928     4042806 : void DeclarationScope::DeclareParameterName(const AstRawString* name) {
     929             :   DCHECK(!already_resolved_);
     930             :   DCHECK(is_function_scope() || is_module_scope());
     931             :   DCHECK(is_being_lazily_parsed_);
     932             :   // The resulting variable isn't added to params. In the case of non-simple
     933             :   // params, a dummy temp variable is added in AddNonSimpleParameterTemp.
     934     4042806 :   Variable* var = Declare(zone(), name, VariableMode::kVar, PARAMETER_VARIABLE);
     935             :   // Params are automatically marked as used to make sure that the debugger and
     936             :   // function.arguments sees them.
     937             :   // TODO(verwaest): Reevaluate whether we always need to do this, since
     938             :   // strict-mode function.arguments does not make the arguments available.
     939             :   var->set_is_used();
     940     4042906 : }
     941             : 
     942       68082 : Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode,
     943    15269194 :                               VariableKind kind, InitializationFlag init_flag) {
     944             :   DCHECK(!already_resolved_);
     945             :   // This function handles VariableMode::kVar, VariableMode::kLet, and
     946             :   // VariableMode::kConst modes.  VariableMode::kDynamic variables are
     947             :   // introduced during variable allocation, and VariableMode::kTemporary
     948             :   // variables are allocated via NewTemporary().
     949             :   DCHECK(IsDeclaredVariableMode(mode));
     950             :   DCHECK_IMPLIES(GetDeclarationScope()->is_being_lazily_parsed(),
     951             :                  mode == VariableMode::kVar || mode == VariableMode::kLet ||
     952             :                      mode == VariableMode::kConst);
     953             :   DCHECK(!GetDeclarationScope()->was_lazily_parsed());
     954       68083 :   return Declare(zone(), name, mode, kind, init_flag);
     955             : }
     956             : 
     957             : // TODO(leszeks): Avoid passing the proxy into here, passing the raw_name alone
     958             : // instead.
     959    11056089 : void Scope::DeclareVariable(Declaration* declaration, VariableProxy* proxy,
     960             :                             VariableMode mode, VariableKind kind,
     961             :                             InitializationFlag init,
     962             :                             bool* sloppy_mode_block_scope_function_redefinition,
     963    20908655 :                             bool* ok) {
     964             :   DCHECK(IsDeclaredVariableMode(mode));
     965             :   DCHECK(!already_resolved_);
     966             :   DCHECK(!GetDeclarationScope()->is_being_lazily_parsed());
     967             :   DCHECK(!GetDeclarationScope()->was_lazily_parsed());
     968             : 
     969    20343343 :   if (mode == VariableMode::kVar && !is_declaration_scope()) {
     970             :     return GetDeclarationScope()->DeclareVariable(
     971             :         declaration, proxy, mode, kind, init,
     972    11878054 :         sloppy_mode_block_scope_function_redefinition, ok);
     973             :   }
     974             :   DCHECK(!is_catch_scope());
     975             :   DCHECK(!is_with_scope());
     976             :   DCHECK(is_declaration_scope() ||
     977             :          (IsLexicalVariableMode(mode) && is_block_scope()));
     978             : 
     979             :   DCHECK_NOT_NULL(proxy->raw_name());
     980         235 :   const AstRawString* name = proxy->raw_name();
     981             : 
     982             :   // Pessimistically assume that top-level variables will be assigned.
     983             :   //
     984             :   // Top-level variables in a script can be accessed by other scripts or even
     985             :   // become global properties. While this does not apply to top-level variables
     986             :   // in a module (assuming they are not exported), we must still mark these as
     987             :   // assigned because they might be accessed by a lazily parsed top-level
     988             :   // function, which, for efficiency, we preparse without variable tracking.
     989    10645126 :   if (is_script_scope() || is_module_scope()) {
     990     3002403 :     if (mode != VariableMode::kConst) proxy->set_is_assigned();
     991             :   }
     992             : 
     993             :   Variable* var = LookupLocal(name);
     994             :   // Declare the variable in the declaration scope.
     995    10645407 :   if (V8_LIKELY(var == nullptr)) {
     996    11069119 :     if (V8_UNLIKELY(is_eval_scope() && is_sloppy(language_mode()) &&
     997             :                     mode == VariableMode::kVar)) {
     998             :       // In a var binding in a sloppy direct eval, pollute the enclosing scope
     999             :       // with this new binding by doing the following:
    1000             :       // The proxy is bound to a lookup variable to force a dynamic declaration
    1001             :       // using the DeclareEvalVar or DeclareEvalFunction runtime functions.
    1002             :       DCHECK_EQ(NORMAL_VARIABLE, kind);
    1003      306281 :       var = NonLocal(proxy->raw_name(), VariableMode::kDynamic);
    1004             :     } else {
    1005             :       // Declare the name.
    1006             :       var = DeclareLocal(name, mode, kind, init);
    1007             :     }
    1008             :   } else {
    1009             :     var->set_maybe_assigned();
    1010      712336 :     if (V8_UNLIKELY(IsLexicalVariableMode(mode) ||
    1011             :                     IsLexicalVariableMode(var->mode()))) {
    1012             :       // The name was declared in this scope before; check for conflicting
    1013             :       // re-declarations. We have a conflict if either of the declarations is
    1014             :       // not a var (in script scope, we also have to ignore legacy const for
    1015             :       // compatibility). There is similar code in runtime.cc in the Declare
    1016             :       // functions. The function CheckConflictingVarDeclarations checks for
    1017             :       // var and let bindings from different scopes whereas this is a check
    1018             :       // for conflicting declarations within the same scope. This check also
    1019             :       // covers the special case
    1020             :       //
    1021             :       // function () { let x; { var x; } }
    1022             :       //
    1023             :       // because the var declaration is hoisted to the function scope where
    1024             :       // 'x' is already bound.
    1025             :       //
    1026             :       // In harmony we treat re-declarations as early errors. See ES5 16 for a
    1027             :       // definition of early errors.
    1028             :       //
    1029             :       // Allow duplicate function decls for web compat, see bug 4693. If the
    1030             :       // duplication is allowed, then the var will show up in the
    1031             :       // SloppyBlockFunctionMap.
    1032             :       SloppyBlockFunctionMap* map =
    1033       65575 :           GetDeclarationScope()->sloppy_block_function_map();
    1034             :       *ok =
    1035         756 :           map != nullptr && declaration->IsFunctionDeclaration() &&
    1036             :           declaration->AsFunctionDeclaration()
    1037       66440 :               ->declares_sloppy_block_function() &&
    1038       65810 :           map->Lookup(const_cast<AstRawString*>(name), name->Hash()) != nullptr;
    1039       65575 :       *sloppy_mode_block_scope_function_redefinition = *ok;
    1040             :     }
    1041             :   }
    1042             :   DCHECK_NOT_NULL(var);
    1043             : 
    1044             :   // We add a declaration node for every declaration. The compiler
    1045             :   // will only generate code if necessary. In particular, declarations
    1046             :   // for inner local variables that do not represent functions won't
    1047             :   // result in any generated code.
    1048             :   //
    1049             :   // This will lead to multiple declaration nodes for the
    1050             :   // same variable if it is declared several times. This is not a
    1051             :   // semantic issue, but it may be a performance issue since it may
    1052             :   // lead to repeated DeclareEvalVar or DeclareEvalFunction calls.
    1053             :   decls_.Add(declaration);
    1054             :   declaration->set_var(var);
    1055    10645186 :   proxy->BindTo(var);
    1056             : }
    1057             : 
    1058     5467211 : Variable* Scope::DeclareVariableName(const AstRawString* name,
    1059             :                                      VariableMode mode) {
    1060             :   DCHECK(IsDeclaredVariableMode(mode));
    1061             :   DCHECK(!already_resolved_);
    1062             :   DCHECK(GetDeclarationScope()->is_being_lazily_parsed());
    1063             : 
    1064    10795448 :   if (mode == VariableMode::kVar && !is_declaration_scope()) {
    1065      575238 :     return GetDeclarationScope()->DeclareVariableName(name, mode);
    1066             :   }
    1067             :   DCHECK(!is_with_scope());
    1068             :   DCHECK(!is_eval_scope());
    1069             :   DCHECK(is_declaration_scope() || IsLexicalVariableMode(mode));
    1070             :   DCHECK(scope_info_.is_null());
    1071             : 
    1072             :   // Declare the variable in the declaration scope.
    1073      222960 :   Variable* var = LookupLocal(name);
    1074     5467330 :   if (var == nullptr) {
    1075             :     var = DeclareLocal(name, mode);
    1076      446426 :   } else if (IsLexicalVariableMode(mode) ||
    1077             :              IsLexicalVariableMode(var->mode())) {
    1078             :     // Duplicate functions are allowed in the sloppy mode, but if this is not
    1079             :     // a function declaration, it's an error. This is an error PreParser
    1080             :     // hasn't previously detected.
    1081             :     return nullptr;
    1082      222946 :   } else if (mode == VariableMode::kVar) {
    1083             :     var->set_maybe_assigned();
    1084             :   }
    1085             :   var->set_is_used();
    1086     5466825 :   return var;
    1087             : }
    1088             : 
    1089      370864 : Variable* Scope::DeclareCatchVariableName(const AstRawString* name) {
    1090             :   DCHECK(!already_resolved_);
    1091             :   DCHECK(is_catch_scope());
    1092             :   DCHECK(scope_info_.is_null());
    1093             : 
    1094      370907 :   return Declare(zone(), name, VariableMode::kVar);
    1095             : }
    1096             : 
    1097    53749769 : void Scope::AddUnresolved(VariableProxy* proxy) {
    1098             :   DCHECK(!already_resolved_);
    1099             :   DCHECK(!proxy->is_resolved());
    1100             :   unresolved_list_.Add(proxy);
    1101    53748844 : }
    1102             : 
    1103     5516013 : Variable* DeclarationScope::DeclareDynamicGlobal(const AstRawString* name,
    1104             :                                                  VariableKind kind,
    1105             :                                                  Scope* cache) {
    1106             :   DCHECK(is_script_scope());
    1107             :   return cache->variables_.Declare(zone(), this, name,
    1108     5516013 :                                    VariableMode::kDynamicGlobal, kind);
    1109             :   // TODO(neis): Mark variable as maybe-assigned?
    1110             : }
    1111             : 
    1112        1269 : bool Scope::RemoveUnresolved(VariableProxy* var) {
    1113        1269 :   return unresolved_list_.Remove(var);
    1114             : }
    1115             : 
    1116       15783 : void Scope::DeleteUnresolved(VariableProxy* var) {
    1117             :   DCHECK(unresolved_list_.Contains(var));
    1118             :   var->mark_removed_from_unresolved();
    1119       15783 : }
    1120             : 
    1121     1239689 : Variable* Scope::NewTemporary(const AstRawString* name) {
    1122     1346176 :   return NewTemporary(name, kMaybeAssigned);
    1123             : }
    1124             : 
    1125     1480624 : Variable* Scope::NewTemporary(const AstRawString* name,
    1126     1480624 :                               MaybeAssignedFlag maybe_assigned) {
    1127             :   DeclarationScope* scope = GetClosureScope();
    1128             :   Variable* var = new (zone()) Variable(scope, name, VariableMode::kTemporary,
    1129             :                                         NORMAL_VARIABLE, kCreatedInitialized);
    1130             :   scope->AddLocal(var);
    1131     1480631 :   if (maybe_assigned == kMaybeAssigned) var->set_maybe_assigned();
    1132     1480631 :   return var;
    1133             : }
    1134             : 
    1135    14870084 : Declaration* Scope::CheckConflictingVarDeclarations() {
    1136    22298294 :   for (Declaration* decl : decls_) {
    1137             :     // Lexical vs lexical conflicts within the same scope have already been
    1138             :     // captured in Parser::Declare. The only conflicts we still need to check
    1139             :     // are lexical vs nested var.
    1140     1228788 :     Scope* current = nullptr;
    1141    18675560 :     if (decl->IsVariableDeclaration() &&
    1142     8922133 :         decl->AsVariableDeclaration()->AsNested() != nullptr) {
    1143      783608 :       current = decl->AsVariableDeclaration()->AsNested()->scope();
    1144    10089577 :     } else if (is_eval_scope() && is_sloppy(language_mode())) {
    1145      600396 :       if (IsLexicalVariableMode(decl->var()->mode())) continue;
    1146      288675 :       current = outer_scope_;
    1147             :     }
    1148     9741904 :     if (current == nullptr) continue;
    1149             :     DCHECK(decl->var()->mode() == VariableMode::kVar ||
    1150             :            decl->var()->mode() == VariableMode::kDynamic);
    1151             :     // Iterate through all scopes until and including the declaration scope.
    1152             :     while (true) {
    1153             :       // There is a conflict if there exists a non-VAR binding.
    1154      393625 :       Variable* other_var =
    1155     1241026 :           current->LookupInScopeOrScopeInfo(decl->var()->raw_name());
    1156     1634637 :       if (other_var != nullptr && IsLexicalVariableMode(other_var->mode())) {
    1157             :         return decl;
    1158             :       }
    1159     3123733 :       if (current->is_declaration_scope() &&
    1160        1851 :           !(current->is_eval_scope() && is_sloppy(current->language_mode()))) {
    1161             :         break;
    1162             :       }
    1163             :       current = current->outer_scope();
    1164             :     }
    1165      560549 :   }
    1166             :   return nullptr;
    1167             : }
    1168             : 
    1169       85322 : const AstRawString* Scope::FindVariableDeclaredIn(Scope* scope,
    1170             :                                                   VariableMode mode_limit) {
    1171             :   const VariableMap& variables = scope->variables_;
    1172      649266 :   for (ZoneHashMap::Entry* p = variables.Start(); p != nullptr;
    1173             :        p = variables.Next(p)) {
    1174      478882 :     const AstRawString* name = static_cast<const AstRawString*>(p->key);
    1175        1585 :     Variable* var = LookupLocal(name);
    1176      480472 :     if (var != nullptr && var->mode() <= mode_limit) return name;
    1177             :   }
    1178             :   return nullptr;
    1179             : }
    1180             : 
    1181     1812151 : bool DeclarationScope::AllocateVariables(ParseInfo* info) {
    1182             :   // Module variables must be allocated before variable resolution
    1183             :   // to ensure that UpdateNeedsHoleCheck() can detect import variables.
    1184     1812151 :   if (is_module_scope()) AsModuleScope()->AllocateModuleVariables();
    1185             : 
    1186     1812151 :   if (!ResolveVariablesRecursively(info)) {
    1187             :     DCHECK(info->pending_error_handler()->has_pending_error());
    1188             :     return false;
    1189             :   }
    1190     1812019 :   AllocateVariablesRecursively();
    1191             : 
    1192     1812018 :   return true;
    1193             : }
    1194             : 
    1195     4066833 : bool Scope::AllowsLazyParsingWithoutUnresolvedVariables(
    1196             :     const Scope* outer) const {
    1197             :   // If none of the outer scopes need to decide whether to context allocate
    1198             :   // specific variables, we can preparse inner functions without unresolved
    1199             :   // variables. Otherwise we need to find unresolved variables to force context
    1200             :   // allocation of the matching declarations. We can stop at the outer scope for
    1201             :   // the parse, since context allocation of those variables is already
    1202             :   // guaranteed to be correct.
    1203     4066962 :   for (const Scope* s = this; s != outer; s = s->outer_scope_) {
    1204             :     // Eval forces context allocation on all outer scopes, so we don't need to
    1205             :     // look at those scopes. Sloppy eval makes top-level non-lexical variables
    1206             :     // dynamic, whereas strict-mode requires context allocation.
    1207     3031229 :     if (s->is_eval_scope()) return is_sloppy(s->language_mode());
    1208             :     // Catch scopes force context allocation of all variables.
    1209     2005685 :     if (s->is_catch_scope()) continue;
    1210             :     // With scopes do not introduce variables that need allocation.
    1211     2005691 :     if (s->is_with_scope()) continue;
    1212             :     DCHECK(s->is_module_scope() || s->is_block_scope() ||
    1213             :            s->is_function_scope());
    1214             :     return false;
    1215             :   }
    1216             :   return true;
    1217             : }
    1218             : 
    1219     3564344 : bool DeclarationScope::AllowsLazyCompilation() const {
    1220     3564344 :   return !force_eager_compilation_;
    1221             : }
    1222             : 
    1223     2785650 : int Scope::ContextChainLength(Scope* scope) const {
    1224             :   int n = 0;
    1225     3413443 :   for (const Scope* s = this; s != scope; s = s->outer_scope_) {
    1226             :     DCHECK_NOT_NULL(s);  // scope must be in the scope chain
    1227      627793 :     if (s->NeedsContext()) n++;
    1228             :   }
    1229     2785650 :   return n;
    1230             : }
    1231             : 
    1232      372469 : int Scope::ContextChainLengthUntilOutermostSloppyEval() const {
    1233             :   int result = 0;
    1234             :   int length = 0;
    1235             : 
    1236     1540319 :   for (const Scope* s = this; s != nullptr; s = s->outer_scope()) {
    1237     1167850 :     if (!s->NeedsContext()) continue;
    1238      868341 :     length++;
    1239     1700153 :     if (s->is_declaration_scope() &&
    1240             :         s->AsDeclarationScope()->calls_sloppy_eval()) {
    1241             :       result = length;
    1242             :     }
    1243             :   }
    1244             : 
    1245      372469 :   return result;
    1246             : }
    1247             : 
    1248     3730590 : DeclarationScope* Scope::GetDeclarationScope() {
    1249     3971009 :   Scope* scope = this;
    1250    12880804 :   while (!scope->is_declaration_scope()) {
    1251             :     scope = scope->outer_scope();
    1252             :   }
    1253     3730590 :   return scope->AsDeclarationScope();
    1254             : }
    1255             : 
    1256           0 : const DeclarationScope* Scope::GetClosureScope() const {
    1257           0 :   const Scope* scope = this;
    1258           0 :   while (!scope->is_declaration_scope() || scope->is_block_scope()) {
    1259             :     scope = scope->outer_scope();
    1260             :   }
    1261           0 :   return scope->AsDeclarationScope();
    1262             : }
    1263             : 
    1264     3787381 : DeclarationScope* Scope::GetClosureScope() {
    1265    17986800 :   Scope* scope = this;
    1266    34926226 :   while (!scope->is_declaration_scope() || scope->is_block_scope()) {
    1267             :     scope = scope->outer_scope();
    1268             :   }
    1269     3787381 :   return scope->AsDeclarationScope();
    1270             : }
    1271             : 
    1272     2415046 : bool Scope::NeedsScopeInfo() const {
    1273             :   DCHECK(!already_resolved_);
    1274             :   DCHECK(GetClosureScope()->ShouldEagerCompile());
    1275             :   // The debugger expects all functions to have scope infos.
    1276             :   // TODO(jochen|yangguo): Remove this requirement.
    1277     2415046 :   if (is_function_scope()) return true;
    1278           0 :   return NeedsContext();
    1279             : }
    1280             : 
    1281       86943 : bool Scope::ShouldBanArguments() {
    1282      173888 :   return GetReceiverScope()->should_ban_arguments();
    1283             : }
    1284             : 
    1285      123307 : DeclarationScope* Scope::GetReceiverScope() {
    1286      133651 :   Scope* scope = this;
    1287      637223 :   while (!scope->is_script_scope() &&
    1288      117855 :          (!scope->is_function_scope() ||
    1289             :           scope->AsDeclarationScope()->is_arrow_scope())) {
    1290             :     scope = scope->outer_scope();
    1291             :   }
    1292      123307 :   return scope->AsDeclarationScope();
    1293             : }
    1294             : 
    1295     2557481 : Scope* Scope::GetOuterScopeWithContext() {
    1296     3494437 :   Scope* scope = outer_scope_;
    1297     9150085 :   while (scope && !scope->NeedsContext()) {
    1298             :     scope = scope->outer_scope();
    1299             :   }
    1300     2557481 :   return scope;
    1301             : }
    1302             : 
    1303       16784 : void Scope::CollectNonLocals(DeclarationScope* max_outer_scope,
    1304             :                              Isolate* isolate, ParseInfo* info,
    1305       17517 :                              Handle<StringSet>* non_locals) {
    1306             :   // Module variables must be allocated before variable resolution
    1307             :   // to ensure that UpdateNeedsHoleCheck() can detect import variables.
    1308       16784 :   if (is_module_scope()) AsModuleScope()->AllocateModuleVariables();
    1309             : 
    1310             :   // Lazy parsed declaration scopes are already partially analyzed. If there are
    1311             :   // unresolved references remaining, they just need to be resolved in outer
    1312             :   // scopes.
    1313             :   Scope* lookup =
    1314       14898 :       is_declaration_scope() && AsDeclarationScope()->was_lazily_parsed()
    1315             :           ? outer_scope()
    1316       17517 :           : this;
    1317             : 
    1318       91242 :   for (VariableProxy* proxy : unresolved_list_) {
    1319             :     DCHECK(!proxy->is_resolved());
    1320             :     Variable* var =
    1321       57674 :         Lookup<kParsedScope>(proxy, lookup, max_outer_scope->outer_scope());
    1322       57674 :     if (var == nullptr) {
    1323       16507 :       *non_locals = StringSet::Add(isolate, *non_locals, proxy->name());
    1324             :     } else {
    1325             :       // In this case we need to leave scopes in a way that they can be
    1326             :       // allocated. If we resolved variables from lazy parsed scopes, we need
    1327             :       // to context allocate the var.
    1328             :       ResolveTo(info, proxy, var);
    1329       41167 :       if (!var->is_dynamic() && lookup != this) var->ForceContextAllocation();
    1330             :     }
    1331             :   }
    1332             : 
    1333             :   // Clear unresolved_list_ as it's in an inconsistent state.
    1334             :   unresolved_list_.Clear();
    1335             : 
    1336       21235 :   for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
    1337        4451 :     scope->CollectNonLocals(max_outer_scope, isolate, info, non_locals);
    1338             :   }
    1339       16784 : }
    1340             : 
    1341     2956767 : void Scope::AnalyzePartially(DeclarationScope* max_outer_scope,
    1342     5679836 :                              AstNodeFactory* ast_node_factory,
    1343             :                              UnresolvedList* new_unresolved_list) {
    1344             :   DCHECK_IMPLIES(is_declaration_scope(),
    1345             :                  !AsDeclarationScope()->was_lazily_parsed());
    1346             : 
    1347    43910290 :   for (VariableProxy* proxy = unresolved_list_.first(); proxy != nullptr;
    1348             :        proxy = proxy->next_unresolved()) {
    1349             :     DCHECK(!proxy->is_resolved());
    1350             :     Variable* var =
    1351    29261352 :         Lookup<kParsedScope>(proxy, this, max_outer_scope->outer_scope());
    1352    23404971 :     if (var == nullptr) {
    1353             :       // Don't copy unresolved references to the script scope, unless it's a
    1354             :       // reference to a private name or method. In that case keep it so we
    1355             :       // can fail later.
    1356     6034997 :       if (!max_outer_scope->outer_scope()->is_script_scope() ||
    1357      178599 :           proxy->IsPrivateName()) {
    1358             :         VariableProxy* copy = ast_node_factory->CopyVariableProxy(proxy);
    1359             :         new_unresolved_list->Add(copy);
    1360             :       }
    1361             :     } else {
    1362             :       var->set_is_used();
    1363    17548579 :       if (proxy->is_assigned()) var->set_maybe_assigned();
    1364             :     }
    1365             :   }
    1366             : 
    1367             :   // Clear unresolved_list_ as it's in an inconsistent state.
    1368             :   unresolved_list_.Clear();
    1369             : 
    1370     4120907 :   for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
    1371             :     scope->AnalyzePartially(max_outer_scope, ast_node_factory,
    1372     1164124 :                             new_unresolved_list);
    1373             :   }
    1374     2956783 : }
    1375             : 
    1376       12333 : Handle<StringSet> DeclarationScope::CollectNonLocals(
    1377             :     Isolate* isolate, ParseInfo* info, Handle<StringSet> non_locals) {
    1378       12333 :   Scope::CollectNonLocals(this, isolate, info, &non_locals);
    1379       12333 :   return non_locals;
    1380             : }
    1381             : 
    1382     2540338 : void DeclarationScope::ResetAfterPreparsing(AstValueFactory* ast_value_factory,
    1383             :                                             bool aborted) {
    1384             :   DCHECK(is_function_scope());
    1385             : 
    1386             :   // Reset all non-trivial members.
    1387             :   params_.Clear();
    1388             :   decls_.Clear();
    1389             :   locals_.Clear();
    1390     2497421 :   inner_scope_ = nullptr;
    1391             :   unresolved_list_.Clear();
    1392     2497421 :   sloppy_block_function_map_ = nullptr;
    1393     2497421 :   rare_data_ = nullptr;
    1394     2497421 :   has_rest_ = false;
    1395             : 
    1396             :   DCHECK_NE(zone_, ast_value_factory->zone());
    1397     2497421 :   zone_->ReleaseMemory();
    1398             : 
    1399     2497694 :   if (aborted) {
    1400             :     // Prepare scope for use in the outer zone.
    1401       42917 :     zone_ = ast_value_factory->zone();
    1402       42917 :     variables_.Reset(ZoneAllocationPolicy(zone_));
    1403       85834 :     if (!IsArrowFunction(function_kind_)) {
    1404       40306 :       has_simple_parameters_ = true;
    1405       40306 :       DeclareDefaultFunctionVariables(ast_value_factory);
    1406             :     }
    1407             :   } else {
    1408             :     // Make sure this scope isn't used for allocation anymore.
    1409     2454777 :     zone_ = nullptr;
    1410             :     variables_.Invalidate();
    1411             :   }
    1412             : 
    1413             : #ifdef DEBUG
    1414             :   needs_migration_ = false;
    1415             :   is_being_lazily_parsed_ = false;
    1416             : #endif
    1417             : 
    1418     2497694 :   was_lazily_parsed_ = !aborted;
    1419     2497694 : }
    1420             : 
    1421     2956714 : void Scope::SavePreparseData(Parser* parser) {
    1422     2956714 :   if (PreparseDataBuilder::ScopeIsSkippableFunctionScope(this)) {
    1423             :     AsDeclarationScope()->SavePreparseDataForDeclarationScope(parser);
    1424             :   }
    1425             : 
    1426     4120805 :   for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
    1427     1164130 :     scope->SavePreparseData(parser);
    1428             :   }
    1429     2956675 : }
    1430             : 
    1431           0 : void DeclarationScope::SavePreparseDataForDeclarationScope(Parser* parser) {
    1432     1935981 :   if (preparse_data_builder_ == nullptr) return;
    1433     1935987 :   preparse_data_builder_->SaveScopeAllocationData(this, parser);
    1434             : }
    1435             : 
    1436     2392149 : void DeclarationScope::AnalyzePartially(Parser* parser,
    1437     3213109 :                                         AstNodeFactory* ast_node_factory) {
    1438             :   DCHECK(!force_eager_compilation_);
    1439             :   UnresolvedList new_unresolved_list;
    1440     9544344 :   if (!IsArrowFunction(function_kind_) &&
    1441     3003809 :       (!outer_scope_->is_script_scope() ||
    1442     1271842 :        (preparse_data_builder_ != nullptr &&
    1443      635930 :         preparse_data_builder_->HasInnerFunctions()))) {
    1444             :     // Try to resolve unresolved variables for this Scope and migrate those
    1445             :     // which cannot be resolved inside. It doesn't make sense to try to resolve
    1446             :     // them in the outer Scopes here, because they are incomplete.
    1447     1792697 :     Scope::AnalyzePartially(this, ast_node_factory, &new_unresolved_list);
    1448             : 
    1449             :     // Migrate function_ to the right Zone.
    1450     1792688 :     if (function_ != nullptr) {
    1451      821007 :       function_ = ast_node_factory->CopyVariable(function_);
    1452             :     }
    1453             : 
    1454     1792682 :     SavePreparseData(parser);
    1455             :   }
    1456             : 
    1457             : #ifdef DEBUG
    1458             :   if (FLAG_print_scopes) {
    1459             :     PrintF("Inner function scope:\n");
    1460             :     Print();
    1461             :   }
    1462             : #endif
    1463             : 
    1464     2392096 :   ResetAfterPreparsing(ast_node_factory->ast_value_factory(), false);
    1465             : 
    1466             :   unresolved_list_ = std::move(new_unresolved_list);
    1467     2392437 : }
    1468             : 
    1469             : #ifdef DEBUG
    1470             : namespace {
    1471             : 
    1472             : const char* Header(ScopeType scope_type, FunctionKind function_kind,
    1473             :                    bool is_declaration_scope) {
    1474             :   switch (scope_type) {
    1475             :     case EVAL_SCOPE: return "eval";
    1476             :     // TODO(adamk): Should we print concise method scopes specially?
    1477             :     case FUNCTION_SCOPE:
    1478             :       if (IsGeneratorFunction(function_kind)) return "function*";
    1479             :       if (IsAsyncFunction(function_kind)) return "async function";
    1480             :       if (IsArrowFunction(function_kind)) return "arrow";
    1481             :       return "function";
    1482             :     case MODULE_SCOPE: return "module";
    1483             :     case SCRIPT_SCOPE: return "global";
    1484             :     case CATCH_SCOPE: return "catch";
    1485             :     case BLOCK_SCOPE: return is_declaration_scope ? "varblock" : "block";
    1486             :     case WITH_SCOPE: return "with";
    1487             :   }
    1488             :   UNREACHABLE();
    1489             : }
    1490             : 
    1491             : void Indent(int n, const char* str) { PrintF("%*s%s", n, "", str); }
    1492             : 
    1493             : void PrintName(const AstRawString* name) {
    1494             :   PrintF("%.*s", name->length(), name->raw_data());
    1495             : }
    1496             : 
    1497             : void PrintLocation(Variable* var) {
    1498             :   switch (var->location()) {
    1499             :     case VariableLocation::UNALLOCATED:
    1500             :       break;
    1501             :     case VariableLocation::PARAMETER:
    1502             :       PrintF("parameter[%d]", var->index());
    1503             :       break;
    1504             :     case VariableLocation::LOCAL:
    1505             :       PrintF("local[%d]", var->index());
    1506             :       break;
    1507             :     case VariableLocation::CONTEXT:
    1508             :       PrintF("context[%d]", var->index());
    1509             :       break;
    1510             :     case VariableLocation::LOOKUP:
    1511             :       PrintF("lookup");
    1512             :       break;
    1513             :     case VariableLocation::MODULE:
    1514             :       PrintF("module");
    1515             :       break;
    1516             :   }
    1517             : }
    1518             : 
    1519             : void PrintVar(int indent, Variable* var) {
    1520             :   Indent(indent, VariableMode2String(var->mode()));
    1521             :   PrintF(" ");
    1522             :   if (var->raw_name()->IsEmpty())
    1523             :     PrintF(".%p", reinterpret_cast<void*>(var));
    1524             :   else
    1525             :     PrintName(var->raw_name());
    1526             :   PrintF(";  // (%p) ", reinterpret_cast<void*>(var));
    1527             :   PrintLocation(var);
    1528             :   bool comma = !var->IsUnallocated();
    1529             :   if (var->has_forced_context_allocation()) {
    1530             :     if (comma) PrintF(", ");
    1531             :     PrintF("forced context allocation");
    1532             :     comma = true;
    1533             :   }
    1534             :   if (var->maybe_assigned() == kNotAssigned) {
    1535             :     if (comma) PrintF(", ");
    1536             :     PrintF("never assigned");
    1537             :     comma = true;
    1538             :   }
    1539             :   if (var->initialization_flag() == kNeedsInitialization &&
    1540             :       !var->binding_needs_init()) {
    1541             :     if (comma) PrintF(", ");
    1542             :     PrintF("hole initialization elided");
    1543             :   }
    1544             :   PrintF("\n");
    1545             : }
    1546             : 
    1547             : void PrintMap(int indent, const char* label, VariableMap* map, bool locals,
    1548             :               Variable* function_var) {
    1549             :   bool printed_label = false;
    1550             :   for (VariableMap::Entry* p = map->Start(); p != nullptr; p = map->Next(p)) {
    1551             :     Variable* var = reinterpret_cast<Variable*>(p->value);
    1552             :     if (var == function_var) continue;
    1553             :     bool local = !IsDynamicVariableMode(var->mode());
    1554             :     if ((locals ? local : !local) &&
    1555             :         (var->is_used() || !var->IsUnallocated())) {
    1556             :       if (!printed_label) {
    1557             :         Indent(indent, label);
    1558             :         printed_label = true;
    1559             :       }
    1560             :       PrintVar(indent, var);
    1561             :     }
    1562             :   }
    1563             : }
    1564             : 
    1565             : }  // anonymous namespace
    1566             : 
    1567             : void DeclarationScope::PrintParameters() {
    1568             :   PrintF(" (");
    1569             :   for (int i = 0; i < params_.length(); i++) {
    1570             :     if (i > 0) PrintF(", ");
    1571             :     const AstRawString* name = params_[i]->raw_name();
    1572             :     if (name->IsEmpty()) {
    1573             :       PrintF(".%p", reinterpret_cast<void*>(params_[i]));
    1574             :     } else {
    1575             :       PrintName(name);
    1576             :     }
    1577             :   }
    1578             :   PrintF(")");
    1579             : }
    1580             : 
    1581             : void Scope::Print(int n) {
    1582             :   int n0 = (n > 0 ? n : 0);
    1583             :   int n1 = n0 + 2;  // indentation
    1584             : 
    1585             :   // Print header.
    1586             :   FunctionKind function_kind = is_function_scope()
    1587             :                                    ? AsDeclarationScope()->function_kind()
    1588             :                                    : kNormalFunction;
    1589             :   Indent(n0, Header(scope_type_, function_kind, is_declaration_scope()));
    1590             :   if (scope_name_ != nullptr && !scope_name_->IsEmpty()) {
    1591             :     PrintF(" ");
    1592             :     PrintName(scope_name_);
    1593             :   }
    1594             : 
    1595             :   // Print parameters, if any.
    1596             :   Variable* function = nullptr;
    1597             :   if (is_function_scope()) {
    1598             :     AsDeclarationScope()->PrintParameters();
    1599             :     function = AsDeclarationScope()->function_var();
    1600             :   }
    1601             : 
    1602             :   PrintF(" { // (%p) (%d, %d)\n", reinterpret_cast<void*>(this),
    1603             :          start_position(), end_position());
    1604             :   if (is_hidden()) {
    1605             :     Indent(n1, "// is hidden\n");
    1606             :   }
    1607             : 
    1608             :   // Function name, if any (named function literals, only).
    1609             :   if (function != nullptr) {
    1610             :     Indent(n1, "// (local) function name: ");
    1611             :     PrintName(function->raw_name());
    1612             :     PrintF("\n");
    1613             :   }
    1614             : 
    1615             :   // Scope info.
    1616             :   if (is_strict(language_mode())) {
    1617             :     Indent(n1, "// strict mode scope\n");
    1618             :   }
    1619             :   if (IsAsmModule()) Indent(n1, "// scope is an asm module\n");
    1620             :   if (is_declaration_scope() && AsDeclarationScope()->calls_sloppy_eval()) {
    1621             :     Indent(n1, "// scope calls sloppy 'eval'\n");
    1622             :   }
    1623             :   if (is_declaration_scope() && AsDeclarationScope()->NeedsHomeObject()) {
    1624             :     Indent(n1, "// scope needs home object\n");
    1625             :   }
    1626             :   if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n");
    1627             :   if (is_declaration_scope()) {
    1628             :     DeclarationScope* scope = AsDeclarationScope();
    1629             :     if (scope->was_lazily_parsed()) Indent(n1, "// lazily parsed\n");
    1630             :     if (scope->ShouldEagerCompile()) Indent(n1, "// will be compiled\n");
    1631             :   }
    1632             :   if (num_stack_slots_ > 0) {
    1633             :     Indent(n1, "// ");
    1634             :     PrintF("%d stack slots\n", num_stack_slots_);
    1635             :   }
    1636             :   if (num_heap_slots_ > 0) {
    1637             :     Indent(n1, "// ");
    1638             :     PrintF("%d heap slots\n", num_heap_slots_);
    1639             :   }
    1640             : 
    1641             :   // Print locals.
    1642             :   if (function != nullptr) {
    1643             :     Indent(n1, "// function var:\n");
    1644             :     PrintVar(n1, function);
    1645             :   }
    1646             : 
    1647             :   // Print temporaries.
    1648             :   {
    1649             :     bool printed_header = false;
    1650             :     for (Variable* local : locals_) {
    1651             :       if (local->mode() != VariableMode::kTemporary) continue;
    1652             :       if (!printed_header) {
    1653             :         printed_header = true;
    1654             :         Indent(n1, "// temporary vars:\n");
    1655             :       }
    1656             :       PrintVar(n1, local);
    1657             :     }
    1658             :   }
    1659             : 
    1660             :   if (variables_.occupancy() > 0) {
    1661             :     PrintMap(n1, "// local vars:\n", &variables_, true, function);
    1662             :     PrintMap(n1, "// dynamic vars:\n", &variables_, false, function);
    1663             :   }
    1664             : 
    1665             :   // Print inner scopes (disable by providing negative n).
    1666             :   if (n >= 0) {
    1667             :     for (Scope* scope = inner_scope_; scope != nullptr;
    1668             :          scope = scope->sibling_) {
    1669             :       PrintF("\n");
    1670             :       scope->Print(n1);
    1671             :     }
    1672             :   }
    1673             : 
    1674             :   Indent(n0, "}\n");
    1675             : }
    1676             : 
    1677             : void Scope::CheckScopePositions() {
    1678             :   // Visible leaf scopes must have real positions.
    1679             :   if (!is_hidden() && inner_scope_ == nullptr) {
    1680             :     DCHECK_NE(kNoSourcePosition, start_position());
    1681             :     DCHECK_NE(kNoSourcePosition, end_position());
    1682             :   }
    1683             :   for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
    1684             :     scope->CheckScopePositions();
    1685             :   }
    1686             : }
    1687             : 
    1688             : void Scope::CheckZones() {
    1689             :   DCHECK(!needs_migration_);
    1690             :   for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
    1691             :     if (scope->is_declaration_scope() &&
    1692             :         scope->AsDeclarationScope()->was_lazily_parsed()) {
    1693             :       DCHECK_NULL(scope->zone());
    1694             :       DCHECK_NULL(scope->inner_scope_);
    1695             :       continue;
    1696             :     }
    1697             :     scope->CheckZones();
    1698             :   }
    1699             : }
    1700             : #endif  // DEBUG
    1701             : 
    1702      808932 : Variable* Scope::NonLocal(const AstRawString* name, VariableMode mode) {
    1703             :   // Declare a new non-local.
    1704             :   DCHECK(IsDynamicVariableMode(mode));
    1705      808932 :   Variable* var = variables_.Declare(zone(), this, name, mode);
    1706             :   // Allocate it by giving it a dynamic lookup.
    1707             :   var->AllocateTo(VariableLocation::LOOKUP, -1);
    1708      808933 :   return var;
    1709             : }
    1710             : 
    1711             : // static
    1712             : template <Scope::ScopeLookupMode mode>
    1713    53342185 : Variable* Scope::Lookup(VariableProxy* proxy, Scope* scope,
    1714             :                         Scope* outer_scope_end, Scope* entry_point,
    1715             :                         bool force_context_allocation) {
    1716             :   if (mode == kDeserializedScope) {
    1717     2121909 :     Variable* var = entry_point->variables_.Lookup(proxy->raw_name());
    1718     2121913 :     if (var != nullptr) return var;
    1719             :   }
    1720             : 
    1721             :   while (true) {
    1722             :     DCHECK_IMPLIES(mode == kParsedScope, !scope->is_debug_evaluate_scope_);
    1723             :     // Short-cut: whenever we find a debug-evaluate scope, just look everything
    1724             :     // up dynamically. Debug-evaluate doesn't properly create scope info for the
    1725             :     // lookups it does. It may not have a valid 'this' declaration, and anything
    1726             :     // accessed through debug-evaluate might invalidly resolve to
    1727             :     // stack-allocated variables.
    1728             :     // TODO(yangguo): Remove once debug-evaluate creates proper ScopeInfo for
    1729             :     // the scopes in which it's evaluating.
    1730     2239214 :     if (mode == kDeserializedScope &&
    1731     2239214 :         V8_UNLIKELY(scope->is_debug_evaluate_scope_)) {
    1732       11339 :       return entry_point->NonLocal(proxy->raw_name(), VariableMode::kDynamic);
    1733             :     }
    1734             : 
    1735             :     // Try to find the variable in this scope.
    1736             :     Variable* var = mode == kParsedScope ? scope->LookupLocal(proxy->raw_name())
    1737             :                                          : scope->LookupInScopeInfo(
    1738     2227875 :                                                proxy->raw_name(), entry_point);
    1739             : 
    1740             :     // We found a variable and we are done. (Even if there is an 'eval' in this
    1741             :     // scope which introduces the same variable again, the resulting variable
    1742             :     // remains the same.)
    1743    73581473 :     if (var != nullptr) {
    1744    51144585 :       if (mode == kParsedScope && force_context_allocation &&
    1745             :           !var->is_dynamic()) {
    1746             :         var->ForceContextAllocation();
    1747             :       }
    1748    41162601 :       return var;
    1749             :     }
    1750             : 
    1751    32023605 :     if (scope->outer_scope_ == outer_scope_end) break;
    1752             : 
    1753             :     DCHECK(!scope->is_script_scope());
    1754    23583385 :     if (V8_UNLIKELY(scope->is_with_scope())) {
    1755             :       return LookupWith(proxy, scope, outer_scope_end, entry_point,
    1756       46987 :                         force_context_allocation);
    1757             :     }
    1758    42184299 :     if (V8_UNLIKELY(scope->is_declaration_scope() &&
    1759             :                     scope->AsDeclarationScope()->calls_sloppy_eval())) {
    1760             :       return LookupSloppyEval(proxy, scope, outer_scope_end, entry_point,
    1761      406567 :                               force_context_allocation);
    1762             :     }
    1763             : 
    1764    23129831 :     force_context_allocation |= scope->is_function_scope();
    1765             :     scope = scope->outer_scope_;
    1766             :     // TODO(verwaest): Separate through AnalyzePartially.
    1767    22662947 :     if (mode == kParsedScope && !scope->scope_info_.is_null()) {
    1768     1782587 :       return Lookup<kDeserializedScope>(proxy, scope, outer_scope_end, scope);
    1769             :     }
    1770             :   }
    1771             : 
    1772             :   // We may just be trying to find all free variables. In that case, don't
    1773             :   // declare them in the outer scope.
    1774             :   // TODO(marja): Separate Lookup for preparsed scopes better.
    1775     7371362 :   if (mode == kParsedScope && !scope->is_script_scope()) {
    1776             :     return nullptr;
    1777             :   }
    1778     2565580 :   if (V8_UNLIKELY(proxy->IsPrivateName())) return nullptr;
    1779             : 
    1780             :   // No binding has been found. Declare a variable on the global object.
    1781             :   return scope->AsDeclarationScope()->DeclareDynamicGlobal(
    1782             :       proxy->raw_name(), NORMAL_VARIABLE,
    1783     3032294 :       mode == kDeserializedScope ? entry_point : scope);
    1784             : }
    1785             : 
    1786             : template Variable* Scope::Lookup<Scope::kParsedScope>(
    1787             :     VariableProxy* proxy, Scope* scope, Scope* outer_scope_end,
    1788             :     Scope* entry_point, bool force_context_allocation);
    1789             : template Variable* Scope::Lookup<Scope::kDeserializedScope>(
    1790             :     VariableProxy* proxy, Scope* scope, Scope* outer_scope_end,
    1791             :     Scope* entry_point, bool force_context_allocation);
    1792             : 
    1793             : namespace {
    1794             : bool CanBeShadowed(Scope* scope, Variable* var) {
    1795      453555 :   if (var == nullptr) return false;
    1796             : 
    1797             :   // "this" can't be shadowed by "eval"-introduced bindings or by "with" scopes.
    1798             :   // TODO(wingo): There are other variables in this category; add them.
    1799      429815 :   return !var->is_this();
    1800             : }
    1801             : };  // namespace
    1802             : 
    1803       58834 : Variable* Scope::LookupWith(VariableProxy* proxy, Scope* scope,
    1804             :                             Scope* outer_scope_end, Scope* entry_point,
    1805             :                             bool force_context_allocation) {
    1806             :   DCHECK(scope->is_with_scope());
    1807             : 
    1808             :   Variable* var =
    1809       46987 :       scope->outer_scope_->scope_info_.is_null()
    1810             :           ? Lookup<kParsedScope>(proxy, scope->outer_scope_, outer_scope_end,
    1811       44924 :                                  nullptr, force_context_allocation)
    1812             :           : Lookup<kDeserializedScope>(proxy, scope->outer_scope_,
    1813       91911 :                                        outer_scope_end, entry_point);
    1814             : 
    1815       46989 :   if (!CanBeShadowed(scope, var)) return var;
    1816             : 
    1817             :   // The current scope is a with scope, so the variable binding can not be
    1818             :   // statically resolved. However, note that it was necessary to do a lookup
    1819             :   // in the outer scope anyway, because if a binding exists in an outer
    1820             :   // scope, the associated variable has to be marked as potentially being
    1821             :   // accessed from inside of an inner with scope (the property may not be in
    1822             :   // the 'with' object).
    1823       41222 :   if (!var->is_dynamic() && var->IsUnallocated()) {
    1824             :     DCHECK(!scope->already_resolved_);
    1825             :     var->set_is_used();
    1826             :     var->ForceContextAllocation();
    1827       11847 :     if (proxy->is_assigned()) var->set_maybe_assigned();
    1828             :   }
    1829       29124 :   if (entry_point != nullptr) entry_point->variables_.Remove(var);
    1830       29124 :   Scope* target = entry_point == nullptr ? scope : entry_point;
    1831       29124 :   return target->NonLocal(proxy->raw_name(), VariableMode::kDynamic);
    1832             : }
    1833             : 
    1834      406567 : Variable* Scope::LookupSloppyEval(VariableProxy* proxy, Scope* scope,
    1835             :                                   Scope* outer_scope_end, Scope* entry_point,
    1836             :                                   bool force_context_allocation) {
    1837             :   DCHECK(scope->is_declaration_scope() &&
    1838             :          scope->AsDeclarationScope()->calls_sloppy_eval());
    1839             : 
    1840             :   // If we're compiling eval, it's possible that the outer scope is the first
    1841             :   // ScopeInfo-backed scope.
    1842      406567 :   Scope* entry = entry_point == nullptr ? scope->outer_scope_ : entry_point;
    1843             :   Variable* var =
    1844      406567 :       scope->outer_scope_->scope_info_.is_null()
    1845             :           ? Lookup<kParsedScope>(proxy, scope->outer_scope_, outer_scope_end,
    1846       69304 :                                  nullptr, force_context_allocation)
    1847             :           : Lookup<kDeserializedScope>(proxy, scope->outer_scope_,
    1848      475871 :                                        outer_scope_end, entry);
    1849      406566 :   if (!CanBeShadowed(scope, var)) return var;
    1850             : 
    1851             :   // A variable binding may have been found in an outer scope, but the current
    1852             :   // scope makes a sloppy 'eval' call, so the found variable may not be the
    1853             :   // correct one (the 'eval' may introduce a binding with the same name). In
    1854             :   // that case, change the lookup result to reflect this situation. Only
    1855             :   // scopes that can host var bindings (declaration scopes) need be considered
    1856             :   // here (this excludes block and catch scopes), and variable lookups at
    1857             :   // script scope are always dynamic.
    1858      400081 :   if (var->IsGlobalObjectProperty()) {
    1859      393532 :     Scope* target = entry_point == nullptr ? scope : entry_point;
    1860      393532 :     return target->NonLocal(proxy->raw_name(), VariableMode::kDynamicGlobal);
    1861             :   }
    1862             : 
    1863        6549 :   if (var->is_dynamic()) return var;
    1864             : 
    1865             :   Variable* invalidated = var;
    1866        4618 :   if (entry_point != nullptr) entry_point->variables_.Remove(invalidated);
    1867             : 
    1868        4618 :   Scope* target = entry_point == nullptr ? scope : entry_point;
    1869        4618 :   var = target->NonLocal(proxy->raw_name(), VariableMode::kDynamicLocal);
    1870             :   var->set_local_if_not_shadowed(invalidated);
    1871             : 
    1872        4618 :   return var;
    1873             : }
    1874             : 
    1875    21224327 : bool Scope::ResolveVariable(ParseInfo* info, VariableProxy* proxy) {
    1876             :   DCHECK(info->script_scope()->is_script_scope());
    1877             :   DCHECK(!proxy->is_resolved());
    1878    21224327 :   Variable* var = Lookup<kParsedScope>(proxy, this, nullptr);
    1879    21224466 :   if (var == nullptr) {
    1880             :     DCHECK(proxy->IsPrivateName());
    1881             :     info->pending_error_handler()->ReportMessageAt(
    1882         133 :         proxy->position(), proxy->position() + 1,
    1883             :         MessageTemplate::kInvalidPrivateFieldResolution, proxy->raw_name(),
    1884         133 :         kSyntaxError);
    1885         133 :     return false;
    1886             :   }
    1887             :   ResolveTo(info, proxy, var);
    1888    21224298 :   return true;
    1889             : }
    1890             : 
    1891             : namespace {
    1892             : 
    1893             : void SetNeedsHoleCheck(Variable* var, VariableProxy* proxy) {
    1894             :   proxy->set_needs_hole_check();
    1895             :   var->ForceHoleInitialization();
    1896             : }
    1897             : 
    1898    25867481 : void UpdateNeedsHoleCheck(Variable* var, VariableProxy* proxy, Scope* scope) {
    1899    21269583 :   if (var->mode() == VariableMode::kDynamicLocal) {
    1900             :     // Dynamically introduced variables never need a hole check (since they're
    1901             :     // VariableMode::kVar bindings, either from var or function declarations),
    1902             :     // but the variable they shadow might need a hole check, which we want to do
    1903             :     // if we decide that no shadowing variable was dynamically introoduced.
    1904             :     DCHECK_EQ(kCreatedInitialized, var->initialization_flag());
    1905        4058 :     return UpdateNeedsHoleCheck(var->local_if_not_shadowed(), proxy, scope);
    1906             :   }
    1907             : 
    1908    21265525 :   if (var->initialization_flag() == kCreatedInitialized) return;
    1909             : 
    1910             :   // It's impossible to eliminate module import hole checks here, because it's
    1911             :   // unknown at compilation time whether the binding referred to in the
    1912             :   // exporting module itself requires hole checks.
    1913     3666968 :   if (var->location() == VariableLocation::MODULE && !var->IsExport()) {
    1914             :     return SetNeedsHoleCheck(var, proxy);
    1915             :   }
    1916             : 
    1917             :   // Check if the binding really needs an initialization check. The check
    1918             :   // can be skipped in the following situation: we have a VariableMode::kLet or
    1919             :   // VariableMode::kConst binding, both the Variable and the VariableProxy have
    1920             :   // the same declaration scope (i.e. they are both in global code, in the same
    1921             :   // function or in the same eval code), the VariableProxy is in the source
    1922             :   // physically located after the initializer of the variable, and that the
    1923             :   // initializer cannot be skipped due to a nonlinear scope.
    1924             :   //
    1925             :   // The condition on the closure scopes is a conservative check for
    1926             :   // nested functions that access a binding and are called before the
    1927             :   // binding is initialized:
    1928             :   //   function() { f(); let x = 1; function f() { x = 2; } }
    1929             :   //
    1930             :   // The check cannot be skipped on non-linear scopes, namely switch
    1931             :   // scopes, to ensure tests are done in cases like the following:
    1932             :   //   switch (1) { case 0: let x = 2; case 1: f(x); }
    1933             :   // The scope of the variable needs to be checked, in case the use is
    1934             :   // in a sub-block which may be linear.
    1935     3663570 :   if (var->scope()->GetClosureScope() != scope->GetClosureScope()) {
    1936             :     return SetNeedsHoleCheck(var, proxy);
    1937             :   }
    1938             : 
    1939     3117655 :   if (var->is_this()) {
    1940             :     DCHECK(IsDerivedConstructor(scope->GetClosureScope()->function_kind()));
    1941             :     // TODO(littledan): implement 'this' hole check elimination.
    1942             :     return SetNeedsHoleCheck(var, proxy);
    1943             :   }
    1944             : 
    1945             :   // We should always have valid source positions.
    1946             :   DCHECK_NE(var->initializer_position(), kNoSourcePosition);
    1947             :   DCHECK_NE(proxy->position(), kNoSourcePosition);
    1948             : 
    1949     1868763 :   if (var->scope()->is_nonlinear() ||
    1950      934328 :       var->initializer_position() >= proxy->position()) {
    1951             :     return SetNeedsHoleCheck(var, proxy);
    1952             :   }
    1953             : }
    1954             : 
    1955             : }  // anonymous namespace
    1956             : 
    1957           0 : void Scope::ResolveTo(ParseInfo* info, VariableProxy* proxy, Variable* var) {
    1958             : #ifdef DEBUG
    1959             :   if (info->is_native()) {
    1960             :     // To avoid polluting the global object in native scripts
    1961             :     //  - Variables must not be allocated to the global scope.
    1962             :     DCHECK_NOT_NULL(outer_scope());
    1963             :     //  - Variables must be bound locally or unallocated.
    1964             :     if (var->IsGlobalObjectProperty()) {
    1965             :       // The following variable name may be minified. If so, disable
    1966             :       // minification in js2c.py for better output.
    1967             :       Handle<String> name = proxy->raw_name()->string();
    1968             :       FATAL("Unbound variable: '%s' in native script.",
    1969             :             name->ToCString().get());
    1970             :     }
    1971             :     VariableLocation location = var->location();
    1972             :     DCHECK(location == VariableLocation::LOCAL ||
    1973             :            location == VariableLocation::CONTEXT ||
    1974             :            location == VariableLocation::PARAMETER ||
    1975             :            location == VariableLocation::UNALLOCATED);
    1976             :   }
    1977             : #endif
    1978             : 
    1979             :   DCHECK_NOT_NULL(var);
    1980    21265500 :   UpdateNeedsHoleCheck(var, proxy, this);
    1981    21265602 :   proxy->BindTo(var);
    1982           0 : }
    1983             : 
    1984    11262765 : bool Scope::ResolveVariablesRecursively(ParseInfo* info) {
    1985             :   DCHECK(info->script_scope()->is_script_scope());
    1986             :   // Lazy parsed declaration scopes are already partially analyzed. If there are
    1987             :   // unresolved references remaining, they just need to be resolved in outer
    1988             :   // scopes.
    1989    10677524 :   if (is_declaration_scope() && AsDeclarationScope()->was_lazily_parsed()) {
    1990             :     DCHECK_EQ(variables_.occupancy(), 0);
    1991    14411141 :     for (VariableProxy* proxy : unresolved_list_) {
    1992     5674528 :       Variable* var = Lookup<kParsedScope>(proxy, outer_scope(), nullptr);
    1993     5674382 :       if (var == nullptr) {
    1994             :         info->pending_error_handler()->ReportMessageAt(
    1995          40 :             proxy->position(), proxy->position() + 1,
    1996             :             MessageTemplate::kInvalidPrivateFieldResolution, proxy->raw_name(),
    1997          40 :             kSyntaxError);
    1998             :         DCHECK(proxy->IsPrivateName());
    1999             :         return false;
    2000             :       }
    2001     5674342 :       if (!var->is_dynamic()) {
    2002             :         var->set_is_used();
    2003             :         var->ForceContextAllocation();
    2004     4029018 :         if (proxy->is_assigned()) var->set_maybe_assigned();
    2005             :       }
    2006             :     }
    2007             :   } else {
    2008             :     // Resolve unresolved variables for this scope.
    2009    27693119 :     for (VariableProxy* proxy : unresolved_list_) {
    2010    21224441 :       if (!ResolveVariable(info, proxy)) return false;
    2011             :     }
    2012             : 
    2013             :     // Resolve unresolved variables for inner scopes.
    2014     7010165 :     for (Scope* scope = inner_scope_; scope != nullptr;
    2015             :          scope = scope->sibling_) {
    2016     3776018 :       if (!scope->ResolveVariablesRecursively(info)) return false;
    2017             :     }
    2018             :   }
    2019             :   return true;
    2020             : }
    2021             : 
    2022    72185191 : bool Scope::MustAllocate(Variable* var) {
    2023             :   DCHECK(var->location() != VariableLocation::MODULE);
    2024             :   // Give var a read/write use if there is a chance it might be accessed
    2025             :   // via an eval() call.  This is only possible if the variable has a
    2026             :   // visible name.
    2027    57506926 :   if ((var->is_this() || !var->raw_name()->IsEmpty()) &&
    2028    16439182 :       (inner_scope_calls_eval_ || is_catch_scope() || is_script_scope())) {
    2029             :     var->set_is_used();
    2030     4088199 :     if (inner_scope_calls_eval_) var->set_maybe_assigned();
    2031             :   }
    2032             :   DCHECK(!var->has_forced_context_allocation() || var->is_used());
    2033             :   // Global variables do not need to be allocated.
    2034    37925359 :   return !var->IsGlobalObjectProperty() && var->is_used();
    2035             : }
    2036             : 
    2037             : 
    2038    22171451 : bool Scope::MustAllocateInContext(Variable* var) {
    2039             :   // If var is accessed from an inner scope, or if there is a possibility
    2040             :   // that it might be accessed from the current or an inner scope (through
    2041             :   // an eval() call or a runtime with lookup), it must be allocated in the
    2042             :   // context.
    2043             :   //
    2044             :   // Temporary variables are always stack-allocated.  Catch-bound variables are
    2045             :   // always context-allocated.
    2046    11715073 :   if (var->mode() == VariableMode::kTemporary) return false;
    2047    10456378 :   if (is_catch_scope()) return true;
    2048    10359907 :   if ((is_script_scope() || is_eval_scope()) &&
    2049             :       IsLexicalVariableMode(var->mode())) {
    2050             :     return true;
    2051             :   }
    2052     9695512 :   return var->has_forced_context_allocation() || inner_scope_calls_eval_;
    2053             : }
    2054             : 
    2055             : 
    2056     7315679 : void Scope::AllocateStackSlot(Variable* var) {
    2057     7315679 :   if (is_block_scope()) {
    2058      395471 :     outer_scope()->GetDeclarationScope()->AllocateStackSlot(var);
    2059             :   } else {
    2060     6920208 :     var->AllocateTo(VariableLocation::LOCAL, num_stack_slots_++);
    2061             :   }
    2062     6920208 : }
    2063             : 
    2064             : 
    2065           0 : void Scope::AllocateHeapSlot(Variable* var) {
    2066     2290132 :   var->AllocateTo(VariableLocation::CONTEXT, num_heap_slots_++);
    2067           0 : }
    2068             : 
    2069     3238602 : void DeclarationScope::AllocateParameterLocals() {
    2070             :   DCHECK(is_function_scope());
    2071             : 
    2072             :   bool has_mapped_arguments = false;
    2073     1619292 :   if (arguments_ != nullptr) {
    2074             :     DCHECK(!is_arrow_scope());
    2075     1063309 :     if (MustAllocate(arguments_) && !has_arguments_parameter_) {
    2076             :       // 'arguments' is used and does not refer to a function
    2077             :       // parameter of the same name. If the arguments object
    2078             :       // aliases formal parameters, we conservatively allocate
    2079             :       // them specially in the loop below.
    2080             :       has_mapped_arguments =
    2081      116135 :           GetArgumentsType() == CreateArgumentsType::kMappedArguments;
    2082             :     } else {
    2083             :       // 'arguments' is unused. Tell the code generator that it does not need to
    2084             :       // allocate the arguments object by nulling out arguments_.
    2085      947192 :       arguments_ = nullptr;
    2086             :     }
    2087             :   }
    2088             : 
    2089             :   // The same parameter may occur multiple times in the parameters_ list.
    2090             :   // If it does, and if it is not copied into the context object, it must
    2091             :   // receive the highest parameter index for that parameter; thus iteration
    2092             :   // order is relevant!
    2093     4087072 :   for (int i = num_parameters() - 1; i >= 0; --i) {
    2094     4935514 :     Variable* var = params_[i];
    2095             :     DCHECK_NOT_NULL(var);
    2096             :     DCHECK(!has_rest_ || var != rest_parameter());
    2097             :     DCHECK_EQ(this, var->scope());
    2098     2467757 :     if (has_mapped_arguments) {
    2099             :       var->set_is_used();
    2100             :       var->set_maybe_assigned();
    2101             :       var->ForceContextAllocation();
    2102             :     }
    2103     2467757 :     AllocateParameter(var, i);
    2104             :   }
    2105     1619315 : }
    2106             : 
    2107     3583828 : void DeclarationScope::AllocateParameter(Variable* var, int index) {
    2108     3583828 :   if (MustAllocate(var)) {
    2109     5354447 :     if (has_forced_context_allocation_for_parameters() ||
    2110     2677225 :         MustAllocateInContext(var)) {
    2111             :       DCHECK(var->IsUnallocated() || var->IsContextSlot());
    2112      172760 :       if (var->IsUnallocated()) {
    2113             :         AllocateHeapSlot(var);
    2114             :       }
    2115             :     } else {
    2116             :       DCHECK(var->IsUnallocated() || var->IsParameter());
    2117     2504462 :       if (var->IsUnallocated()) {
    2118             :         var->AllocateTo(VariableLocation::PARAMETER, index);
    2119             :       }
    2120             :     }
    2121             :   }
    2122     3583835 : }
    2123             : 
    2124     3851338 : void DeclarationScope::AllocateReceiver() {
    2125     5470550 :   if (!has_this_declaration()) return;
    2126             :   DCHECK_NOT_NULL(receiver());
    2127             :   DCHECK_EQ(receiver()->scope(), this);
    2128     1116068 :   AllocateParameter(receiver(), -1);
    2129             : }
    2130             : 
    2131    16510906 : void Scope::AllocateNonParameterLocal(Variable* var) {
    2132             :   DCHECK(var->scope() == this);
    2133    16510906 :   if (var->IsUnallocated() && MustAllocate(var)) {
    2134     9035800 :     if (MustAllocateInContext(var)) {
    2135             :       AllocateHeapSlot(var);
    2136             :       DCHECK_IMPLIES(is_catch_scope(),
    2137             :                      var->index() == Context::THROWN_OBJECT_INDEX);
    2138             :     } else {
    2139     6920214 :       AllocateStackSlot(var);
    2140             :     }
    2141             :   }
    2142    16510995 : }
    2143             : 
    2144     3234069 : void Scope::AllocateNonParameterLocalsAndDeclaredGlobals() {
    2145    22952831 :   for (Variable* local : locals_) {
    2146    16484677 :     AllocateNonParameterLocal(local);
    2147             :   }
    2148             : 
    2149     3234085 :   if (is_declaration_scope()) {
    2150     2735298 :     AsDeclarationScope()->AllocateLocals();
    2151             :   }
    2152     3234060 : }
    2153             : 
    2154     5470527 : void DeclarationScope::AllocateLocals() {
    2155             :   // For now, function_ must be allocated at the very end.  If it gets
    2156             :   // allocated in the context, it must be the last slot in the context,
    2157             :   // because of the current ScopeInfo implementation (see
    2158             :   // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor).
    2159     2735255 :   if (function_ != nullptr && MustAllocate(function_)) {
    2160       26217 :     AllocateNonParameterLocal(function_);
    2161             :   } else {
    2162     2709045 :     function_ = nullptr;
    2163             :   }
    2164             : 
    2165             :   DCHECK(!has_rest_ || !MustAllocate(rest_parameter()) ||
    2166             :          !rest_parameter()->IsUnallocated());
    2167             : 
    2168     2735271 :   if (new_target_ != nullptr && !MustAllocate(new_target_)) {
    2169      985458 :     new_target_ = nullptr;
    2170             :   }
    2171             : 
    2172             :   NullifyRareVariableIf(RareVariable::kThisFunction,
    2173      165942 :                         [=](Variable* var) { return !MustAllocate(var); });
    2174     2735273 : }
    2175             : 
    2176       17942 : void ModuleScope::AllocateModuleVariables() {
    2177       19073 :   for (const auto& it : module()->regular_imports()) {
    2178        1131 :     Variable* var = LookupLocal(it.first);
    2179        1131 :     var->AllocateTo(VariableLocation::MODULE, it.second->cell_index);
    2180             :     DCHECK(!var->IsExport());
    2181             :   }
    2182             : 
    2183       36598 :   for (const auto& it : module()->regular_exports()) {
    2184       18656 :     Variable* var = LookupLocal(it.first);
    2185       18656 :     var->AllocateTo(VariableLocation::MODULE, it.second->cell_index);
    2186             :     DCHECK(var->IsExport());
    2187             :   }
    2188        8971 : }
    2189             : 
    2190    11557309 : void Scope::AllocateVariablesRecursively() {
    2191             :   DCHECK(!already_resolved_);
    2192             : 
    2193             :   // Don't allocate variables of preparsed scopes.
    2194    10677055 :   if (is_declaration_scope() && AsDeclarationScope()->was_lazily_parsed()) {
    2195     5587906 :     return;
    2196             :   }
    2197             : 
    2198             :   // Allocate variables for inner scopes.
    2199     7010042 :   for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
    2200     3775958 :     scope->AllocateVariablesRecursively();
    2201             :   }
    2202             : 
    2203             :   DCHECK(!already_resolved_);
    2204             :   DCHECK_EQ(Context::MIN_CONTEXT_SLOTS, num_heap_slots_);
    2205             : 
    2206             :   // Allocate variables for this scope.
    2207             :   // Parameters must be allocated first, if any.
    2208     3234084 :   if (is_declaration_scope()) {
    2209     2735299 :     if (is_function_scope()) {
    2210     1619331 :       AsDeclarationScope()->AllocateParameterLocals();
    2211             :     }
    2212     2735288 :     AsDeclarationScope()->AllocateReceiver();
    2213             :   }
    2214     3234089 :   AllocateNonParameterLocalsAndDeclaredGlobals();
    2215             : 
    2216             :   // Force allocation of a context for this scope if necessary. For a 'with'
    2217             :   // scope and for a function scope that makes an 'eval' call we need a context,
    2218             :   // even if no local variables were statically allocated in the scope.
    2219             :   // Likewise for modules and function scopes representing asm.js modules.
    2220             :   // Also force a context, if the scope is stricter than the outer scope.
    2221             :   bool must_have_context =
    2222     9567134 :       is_with_scope() || is_module_scope() || IsAsmModule() ||
    2223     3137226 :       ForceContextForLanguageMode() ||
    2224     4848583 :       (is_function_scope() && AsDeclarationScope()->calls_sloppy_eval()) ||
    2225      365415 :       (is_block_scope() && is_declaration_scope() &&
    2226             :        AsDeclarationScope()->calls_sloppy_eval());
    2227             : 
    2228             :   // If we didn't allocate any locals in the local context, then we only
    2229             :   // need the minimal number of slots if we must have a context.
    2230     3234069 :   if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && !must_have_context) {
    2231     2789095 :     num_heap_slots_ = 0;
    2232             :   }
    2233             : 
    2234             :   // Allocation done.
    2235             :   DCHECK(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS);
    2236             : }
    2237             : 
    2238     2415046 : void Scope::AllocateScopeInfosRecursively(Isolate* isolate,
    2239     1263369 :                                           MaybeHandle<ScopeInfo> outer_scope) {
    2240             :   DCHECK(scope_info_.is_null());
    2241     2415046 :   MaybeHandle<ScopeInfo> next_outer_scope = outer_scope;
    2242             : 
    2243     2415046 :   if (NeedsScopeInfo()) {
    2244     1263369 :     scope_info_ = ScopeInfo::Create(isolate, zone(), this, outer_scope);
    2245             :     // The ScopeInfo chain should mirror the context chain, so we only link to
    2246             :     // the next outer scope that needs a context.
    2247     1263382 :     if (NeedsContext()) next_outer_scope = scope_info_;
    2248             :   }
    2249             : 
    2250             :   // Allocate ScopeInfos for inner scopes.
    2251     5318907 :   for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
    2252     5482737 :     if (!scope->is_function_scope() ||
    2253             :         scope->AsDeclarationScope()->ShouldEagerCompile()) {
    2254      839195 :       scope->AllocateScopeInfosRecursively(isolate, next_outer_scope);
    2255             :     }
    2256             :   }
    2257     2415076 : }
    2258             : 
    2259             : // static
    2260     3151752 : void DeclarationScope::AllocateScopeInfos(ParseInfo* info, Isolate* isolate) {
    2261     1575864 :   DeclarationScope* scope = info->literal()->scope();
    2262     1575864 :   if (!scope->scope_info_.is_null()) return;  // Allocated by outer function.
    2263             : 
    2264     1575864 :   MaybeHandle<ScopeInfo> outer_scope;
    2265     1575864 :   if (scope->outer_scope_ != nullptr) {
    2266     1420126 :     outer_scope = scope->outer_scope_->scope_info_;
    2267             :   }
    2268             : 
    2269     2527506 :   scope->AllocateScopeInfosRecursively(isolate, outer_scope);
    2270             : 
    2271             :   // The debugger expects all shared function infos to contain a scope info.
    2272             :   // Since the top-most scope will end up in a shared function info, make sure
    2273             :   // it has one, even if it doesn't need a scope info.
    2274             :   // TODO(jochen|yangguo): Remove this requirement.
    2275     1575885 :   if (scope->scope_info_.is_null()) {
    2276             :     scope->scope_info_ =
    2277      951642 :         ScopeInfo::Create(isolate, scope->zone(), scope, outer_scope);
    2278             :   }
    2279             : 
    2280             :   // Ensuring that the outer script scope has a scope info avoids having
    2281             :   // special case for native contexts vs other contexts.
    2282     3151779 :   if (info->script_scope() && info->script_scope()->scope_info_.is_null()) {
    2283             :     info->script_scope()->scope_info_ =
    2284     1069768 :         handle(ScopeInfo::Empty(isolate), isolate);
    2285             :   }
    2286             : }
    2287             : 
    2288         145 : int Scope::ContextLocalCount() const {
    2289          90 :   if (num_heap_slots() == 0) return 0;
    2290             :   Variable* function =
    2291          55 :       is_function_scope() ? AsDeclarationScope()->function_var() : nullptr;
    2292             :   bool is_function_var_in_context =
    2293          55 :       function != nullptr && function->IsContextSlot();
    2294          55 :   return num_heap_slots() - Context::MIN_CONTEXT_SLOTS -
    2295          55 :          (is_function_var_in_context ? 1 : 0);
    2296             : }
    2297             : 
    2298             : }  // namespace internal
    2299      183867 : }  // namespace v8

Generated by: LCOV version 1.10