LCOV - code coverage report
Current view: top level - src/ast - scopes.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 716 766 93.5 %
Date: 2017-10-20 Functions: 90 108 83.3 %

          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/messages.h"
      15             : #include "src/objects-inl.h"
      16             : #include "src/objects/module.h"
      17             : #include "src/objects/scope-info.h"
      18             : #include "src/parsing/parse-info.h"
      19             : #include "src/parsing/preparsed-scope-data.h"
      20             : 
      21             : namespace v8 {
      22             : namespace internal {
      23             : 
      24             : namespace {
      25             : void* kDummyPreParserVariable = reinterpret_cast<void*>(0x1);
      26             : void* kDummyPreParserLexicalVariable = reinterpret_cast<void*>(0x2);
      27             : 
      28        4180 : bool IsLexical(Variable* variable) {
      29        4180 :   if (variable == kDummyPreParserLexicalVariable) return true;
      30        4180 :   if (variable == kDummyPreParserVariable) return false;
      31             :   return IsLexicalVariableMode(variable->mode());
      32             : }
      33             : 
      34             : }  // namespace
      35             : 
      36             : // ----------------------------------------------------------------------------
      37             : // Implementation of LocalsMap
      38             : //
      39             : // Note: We are storing the handle locations as key values in the hash map.
      40             : //       When inserting a new variable via Declare(), we rely on the fact that
      41             : //       the handle location remains alive for the duration of that variable
      42             : //       use. Because a Variable holding a handle with the same location exists
      43             : //       this is ensured.
      44             : 
      45           0 : VariableMap::VariableMap(Zone* zone)
      46           0 :     : ZoneHashMap(8, ZoneAllocationPolicy(zone)) {}
      47             : 
      48    46900384 : Variable* VariableMap::Declare(Zone* zone, Scope* scope,
      49    46900384 :                                const AstRawString* name, VariableMode mode,
      50             :                                VariableKind kind,
      51             :                                InitializationFlag initialization_flag,
      52             :                                MaybeAssignedFlag maybe_assigned_flag,
      53             :                                bool* added) {
      54             :   // AstRawStrings are unambiguous, i.e., the same string is always represented
      55             :   // by the same AstRawString*.
      56             :   // FIXME(marja): fix the type of Lookup.
      57             :   Entry* p =
      58             :       ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->Hash(),
      59    93800780 :                                   ZoneAllocationPolicy(zone));
      60    46900396 :   if (added) *added = p->value == nullptr;
      61    46900396 :   if (p->value == nullptr) {
      62             :     // The variable has not been declared yet -> insert it.
      63             :     DCHECK_EQ(name, p->key);
      64             :     p->value = new (zone) Variable(scope, name, mode, kind, initialization_flag,
      65    46886967 :                                    maybe_assigned_flag);
      66             :   }
      67    46900372 :   return reinterpret_cast<Variable*>(p->value);
      68             : }
      69             : 
      70           0 : Variable* VariableMap::DeclareName(Zone* zone, const AstRawString* name,
      71             :                                    VariableMode mode) {
      72             :   Entry* p =
      73             :       ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->Hash(),
      74           0 :                                   ZoneAllocationPolicy(zone));
      75           0 :   if (p->value == nullptr) {
      76             :     // The variable has not been declared yet -> insert it.
      77             :     DCHECK_EQ(name, p->key);
      78             :     p->value =
      79           0 :         mode == VAR ? kDummyPreParserVariable : kDummyPreParserLexicalVariable;
      80             :   }
      81           0 :   return reinterpret_cast<Variable*>(p->value);
      82             : }
      83             : 
      84          20 : void VariableMap::Remove(Variable* var) {
      85          20 :   const AstRawString* name = var->raw_name();
      86          20 :   ZoneHashMap::Remove(const_cast<AstRawString*>(name), name->Hash());
      87           0 : }
      88             : 
      89      677250 : void VariableMap::Add(Zone* zone, Variable* var) {
      90      677250 :   const AstRawString* name = var->raw_name();
      91             :   Entry* p =
      92             :       ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->Hash(),
      93     1354501 :                                   ZoneAllocationPolicy(zone));
      94             :   DCHECK_NULL(p->value);
      95             :   DCHECK_EQ(name, p->key);
      96      677251 :   p->value = var;
      97      677251 : }
      98             : 
      99   114897349 : Variable* VariableMap::Lookup(const AstRawString* name) {
     100   114897349 :   Entry* p = ZoneHashMap::Lookup(const_cast<AstRawString*>(name), name->Hash());
     101   114897375 :   if (p != nullptr) {
     102             :     DCHECK(reinterpret_cast<const AstRawString*>(p->key) == name);
     103             :     DCHECK_NOT_NULL(p->value);
     104    68065834 :     return reinterpret_cast<Variable*>(p->value);
     105             :   }
     106             :   return nullptr;
     107             : }
     108             : 
     109           0 : void SloppyBlockFunctionMap::Delegate::set_statement(Statement* statement) {
     110        6678 :   if (statement_ != nullptr) {
     111             :     statement_->set_statement(statement);
     112             :   }
     113           0 : }
     114             : 
     115           0 : SloppyBlockFunctionMap::SloppyBlockFunctionMap(Zone* zone)
     116        9314 :     : ZoneHashMap(8, ZoneAllocationPolicy(zone)), count_(0) {}
     117             : 
     118       20934 : void SloppyBlockFunctionMap::Declare(Zone* zone, const AstRawString* name,
     119             :                                      Scope* scope,
     120             :                                      SloppyBlockFunctionStatement* statement) {
     121       10467 :   auto* delegate = new (zone) Delegate(scope, statement, count_++);
     122             :   // AstRawStrings are unambiguous, i.e., the same string is always represented
     123             :   // by the same AstRawString*.
     124             :   Entry* p =
     125             :       ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->Hash(),
     126       20934 :                                   ZoneAllocationPolicy(zone));
     127       10467 :   delegate->set_next(static_cast<SloppyBlockFunctionMap::Delegate*>(p->value));
     128       10467 :   p->value = delegate;
     129       10467 : }
     130             : 
     131             : // ----------------------------------------------------------------------------
     132             : // Implementation of Scope
     133             : 
     134     3697312 : Scope::Scope(Zone* zone)
     135             :     : zone_(zone),
     136             :       outer_scope_(nullptr),
     137             :       variables_(zone),
     138     7394620 :       scope_type_(SCRIPT_SCOPE) {
     139             :   SetDefaults();
     140     3697308 : }
     141             : 
     142    14964174 : Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type)
     143             :     : zone_(zone),
     144             :       outer_scope_(outer_scope),
     145             :       variables_(zone),
     146    29928327 :       scope_type_(scope_type) {
     147             :   DCHECK_NE(SCRIPT_SCOPE, scope_type);
     148             :   SetDefaults();
     149             :   set_language_mode(outer_scope->language_mode());
     150             :   force_context_allocation_ =
     151    23275120 :       !is_function_scope() && outer_scope->has_forced_context_allocation();
     152    14964153 :   outer_scope_->AddInnerScope(this);
     153    14964153 : }
     154             : 
     155    97472919 : Scope::Snapshot::Snapshot(Scope* scope)
     156             :     : outer_scope_(scope),
     157             :       top_inner_scope_(scope->inner_scope_),
     158             :       top_unresolved_(scope->unresolved_),
     159    97472919 :       top_local_(scope->GetClosureScope()->locals_.end()),
     160    97472919 :       top_decl_(scope->GetClosureScope()->decls_.end()),
     161   292418757 :       outer_scope_calls_eval_(scope->scope_calls_eval_) {
     162             :   // Reset in order to record eval calls during this Snapshot's lifetime.
     163    97472919 :   outer_scope_->scope_calls_eval_ = false;
     164    97472919 : }
     165             : 
     166    97472860 : Scope::Snapshot::~Snapshot() {
     167             :   // Restore previous calls_eval bit if needed.
     168    97472860 :   if (outer_scope_calls_eval_) {
     169      244150 :     outer_scope_->scope_calls_eval_ = true;
     170             :   }
     171    97472860 : }
     172             : 
     173     3697312 : DeclarationScope::DeclarationScope(Zone* zone,
     174     3697311 :                                    AstValueFactory* ast_value_factory)
     175     3697312 :     : Scope(zone), function_kind_(kNormalFunction), params_(4, zone) {
     176             :   DCHECK_EQ(scope_type_, SCRIPT_SCOPE);
     177             :   SetDefaults();
     178             : 
     179             :   // Make sure that if we don't find the global 'this', it won't be declared as
     180             :   // a regular dynamic global by predeclaring it with the right variable kind.
     181     3697311 :   DeclareDynamicGlobal(ast_value_factory->this_string(), THIS_VARIABLE);
     182     3697311 : }
     183             : 
     184     7801850 : DeclarationScope::DeclarationScope(Zone* zone, Scope* outer_scope,
     185             :                                    ScopeType scope_type,
     186             :                                    FunctionKind function_kind)
     187             :     : Scope(zone, outer_scope, scope_type),
     188             :       function_kind_(function_kind),
     189     7801850 :       params_(4, zone) {
     190             :   DCHECK_NE(scope_type, SCRIPT_SCOPE);
     191             :   SetDefaults();
     192     7801851 : }
     193             : 
     194       46326 : ModuleScope::ModuleScope(DeclarationScope* script_scope,
     195       92652 :                          AstValueFactory* ast_value_factory)
     196             :     : DeclarationScope(ast_value_factory->zone(), script_scope, MODULE_SCOPE,
     197       46326 :                        kModule) {
     198             :   Zone* zone = ast_value_factory->zone();
     199       46326 :   module_descriptor_ = new (zone) ModuleDescriptor(zone);
     200             :   set_language_mode(LanguageMode::kStrict);
     201       46326 :   DeclareThis(ast_value_factory);
     202       46326 : }
     203             : 
     204        6149 : ModuleScope::ModuleScope(Handle<ScopeInfo> scope_info,
     205       12298 :                          AstValueFactory* avfactory)
     206        6149 :     : DeclarationScope(avfactory->zone(), MODULE_SCOPE, scope_info) {
     207             :   Zone* zone = avfactory->zone();
     208             :   Isolate* isolate = scope_info->GetIsolate();
     209        6149 :   Handle<ModuleInfo> module_info(scope_info->ModuleDescriptorInfo(), isolate);
     210             : 
     211             :   set_language_mode(LanguageMode::kStrict);
     212        6149 :   module_descriptor_ = new (zone) ModuleDescriptor(zone);
     213             : 
     214             :   // Deserialize special exports.
     215             :   Handle<FixedArray> special_exports(module_info->special_exports(), isolate);
     216        6149 :   for (int i = 0, n = special_exports->length(); i < n; ++i) {
     217             :     Handle<ModuleInfoEntry> serialized_entry(
     218             :         ModuleInfoEntry::cast(special_exports->get(i)), isolate);
     219             :     module_descriptor_->AddSpecialExport(
     220             :         ModuleDescriptor::Entry::Deserialize(isolate, avfactory,
     221           0 :                                              serialized_entry),
     222           0 :         avfactory->zone());
     223             :   }
     224             : 
     225             :   // Deserialize regular exports.
     226             :   module_descriptor_->DeserializeRegularExports(isolate, avfactory,
     227        6149 :                                                 module_info);
     228             : 
     229             :   // Deserialize namespace imports.
     230             :   Handle<FixedArray> namespace_imports(module_info->namespace_imports(),
     231             :                                        isolate);
     232        6369 :   for (int i = 0, n = namespace_imports->length(); i < n; ++i) {
     233             :     Handle<ModuleInfoEntry> serialized_entry(
     234             :         ModuleInfoEntry::cast(namespace_imports->get(i)), isolate);
     235             :     module_descriptor_->AddNamespaceImport(
     236             :         ModuleDescriptor::Entry::Deserialize(isolate, avfactory,
     237         220 :                                              serialized_entry),
     238         220 :         avfactory->zone());
     239             :   }
     240             : 
     241             :   // Deserialize regular imports.
     242             :   Handle<FixedArray> regular_imports(module_info->regular_imports(), isolate);
     243       11243 :   for (int i = 0, n = regular_imports->length(); i < n; ++i) {
     244             :     Handle<ModuleInfoEntry> serialized_entry(
     245             :         ModuleInfoEntry::cast(regular_imports->get(i)), isolate);
     246             :     module_descriptor_->AddRegularImport(ModuleDescriptor::Entry::Deserialize(
     247        5094 :         isolate, avfactory, serialized_entry));
     248             :   }
     249        6149 : }
     250             : 
     251     1844851 : Scope::Scope(Zone* zone, ScopeType scope_type, Handle<ScopeInfo> scope_info)
     252             :     : zone_(zone),
     253             :       outer_scope_(nullptr),
     254             :       variables_(zone),
     255             :       scope_info_(scope_info),
     256     3689702 :       scope_type_(scope_type) {
     257             :   DCHECK(!scope_info.is_null());
     258             :   SetDefaults();
     259             : #ifdef DEBUG
     260             :   already_resolved_ = true;
     261             : #endif
     262     1844851 :   if (scope_info->CallsSloppyEval()) scope_calls_eval_ = true;
     263     1844852 :   set_language_mode(scope_info->language_mode());
     264     1844852 :   num_heap_slots_ = scope_info->ContextLength();
     265             :   DCHECK_LE(Context::MIN_CONTEXT_SLOTS, num_heap_slots_);
     266             :   // We don't really need to use the preparsed scope data; this is just to
     267             :   // shorten the recursion in SetMustUsePreParsedScopeData.
     268     1844852 :   must_use_preparsed_scope_data_ = true;
     269     1844852 : }
     270             : 
     271     1740271 : DeclarationScope::DeclarationScope(Zone* zone, ScopeType scope_type,
     272             :                                    Handle<ScopeInfo> scope_info)
     273             :     : Scope(zone, scope_type, scope_info),
     274     1740272 :       function_kind_(scope_info->function_kind()),
     275     3480543 :       params_(0, zone) {
     276             :   DCHECK_NE(scope_type, SCRIPT_SCOPE);
     277             :   SetDefaults();
     278     1740272 : }
     279             : 
     280        3011 : Scope::Scope(Zone* zone, const AstRawString* catch_variable_name,
     281             :              MaybeAssignedFlag maybe_assigned, Handle<ScopeInfo> scope_info)
     282             :     : zone_(zone),
     283             :       outer_scope_(nullptr),
     284             :       variables_(zone),
     285             :       scope_info_(scope_info),
     286        6022 :       scope_type_(CATCH_SCOPE) {
     287             :   SetDefaults();
     288             : #ifdef DEBUG
     289             :   already_resolved_ = true;
     290             : #endif
     291             :   // Cache the catch variable, even though it's also available via the
     292             :   // scope_info, as the parser expects that a catch scope always has the catch
     293             :   // variable as first and only variable.
     294             :   Variable* variable = Declare(zone, catch_variable_name, VAR, NORMAL_VARIABLE,
     295        3011 :                                kCreatedInitialized, maybe_assigned);
     296             :   AllocateHeapSlot(variable);
     297        3011 : }
     298             : 
     299           0 : void DeclarationScope::SetDefaults() {
     300    13239434 :   is_declaration_scope_ = true;
     301    13239434 :   has_simple_parameters_ = true;
     302    13239434 :   asm_module_ = false;
     303    13239434 :   force_eager_compilation_ = false;
     304    13239434 :   has_arguments_parameter_ = false;
     305    13239434 :   scope_uses_super_property_ = false;
     306    13239434 :   has_rest_ = false;
     307    13239434 :   sloppy_block_function_map_ = nullptr;
     308    13239434 :   receiver_ = nullptr;
     309    13239434 :   new_target_ = nullptr;
     310    13239434 :   function_ = nullptr;
     311    13239434 :   arguments_ = nullptr;
     312           0 :   rare_data_ = nullptr;
     313    13239434 :   should_eager_compile_ = false;
     314    13239434 :   was_lazily_parsed_ = false;
     315    13239434 :   is_skipped_function_ = false;
     316    13239434 :   produced_preparsed_scope_data_ = nullptr;
     317             : #ifdef DEBUG
     318             :   DeclarationScope* outer_declaration_scope =
     319             :       outer_scope_ ? outer_scope_->GetDeclarationScope() : nullptr;
     320             :   is_being_lazily_parsed_ =
     321             :       outer_declaration_scope ? outer_declaration_scope->is_being_lazily_parsed_
     322             :                               : false;
     323             : #endif
     324           0 : }
     325             : 
     326           0 : void Scope::SetDefaults() {
     327             : #ifdef DEBUG
     328             :   scope_name_ = nullptr;
     329             :   already_resolved_ = false;
     330             :   needs_migration_ = false;
     331             : #endif
     332    20509323 :   inner_scope_ = nullptr;
     333    20509323 :   sibling_ = nullptr;
     334    20509323 :   unresolved_ = nullptr;
     335             : 
     336    20509323 :   start_position_ = kNoSourcePosition;
     337    20509323 :   end_position_ = kNoSourcePosition;
     338             : 
     339    20509323 :   num_stack_slots_ = 0;
     340    20509323 :   num_heap_slots_ = Context::MIN_CONTEXT_SLOTS;
     341             : 
     342             :   set_language_mode(LanguageMode::kSloppy);
     343             : 
     344    20509323 :   scope_calls_eval_ = false;
     345    20509323 :   scope_nonlinear_ = false;
     346    20509323 :   is_hidden_ = false;
     347    20509323 :   is_debug_evaluate_scope_ = false;
     348             : 
     349    20509323 :   inner_scope_calls_eval_ = false;
     350    20509323 :   force_context_allocation_ = false;
     351    20509323 :   force_context_allocation_for_parameters_ = false;
     352             : 
     353    20509323 :   is_declaration_scope_ = false;
     354             : 
     355    20509323 :   must_use_preparsed_scope_data_ = false;
     356           0 : }
     357             : 
     358      448256 : bool Scope::HasSimpleParameters() {
     359             :   DeclarationScope* scope = GetClosureScope();
     360      615311 :   return !scope->is_function_scope() || scope->has_simple_parameters();
     361             : }
     362             : 
     363     4231477 : bool DeclarationScope::ShouldEagerCompile() const {
     364    12608147 :   return force_eager_compilation_ || should_eager_compile_;
     365             : }
     366             : 
     367      741926 : void DeclarationScope::set_should_eager_compile() {
     368     2502758 :   should_eager_compile_ = !was_lazily_parsed_;
     369      741926 : }
     370             : 
     371        5506 : void DeclarationScope::set_asm_module() {
     372        8643 :   asm_module_ = true;
     373        5506 : }
     374             : 
     375     4512317 : bool Scope::IsAsmModule() const {
     376    14958610 :   return is_function_scope() && AsDeclarationScope()->asm_module();
     377             : }
     378             : 
     379     2719264 : bool Scope::ContainsAsmModule() const {
     380     2719264 :   if (IsAsmModule()) return true;
     381             : 
     382             :   // Check inner scopes recursively
     383     7180269 :   for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
     384             :     // Don't check inner functions which won't be eagerly compiled.
     385     8426158 :     if (!scope->is_function_scope() ||
     386             :         scope->AsDeclarationScope()->ShouldEagerCompile()) {
     387     1023451 :       if (scope->ContainsAsmModule()) return true;
     388             :     }
     389             :   }
     390             : 
     391             :   return false;
     392             : }
     393             : 
     394     1923151 : Scope* Scope::DeserializeScopeChain(Zone* zone, ScopeInfo* scope_info,
     395             :                                     DeclarationScope* script_scope,
     396             :                                     AstValueFactory* ast_value_factory,
     397             :                                     DeserializationMode deserialization_mode) {
     398             :   // Reconstruct the outer scope chain from a closure's context chain.
     399             :   Scope* current_scope = nullptr;
     400             :   Scope* innermost_scope = nullptr;
     401             :   Scope* outer_scope = nullptr;
     402     5694165 :   while (scope_info) {
     403     2405311 :     if (scope_info->scope_type() == WITH_SCOPE) {
     404             :       // For scope analysis, debug-evaluate is equivalent to a with scope.
     405       51200 :       outer_scope = new (zone) Scope(zone, WITH_SCOPE, handle(scope_info));
     406             : 
     407             :       // TODO(yangguo): Remove once debug-evaluate properly keeps track of the
     408             :       // function scope in which we are evaluating.
     409       25600 :       if (scope_info->IsDebugEvaluateScope()) {
     410             :         outer_scope->set_is_debug_evaluate_scope();
     411             :       }
     412     2379711 :     } else if (scope_info->scope_type() == SCRIPT_SCOPE) {
     413             :       // If we reach a script scope, it's the outermost scope. Install the
     414             :       // scope info of this script context onto the existing script scope to
     415             :       // avoid nesting script scopes.
     416      557448 :       if (deserialization_mode == DeserializationMode::kIncludingVariables) {
     417             :         script_scope->SetScriptScopeInfo(handle(scope_info));
     418             :       }
     419             :       DCHECK(!scope_info->HasOuterScopeInfo());
     420             :       break;
     421     1822263 :     } else if (scope_info->scope_type() == FUNCTION_SCOPE) {
     422             :       outer_scope =
     423     3428185 :           new (zone) DeclarationScope(zone, FUNCTION_SCOPE, handle(scope_info));
     424     1714093 :       if (scope_info->IsAsmModule())
     425             :         outer_scope->AsDeclarationScope()->set_asm_module();
     426      108170 :     } else if (scope_info->scope_type() == EVAL_SCOPE) {
     427             :       outer_scope =
     428       12892 :           new (zone) DeclarationScope(zone, EVAL_SCOPE, handle(scope_info));
     429      101724 :     } else if (scope_info->scope_type() == BLOCK_SCOPE) {
     430       92564 :       if (scope_info->is_declaration_scope()) {
     431             :         outer_scope =
     432       27168 :             new (zone) DeclarationScope(zone, BLOCK_SCOPE, handle(scope_info));
     433             :       } else {
     434      157960 :         outer_scope = new (zone) Scope(zone, BLOCK_SCOPE, handle(scope_info));
     435             :       }
     436        9160 :     } else if (scope_info->scope_type() == MODULE_SCOPE) {
     437             :       outer_scope =
     438       12298 :           new (zone) ModuleScope(handle(scope_info), ast_value_factory);
     439             :     } else {
     440             :       DCHECK_EQ(scope_info->scope_type(), CATCH_SCOPE);
     441             :       DCHECK_EQ(scope_info->LocalCount(), 1);
     442             :       DCHECK_EQ(scope_info->ContextLocalCount(), 1);
     443             :       DCHECK_EQ(scope_info->ContextLocalMode(0), VAR);
     444             :       DCHECK_EQ(scope_info->ContextLocalInitFlag(0), kCreatedInitialized);
     445        3011 :       String* name = scope_info->ContextLocalName(0);
     446             :       MaybeAssignedFlag maybe_assigned =
     447        3011 :           scope_info->ContextLocalMaybeAssignedFlag(0);
     448             :       outer_scope =
     449             :           new (zone) Scope(zone, ast_value_factory->GetString(handle(name)),
     450        9033 :                            maybe_assigned, handle(scope_info));
     451             :     }
     452     1847863 :     if (deserialization_mode == DeserializationMode::kScopesOnly) {
     453      991649 :       outer_scope->scope_info_ = Handle<ScopeInfo>::null();
     454             :     }
     455     1847863 :     if (current_scope != nullptr) {
     456             :       outer_scope->AddInnerScope(current_scope);
     457             :     }
     458             :     current_scope = outer_scope;
     459     1847863 :     if (innermost_scope == nullptr) innermost_scope = current_scope;
     460     1847863 :     scope_info = scope_info->HasOuterScopeInfo() ? scope_info->OuterScopeInfo()
     461     1847863 :                                                  : nullptr;
     462             :   }
     463             : 
     464     1923151 :   if (innermost_scope == nullptr) return script_scope;
     465     1576743 :   script_scope->AddInnerScope(current_scope);
     466     1576743 :   return innermost_scope;
     467             : }
     468             : 
     469   103031159 : DeclarationScope* Scope::AsDeclarationScope() {
     470             :   DCHECK(is_declaration_scope());
     471   103031159 :   return static_cast<DeclarationScope*>(this);
     472             : }
     473             : 
     474           0 : const DeclarationScope* Scope::AsDeclarationScope() const {
     475             :   DCHECK(is_declaration_scope());
     476           0 :   return static_cast<const DeclarationScope*>(this);
     477             : }
     478             : 
     479       47016 : ModuleScope* Scope::AsModuleScope() {
     480             :   DCHECK(is_module_scope());
     481       47016 :   return static_cast<ModuleScope*>(this);
     482             : }
     483             : 
     484           0 : const ModuleScope* Scope::AsModuleScope() const {
     485             :   DCHECK(is_module_scope());
     486           0 :   return static_cast<const ModuleScope*>(this);
     487             : }
     488             : 
     489     2519761 : int Scope::num_parameters() const {
     490     5039522 :   return is_declaration_scope() ? AsDeclarationScope()->num_parameters() : 0;
     491             : }
     492             : 
     493       10467 : void DeclarationScope::DeclareSloppyBlockFunction(
     494             :     const AstRawString* name, Scope* scope,
     495             :     SloppyBlockFunctionStatement* statement) {
     496       10467 :   if (sloppy_block_function_map_ == nullptr) {
     497             :     sloppy_block_function_map_ =
     498             :         new (zone()->New(sizeof(SloppyBlockFunctionMap)))
     499       18628 :             SloppyBlockFunctionMap(zone());
     500             :   }
     501       10467 :   sloppy_block_function_map_->Declare(zone(), name, scope, statement);
     502       10467 : }
     503             : 
     504     4241450 : void DeclarationScope::HoistSloppyBlockFunctions(AstNodeFactory* factory) {
     505             :   DCHECK(is_sloppy(language_mode()));
     506             :   DCHECK(is_function_scope() || is_eval_scope() || is_script_scope() ||
     507             :          (is_block_scope() && outer_scope()->is_function_scope()));
     508             :   DCHECK(HasSimpleParameters() || is_block_scope() || is_being_lazily_parsed_);
     509             :   DCHECK_EQ(factory == nullptr, is_being_lazily_parsed_);
     510             : 
     511             :   SloppyBlockFunctionMap* map = sloppy_block_function_map();
     512     8436372 :   if (map == nullptr) return;
     513             : 
     514        8973 :   const bool has_simple_parameters = HasSimpleParameters();
     515             : 
     516             :   // The declarations need to be added in the order they were seen,
     517             :   // so accumulate declared names sorted by index.
     518             :   ZoneMap<int, const AstRawString*> names_to_declare(zone());
     519             : 
     520             :   // For each variable which is used as a function declaration in a sloppy
     521             :   // block,
     522       27725 :   for (ZoneHashMap::Entry* p = map->Start(); p != nullptr; p = map->Next(p)) {
     523        9779 :     const AstRawString* name = static_cast<AstRawString*>(p->key);
     524             : 
     525             :     // If the variable wouldn't conflict with a lexical declaration
     526             :     // or parameter,
     527             : 
     528             :     // Check if there's a conflict with a parameter.
     529             :     // This depends on the fact that functions always have a scope solely to
     530             :     // hold complex parameters, and the names local to that scope are
     531             :     // precisely the names of the parameters. IsDeclaredParameter(name) does
     532             :     // not hold for names declared by complex parameters, nor are those
     533             :     // bindings necessarily declared lexically, so we have to check for them
     534             :     // explicitly. On the other hand, if there are not complex parameters,
     535             :     // it is sufficient to just check IsDeclaredParameter.
     536        9779 :     if (!has_simple_parameters) {
     537         143 :       if (outer_scope_->LookupLocal(name) != nullptr) {
     538             :         continue;
     539             :       }
     540             :     } else {
     541        9636 :       if (IsDeclaredParameter(name)) {
     542             :         continue;
     543             :       }
     544             :     }
     545             : 
     546             :     bool declaration_queued = false;
     547             : 
     548             :     // Write in assignments to var for each block-scoped function declaration
     549        9613 :     auto delegates = static_cast<SloppyBlockFunctionMap::Delegate*>(p->value);
     550             : 
     551             :     DeclarationScope* decl_scope = this;
     552       20584 :     while (decl_scope->is_eval_scope()) {
     553       21942 :       decl_scope = decl_scope->outer_scope()->GetDeclarationScope();
     554             :     }
     555             :     Scope* outer_scope = decl_scope->outer_scope();
     556             : 
     557       34476 :     for (SloppyBlockFunctionMap::Delegate* delegate = delegates;
     558             :          delegate != nullptr; delegate = delegate->next()) {
     559             :       // Check if there's a conflict with a lexical declaration
     560       23088 :       Scope* query_scope = delegate->scope()->outer_scope();
     561             :       Variable* var = nullptr;
     562             :       bool should_hoist = true;
     563             : 
     564             :       // Note that we perform this loop for each delegate named 'name',
     565             :       // which may duplicate work if those delegates share scopes.
     566             :       // It is not sufficient to just do a Lookup on query_scope: for
     567             :       // example, that does not prevent hoisting of the function in
     568             :       // `{ let e; try {} catch (e) { function e(){} } }`
     569       13128 :       do {
     570       14527 :         var = query_scope->LookupLocal(name);
     571       16739 :         if (var != nullptr && IsLexical(var)) {
     572             :           should_hoist = false;
     573             :           break;
     574             :         }
     575             :         query_scope = query_scope->outer_scope();
     576             :       } while (query_scope != outer_scope);
     577             : 
     578        9960 :       if (!should_hoist) continue;
     579             : 
     580        8561 :       if (!declaration_queued) {
     581             :         declaration_queued = true;
     582        8225 :         names_to_declare.insert({delegate->index(), name});
     583             :       }
     584             : 
     585        8561 :       if (factory) {
     586             :         DCHECK(!is_being_lazily_parsed_);
     587             :         Assignment* assignment = factory->NewAssignment(
     588             :             Token::ASSIGN, NewUnresolved(factory, name),
     589        6678 :             delegate->scope()->NewUnresolved(factory, name), kNoSourcePosition);
     590             :         assignment->set_lookup_hoisting_mode(LookupHoistingMode::kLegacySloppy);
     591             :         Statement* statement =
     592             :             factory->NewExpressionStatement(assignment, kNoSourcePosition);
     593             :         delegate->set_statement(statement);
     594             :       }
     595             :     }
     596             :   }
     597             : 
     598        8973 :   if (names_to_declare.empty()) return;
     599             : 
     600       23073 :   for (const auto& index_and_name : names_to_declare) {
     601        8225 :     const AstRawString* name = index_and_name.second;
     602        8225 :     if (factory) {
     603             :       DCHECK(!is_being_lazily_parsed_);
     604        6437 :       VariableProxy* proxy = factory->NewVariableProxy(name, NORMAL_VARIABLE);
     605             :       auto declaration =
     606             :           factory->NewVariableDeclaration(proxy, kNoSourcePosition);
     607             :       // Based on the preceding checks, it doesn't matter what we pass as
     608             :       // allow_harmony_restrictive_generators and
     609             :       // sloppy_mode_block_scope_function_redefinition.
     610        6437 :       bool ok = true;
     611             :       DeclareVariable(declaration, VAR,
     612             :                       Variable::DefaultInitializationFlag(VAR), false, nullptr,
     613        6437 :                       &ok);
     614             :       DCHECK(ok);
     615             :     } else {
     616             :       DCHECK(is_being_lazily_parsed_);
     617        1788 :       Variable* var = DeclareVariableName(name, VAR);
     618        3576 :       if (var != kDummyPreParserVariable &&
     619        1788 :           var != kDummyPreParserLexicalVariable) {
     620             :         DCHECK(FLAG_preparser_scope_analysis);
     621             :         var->set_maybe_assigned();
     622             :       }
     623             :     }
     624             :   }
     625             : }
     626             : 
     627     2030522 : void DeclarationScope::AttachOuterScopeInfo(ParseInfo* info, Isolate* isolate) {
     628             :   DCHECK(scope_info_.is_null());
     629             :   Handle<ScopeInfo> outer_scope_info;
     630     2030522 :   if (info->maybe_outer_scope_info().ToHandle(&outer_scope_info)) {
     631             :     // If we have a scope info we will potentially need to lookup variable names
     632             :     // on the scope info as internalized strings, so make sure ast_value_factory
     633             :     // is internalized.
     634      912768 :     info->ast_value_factory()->Internalize(isolate);
     635      912768 :     if (outer_scope()) {
     636             :       DeclarationScope* script_scope = new (info->zone())
     637      912768 :           DeclarationScope(info->zone(), info->ast_value_factory());
     638             :       info->set_script_scope(script_scope);
     639             :       ReplaceOuterScope(Scope::DeserializeScopeChain(
     640             :           info->zone(), *outer_scope_info, script_scope,
     641             :           info->ast_value_factory(),
     642      912768 :           Scope::DeserializationMode::kIncludingVariables));
     643             :     } else {
     644             :       DCHECK_EQ(outer_scope_info->scope_type(), SCRIPT_SCOPE);
     645             :       SetScriptScopeInfo(outer_scope_info);
     646             :     }
     647             :   }
     648     2030522 : }
     649             : 
     650     3521665 : void DeclarationScope::Analyze(ParseInfo* info) {
     651             :   RuntimeCallTimerScope runtimeTimer(info->runtime_call_stats(),
     652     1760833 :                                      &RuntimeCallStats::CompileScopeAnalysis);
     653             :   DCHECK_NOT_NULL(info->literal());
     654     1760832 :   DeclarationScope* scope = info->literal()->scope();
     655             : 
     656             :   base::Optional<AllowHandleDereference> allow_deref;
     657             :   if (!info->maybe_outer_scope_info().is_null()) {
     658             :     // Allow dereferences to the scope info if there is one.
     659             :     allow_deref.emplace();
     660             :   }
     661             : 
     662     2632063 :   if (scope->is_eval_scope() && is_sloppy(scope->language_mode())) {
     663             :     AstNodeFactory factory(info->ast_value_factory(), info->zone());
     664      745426 :     scope->HoistSloppyBlockFunctions(&factory);
     665             :   }
     666             : 
     667             :   // We are compiling one of four cases:
     668             :   // 1) top-level code,
     669             :   // 2) a function/eval/module on the top-level
     670             :   // 3) a function/eval in a scope that was already resolved.
     671             :   DCHECK(scope->scope_type() == SCRIPT_SCOPE ||
     672             :          scope->outer_scope()->scope_type() == SCRIPT_SCOPE ||
     673             :          scope->outer_scope()->already_resolved_);
     674             : 
     675             :   // The outer scope is never lazy.
     676             :   scope->set_should_eager_compile();
     677             : 
     678     1760832 :   if (scope->must_use_preparsed_scope_data_) {
     679             :     DCHECK(FLAG_preparser_scope_analysis);
     680             :     DCHECK_EQ(scope->scope_type_, ScopeType::FUNCTION_SCOPE);
     681             :     allow_deref.emplace();
     682       19142 :     info->consumed_preparsed_scope_data()->RestoreScopeAllocationData(scope);
     683             :   }
     684             : 
     685     1760832 :   scope->AllocateVariables(info);
     686             : 
     687             : #ifdef DEBUG
     688             :   if (info->is_native() ? FLAG_print_builtin_scopes : FLAG_print_scopes) {
     689             :     PrintF("Global scope:\n");
     690             :     scope->Print();
     691             :   }
     692             :   scope->CheckScopePositions();
     693             :   scope->CheckZones();
     694             : #endif
     695     1760832 : }
     696             : 
     697    11574474 : void DeclarationScope::DeclareThis(AstValueFactory* ast_value_factory) {
     698             :   DCHECK(!already_resolved_);
     699             :   DCHECK(is_declaration_scope());
     700             :   DCHECK(has_this_declaration());
     701             : 
     702     5787237 :   bool derived_constructor = IsDerivedConstructor(function_kind_);
     703             :   Variable* var =
     704             :       Declare(zone(), ast_value_factory->this_string(),
     705             :               derived_constructor ? CONST : VAR, THIS_VARIABLE,
     706    11574474 :               derived_constructor ? kNeedsInitialization : kCreatedInitialized);
     707     5787240 :   receiver_ = var;
     708     5787240 : }
     709             : 
     710    10805763 : void DeclarationScope::DeclareArguments(AstValueFactory* ast_value_factory) {
     711             :   DCHECK(is_function_scope());
     712             :   DCHECK(!is_arrow_scope());
     713             : 
     714    10805763 :   arguments_ = LookupLocal(ast_value_factory->arguments_string());
     715     5403866 :   if (arguments_ == nullptr) {
     716             :     // Declare 'arguments' variable which exists in all non arrow functions.
     717             :     // Note that it might never be accessed, in which case it won't be
     718             :     // allocated during variable allocation.
     719     5401898 :     arguments_ = Declare(zone(), ast_value_factory->arguments_string(), VAR);
     720        1968 :   } else if (IsLexical(arguments_)) {
     721             :     // Check if there's lexically declared variable named arguments to avoid
     722             :     // redeclaration. See ES#sec-functiondeclarationinstantiation, step 20.
     723         544 :     arguments_ = nullptr;
     724             :   }
     725     5403863 : }
     726             : 
     727     5740913 : void DeclarationScope::DeclareDefaultFunctionVariables(
     728     7334278 :     AstValueFactory* ast_value_factory) {
     729             :   DCHECK(is_function_scope());
     730             :   DCHECK(!is_arrow_scope());
     731             : 
     732     5740913 :   DeclareThis(ast_value_factory);
     733     6537596 :   new_target_ = Declare(zone(), ast_value_factory->new_target_string(), CONST);
     734             : 
     735    21664225 :   if (IsConciseMethod(function_kind_) || IsClassConstructor(function_kind_) ||
     736             :       IsAccessorFunction(function_kind_)) {
     737             :     EnsureRareData()->this_function =
     738      796682 :         Declare(zone(), ast_value_factory->this_function_string(), CONST);
     739             :   }
     740     5740914 : }
     741             : 
     742      728721 : Variable* DeclarationScope::DeclareFunctionVar(const AstRawString* name) {
     743             :   DCHECK(is_function_scope());
     744             :   DCHECK_NULL(function_);
     745             :   DCHECK_NULL(variables_.Lookup(name));
     746     1405951 :   VariableKind kind = is_sloppy(language_mode()) ? SLOPPY_FUNCTION_NAME_VARIABLE
     747      728721 :                                                  : NORMAL_VARIABLE;
     748             :   function_ =
     749     1457442 :       new (zone()) Variable(this, name, CONST, kind, kCreatedInitialized);
     750      728721 :   if (calls_sloppy_eval()) {
     751       51491 :     NonLocal(name, DYNAMIC);
     752             :   } else {
     753      677230 :     variables_.Add(zone(), function_);
     754             :   }
     755      728722 :   return function_;
     756             : }
     757             : 
     758      101636 : Variable* DeclarationScope::DeclareGeneratorObjectVar(
     759      101636 :     const AstRawString* name) {
     760             :   DCHECK(is_function_scope() || is_module_scope());
     761             :   DCHECK_NULL(generator_object_var());
     762             : 
     763             :   Variable* result = EnsureRareData()->generator_object =
     764      101636 :       NewTemporary(name, kNotAssigned);
     765             :   result->set_is_used();
     766      101636 :   return result;
     767             : }
     768             : 
     769       28512 : Variable* DeclarationScope::DeclarePromiseVar(const AstRawString* name) {
     770             :   DCHECK(is_function_scope());
     771             :   DCHECK_NULL(promise_var());
     772       57024 :   Variable* result = EnsureRareData()->promise = NewTemporary(name);
     773             :   result->set_is_used();
     774       28512 :   return result;
     775             : }
     776             : 
     777       61538 : bool Scope::HasBeenRemoved() const {
     778       61538 :   if (sibling() == this) {
     779             :     DCHECK_NULL(inner_scope_);
     780             :     DCHECK(is_block_scope());
     781             :     return true;
     782             :   }
     783           0 :   return false;
     784             : }
     785             : 
     786       60758 : Scope* Scope::GetUnremovedScope() {
     787         780 :   Scope* scope = this;
     788      183834 :   while (scope != nullptr && scope->HasBeenRemoved()) {
     789             :     scope = scope->outer_scope();
     790             :   }
     791             :   DCHECK_NOT_NULL(scope);
     792       60758 :   return scope;
     793             : }
     794             : 
     795    22174235 : Scope* Scope::FinalizeBlockScope() {
     796             :   DCHECK(is_block_scope());
     797             :   DCHECK(!HasBeenRemoved());
     798             : 
     799    17830221 :   if (variables_.occupancy() > 0 ||
     800       51965 :       (is_declaration_scope() && AsDeclarationScope()->calls_sloppy_eval())) {
     801             :     return this;
     802             :   }
     803             : 
     804             :   // Remove this scope from outer scope.
     805             :   outer_scope()->RemoveInnerScope(this);
     806             : 
     807             :   // Reparent inner scopes.
     808     5551665 :   if (inner_scope_ != nullptr) {
     809             :     Scope* scope = inner_scope_;
     810      352789 :     scope->outer_scope_ = outer_scope();
     811      763823 :     while (scope->sibling_ != nullptr) {
     812             :       scope = scope->sibling_;
     813       58245 :       scope->outer_scope_ = outer_scope();
     814             :     }
     815      352789 :     scope->sibling_ = outer_scope()->inner_scope_;
     816      352789 :     outer_scope()->inner_scope_ = inner_scope_;
     817      352789 :     inner_scope_ = nullptr;
     818             :   }
     819             : 
     820             :   // Move unresolved variables
     821     5551665 :   if (unresolved_ != nullptr) {
     822     4592035 :     if (outer_scope()->unresolved_ != nullptr) {
     823    27436255 :       VariableProxy* unresolved = unresolved_;
     824    27436255 :       while (unresolved->next_unresolved() != nullptr) {
     825             :         unresolved = unresolved->next_unresolved();
     826             :       }
     827             :       unresolved->set_next_unresolved(outer_scope()->unresolved_);
     828             :     }
     829     4592035 :     outer_scope()->unresolved_ = unresolved_;
     830     4592035 :     unresolved_ = nullptr;
     831             :   }
     832             : 
     833     5735146 :   if (inner_scope_calls_eval_) outer_scope()->inner_scope_calls_eval_ = true;
     834             : 
     835             :   // No need to propagate scope_calls_eval_, since if it was relevant to
     836             :   // this scope we would have had to bail out at the top.
     837             :   DCHECK(!scope_calls_eval_ || !is_declaration_scope() ||
     838             :          !is_sloppy(language_mode()));
     839             : 
     840             :   // This block does not need a context.
     841     5551665 :   num_heap_slots_ = 0;
     842             : 
     843             :   // Mark scope as removed by making it its own sibling.
     844     5551665 :   sibling_ = this;
     845             :   DCHECK(HasBeenRemoved());
     846             : 
     847     5551665 :   return nullptr;
     848             : }
     849             : 
     850           0 : void DeclarationScope::AddLocal(Variable* var) {
     851             :   DCHECK(!already_resolved_);
     852             :   // Temporaries are only placed in ClosureScopes.
     853             :   DCHECK_EQ(GetClosureScope(), this);
     854             :   locals_.Add(var);
     855           0 : }
     856             : 
     857    40288702 : Variable* Scope::Declare(Zone* zone, const AstRawString* name,
     858             :                          VariableMode mode, VariableKind kind,
     859             :                          InitializationFlag initialization_flag,
     860             :                          MaybeAssignedFlag maybe_assigned_flag) {
     861             :   bool added;
     862             :   Variable* var =
     863             :       variables_.Declare(zone, this, name, mode, kind, initialization_flag,
     864    40288702 :                          maybe_assigned_flag, &added);
     865    40288692 :   if (added) locals_.Add(var);
     866    40288692 :   return var;
     867             : }
     868             : 
     869      777278 : void Scope::Snapshot::Reparent(DeclarationScope* new_parent) const {
     870             :   DCHECK_EQ(new_parent, outer_scope_->inner_scope_);
     871             :   DCHECK_EQ(new_parent->outer_scope_, outer_scope_);
     872             :   DCHECK_EQ(new_parent, new_parent->GetClosureScope());
     873             :   DCHECK_NULL(new_parent->inner_scope_);
     874             :   DCHECK_NULL(new_parent->unresolved_);
     875             :   DCHECK(new_parent->locals_.is_empty());
     876      777303 :   Scope* inner_scope = new_parent->sibling_;
     877      777278 :   if (inner_scope != top_inner_scope_) {
     878        2520 :     for (; inner_scope->sibling() != top_inner_scope_;
     879             :          inner_scope = inner_scope->sibling()) {
     880          25 :       inner_scope->outer_scope_ = new_parent;
     881          25 :       if (inner_scope->inner_scope_calls_eval_) {
     882           0 :         new_parent->inner_scope_calls_eval_ = true;
     883             :       }
     884             :       DCHECK_NE(inner_scope, new_parent);
     885             :     }
     886        2495 :     inner_scope->outer_scope_ = new_parent;
     887        2495 :     if (inner_scope->inner_scope_calls_eval_) {
     888         110 :       new_parent->inner_scope_calls_eval_ = true;
     889             :     }
     890        2495 :     new_parent->inner_scope_ = new_parent->sibling_;
     891        2495 :     inner_scope->sibling_ = nullptr;
     892             :     // Reset the sibling rather than the inner_scope_ since we
     893             :     // want to keep new_parent there.
     894        2495 :     new_parent->sibling_ = top_inner_scope_;
     895             :   }
     896             : 
     897      777278 :   if (outer_scope_->unresolved_ != top_unresolved_) {
     898      388005 :     VariableProxy* last = outer_scope_->unresolved_;
     899      388005 :     while (last->next_unresolved() != top_unresolved_) {
     900             :       last = last->next_unresolved();
     901             :     }
     902             :     last->set_next_unresolved(nullptr);
     903      335867 :     new_parent->unresolved_ = outer_scope_->unresolved_;
     904      335867 :     outer_scope_->unresolved_ = top_unresolved_;
     905             :   }
     906             : 
     907             :   // TODO(verwaest): This currently only moves do-expression declared variables
     908             :   // in default arguments that weren't already previously declared with the same
     909             :   // name in the closure-scope. See
     910             :   // test/mjsunit/harmony/default-parameter-do-expression.js.
     911      777278 :   DeclarationScope* outer_closure = outer_scope_->GetClosureScope();
     912             : 
     913             :   new_parent->locals_.MoveTail(outer_closure->locals(), top_local_);
     914     1555286 :   for (Variable* local : new_parent->locals_) {
     915             :     DCHECK(local->mode() == TEMPORARY || local->mode() == VAR);
     916             :     DCHECK_EQ(local->scope(), local->scope()->GetClosureScope());
     917             :     DCHECK_NE(local->scope(), new_parent);
     918             :     local->set_scope(new_parent);
     919         365 :     if (local->mode() == VAR) {
     920             :       outer_closure->variables_.Remove(local);
     921          20 :       new_parent->variables_.Add(new_parent->zone(), local);
     922             :     }
     923             :   }
     924             :   outer_closure->locals_.Rewind(top_local_);
     925             :   outer_closure->decls_.Rewind(top_decl_);
     926             : 
     927             :   // Move eval calls since Snapshot's creation into new_parent.
     928      777278 :   if (outer_scope_->scope_calls_eval_) {
     929         410 :     new_parent->scope_calls_eval_ = true;
     930         410 :     new_parent->inner_scope_calls_eval_ = true;
     931             :   }
     932             :   // Reset the outer_scope's eval state. It will be restored to its
     933             :   // original value as necessary in the destructor of this class.
     934      777278 :   outer_scope_->scope_calls_eval_ = false;
     935      777278 : }
     936             : 
     937      913000 : void Scope::ReplaceOuterScope(Scope* outer) {
     938             :   DCHECK_NOT_NULL(outer);
     939             :   DCHECK_NOT_NULL(outer_scope_);
     940             :   DCHECK(!already_resolved_);
     941      913000 :   outer_scope_->RemoveInnerScope(this);
     942             :   outer->AddInnerScope(this);
     943             :   outer_scope_ = outer;
     944      913000 : }
     945             : 
     946     3073623 : Variable* Scope::LookupInScopeInfo(const AstRawString* name) {
     947             :   Handle<String> name_handle = name->string();
     948             :   // The Scope is backed up by ScopeInfo. This means it cannot operate in a
     949             :   // heap-independent mode, and all strings must be internalized immediately. So
     950             :   // it's ok to get the Handle<String> here.
     951             :   // If we have a serialized scope info, we might find the variable there.
     952             :   // There should be no local slot with the given name.
     953             :   DCHECK_LT(scope_info_->StackSlotIndex(*name_handle), 0);
     954             : 
     955             :   bool found = false;
     956             : 
     957             :   VariableLocation location;
     958             :   int index;
     959             :   VariableMode mode;
     960             :   InitializationFlag init_flag;
     961             :   MaybeAssignedFlag maybe_assigned_flag;
     962             : 
     963             :   {
     964             :     location = VariableLocation::CONTEXT;
     965             :     index = ScopeInfo::ContextSlotIndex(scope_info_, name_handle, &mode,
     966     1536588 :                                         &init_flag, &maybe_assigned_flag);
     967     1536588 :     found = index >= 0;
     968             :   }
     969             : 
     970     2512387 :   if (!found && scope_type() == MODULE_SCOPE) {
     971             :     location = VariableLocation::MODULE;
     972             :     index = scope_info_->ModuleIndex(name_handle, &mode, &init_flag,
     973        3000 :                                      &maybe_assigned_flag);
     974        3000 :     found = index != 0;
     975             :   }
     976             : 
     977     1536588 :   if (!found) {
     978      975352 :     index = scope_info_->FunctionContextSlotIndex(*name_handle);
     979      975352 :     if (index < 0) return nullptr;  // Nowhere found.
     980         864 :     Variable* var = AsDeclarationScope()->DeclareFunctionVar(name);
     981             :     DCHECK_EQ(CONST, var->mode());
     982             :     var->AllocateTo(VariableLocation::CONTEXT, index);
     983         864 :     return variables_.Lookup(name);
     984             :   }
     985             : 
     986             :   VariableKind kind = NORMAL_VARIABLE;
     987     1122025 :   if (location == VariableLocation::CONTEXT &&
     988      560789 :       index == scope_info_->ReceiverContextSlotIndex()) {
     989             :     kind = THIS_VARIABLE;
     990             :   }
     991             :   // TODO(marja, rossberg): Correctly declare FUNCTION, CLASS, NEW_TARGET, and
     992             :   // ARGUMENTS bindings as their corresponding VariableKind.
     993             : 
     994             :   Variable* var = variables_.Declare(zone(), this, name, mode, kind, init_flag,
     995     1122472 :                                      maybe_assigned_flag);
     996             :   var->AllocateTo(location, index);
     997      561236 :   return var;
     998             : }
     999             : 
    1000       26287 : Variable* Scope::Lookup(const AstRawString* name) {
    1001       27673 :   for (Scope* scope = this; scope != nullptr; scope = scope->outer_scope()) {
    1002       27673 :     Variable* var = scope->LookupLocal(name);
    1003       27673 :     if (var != nullptr) return var;
    1004             :   }
    1005             :   return nullptr;
    1006             : }
    1007             : 
    1008     4616582 : Variable* DeclarationScope::DeclareParameter(
    1009             :     const AstRawString* name, VariableMode mode, bool is_optional, bool is_rest,
    1010     4616582 :     bool* is_duplicate, AstValueFactory* ast_value_factory, int position) {
    1011             :   DCHECK(!already_resolved_);
    1012             :   DCHECK(is_function_scope() || is_module_scope());
    1013             :   DCHECK(!has_rest_);
    1014             :   DCHECK(!is_optional || !is_rest);
    1015             :   DCHECK(!is_being_lazily_parsed_);
    1016             :   DCHECK(!was_lazily_parsed_);
    1017             :   Variable* var;
    1018     4616582 :   if (mode == TEMPORARY) {
    1019     9309160 :     var = NewTemporary(name);
    1020             :   } else {
    1021             :     DCHECK_EQ(mode, VAR);
    1022     9081174 :     var = Declare(zone(), name, mode);
    1023             :     // TODO(wingo): Avoid O(n^2) check.
    1024     4540588 :     if (is_duplicate != nullptr) {
    1025      227120 :       *is_duplicate = *is_duplicate || IsDeclaredParameter(name);
    1026             :     }
    1027             :   }
    1028     4616583 :   has_rest_ = is_rest;
    1029     4616583 :   var->set_initializer_position(position);
    1030     4616583 :   params_.Add(var, zone());
    1031     4616582 :   if (name == ast_value_factory->arguments_string()) {
    1032         997 :     has_arguments_parameter_ = true;
    1033             :   }
    1034     4616582 :   return var;
    1035             : }
    1036             : 
    1037     3295647 : Variable* DeclarationScope::DeclareParameterName(
    1038     3295647 :     const AstRawString* name, bool is_rest, AstValueFactory* ast_value_factory,
    1039             :     bool declare_as_local, bool add_parameter) {
    1040             :   DCHECK(!already_resolved_);
    1041             :   DCHECK(is_function_scope() || is_module_scope());
    1042             :   DCHECK(!has_rest_ || is_rest);
    1043             :   DCHECK(is_being_lazily_parsed_);
    1044     3295647 :   has_rest_ = is_rest;
    1045     3295647 :   if (name == ast_value_factory->arguments_string()) {
    1046         510 :     has_arguments_parameter_ = true;
    1047             :   }
    1048     3295647 :   if (FLAG_preparser_scope_analysis) {
    1049             :     Variable* var;
    1050     3295647 :     if (declare_as_local) {
    1051     6580178 :       var = Declare(zone(), name, VAR);
    1052             :     } else {
    1053             :       var = new (zone())
    1054        1310 :           Variable(this, name, TEMPORARY, NORMAL_VARIABLE, kCreatedInitialized);
    1055             :     }
    1056     3295647 :     if (add_parameter) {
    1057     3285186 :       params_.Add(var, zone());
    1058             :     }
    1059     3295647 :     return var;
    1060             :   }
    1061           0 :   DeclareVariableName(name, VAR);
    1062           0 :   return nullptr;
    1063             : }
    1064             : 
    1065      455374 : Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode,
    1066             :                               InitializationFlag init_flag, VariableKind kind,
    1067    14506068 :                               MaybeAssignedFlag maybe_assigned_flag) {
    1068             :   DCHECK(!already_resolved_);
    1069             :   // This function handles VAR, LET, and CONST modes.  DYNAMIC variables are
    1070             :   // introduced during variable allocation, and TEMPORARY variables are
    1071             :   // allocated via NewTemporary().
    1072             :   DCHECK(IsDeclaredVariableMode(mode));
    1073             :   DCHECK_IMPLIES(GetDeclarationScope()->is_being_lazily_parsed(),
    1074             :                  mode == VAR || mode == LET || mode == CONST);
    1075             :   DCHECK(!GetDeclarationScope()->was_lazily_parsed());
    1076    29012136 :   return Declare(zone(), name, mode, kind, init_flag, maybe_assigned_flag);
    1077             : }
    1078             : 
    1079    11505972 : Variable* Scope::DeclareVariable(
    1080    10708737 :     Declaration* declaration, VariableMode mode, InitializationFlag init,
    1081             :     bool allow_harmony_restrictive_generators,
    1082    21726908 :     bool* sloppy_mode_block_scope_function_redefinition, bool* ok) {
    1083             :   DCHECK(IsDeclaredVariableMode(mode));
    1084             :   DCHECK(!already_resolved_);
    1085             :   DCHECK(!GetDeclarationScope()->is_being_lazily_parsed());
    1086             :   DCHECK(!GetDeclarationScope()->was_lazily_parsed());
    1087             : 
    1088    21788572 :   if (mode == VAR && !is_declaration_scope()) {
    1089             :     return GetDeclarationScope()->DeclareVariable(
    1090             :         declaration, mode, init, allow_harmony_restrictive_generators,
    1091     1594470 :         sloppy_mode_block_scope_function_redefinition, ok);
    1092             :   }
    1093             :   DCHECK(!is_catch_scope());
    1094             :   DCHECK(!is_with_scope());
    1095             :   DCHECK(is_declaration_scope() ||
    1096             :          (IsLexicalVariableMode(mode) && is_block_scope()));
    1097             : 
    1098             :   VariableProxy* proxy = declaration->proxy();
    1099             :   DCHECK_NOT_NULL(proxy->raw_name());
    1100         400 :   const AstRawString* name = proxy->raw_name();
    1101             :   bool is_function_declaration = declaration->IsFunctionDeclaration();
    1102             : 
    1103             :   // Pessimistically assume that top-level variables will be assigned.
    1104             :   //
    1105             :   // Top-level variables in a script can be accessed by other scripts or even
    1106             :   // become global properties. While this does not apply to top-level variables
    1107             :   // in a module (assuming they are not exported), we must still mark these as
    1108             :   // assigned because they might be accessed by a lazily parsed top-level
    1109             :   // function, which, for efficiency, we preparse without variable tracking.
    1110    10708737 :   if (is_script_scope() || is_module_scope()) {
    1111     2112898 :     if (mode != CONST) proxy->set_is_assigned();
    1112             :   }
    1113             : 
    1114      386511 :   Variable* var = nullptr;
    1115    11555279 :   if (is_eval_scope() && is_sloppy(language_mode()) && mode == VAR) {
    1116             :     // In a var binding in a sloppy direct eval, pollute the enclosing scope
    1117             :     // with this new binding by doing the following:
    1118             :     // The proxy is bound to a lookup variable to force a dynamic declaration
    1119             :     // using the DeclareEvalVar or DeclareEvalFunction runtime functions.
    1120             :     var = new (zone())
    1121             :         Variable(this, name, mode, NORMAL_VARIABLE, init, kMaybeAssigned);
    1122             :     var->AllocateTo(VariableLocation::LOOKUP, -1);
    1123             :   } else {
    1124             :     // Declare the variable in the declaration scope.
    1125    10399303 :     var = LookupLocal(name);
    1126    10399303 :     if (var == nullptr) {
    1127             :       // Declare the name.
    1128             :       VariableKind kind = NORMAL_VARIABLE;
    1129     9969254 :       if (is_function_declaration) {
    1130             :         kind = FUNCTION_VARIABLE;
    1131             :       }
    1132             :       var = DeclareLocal(name, mode, init, kind, kNotAssigned);
    1133      816560 :     } else if (IsLexicalVariableMode(mode) ||
    1134             :                IsLexicalVariableMode(var->mode())) {
    1135             :       // Allow duplicate function decls for web compat, see bug 4693.
    1136             :       bool duplicate_allowed = false;
    1137       52906 :       if (is_sloppy(language_mode()) && is_function_declaration &&
    1138             :           var->is_function()) {
    1139             :         DCHECK(IsLexicalVariableMode(mode) &&
    1140             :                IsLexicalVariableMode(var->mode()));
    1141             :         // If the duplication is allowed, then the var will show up
    1142             :         // in the SloppyBlockFunctionMap and the new FunctionKind
    1143             :         // will be a permitted duplicate.
    1144             :         FunctionKind function_kind =
    1145        1200 :             declaration->AsFunctionDeclaration()->fun()->kind();
    1146             :         SloppyBlockFunctionMap* map =
    1147         600 :             GetDeclarationScope()->sloppy_block_function_map();
    1148         400 :         duplicate_allowed = map != nullptr &&
    1149             :                             map->Lookup(const_cast<AstRawString*>(name),
    1150        1800 :                                         name->Hash()) != nullptr &&
    1151         840 :                             !IsAsyncFunction(function_kind) &&
    1152             :                             !(allow_harmony_restrictive_generators &&
    1153         440 :                               IsGeneratorFunction(function_kind));
    1154             :       }
    1155       52062 :       if (duplicate_allowed) {
    1156         200 :         *sloppy_mode_block_scope_function_redefinition = true;
    1157             :       } else {
    1158             :         // The name was declared in this scope before; check for conflicting
    1159             :         // re-declarations. We have a conflict if either of the declarations
    1160             :         // is not a var (in script scope, we also have to ignore legacy const
    1161             :         // for compatibility). There is similar code in runtime.cc in the
    1162             :         // Declare functions. The function CheckConflictingVarDeclarations
    1163             :         // checks for var and let bindings from different scopes whereas this
    1164             :         // is a check for conflicting declarations within the same scope. This
    1165             :         // check also covers the special case
    1166             :         //
    1167             :         // function () { let x; { var x; } }
    1168             :         //
    1169             :         // because the var declaration is hoisted to the function scope where
    1170             :         // 'x' is already bound.
    1171             :         DCHECK(IsDeclaredVariableMode(var->mode()));
    1172             :         // In harmony we treat re-declarations as early errors. See
    1173             :         // ES5 16 for a definition of early errors.
    1174       51862 :         *ok = false;
    1175       51862 :         return nullptr;
    1176             :       }
    1177      377987 :     } else if (mode == VAR) {
    1178             :       var->set_maybe_assigned();
    1179             :     }
    1180             :   }
    1181             :   DCHECK_NOT_NULL(var);
    1182             : 
    1183             :   // We add a declaration node for every declaration. The compiler
    1184             :   // will only generate code if necessary. In particular, declarations
    1185             :   // for inner local variables that do not represent functions won't
    1186             :   // result in any generated code.
    1187             :   //
    1188             :   // This will lead to multiple declaration nodes for the
    1189             :   // same variable if it is declared several times. This is not a
    1190             :   // semantic issue, but it may be a performance issue since it may
    1191             :   // lead to repeated DeclareEvalVar or DeclareEvalFunction calls.
    1192             :   decls_.Add(declaration);
    1193    10656875 :   proxy->BindTo(var);
    1194    10656875 :   return var;
    1195             : }
    1196             : 
    1197     5057845 : Variable* Scope::DeclareVariableName(const AstRawString* name,
    1198           0 :                                      VariableMode mode) {
    1199             :   DCHECK(IsDeclaredVariableMode(mode));
    1200             :   DCHECK(!already_resolved_);
    1201             :   DCHECK(GetDeclarationScope()->is_being_lazily_parsed());
    1202             : 
    1203     9244445 :   if (mode == VAR && !is_declaration_scope()) {
    1204     1411344 :     return GetDeclarationScope()->DeclareVariableName(name, mode);
    1205             :   }
    1206             :   DCHECK(!is_with_scope());
    1207             :   DCHECK(!is_eval_scope());
    1208             :   DCHECK(is_declaration_scope() || IsLexicalVariableMode(mode));
    1209             :   DCHECK(scope_info_.is_null());
    1210             : 
    1211             :   // Declare the variable in the declaration scope.
    1212     4352173 :   if (FLAG_preparser_scope_analysis) {
    1213     4622811 :     Variable* var = LookupLocal(name);
    1214             :     DCHECK_NE(var, kDummyPreParserLexicalVariable);
    1215             :     DCHECK_NE(var, kDummyPreParserVariable);
    1216     4352173 :     if (var == nullptr) {
    1217             :       var = DeclareLocal(name, mode);
    1218      541371 :     } else if (IsLexicalVariableMode(mode) ||
    1219             :                IsLexicalVariableMode(var->mode())) {
    1220             :       // Duplicate functions are allowed in the sloppy mode, but if this is not
    1221             :       // a function declaration, it's an error. This is an error PreParser
    1222             :       // hasn't previously detected. TODO(marja): Investigate whether we can now
    1223             :       // start returning this error.
    1224      270632 :     } else if (mode == VAR) {
    1225             :       var->set_maybe_assigned();
    1226             :     }
    1227             :     var->set_is_used();
    1228     4352173 :     return var;
    1229             :   } else {
    1230           0 :     return variables_.DeclareName(zone(), name, mode);
    1231             :   }
    1232             : }
    1233             : 
    1234      434706 : void Scope::DeclareCatchVariableName(const AstRawString* name) {
    1235             :   DCHECK(!already_resolved_);
    1236             :   DCHECK(GetDeclarationScope()->is_being_lazily_parsed());
    1237             :   DCHECK(is_catch_scope());
    1238             :   DCHECK(scope_info_.is_null());
    1239             : 
    1240      217353 :   if (FLAG_preparser_scope_analysis) {
    1241      217353 :     Declare(zone(), name, VAR);
    1242             :   } else {
    1243           0 :     variables_.DeclareName(zone(), name, VAR);
    1244             :   }
    1245      217353 : }
    1246             : 
    1247        1259 : void Scope::AddUnresolved(VariableProxy* proxy) {
    1248             :   DCHECK(!already_resolved_);
    1249             :   DCHECK(!proxy->is_resolved());
    1250        1259 :   proxy->set_next_unresolved(unresolved_);
    1251        1259 :   unresolved_ = proxy;
    1252        1259 : }
    1253             : 
    1254     5612368 : Variable* DeclarationScope::DeclareDynamicGlobal(const AstRawString* name,
    1255             :                                                  VariableKind kind) {
    1256             :   DCHECK(is_script_scope());
    1257     5612368 :   return variables_.Declare(zone(), this, name, DYNAMIC_GLOBAL, kind);
    1258             :   // TODO(neis): Mark variable as maybe-assigned?
    1259             : }
    1260             : 
    1261             : 
    1262    23263344 : bool Scope::RemoveUnresolved(VariableProxy* var) {
    1263    13264993 :   if (unresolved_ == var) {
    1264     9998351 :     unresolved_ = var->next_unresolved();
    1265             :     var->set_next_unresolved(nullptr);
    1266     9998351 :     return true;
    1267             :   }
    1268     6414987 :   VariableProxy* current = unresolved_;
    1269     6416399 :   while (current != nullptr) {
    1270     3265230 :     VariableProxy* next = current->next_unresolved();
    1271     6414987 :     if (var == next) {
    1272             :       current->set_next_unresolved(next->next_unresolved());
    1273             :       var->set_next_unresolved(nullptr);
    1274     3265230 :       return true;
    1275             :     }
    1276             :     current = next;
    1277             :   }
    1278             :   return false;
    1279             : }
    1280             : 
    1281     2536342 : Variable* Scope::NewTemporary(const AstRawString* name) {
    1282     2640849 :   return NewTemporary(name, kMaybeAssigned);
    1283             : }
    1284             : 
    1285     2742485 : Variable* Scope::NewTemporary(const AstRawString* name,
    1286     2742485 :                               MaybeAssignedFlag maybe_assigned) {
    1287             :   DeclarationScope* scope = GetClosureScope();
    1288             :   Variable* var = new (zone())
    1289             :       Variable(scope, name, TEMPORARY, NORMAL_VARIABLE, kCreatedInitialized);
    1290             :   scope->AddLocal(var);
    1291     2742485 :   if (maybe_assigned == kMaybeAssigned) var->set_maybe_assigned();
    1292     2742485 :   return var;
    1293             : }
    1294             : 
    1295     7730426 : Declaration* Scope::CheckConflictingVarDeclarations() {
    1296    44810136 :   for (Declaration* decl : decls_) {
    1297    10042379 :     VariableMode mode = decl->proxy()->var()->mode();
    1298             : 
    1299             :     // Lexical vs lexical conflicts within the same scope have already been
    1300             :     // captured in Parser::Declare. The only conflicts we still need to check
    1301             :     // are lexical vs nested var, or any declarations within a declaration
    1302             :     // block scope vs lexical declarations in its surrounding (function) scope.
    1303     1155927 :     Scope* current = this;
    1304    18888560 :     if (decl->IsVariableDeclaration() &&
    1305     8846180 :         decl->AsVariableDeclaration()->AsNested() != nullptr) {
    1306             :       DCHECK_EQ(mode, VAR);
    1307     1566484 :       current = decl->AsVariableDeclaration()->AsNested()->scope();
    1308     9259138 :     } else if (IsLexicalVariableMode(mode)) {
    1309      633287 :       if (!is_block_scope()) continue;
    1310             :       DCHECK(is_declaration_scope());
    1311             :       DCHECK_EQ(outer_scope()->scope_type(), FUNCTION_SCOPE);
    1312             :       current = outer_scope();
    1313             :     }
    1314             : 
    1315             :     // Iterate through all scopes until and including the declaration scope.
    1316             :     while (true) {
    1317             :       // There is a conflict if there exists a non-VAR binding.
    1318     9118542 :       Variable* other_var =
    1319    10574515 :           current->variables_.Lookup(decl->proxy()->raw_name());
    1320    19693057 :       if (other_var != nullptr && IsLexicalVariableMode(other_var->mode())) {
    1321             :         return decl;
    1322             :       }
    1323    10550089 :       if (current->is_declaration_scope()) break;
    1324             :       current = current->outer_scope();
    1325             :     }
    1326     1155927 :   }
    1327             :   return nullptr;
    1328             : }
    1329             : 
    1330        1191 : Declaration* Scope::CheckLexDeclarationsConflictingWith(
    1331        2256 :     const ZoneList<const AstRawString*>& names) {
    1332             :   DCHECK(is_block_scope());
    1333        4512 :   for (int i = 0; i < names.length(); ++i) {
    1334        1407 :     Variable* var = LookupLocal(names.at(i));
    1335        1407 :     if (var != nullptr) {
    1336             :       // Conflict; find and return its declaration.
    1337             :       DCHECK(IsLexicalVariableMode(var->mode()));
    1338         342 :       const AstRawString* name = names.at(i);
    1339        1386 :       for (Declaration* decl : decls_) {
    1340         522 :         if (decl->proxy()->raw_name() == name) return decl;
    1341             :       }
    1342             :       DCHECK(false);
    1343             :     }
    1344             :   }
    1345             :   return nullptr;
    1346             : }
    1347             : 
    1348     1760829 : void DeclarationScope::AllocateVariables(ParseInfo* info) {
    1349             :   // Module variables must be allocated before variable resolution
    1350             :   // to ensure that UpdateNeedsHoleCheck() can detect import variables.
    1351     1760829 :   if (is_module_scope()) AsModuleScope()->AllocateModuleVariables();
    1352             : 
    1353     1760829 :   ResolveVariablesRecursively(info);
    1354     1760832 :   AllocateVariablesRecursively();
    1355     1760832 : }
    1356             : 
    1357     5642386 : bool Scope::AllowsLazyParsingWithoutUnresolvedVariables(
    1358             :     const Scope* outer) const {
    1359             :   // If none of the outer scopes need to decide whether to context allocate
    1360             :   // specific variables, we can preparse inner functions without unresolved
    1361             :   // variables. Otherwise we need to find unresolved variables to force context
    1362             :   // allocation of the matching declarations. We can stop at the outer scope for
    1363             :   // the parse, since context allocation of those variables is already
    1364             :   // guaranteed to be correct.
    1365     5672505 :   for (const Scope* s = this; s != outer; s = s->outer_scope_) {
    1366             :     // Eval forces context allocation on all outer scopes, so we don't need to
    1367             :     // look at those scopes. Sloppy eval makes top-level non-lexical variables
    1368             :     // dynamic, whereas strict-mode requires context allocation.
    1369     4729301 :     if (s->is_eval_scope()) return is_sloppy(s->language_mode());
    1370             :     // Catch scopes force context allocation of all variables.
    1371     3667189 :     if (s->is_catch_scope()) continue;
    1372             :     // With scopes do not introduce variables that need allocation.
    1373     3667189 :     if (s->is_with_scope()) continue;
    1374             :     // Module scopes context-allocate all variables, and have no
    1375             :     // {this} or {arguments} variables whose existence depends on
    1376             :     // references to them.
    1377     3667060 :     if (s->is_module_scope()) continue;
    1378             :     // Only block scopes and function scopes should disallow preparsing.
    1379             :     DCHECK(s->is_block_scope() || s->is_function_scope());
    1380             :     return false;
    1381             :   }
    1382             :   return true;
    1383             : }
    1384             : 
    1385     5166990 : bool DeclarationScope::AllowsLazyCompilation() const {
    1386     5166990 :   return !force_eager_compilation_;
    1387             : }
    1388             : 
    1389     4336595 : int Scope::ContextChainLength(Scope* scope) const {
    1390             :   int n = 0;
    1391     5216473 :   for (const Scope* s = this; s != scope; s = s->outer_scope_) {
    1392             :     DCHECK_NOT_NULL(s);  // scope must be in the scope chain
    1393      879878 :     if (s->NeedsContext()) n++;
    1394             :   }
    1395     4336595 :   return n;
    1396             : }
    1397             : 
    1398      365759 : int Scope::ContextChainLengthUntilOutermostSloppyEval() const {
    1399             :   int result = 0;
    1400             :   int length = 0;
    1401             : 
    1402     1474040 :   for (const Scope* s = this; s != nullptr; s = s->outer_scope()) {
    1403     1108281 :     if (!s->NeedsContext()) continue;
    1404      804101 :     length++;
    1405     1602659 :     if (s->is_declaration_scope() &&
    1406             :         s->AsDeclarationScope()->calls_sloppy_eval()) {
    1407             :       result = length;
    1408             :     }
    1409             :   }
    1410             : 
    1411      365759 :   return result;
    1412             : }
    1413             : 
    1414    13316924 : DeclarationScope* Scope::GetDeclarationScope() {
    1415     6117488 :   Scope* scope = this;
    1416    34565564 :   while (!scope->is_declaration_scope()) {
    1417             :     scope = scope->outer_scope();
    1418             :   }
    1419    13316924 :   return scope->AsDeclarationScope();
    1420             : }
    1421             : 
    1422           0 : const DeclarationScope* Scope::GetClosureScope() const {
    1423           0 :   const Scope* scope = this;
    1424           0 :   while (!scope->is_declaration_scope() || scope->is_block_scope()) {
    1425             :     scope = scope->outer_scope();
    1426             :   }
    1427           0 :   return scope->AsDeclarationScope();
    1428             : }
    1429             : 
    1430      671851 : DeclarationScope* Scope::GetClosureScope() {
    1431   295119906 :   Scope* scope = this;
    1432   497255487 :   while (!scope->is_declaration_scope() || scope->is_block_scope()) {
    1433             :     scope = scope->outer_scope();
    1434             :   }
    1435      671851 :   return scope->AsDeclarationScope();
    1436             : }
    1437             : 
    1438     2690816 : bool Scope::NeedsScopeInfo() const {
    1439             :   DCHECK(!already_resolved_);
    1440             :   DCHECK(GetClosureScope()->ShouldEagerCompile());
    1441             :   // The debugger expects all functions to have scope infos.
    1442             :   // TODO(jochen|yangguo): Remove this requirement.
    1443     2690816 :   if (is_function_scope()) return true;
    1444           0 :   return NeedsContext();
    1445             : }
    1446             : 
    1447           0 : ModuleScope* Scope::GetModuleScope() {
    1448           0 :   Scope* scope = this;
    1449             :   DCHECK(!scope->is_script_scope());
    1450           0 :   while (!scope->is_module_scope()) {
    1451             :     scope = scope->outer_scope();
    1452             :     DCHECK_NOT_NULL(scope);
    1453             :   }
    1454           0 :   return scope->AsModuleScope();
    1455             : }
    1456             : 
    1457       43290 : DeclarationScope* Scope::GetReceiverScope() {
    1458       13589 :   Scope* scope = this;
    1459      157048 :   while (!scope->is_script_scope() &&
    1460       40128 :          (!scope->is_function_scope() ||
    1461             :           scope->AsDeclarationScope()->is_arrow_scope())) {
    1462             :     scope = scope->outer_scope();
    1463             :   }
    1464       43290 :   return scope->AsDeclarationScope();
    1465             : }
    1466             : 
    1467     6290615 : Scope* Scope::GetOuterScopeWithContext() {
    1468     8038618 :   Scope* scope = outer_scope_;
    1469    21758993 :   while (scope && !scope->NeedsContext()) {
    1470             :     scope = scope->outer_scope();
    1471             :   }
    1472     6290615 :   return scope;
    1473             : }
    1474             : 
    1475      130903 : Handle<StringSet> DeclarationScope::CollectNonLocals(
    1476             :     ParseInfo* info, Handle<StringSet> non_locals) {
    1477      130903 :   VariableProxy* free_variables = FetchFreeVariables(this, info);
    1478     1900129 :   for (VariableProxy* proxy = free_variables; proxy != nullptr;
    1479             :        proxy = proxy->next_unresolved()) {
    1480     1769226 :     non_locals = StringSet::Add(non_locals, proxy->name());
    1481             :   }
    1482      130903 :   return non_locals;
    1483             : }
    1484             : 
    1485     2218998 : void DeclarationScope::ResetAfterPreparsing(AstValueFactory* ast_value_factory,
    1486             :                                             bool aborted) {
    1487             :   DCHECK(is_function_scope());
    1488             : 
    1489             :   // Reset all non-trivial members.
    1490     2218998 :   if (!aborted || !IsArrowFunction(function_kind_)) {
    1491             :     // Do not remove parameters when lazy parsing an Arrow Function has failed,
    1492             :     // as the formal parameters are not re-parsed.
    1493             :     params_.Clear();
    1494             :   }
    1495             :   decls_.Clear();
    1496             :   locals_.Clear();
    1497     2218949 :   inner_scope_ = nullptr;
    1498     2218949 :   unresolved_ = nullptr;
    1499     2218949 :   sloppy_block_function_map_ = nullptr;
    1500     2218949 :   rare_data_ = nullptr;
    1501             : 
    1502     2218949 :   if (aborted) {
    1503             :     // Prepare scope for use in the outer zone.
    1504          49 :     zone_ = ast_value_factory->zone();
    1505          49 :     variables_.Reset(ZoneAllocationPolicy(zone_));
    1506          98 :     if (!IsArrowFunction(function_kind_)) {
    1507          49 :       DeclareDefaultFunctionVariables(ast_value_factory);
    1508             :     }
    1509             :   } else {
    1510             :     // Make sure this scope isn't used for allocation anymore.
    1511     2218900 :     zone_ = nullptr;
    1512             :     variables_.Invalidate();
    1513             :   }
    1514             : 
    1515             : #ifdef DEBUG
    1516             :   needs_migration_ = false;
    1517             :   is_being_lazily_parsed_ = false;
    1518             : #endif
    1519             : 
    1520     2218949 :   was_lazily_parsed_ = !aborted;
    1521     2218949 : }
    1522             : 
    1523     2610685 : void Scope::SavePreParsedScopeData() {
    1524             :   DCHECK(FLAG_preparser_scope_analysis);
    1525     2610685 :   if (ProducedPreParsedScopeData::ScopeIsSkippableFunctionScope(this)) {
    1526             :     AsDeclarationScope()->SavePreParsedScopeDataForDeclarationScope();
    1527             :   }
    1528             : 
    1529     3527756 :   for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
    1530      917071 :     scope->SavePreParsedScopeData();
    1531             :   }
    1532     2610685 : }
    1533             : 
    1534           0 : void DeclarationScope::SavePreParsedScopeDataForDeclarationScope() {
    1535     1803440 :   if (produced_preparsed_scope_data_ != nullptr) {
    1536             :     DCHECK(FLAG_preparser_scope_analysis);
    1537     1803440 :     produced_preparsed_scope_data_->SaveScopeAllocationData(this);
    1538             :   }
    1539           0 : }
    1540             : 
    1541    10033778 : void DeclarationScope::AnalyzePartially(AstNodeFactory* ast_node_factory) {
    1542             :   DCHECK(!force_eager_compilation_);
    1543             :   VariableProxy* unresolved = nullptr;
    1544             : 
    1545     4394226 :   if (!outer_scope_->is_script_scope() ||
    1546      541070 :       (FLAG_preparser_scope_analysis &&
    1547     1082050 :        produced_preparsed_scope_data_ != nullptr &&
    1548      540980 :        produced_preparsed_scope_data_->ContainsInnerFunctions())) {
    1549             :     // Try to resolve unresolved variables for this Scope and migrate those
    1550             :     // which cannot be resolved inside. It doesn't make sense to try to resolve
    1551             :     // them in the outer Scopes here, because they are incomplete.
    1552     6752397 :     for (VariableProxy* proxy = FetchFreeVariables(this); proxy != nullptr;
    1553             :          proxy = proxy->next_unresolved()) {
    1554             :       DCHECK(!proxy->is_resolved());
    1555             :       VariableProxy* copy = ast_node_factory->CopyVariableProxy(proxy);
    1556             :       copy->set_next_unresolved(unresolved);
    1557             :       unresolved = copy;
    1558             :     }
    1559             : 
    1560             :     // Migrate function_ to the right Zone.
    1561     1693614 :     if (function_ != nullptr) {
    1562      580769 :       function_ = ast_node_factory->CopyVariable(function_);
    1563             :     }
    1564             : 
    1565     1693614 :     if (FLAG_preparser_scope_analysis) {
    1566     1693614 :       SavePreParsedScopeData();
    1567             :     }
    1568             :   }
    1569             : 
    1570             : #ifdef DEBUG
    1571             :   if (FLAG_print_scopes) {
    1572             :     PrintF("Inner function scope:\n");
    1573             :     Print();
    1574             :   }
    1575             : #endif
    1576             : 
    1577     2197113 :   ResetAfterPreparsing(ast_node_factory->ast_value_factory(), false);
    1578             : 
    1579     2197113 :   unresolved_ = unresolved;
    1580     2197113 : }
    1581             : 
    1582             : #ifdef DEBUG
    1583             : namespace {
    1584             : 
    1585             : const char* Header(ScopeType scope_type, FunctionKind function_kind,
    1586             :                    bool is_declaration_scope) {
    1587             :   switch (scope_type) {
    1588             :     case EVAL_SCOPE: return "eval";
    1589             :     // TODO(adamk): Should we print concise method scopes specially?
    1590             :     case FUNCTION_SCOPE:
    1591             :       if (IsGeneratorFunction(function_kind)) return "function*";
    1592             :       if (IsAsyncFunction(function_kind)) return "async function";
    1593             :       if (IsArrowFunction(function_kind)) return "arrow";
    1594             :       return "function";
    1595             :     case MODULE_SCOPE: return "module";
    1596             :     case SCRIPT_SCOPE: return "global";
    1597             :     case CATCH_SCOPE: return "catch";
    1598             :     case BLOCK_SCOPE: return is_declaration_scope ? "varblock" : "block";
    1599             :     case WITH_SCOPE: return "with";
    1600             :   }
    1601             :   UNREACHABLE();
    1602             : }
    1603             : 
    1604             : void Indent(int n, const char* str) { PrintF("%*s%s", n, "", str); }
    1605             : 
    1606             : void PrintName(const AstRawString* name) {
    1607             :   PrintF("%.*s", name->length(), name->raw_data());
    1608             : }
    1609             : 
    1610             : void PrintLocation(Variable* var) {
    1611             :   switch (var->location()) {
    1612             :     case VariableLocation::UNALLOCATED:
    1613             :       break;
    1614             :     case VariableLocation::PARAMETER:
    1615             :       PrintF("parameter[%d]", var->index());
    1616             :       break;
    1617             :     case VariableLocation::LOCAL:
    1618             :       PrintF("local[%d]", var->index());
    1619             :       break;
    1620             :     case VariableLocation::CONTEXT:
    1621             :       PrintF("context[%d]", var->index());
    1622             :       break;
    1623             :     case VariableLocation::LOOKUP:
    1624             :       PrintF("lookup");
    1625             :       break;
    1626             :     case VariableLocation::MODULE:
    1627             :       PrintF("module");
    1628             :       break;
    1629             :   }
    1630             : }
    1631             : 
    1632             : void PrintVar(int indent, Variable* var) {
    1633             :   Indent(indent, VariableMode2String(var->mode()));
    1634             :   PrintF(" ");
    1635             :   if (var->raw_name()->IsEmpty())
    1636             :     PrintF(".%p", reinterpret_cast<void*>(var));
    1637             :   else
    1638             :     PrintName(var->raw_name());
    1639             :   PrintF(";  // (%p) ", reinterpret_cast<void*>(var));
    1640             :   PrintLocation(var);
    1641             :   bool comma = !var->IsUnallocated();
    1642             :   if (var->has_forced_context_allocation()) {
    1643             :     if (comma) PrintF(", ");
    1644             :     PrintF("forced context allocation");
    1645             :     comma = true;
    1646             :   }
    1647             :   if (var->maybe_assigned() == kNotAssigned) {
    1648             :     if (comma) PrintF(", ");
    1649             :     PrintF("never assigned");
    1650             :     comma = true;
    1651             :   }
    1652             :   if (var->initialization_flag() == kNeedsInitialization &&
    1653             :       !var->binding_needs_init()) {
    1654             :     if (comma) PrintF(", ");
    1655             :     PrintF("hole initialization elided");
    1656             :   }
    1657             :   PrintF("\n");
    1658             : }
    1659             : 
    1660             : void PrintMap(int indent, const char* label, VariableMap* map, bool locals,
    1661             :               Variable* function_var) {
    1662             :   bool printed_label = false;
    1663             :   for (VariableMap::Entry* p = map->Start(); p != nullptr; p = map->Next(p)) {
    1664             :     Variable* var = reinterpret_cast<Variable*>(p->value);
    1665             :     if (var == function_var) continue;
    1666             :     if (var == kDummyPreParserVariable ||
    1667             :         var == kDummyPreParserLexicalVariable) {
    1668             :       continue;
    1669             :     }
    1670             :     bool local = !IsDynamicVariableMode(var->mode());
    1671             :     if ((locals ? local : !local) &&
    1672             :         (var->is_used() || !var->IsUnallocated())) {
    1673             :       if (!printed_label) {
    1674             :         Indent(indent, label);
    1675             :         printed_label = true;
    1676             :       }
    1677             :       PrintVar(indent, var);
    1678             :     }
    1679             :   }
    1680             : }
    1681             : 
    1682             : }  // anonymous namespace
    1683             : 
    1684             : void DeclarationScope::PrintParameters() {
    1685             :   PrintF(" (");
    1686             :   for (int i = 0; i < params_.length(); i++) {
    1687             :     if (i > 0) PrintF(", ");
    1688             :     const AstRawString* name = params_[i]->raw_name();
    1689             :     if (name->IsEmpty())
    1690             :       PrintF(".%p", reinterpret_cast<void*>(params_[i]));
    1691             :     else
    1692             :       PrintName(name);
    1693             :   }
    1694             :   PrintF(")");
    1695             : }
    1696             : 
    1697             : void Scope::Print(int n) {
    1698             :   int n0 = (n > 0 ? n : 0);
    1699             :   int n1 = n0 + 2;  // indentation
    1700             : 
    1701             :   // Print header.
    1702             :   FunctionKind function_kind = is_function_scope()
    1703             :                                    ? AsDeclarationScope()->function_kind()
    1704             :                                    : kNormalFunction;
    1705             :   Indent(n0, Header(scope_type_, function_kind, is_declaration_scope()));
    1706             :   if (scope_name_ != nullptr && !scope_name_->IsEmpty()) {
    1707             :     PrintF(" ");
    1708             :     PrintName(scope_name_);
    1709             :   }
    1710             : 
    1711             :   // Print parameters, if any.
    1712             :   Variable* function = nullptr;
    1713             :   if (is_function_scope()) {
    1714             :     AsDeclarationScope()->PrintParameters();
    1715             :     function = AsDeclarationScope()->function_var();
    1716             :   }
    1717             : 
    1718             :   PrintF(" { // (%p) (%d, %d)\n", reinterpret_cast<void*>(this),
    1719             :          start_position(), end_position());
    1720             :   if (is_hidden()) {
    1721             :     Indent(n1, "// is hidden\n");
    1722             :   }
    1723             : 
    1724             :   // Function name, if any (named function literals, only).
    1725             :   if (function != nullptr) {
    1726             :     Indent(n1, "// (local) function name: ");
    1727             :     PrintName(function->raw_name());
    1728             :     PrintF("\n");
    1729             :   }
    1730             : 
    1731             :   // Scope info.
    1732             :   if (is_strict(language_mode())) {
    1733             :     Indent(n1, "// strict mode scope\n");
    1734             :   }
    1735             :   if (IsAsmModule()) Indent(n1, "// scope is an asm module\n");
    1736             :   if (is_declaration_scope() && AsDeclarationScope()->calls_sloppy_eval()) {
    1737             :     Indent(n1, "// scope calls sloppy 'eval'\n");
    1738             :   }
    1739             :   if (is_declaration_scope() && AsDeclarationScope()->NeedsHomeObject()) {
    1740             :     Indent(n1, "// scope needs home object\n");
    1741             :   }
    1742             :   if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n");
    1743             :   if (is_declaration_scope()) {
    1744             :     DeclarationScope* scope = AsDeclarationScope();
    1745             :     if (scope->was_lazily_parsed()) Indent(n1, "// lazily parsed\n");
    1746             :     if (scope->ShouldEagerCompile()) Indent(n1, "// will be compiled\n");
    1747             :   }
    1748             :   if (has_forced_context_allocation()) {
    1749             :     Indent(n1, "// forces context allocation\n");
    1750             :   }
    1751             :   if (num_stack_slots_ > 0) {
    1752             :     Indent(n1, "// ");
    1753             :     PrintF("%d stack slots\n", num_stack_slots_);
    1754             :   }
    1755             :   if (num_heap_slots_ > 0) {
    1756             :     Indent(n1, "// ");
    1757             :     PrintF("%d heap slots\n", num_heap_slots_);
    1758             :   }
    1759             : 
    1760             :   // Print locals.
    1761             :   if (function != nullptr) {
    1762             :     Indent(n1, "// function var:\n");
    1763             :     PrintVar(n1, function);
    1764             :   }
    1765             : 
    1766             :   // Print temporaries.
    1767             :   {
    1768             :     bool printed_header = false;
    1769             :     for (Variable* local : locals_) {
    1770             :       if (local->mode() != TEMPORARY) continue;
    1771             :       if (!printed_header) {
    1772             :         printed_header = true;
    1773             :         Indent(n1, "// temporary vars:\n");
    1774             :       }
    1775             :       PrintVar(n1, local);
    1776             :     }
    1777             :   }
    1778             : 
    1779             :   if (variables_.occupancy() > 0) {
    1780             :     PrintMap(n1, "// local vars:\n", &variables_, true, function);
    1781             :     PrintMap(n1, "// dynamic vars:\n", &variables_, false, function);
    1782             :   }
    1783             : 
    1784             :   // Print inner scopes (disable by providing negative n).
    1785             :   if (n >= 0) {
    1786             :     for (Scope* scope = inner_scope_; scope != nullptr;
    1787             :          scope = scope->sibling_) {
    1788             :       PrintF("\n");
    1789             :       scope->Print(n1);
    1790             :     }
    1791             :   }
    1792             : 
    1793             :   Indent(n0, "}\n");
    1794             : }
    1795             : 
    1796             : void Scope::CheckScopePositions() {
    1797             :   // Visible leaf scopes must have real positions.
    1798             :   if (!is_hidden() && inner_scope_ == nullptr) {
    1799             :     DCHECK_NE(kNoSourcePosition, start_position());
    1800             :     DCHECK_NE(kNoSourcePosition, end_position());
    1801             :   }
    1802             :   for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
    1803             :     scope->CheckScopePositions();
    1804             :   }
    1805             : }
    1806             : 
    1807             : void Scope::CheckZones() {
    1808             :   DCHECK(!needs_migration_);
    1809             :   for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
    1810             :     if (scope->is_declaration_scope() &&
    1811             :         scope->AsDeclarationScope()->was_lazily_parsed()) {
    1812             :       DCHECK_NULL(scope->zone());
    1813             :       DCHECK_NULL(scope->inner_scope_);
    1814             :       continue;
    1815             :     }
    1816             :     scope->CheckZones();
    1817             :   }
    1818             : }
    1819             : #endif  // DEBUG
    1820             : 
    1821      876218 : Variable* Scope::NonLocal(const AstRawString* name, VariableMode mode) {
    1822             :   // Declare a new non-local.
    1823             :   DCHECK(IsDynamicVariableMode(mode));
    1824      876218 :   Variable* var = variables_.Declare(zone(), nullptr, name, mode);
    1825             :   // Allocate it by giving it a dynamic lookup.
    1826             :   var->AllocateTo(VariableLocation::LOOKUP, -1);
    1827      438109 :   return var;
    1828             : }
    1829             : 
    1830   119972920 : Variable* Scope::LookupRecursive(VariableProxy* proxy, Scope* outer_scope_end) {
    1831             :   DCHECK_NE(outer_scope_end, this);
    1832             :   // Short-cut: whenever we find a debug-evaluate scope, just look everything up
    1833             :   // dynamically. Debug-evaluate doesn't properly create scope info for the
    1834             :   // lookups it does. It may not have a valid 'this' declaration, and anything
    1835             :   // accessed through debug-evaluate might invalidly resolve to stack-allocated
    1836             :   // variables.
    1837             :   // TODO(yangguo): Remove once debug-evaluate creates proper ScopeInfo for the
    1838             :   // scopes in which it's evaluating.
    1839    83133787 :   if (is_debug_evaluate_scope_) return NonLocal(proxy->raw_name(), DYNAMIC);
    1840             : 
    1841             :   // Try to find the variable in this scope.
    1842    83114185 :   Variable* var = LookupLocal(proxy->raw_name());
    1843             : 
    1844             :   // We found a variable and we are done. (Even if there is an 'eval' in this
    1845             :   // scope which introduces the same variable again, the resulting variable
    1846             :   // remains the same.)
    1847    83114198 :   if (var != nullptr) return var;
    1848             : 
    1849    24606194 :   if (outer_scope_ == outer_scope_end) {
    1850             :     // We may just be trying to find all free variables. In that case, don't
    1851             :     // declare them in the outer scope.
    1852     8743065 :     if (!is_script_scope()) return nullptr;
    1853             :     // No binding has been found. Declare a variable on the global object.
    1854             :     return AsDeclarationScope()->DeclareDynamicGlobal(proxy->raw_name(),
    1855     1915056 :                                                       NORMAL_VARIABLE);
    1856             :   }
    1857             : 
    1858             :   DCHECK(!is_script_scope());
    1859             : 
    1860    15863129 :   var = outer_scope_->LookupRecursive(proxy, outer_scope_end);
    1861             : 
    1862             :   // The variable could not be resolved statically.
    1863    15863129 :   if (var == nullptr) return var;
    1864             : 
    1865             :   // TODO(marja): Separate LookupRecursive for preparsed scopes better.
    1866    14220346 :   if (var == kDummyPreParserVariable || var == kDummyPreParserLexicalVariable) {
    1867             :     DCHECK(GetDeclarationScope()->is_being_lazily_parsed());
    1868             :     DCHECK(FLAG_lazy_inner_functions);
    1869             :     return var;
    1870             :   }
    1871             : 
    1872    24215988 :   if (is_function_scope() && !var->is_dynamic()) {
    1873             :     var->ForceContextAllocation();
    1874             :   }
    1875             :   // "this" can't be shadowed by "eval"-introduced bindings or by "with"
    1876             :   // scopes.
    1877             :   // TODO(wingo): There are other variables in this category; add them.
    1878    14220346 :   if (var->is_this()) return var;
    1879             : 
    1880    13873849 :   if (is_with_scope()) {
    1881             :     // The current scope is a with scope, so the variable binding can not be
    1882             :     // statically resolved. However, note that it was necessary to do a lookup
    1883             :     // in the outer scope anyway, because if a binding exists in an outer
    1884             :     // scope, the associated variable has to be marked as potentially being
    1885             :     // accessed from inside of an inner with scope (the property may not be in
    1886             :     // the 'with' object).
    1887       33006 :     if (!var->is_dynamic() && var->IsUnallocated()) {
    1888             :       DCHECK(!already_resolved_);
    1889             :       var->set_is_used();
    1890             :       var->ForceContextAllocation();
    1891       11674 :       if (proxy->is_assigned()) var->set_maybe_assigned();
    1892             :     }
    1893       21106 :     return NonLocal(proxy->raw_name(), DYNAMIC);
    1894             :   }
    1895             : 
    1896    24870865 :   if (is_declaration_scope() && AsDeclarationScope()->calls_sloppy_eval()) {
    1897             :     // A variable binding may have been found in an outer scope, but the current
    1898             :     // scope makes a sloppy 'eval' call, so the found variable may not be the
    1899             :     // correct one (the 'eval' may introduce a binding with the same name). In
    1900             :     // that case, change the lookup result to reflect this situation. Only
    1901             :     // scopes that can host var bindings (declaration scopes) need be considered
    1902             :     // here (this excludes block and catch scopes), and variable lookups at
    1903             :     // script scope are always dynamic.
    1904      392770 :     if (var->IsGlobalObjectProperty()) {
    1905      350388 :       return NonLocal(proxy->raw_name(), DYNAMIC_GLOBAL);
    1906             :     }
    1907             : 
    1908       42382 :     if (var->is_dynamic()) return var;
    1909             : 
    1910             :     Variable* invalidated = var;
    1911        5323 :     var = NonLocal(proxy->raw_name(), DYNAMIC_LOCAL);
    1912             :     var->set_local_if_not_shadowed(invalidated);
    1913             :   }
    1914             : 
    1915    13465296 :   return var;
    1916             : }
    1917             : 
    1918    30220011 : void Scope::ResolveVariable(ParseInfo* info, VariableProxy* proxy) {
    1919             :   DCHECK(info->script_scope()->is_script_scope());
    1920             :   DCHECK(!proxy->is_resolved());
    1921    30220011 :   Variable* var = LookupRecursive(proxy, nullptr);
    1922             :   ResolveTo(info, proxy, var);
    1923    30220013 : }
    1924             : 
    1925             : namespace {
    1926             : 
    1927             : void SetNeedsHoleCheck(Variable* var, VariableProxy* proxy) {
    1928             :   proxy->set_needs_hole_check();
    1929             :   var->ForceHoleInitialization();
    1930             : }
    1931             : 
    1932    39405881 : void UpdateNeedsHoleCheck(Variable* var, VariableProxy* proxy, Scope* scope) {
    1933    37915697 :   if (var->mode() == DYNAMIC_LOCAL) {
    1934             :     // Dynamically introduced variables never need a hole check (since they're
    1935             :     // VAR bindings, either from var or function declarations), but the variable
    1936             :     // they shadow might need a hole check, which we want to do if we decide
    1937             :     // that no shadowing variable was dynamically introoduced.
    1938             :     DCHECK_EQ(kCreatedInitialized, var->initialization_flag());
    1939        4767 :     return UpdateNeedsHoleCheck(var->local_if_not_shadowed(), proxy, scope);
    1940             :   }
    1941             : 
    1942    37910930 :   if (var->initialization_flag() == kCreatedInitialized) return;
    1943             : 
    1944             :   // It's impossible to eliminate module import hole checks here, because it's
    1945             :   // unknown at compilation time whether the binding referred to in the
    1946             :   // exporting module itself requires hole checks.
    1947      943419 :   if (var->location() == VariableLocation::MODULE && !var->IsExport()) {
    1948             :     return SetNeedsHoleCheck(var, proxy);
    1949             :   }
    1950             : 
    1951             :   // Check if the binding really needs an initialization check. The check
    1952             :   // can be skipped in the following situation: we have a LET or CONST
    1953             :   // binding, both the Variable and the VariableProxy have the same
    1954             :   // declaration scope (i.e. they are both in global code, in the
    1955             :   // same function or in the same eval code), the VariableProxy is in
    1956             :   // the source physically located after the initializer of the variable,
    1957             :   // and that the initializer cannot be skipped due to a nonlinear scope.
    1958             :   //
    1959             :   // The condition on the closure scopes is a conservative check for
    1960             :   // nested functions that access a binding and are called before the
    1961             :   // binding is initialized:
    1962             :   //   function() { f(); let x = 1; function f() { x = 2; } }
    1963             :   //
    1964             :   // The check cannot be skipped on non-linear scopes, namely switch
    1965             :   // scopes, to ensure tests are done in cases like the following:
    1966             :   //   switch (1) { case 0: let x = 2; case 1: f(x); }
    1967             :   // The scope of the variable needs to be checked, in case the use is
    1968             :   // in a sub-block which may be linear.
    1969      939011 :   if (var->scope()->GetClosureScope() != scope->GetClosureScope()) {
    1970             :     return SetNeedsHoleCheck(var, proxy);
    1971             :   }
    1972             : 
    1973      579219 :   if (var->is_this()) {
    1974             :     DCHECK(IsDerivedConstructor(scope->GetClosureScope()->function_kind()));
    1975             :     // TODO(littledan): implement 'this' hole check elimination.
    1976             :     return SetNeedsHoleCheck(var, proxy);
    1977             :   }
    1978             : 
    1979             :   // We should always have valid source positions.
    1980             :   DCHECK_NE(var->initializer_position(), kNoSourcePosition);
    1981             :   DCHECK_NE(proxy->position(), kNoSourcePosition);
    1982             : 
    1983     1102438 :   if (var->scope()->is_nonlinear() ||
    1984      551173 :       var->initializer_position() >= proxy->position()) {
    1985             :     return SetNeedsHoleCheck(var, proxy);
    1986             :   }
    1987             : }
    1988             : 
    1989             : }  // anonymous namespace
    1990             : 
    1991           0 : void Scope::ResolveTo(ParseInfo* info, VariableProxy* proxy, Variable* var) {
    1992             : #ifdef DEBUG
    1993             :   if (info->is_native()) {
    1994             :     // To avoid polluting the global object in native scripts
    1995             :     //  - Variables must not be allocated to the global scope.
    1996             :     DCHECK_NOT_NULL(outer_scope());
    1997             :     //  - Variables must be bound locally or unallocated.
    1998             :     if (var->IsGlobalObjectProperty()) {
    1999             :       // The following variable name may be minified. If so, disable
    2000             :       // minification in js2c.py for better output.
    2001             :       Handle<String> name = proxy->raw_name()->string();
    2002             :       V8_Fatal(__FILE__, __LINE__, "Unbound variable: '%s' in native script.",
    2003             :                name->ToCString().get());
    2004             :     }
    2005             :     VariableLocation location = var->location();
    2006             :     DCHECK(location == VariableLocation::LOCAL ||
    2007             :            location == VariableLocation::CONTEXT ||
    2008             :            location == VariableLocation::PARAMETER ||
    2009             :            location == VariableLocation::UNALLOCATED);
    2010             :   }
    2011             : #endif
    2012             : 
    2013             :   DCHECK_NOT_NULL(var);
    2014    37910935 :   UpdateNeedsHoleCheck(var, proxy, this);
    2015    37910927 :   proxy->BindTo(var);
    2016           0 : }
    2017             : 
    2018    11987853 : void Scope::ResolveVariablesRecursively(ParseInfo* info) {
    2019             :   DCHECK(info->script_scope()->is_script_scope());
    2020             :   // Lazy parsed declaration scopes are already partially analyzed. If there are
    2021             :   // unresolved references remaining, they just need to be resolved in outer
    2022             :   // scopes.
    2023    13667467 :   if (is_declaration_scope() && AsDeclarationScope()->was_lazily_parsed()) {
    2024             :     DCHECK_EQ(variables_.occupancy(), 0);
    2025    10546474 :     for (VariableProxy* proxy = unresolved_; proxy != nullptr;
    2026             :          proxy = proxy->next_unresolved()) {
    2027     4875439 :       Variable* var = outer_scope()->LookupRecursive(proxy, nullptr);
    2028     4875439 :       if (!var->is_dynamic()) {
    2029             :         var->set_is_used();
    2030             :         var->ForceContextAllocation();
    2031     3563037 :         if (proxy->is_assigned()) var->set_maybe_assigned();
    2032             :       }
    2033             :     }
    2034             :   } else {
    2035             :     // Resolve unresolved variables for this scope.
    2036    35224430 :     for (VariableProxy* proxy = unresolved_; proxy != nullptr;
    2037             :          proxy = proxy->next_unresolved()) {
    2038    30220011 :       ResolveVariable(info, proxy);
    2039             :     }
    2040             : 
    2041             :     // Resolve unresolved variables for inner scopes.
    2042    10356005 :     for (Scope* scope = inner_scope_; scope != nullptr;
    2043             :          scope = scope->sibling_) {
    2044     5351585 :       scope->ResolveVariablesRecursively(info);
    2045             :     }
    2046             :   }
    2047     7112418 : }
    2048             : 
    2049     3068512 : VariableProxy* Scope::FetchFreeVariables(DeclarationScope* max_outer_scope,
    2050             :                                          ParseInfo* info,
    2051      681686 :                                          VariableProxy* stack) {
    2052             :   // Module variables must be allocated before variable resolution
    2053             :   // to ensure that UpdateNeedsHoleCheck() can detect import variables.
    2054     3526339 :   if (info != nullptr && is_module_scope()) {
    2055         657 :     AsModuleScope()->AllocateModuleVariables();
    2056             :   }
    2057             :   // Lazy parsed declaration scopes are already partially analyzed. If there are
    2058             :   // unresolved references remaining, they just need to be resolved in outer
    2059             :   // scopes.
    2060             :   Scope* lookup =
    2061     2540004 :       is_declaration_scope() && AsDeclarationScope()->was_lazily_parsed()
    2062             :           ? outer_scope()
    2063     3292371 :           : this;
    2064    55949310 :   for (VariableProxy *proxy = unresolved_, *next = nullptr; proxy != nullptr;
    2065             :        proxy = next) {
    2066             :     next = proxy->next_unresolved();
    2067             :     DCHECK(!proxy->is_resolved());
    2068             :     Variable* var =
    2069    32165603 :         lookup->LookupRecursive(proxy, max_outer_scope->outer_scope());
    2070    32165603 :     if (var == nullptr) {
    2071             :       proxy->set_next_unresolved(stack);
    2072             :       stack = proxy;
    2073    50675188 :     } else if (var != kDummyPreParserVariable &&
    2074    25337594 :                var != kDummyPreParserLexicalVariable) {
    2075    25337594 :       if (info != nullptr) {
    2076             :         // In this case we need to leave scopes in a way that they can be
    2077             :         // allocated. If we resolved variables from lazy parsed scopes, we need
    2078             :         // to context allocate the var.
    2079             :         ResolveTo(info, proxy, var);
    2080     7690911 :         if (!var->is_dynamic() && lookup != this) var->ForceContextAllocation();
    2081             :       } else {
    2082             :         var->set_is_used();
    2083    17646683 :         if (proxy->is_assigned()) {
    2084             :           var->set_maybe_assigned();
    2085             :         }
    2086             :       }
    2087             :     }
    2088             :   }
    2089             : 
    2090             :   // Clear unresolved_ as it's in an inconsistent state.
    2091     3068512 :   unresolved_ = nullptr;
    2092             : 
    2093     4312507 :   for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
    2094     1243995 :     stack = scope->FetchFreeVariables(max_outer_scope, info, stack);
    2095             :   }
    2096             : 
    2097     3068512 :   return stack;
    2098             : }
    2099             : 
    2100   117007466 : bool Scope::MustAllocate(Variable* var) {
    2101    31426281 :   if (var == kDummyPreParserLexicalVariable || var == kDummyPreParserVariable) {
    2102             :     return true;
    2103             :   }
    2104             :   DCHECK(var->location() != VariableLocation::MODULE);
    2105             :   // Give var a read/write use if there is a chance it might be accessed
    2106             :   // via an eval() call.  This is only possible if the variable has a
    2107             :   // visible name.
    2108    90004802 :   if ((var->is_this() || !var->raw_name()->IsEmpty()) &&
    2109    28397873 :       (inner_scope_calls_eval_ || is_catch_scope() || is_script_scope())) {
    2110             :     var->set_is_used();
    2111     3391573 :     if (inner_scope_calls_eval_) var->set_maybe_assigned();
    2112             :   }
    2113             :   DCHECK(!var->has_forced_context_allocation() || var->is_used());
    2114             :   // Global variables do not need to be allocated.
    2115    61457362 :   return !var->IsGlobalObjectProperty() && var->is_used();
    2116             : }
    2117             : 
    2118             : 
    2119    45653856 : bool Scope::MustAllocateInContext(Variable* var) {
    2120             :   // If var is accessed from an inner scope, or if there is a possibility
    2121             :   // that it might be accessed from the current or an inner scope (through
    2122             :   // an eval() call or a runtime with lookup), it must be allocated in the
    2123             :   // context.
    2124             :   //
    2125             :   // Exceptions: If the scope as a whole has forced context allocation, all
    2126             :   // variables will have context allocation, even temporaries.  Otherwise
    2127             :   // temporary variables are always stack-allocated.  Catch-bound variables are
    2128             :   // always context-allocated.
    2129    15830053 :   if (has_forced_context_allocation()) return true;
    2130    15775864 :   if (var->mode() == TEMPORARY) return false;
    2131    14047939 :   if (is_catch_scope()) return true;
    2132    13817757 :   if ((is_script_scope() || is_eval_scope()) &&
    2133             :       IsLexicalVariableMode(var->mode())) {
    2134             :     return true;
    2135             :   }
    2136    13531602 :   return var->has_forced_context_allocation() || inner_scope_calls_eval_;
    2137             : }
    2138             : 
    2139             : 
    2140     8004290 : void Scope::AllocateStackSlot(Variable* var) {
    2141     8004290 :   if (is_block_scope()) {
    2142      309363 :     outer_scope()->GetDeclarationScope()->AllocateStackSlot(var);
    2143             :   } else {
    2144     7694927 :     var->AllocateTo(VariableLocation::LOCAL, num_stack_slots_++);
    2145             :   }
    2146     7694927 : }
    2147             : 
    2148             : 
    2149           0 : void Scope::AllocateHeapSlot(Variable* var) {
    2150     2730969 :   var->AllocateTo(VariableLocation::CONTEXT, num_heap_slots_++);
    2151           0 : }
    2152             : 
    2153     3390597 : void DeclarationScope::AllocateParameterLocals() {
    2154             :   DCHECK(is_function_scope());
    2155             : 
    2156             :   bool uses_sloppy_arguments = false;
    2157             : 
    2158     3390597 :   if (arguments_ != nullptr) {
    2159             :     DCHECK(!is_arrow_scope());
    2160             :     // 'arguments' is used. Unless there is also a parameter called
    2161             :     // 'arguments', we must be conservative and allocate all parameters to
    2162             :     // the context assuming they will be captured by the arguments object.
    2163             :     // If we have a parameter named 'arguments', a (new) value is always
    2164             :     // assigned to it via the function invocation. Then 'arguments' denotes
    2165             :     // that specific parameter value and cannot be used to access the
    2166             :     // parameters, which is why we don't need to allocate an arguments
    2167             :     // object in that case.
    2168     2802779 :     if (MustAllocate(arguments_) && !has_arguments_parameter_) {
    2169             :       // In strict mode 'arguments' does not alias formal parameters.
    2170             :       // Therefore in strict mode we allocate parameters as if 'arguments'
    2171             :       // were not used.
    2172             :       // If the parameter list is not simple, arguments isn't sloppy either.
    2173             :       uses_sloppy_arguments =
    2174      182400 :           is_sloppy(language_mode()) && has_simple_parameters();
    2175             :     } else {
    2176             :       // 'arguments' is unused. Tell the code generator that it does not need to
    2177             :       // allocate the arguments object by nulling out arguments_.
    2178     2689657 :       arguments_ = nullptr;
    2179             :     }
    2180             :   }
    2181             : 
    2182             :   // The same parameter may occur multiple times in the parameters_ list.
    2183             :   // If it does, and if it is not copied into the context object, it must
    2184             :   // receive the highest parameter index for that parameter; thus iteration
    2185             :   // order is relevant!
    2186     7591982 :   for (int i = num_parameters() - 1; i >= 0; --i) {
    2187     8402770 :     Variable* var = params_[i];
    2188             :     DCHECK(!has_rest_ || var != rest_parameter());
    2189             :     DCHECK_EQ(this, var->scope());
    2190     4201385 :     if (uses_sloppy_arguments) {
    2191             :       var->set_is_used();
    2192             :       var->set_maybe_assigned();
    2193             :       var->ForceContextAllocation();
    2194             :     }
    2195     4201385 :     AllocateParameter(var, i);
    2196             :   }
    2197     3390597 : }
    2198             : 
    2199     7047881 : void DeclarationScope::AllocateParameter(Variable* var, int index) {
    2200     7047881 :   if (MustAllocate(var)) {
    2201    11232559 :     if (has_forced_context_allocation_for_parameters() ||
    2202     5612231 :         MustAllocateInContext(var)) {
    2203             :       DCHECK(var->IsUnallocated() || var->IsContextSlot());
    2204      207241 :       if (var->IsUnallocated()) {
    2205             :         AllocateHeapSlot(var);
    2206             :       }
    2207             :     } else {
    2208             :       DCHECK(var->IsUnallocated() || var->IsParameter());
    2209     5413087 :       if (var->IsUnallocated()) {
    2210             :         var->AllocateTo(VariableLocation::PARAMETER, index);
    2211             :       }
    2212             :     }
    2213             :   }
    2214     7047882 : }
    2215             : 
    2216     7344891 : void DeclarationScope::AllocateReceiver() {
    2217     8996791 :   if (!has_this_declaration()) return;
    2218             :   DCHECK_NOT_NULL(receiver());
    2219             :   DCHECK_EQ(receiver()->scope(), this);
    2220     2846496 :   AllocateParameter(receiver(), -1);
    2221             : }
    2222             : 
    2223    24238107 : void Scope::AllocateNonParameterLocal(Variable* var) {
    2224             :   DCHECK(var->scope() == this);
    2225    24238107 :   if (var->IsUnallocated() && MustAllocate(var)) {
    2226    10215772 :     if (MustAllocateInContext(var)) {
    2227             :       AllocateHeapSlot(var);
    2228             :     } else {
    2229     7694927 :       AllocateStackSlot(var);
    2230             :     }
    2231             :   }
    2232    24238107 : }
    2233             : 
    2234     5080223 : void Scope::AllocateNonParameterLocalsAndDeclaredGlobals() {
    2235    34300350 :   for (Variable* local : locals_) {
    2236    24139902 :     AllocateNonParameterLocal(local);
    2237             :   }
    2238             : 
    2239     5080225 :   if (is_declaration_scope()) {
    2240     4498396 :     AsDeclarationScope()->AllocateLocals();
    2241             :   }
    2242     5080226 : }
    2243             : 
    2244     8996792 : void DeclarationScope::AllocateLocals() {
    2245             :   // For now, function_ must be allocated at the very end.  If it gets
    2246             :   // allocated in the context, it must be the last slot in the context,
    2247             :   // because of the current ScopeInfo implementation (see
    2248             :   // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor).
    2249     4498395 :   if (function_ != nullptr) {
    2250       98205 :     AllocateNonParameterLocal(function_);
    2251             :   }
    2252             : 
    2253             :   DCHECK(!has_rest_ || !MustAllocate(rest_parameter()) ||
    2254             :          !rest_parameter()->IsUnallocated());
    2255             : 
    2256     4498397 :   if (new_target_ != nullptr && !MustAllocate(new_target_)) {
    2257     2717190 :     new_target_ = nullptr;
    2258             :   }
    2259             : 
    2260             :   NullifyRareVariableIf(RareVariable::kThisFunction,
    2261      136584 :                         [=](Variable* var) { return !MustAllocate(var); });
    2262     4498397 : }
    2263             : 
    2264       12852 : void ModuleScope::AllocateModuleVariables() {
    2265       14372 :   for (const auto& it : module()->regular_imports()) {
    2266        1520 :     Variable* var = LookupLocal(it.first);
    2267        1520 :     var->AllocateTo(VariableLocation::MODULE, it.second->cell_index);
    2268             :     DCHECK(!var->IsExport());
    2269             :   }
    2270             : 
    2271       31829 :   for (const auto& it : module()->regular_exports()) {
    2272       18977 :     Variable* var = LookupLocal(it.first);
    2273       18977 :     var->AllocateTo(VariableLocation::MODULE, it.second->cell_index);
    2274             :     DCHECK(var->IsExport());
    2275             :   }
    2276        6426 : }
    2277             : 
    2278    16766841 : void Scope::AllocateVariablesRecursively() {
    2279             :   DCHECK(!already_resolved_);
    2280             :   DCHECK_IMPLIES(!FLAG_preparser_scope_analysis, num_stack_slots_ == 0);
    2281             : 
    2282             :   // Don't allocate variables of preparsed scopes.
    2283    13794614 :   if (is_declaration_scope() && AsDeclarationScope()->was_lazily_parsed()) {
    2284     7188221 :     return;
    2285             :   }
    2286             : 
    2287             :   // Allocate variables for inner scopes.
    2288    10491175 :   for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
    2289     5410951 :     scope->AllocateVariablesRecursively();
    2290             :   }
    2291             : 
    2292             :   DCHECK(!already_resolved_);
    2293             :   DCHECK_EQ(Context::MIN_CONTEXT_SLOTS, num_heap_slots_);
    2294             : 
    2295             :   // Allocate variables for this scope.
    2296             :   // Parameters must be allocated first, if any.
    2297     5080224 :   if (is_declaration_scope()) {
    2298     4498395 :     if (is_function_scope()) {
    2299     3390597 :       AsDeclarationScope()->AllocateParameterLocals();
    2300             :     }
    2301     4498395 :     AsDeclarationScope()->AllocateReceiver();
    2302             :   }
    2303     5080225 :   AllocateNonParameterLocalsAndDeclaredGlobals();
    2304             : 
    2305             :   // Force allocation of a context for this scope if necessary. For a 'with'
    2306             :   // scope and for a function scope that makes an 'eval' call we need a context,
    2307             :   // even if no local variables were statically allocated in the scope.
    2308             :   // Likewise for modules and function scopes representing asm.js modules.
    2309             :   bool must_have_context =
    2310    10081747 :       is_with_scope() || is_module_scope() || IsAsmModule() ||
    2311     8465341 :       (is_function_scope() && AsDeclarationScope()->calls_sloppy_eval()) ||
    2312      330009 :       (is_block_scope() && is_declaration_scope() &&
    2313             :        AsDeclarationScope()->calls_sloppy_eval());
    2314             : 
    2315             :   // If we didn't allocate any locals in the local context, then we only
    2316             :   // need the minimal number of slots if we must have a context.
    2317     5080226 :   if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && !must_have_context) {
    2318     4462582 :     num_heap_slots_ = 0;
    2319             :   }
    2320             : 
    2321             :   // Allocation done.
    2322             :   DCHECK(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS);
    2323             : }
    2324             : 
    2325     2690816 : void Scope::AllocateScopeInfosRecursively(Isolate* isolate,
    2326     1475016 :                                           MaybeHandle<ScopeInfo> outer_scope) {
    2327             :   DCHECK(scope_info_.is_null());
    2328     2690816 :   MaybeHandle<ScopeInfo> next_outer_scope = outer_scope;
    2329             : 
    2330     2690816 :   if (NeedsScopeInfo()) {
    2331     1475016 :     scope_info_ = ScopeInfo::Create(isolate, zone(), this, outer_scope);
    2332             :     // The ScopeInfo chain should mirror the context chain, so we only link to
    2333             :     // the next outer scope that needs a context.
    2334     1475016 :     if (NeedsContext()) next_outer_scope = scope_info_;
    2335             :   }
    2336             : 
    2337             :   // Allocate ScopeInfos for inner scopes.
    2338     7525042 :   for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
    2339     9252667 :     if (!scope->is_function_scope() ||
    2340             :         scope->AsDeclarationScope()->ShouldEagerCompile()) {
    2341      972542 :       scope->AllocateScopeInfosRecursively(isolate, next_outer_scope);
    2342             :     }
    2343             :   }
    2344     2690816 : }
    2345             : 
    2346      210210 : void Scope::AllocateDebuggerScopeInfos(Isolate* isolate,
    2347       62662 :                                        MaybeHandle<ScopeInfo> outer_scope) {
    2348      210210 :   if (scope_info_.is_null()) {
    2349       62662 :     scope_info_ = ScopeInfo::Create(isolate, zone(), this, outer_scope);
    2350             :   }
    2351      340607 :   MaybeHandle<ScopeInfo> outer = NeedsContext() ? scope_info_ : outer_scope;
    2352      525859 :   for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
    2353      315649 :     if (scope->is_function_scope()) continue;
    2354       79748 :     scope->AllocateDebuggerScopeInfos(isolate, outer);
    2355             :   }
    2356      210210 : }
    2357             : 
    2358             : // static
    2359     3436548 : void DeclarationScope::AllocateScopeInfos(ParseInfo* info, Isolate* isolate,
    2360             :                                           AnalyzeMode mode) {
    2361     1718274 :   DeclarationScope* scope = info->literal()->scope();
    2362     1718274 :   if (!scope->scope_info_.is_null()) return;  // Allocated by outer function.
    2363             : 
    2364             :   MaybeHandle<ScopeInfo> outer_scope;
    2365     1718274 :   if (scope->outer_scope_ != nullptr) {
    2366     1527889 :     outer_scope = scope->outer_scope_->scope_info_;
    2367             :   }
    2368             : 
    2369     2700357 :   scope->AllocateScopeInfosRecursively(isolate, outer_scope);
    2370     1718274 :   if (mode == AnalyzeMode::kDebugger) {
    2371      130462 :     scope->AllocateDebuggerScopeInfos(isolate, outer_scope);
    2372             :   }
    2373             : 
    2374             :   // The debugger expects all shared function infos to contain a scope info.
    2375             :   // Since the top-most scope will end up in a shared function info, make sure
    2376             :   // it has one, even if it doesn't need a scope info.
    2377             :   // TODO(jochen|yangguo): Remove this requirement.
    2378     1718274 :   if (scope->scope_info_.is_null()) {
    2379             :     scope->scope_info_ =
    2380      982083 :         ScopeInfo::Create(isolate, scope->zone(), scope, outer_scope);
    2381             :   }
    2382             : 
    2383             :   // Ensuring that the outer script scope has a scope info avoids having
    2384             :   // special case for native contexts vs other contexts.
    2385     3436548 :   if (info->script_scope() && info->script_scope()->scope_info_.is_null()) {
    2386     2502906 :     info->script_scope()->scope_info_ = handle(ScopeInfo::Empty(isolate));
    2387             :   }
    2388             : }
    2389             : 
    2390           0 : int Scope::StackLocalCount() const {
    2391             :   Variable* function =
    2392           0 :       is_function_scope() ? AsDeclarationScope()->function_var() : nullptr;
    2393           0 :   return num_stack_slots() -
    2394           0 :          (function != nullptr && function->IsStackLocal() ? 1 : 0);
    2395             : }
    2396             : 
    2397             : 
    2398       13773 : int Scope::ContextLocalCount() const {
    2399        9759 :   if (num_heap_slots() == 0) return 0;
    2400             :   Variable* function =
    2401        4014 :       is_function_scope() ? AsDeclarationScope()->function_var() : nullptr;
    2402             :   bool is_function_var_in_context =
    2403        4014 :       function != nullptr && function->IsContextSlot();
    2404        4014 :   return num_heap_slots() - Context::MIN_CONTEXT_SLOTS -
    2405        4014 :          (is_function_var_in_context ? 1 : 0);
    2406             : }
    2407             : 
    2408             : }  // namespace internal
    2409             : }  // namespace v8

Generated by: LCOV version 1.10