LCOV - code coverage report
Current view: top level - src/ast - scopes.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 677 712 95.1 %
Date: 2019-04-17 Functions: 98 114 86.0 %

          Line data    Source code
       1             : // Copyright 2012 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/ast/scopes.h"
       6             : 
       7             : #include <set>
       8             : 
       9             : #include "src/accessors.h"
      10             : #include "src/ast/ast.h"
      11             : #include "src/base/optional.h"
      12             : #include "src/bootstrapper.h"
      13             : #include "src/counters.h"
      14             : #include "src/message-template.h"
      15             : #include "src/objects-inl.h"
      16             : #include "src/objects/module-inl.h"
      17             : #include "src/objects/scope-info.h"
      18             : #include "src/parsing/parse-info.h"
      19             : #include "src/parsing/parser.h"
      20             : #include "src/parsing/preparse-data.h"
      21             : #include "src/zone/zone-list-inl.h"
      22             : 
      23             : namespace v8 {
      24             : namespace internal {
      25             : 
      26             : // ----------------------------------------------------------------------------
      27             : // Implementation of LocalsMap
      28             : //
      29             : // Note: We are storing the handle locations as key values in the hash map.
      30             : //       When inserting a new variable via Declare(), we rely on the fact that
      31             : //       the handle location remains alive for the duration of that variable
      32             : //       use. Because a Variable holding a handle with the same location exists
      33             : //       this is ensured.
      34             : 
      35           0 : VariableMap::VariableMap(Zone* zone)
      36           0 :     : ZoneHashMap(8, ZoneAllocationPolicy(zone)) {}
      37             : 
      38    40444898 : Variable* VariableMap::Declare(Zone* zone, Scope* scope,
      39             :                                const AstRawString* name, VariableMode mode,
      40             :                                VariableKind kind,
      41             :                                InitializationFlag initialization_flag,
      42             :                                MaybeAssignedFlag maybe_assigned_flag,
      43             :                                bool* was_added) {
      44             :   // AstRawStrings are unambiguous, i.e., the same string is always represented
      45             :   // by the same AstRawString*.
      46             :   // FIXME(marja): fix the type of Lookup.
      47             :   Entry* p =
      48    80889871 :       ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->Hash(),
      49             :                                   ZoneAllocationPolicy(zone));
      50    40444973 :   *was_added = p->value == nullptr;
      51    40444973 :   if (*was_added) {
      52             :     // The variable has not been declared yet -> insert it.
      53             :     DCHECK_EQ(name, p->key);
      54             :     Variable* variable = new (zone) Variable(
      55             :         scope, name, mode, kind, initialization_flag, maybe_assigned_flag);
      56    39284423 :     p->value = variable;
      57             :   }
      58    40444482 :   return reinterpret_cast<Variable*>(p->value);
      59             : }
      60             : 
      61           0 : void VariableMap::Remove(Variable* var) {
      62             :   const AstRawString* name = var->raw_name();
      63        3919 :   ZoneHashMap::Remove(const_cast<AstRawString*>(name), name->Hash());
      64           0 : }
      65             : 
      66     1015926 : void VariableMap::Add(Zone* zone, Variable* var) {
      67             :   const AstRawString* name = var->raw_name();
      68             :   Entry* p =
      69     1015929 :       ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->Hash(),
      70             :                                   ZoneAllocationPolicy(zone));
      71             :   DCHECK_NULL(p->value);
      72             :   DCHECK_EQ(name, p->key);
      73     1015929 :   p->value = var;
      74     1015929 : }
      75             : 
      76    89431831 : Variable* VariableMap::Lookup(const AstRawString* name) {
      77             :   Entry* p = ZoneHashMap::Lookup(const_cast<AstRawString*>(name), name->Hash());
      78    89431831 :   if (p != nullptr) {
      79             :     DCHECK(reinterpret_cast<const AstRawString*>(p->key) == name);
      80             :     DCHECK_NOT_NULL(p->value);
      81    39283926 :     return reinterpret_cast<Variable*>(p->value);
      82             :   }
      83             :   return nullptr;
      84             : }
      85             : 
      86             : // ----------------------------------------------------------------------------
      87             : // Implementation of Scope
      88             : 
      89     2990137 : Scope::Scope(Zone* zone)
      90             :     : zone_(zone),
      91             :       outer_scope_(nullptr),
      92             :       variables_(zone),
      93     5980286 :       scope_type_(SCRIPT_SCOPE) {
      94             :   SetDefaults();
      95     2990149 : }
      96             : 
      97    13042033 : Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type)
      98             :     : zone_(zone),
      99             :       outer_scope_(outer_scope),
     100             :       variables_(zone),
     101    26084137 :       scope_type_(scope_type) {
     102             :   DCHECK_NE(SCRIPT_SCOPE, scope_type);
     103             :   SetDefaults();
     104             :   set_language_mode(outer_scope->language_mode());
     105    13042104 :   outer_scope_->AddInnerScope(this);
     106    13042104 : }
     107             : 
     108     2990138 : DeclarationScope::DeclarationScope(Zone* zone,
     109             :                                    AstValueFactory* ast_value_factory)
     110     5980287 :     : Scope(zone), function_kind_(kNormalFunction), params_(4, zone) {
     111             :   DCHECK_EQ(scope_type_, SCRIPT_SCOPE);
     112     2990149 :   SetDefaults();
     113             :   receiver_ = DeclareDynamicGlobal(ast_value_factory->this_string(),
     114     2990140 :                                    THIS_VARIABLE, this);
     115     2990140 : }
     116             : 
     117     6872475 : DeclarationScope::DeclarationScope(Zone* zone, Scope* outer_scope,
     118             :                                    ScopeType scope_type,
     119             :                                    FunctionKind function_kind)
     120             :     : Scope(zone, outer_scope, scope_type),
     121             :       function_kind_(function_kind),
     122    13744998 :       params_(4, zone) {
     123             :   DCHECK_NE(scope_type, SCRIPT_SCOPE);
     124     6872523 :   SetDefaults();
     125     6872507 : }
     126             : 
     127       71725 : ModuleScope::ModuleScope(DeclarationScope* script_scope,
     128             :                          AstValueFactory* avfactory)
     129             :     : DeclarationScope(avfactory->zone(), script_scope, MODULE_SCOPE, kModule),
     130             :       module_descriptor_(new (avfactory->zone())
     131      143450 :                              ModuleDescriptor(avfactory->zone())) {
     132             :   set_language_mode(LanguageMode::kStrict);
     133       71725 :   DeclareThis(avfactory);
     134       71725 : }
     135             : 
     136           0 : ModuleScope::ModuleScope(Isolate* isolate, Handle<ScopeInfo> scope_info,
     137             :                          AstValueFactory* avfactory)
     138             :     : DeclarationScope(avfactory->zone(), MODULE_SCOPE, scope_info),
     139        3263 :       module_descriptor_(nullptr) {
     140             :   set_language_mode(LanguageMode::kStrict);
     141           0 : }
     142             : 
     143      316072 : ClassScope::ClassScope(Zone* zone, Scope* outer_scope)
     144      316072 :     : Scope(zone, outer_scope, CLASS_SCOPE) {
     145             :   set_language_mode(LanguageMode::kStrict);
     146      316072 : }
     147             : 
     148           0 : ClassScope::ClassScope(Zone* zone, Handle<ScopeInfo> scope_info)
     149      153480 :     : Scope(zone, CLASS_SCOPE, scope_info) {
     150             :   set_language_mode(LanguageMode::kStrict);
     151           0 : }
     152             : 
     153     1103626 : Scope::Scope(Zone* zone, ScopeType scope_type, Handle<ScopeInfo> scope_info)
     154             :     : zone_(zone),
     155             :       outer_scope_(nullptr),
     156             :       variables_(zone),
     157             :       scope_info_(scope_info),
     158     2207258 :       scope_type_(scope_type) {
     159             :   DCHECK(!scope_info.is_null());
     160             :   SetDefaults();
     161             : #ifdef DEBUG
     162             :   already_resolved_ = true;
     163             : #endif
     164     1103632 :   if (scope_info->CallsSloppyEval()) scope_calls_eval_ = true;
     165     2207264 :   set_language_mode(scope_info->language_mode());
     166     1103632 :   num_heap_slots_ = scope_info->ContextLength();
     167             :   DCHECK_LE(Context::MIN_CONTEXT_SLOTS, num_heap_slots_);
     168             :   // We don't really need to use the preparsed scope data; this is just to
     169             :   // shorten the recursion in SetMustUsePreparseData.
     170     1103633 :   must_use_preparsed_scope_data_ = true;
     171     1103633 : }
     172             : 
     173      905022 : DeclarationScope::DeclarationScope(Zone* zone, ScopeType scope_type,
     174             :                                    Handle<ScopeInfo> scope_info)
     175             :     : Scope(zone, scope_type, scope_info),
     176     1810053 :       function_kind_(scope_info->function_kind()),
     177     3620100 :       params_(0, zone) {
     178             :   DCHECK_NE(scope_type, SCRIPT_SCOPE);
     179      905026 :   SetDefaults();
     180      905026 : }
     181             : 
     182        5042 : Scope::Scope(Zone* zone, const AstRawString* catch_variable_name,
     183             :              MaybeAssignedFlag maybe_assigned, Handle<ScopeInfo> scope_info)
     184             :     : zone_(zone),
     185             :       outer_scope_(nullptr),
     186             :       variables_(zone),
     187             :       scope_info_(scope_info),
     188       10084 :       scope_type_(CATCH_SCOPE) {
     189             :   SetDefaults();
     190             : #ifdef DEBUG
     191             :   already_resolved_ = true;
     192             : #endif
     193             :   // Cache the catch variable, even though it's also available via the
     194             :   // scope_info, as the parser expects that a catch scope always has the catch
     195             :   // variable as first and only variable.
     196             :   bool was_added;
     197             :   Variable* variable =
     198             :       Declare(zone, catch_variable_name, VariableMode::kVar, NORMAL_VARIABLE,
     199             :               kCreatedInitialized, maybe_assigned, &was_added);
     200             :   DCHECK(was_added);
     201             :   AllocateHeapSlot(variable);
     202        5042 : }
     203             : 
     204    10767671 : void DeclarationScope::SetDefaults() {
     205    10767671 :   is_declaration_scope_ = true;
     206    10767671 :   has_simple_parameters_ = true;
     207    10767671 :   is_asm_module_ = false;
     208    10767671 :   force_eager_compilation_ = false;
     209    10767671 :   has_arguments_parameter_ = false;
     210    10767671 :   scope_uses_super_property_ = false;
     211    10767671 :   has_checked_syntax_ = false;
     212    10767671 :   has_this_reference_ = false;
     213             :   has_this_declaration_ =
     214    17296992 :       (is_function_scope() && !is_arrow_scope()) || is_module_scope();
     215    10767671 :   has_rest_ = false;
     216    10767671 :   receiver_ = nullptr;
     217    10767671 :   new_target_ = nullptr;
     218    10767671 :   function_ = nullptr;
     219    10767671 :   arguments_ = nullptr;
     220    10767671 :   rare_data_ = nullptr;
     221    10767671 :   should_eager_compile_ = false;
     222    10767671 :   was_lazily_parsed_ = false;
     223    10767671 :   is_skipped_function_ = false;
     224    10767671 :   preparse_data_builder_ = nullptr;
     225             : #ifdef DEBUG
     226             :   DeclarationScope* outer_declaration_scope =
     227             :       outer_scope_ ? outer_scope_->GetDeclarationScope() : nullptr;
     228             :   is_being_lazily_parsed_ =
     229             :       outer_declaration_scope ? outer_declaration_scope->is_being_lazily_parsed_
     230             :                               : false;
     231             : #endif
     232    10767671 : }
     233             : 
     234           0 : void Scope::SetDefaults() {
     235             : #ifdef DEBUG
     236             :   scope_name_ = nullptr;
     237             :   already_resolved_ = false;
     238             :   needs_migration_ = false;
     239             : #endif
     240    17140927 :   inner_scope_ = nullptr;
     241    17140927 :   sibling_ = nullptr;
     242             :   unresolved_list_.Clear();
     243             : 
     244    17140927 :   start_position_ = kNoSourcePosition;
     245    17140927 :   end_position_ = kNoSourcePosition;
     246             : 
     247    17140927 :   num_stack_slots_ = 0;
     248    17140927 :   num_heap_slots_ = Context::MIN_CONTEXT_SLOTS;
     249             : 
     250             :   set_language_mode(LanguageMode::kSloppy);
     251             : 
     252    17140927 :   scope_calls_eval_ = false;
     253    17140927 :   scope_nonlinear_ = false;
     254    17140927 :   is_hidden_ = false;
     255    17140927 :   is_debug_evaluate_scope_ = false;
     256             : 
     257    17140927 :   inner_scope_calls_eval_ = false;
     258    17140927 :   force_context_allocation_ = false;
     259    17140927 :   force_context_allocation_for_parameters_ = false;
     260             : 
     261    17140927 :   is_declaration_scope_ = false;
     262             : 
     263    17140927 :   must_use_preparsed_scope_data_ = false;
     264           0 : }
     265             : 
     266      432267 : bool Scope::HasSimpleParameters() {
     267             :   DeclarationScope* scope = GetClosureScope();
     268      586639 :   return !scope->is_function_scope() || scope->has_simple_parameters();
     269             : }
     270             : 
     271      726111 : void DeclarationScope::set_should_eager_compile() {
     272     2544162 :   should_eager_compile_ = !was_lazily_parsed_;
     273      726111 : }
     274             : 
     275        5889 : void DeclarationScope::set_is_asm_module() { is_asm_module_ = true; }
     276             : 
     277     1806500 : bool Scope::IsAsmModule() const {
     278     7549083 :   return is_function_scope() && AsDeclarationScope()->is_asm_module();
     279             : }
     280             : 
     281        6375 : bool Scope::ContainsAsmModule() const {
     282        6375 :   if (IsAsmModule()) return true;
     283             : 
     284             :   // Check inner scopes recursively
     285        2553 :   for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
     286             :     // Don't check inner functions which won't be eagerly compiled.
     287        5015 :     if (!scope->is_function_scope() ||
     288             :         scope->AsDeclarationScope()->ShouldEagerCompile()) {
     289        2129 :       if (scope->ContainsAsmModule()) return true;
     290             :     }
     291             :   }
     292             : 
     293             :   return false;
     294             : }
     295             : 
     296     1021725 : Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone,
     297             :                                     ScopeInfo scope_info,
     298             :                                     DeclarationScope* script_scope,
     299             :                                     AstValueFactory* ast_value_factory,
     300             :                                     DeserializationMode deserialization_mode) {
     301             :   // Reconstruct the outer scope chain from a closure's context chain.
     302             :   Scope* current_scope = nullptr;
     303             :   Scope* innermost_scope = nullptr;
     304             :   Scope* outer_scope = nullptr;
     305     2130398 :   while (!scope_info.is_null()) {
     306     1442507 :     if (scope_info->scope_type() == WITH_SCOPE) {
     307       14853 :       if (scope_info->IsDebugEvaluateScope()) {
     308             :         outer_scope = new (zone)
     309       25514 :             DeclarationScope(zone, FUNCTION_SCOPE, handle(scope_info, isolate));
     310             :         outer_scope->set_is_debug_evaluate_scope();
     311             :       } else {
     312             :         // For scope analysis, debug-evaluate is equivalent to a with scope.
     313             :         outer_scope =
     314        4192 :             new (zone) Scope(zone, WITH_SCOPE, handle(scope_info, isolate));
     315             :       }
     316             : 
     317     1427655 :     } else if (scope_info->scope_type() == SCRIPT_SCOPE) {
     318             :       // If we reach a script scope, it's the outermost scope. Install the
     319             :       // scope info of this script context onto the existing script scope to
     320             :       // avoid nesting script scopes.
     321      333835 :       if (deserialization_mode == DeserializationMode::kIncludingVariables) {
     322             :         script_scope->SetScriptScopeInfo(handle(scope_info, isolate));
     323             :       }
     324             :       DCHECK(!scope_info->HasOuterScopeInfo());
     325             :       break;
     326     1093822 :     } else if (scope_info->scope_type() == FUNCTION_SCOPE) {
     327             :       outer_scope = new (zone)
     328     1706884 :           DeclarationScope(zone, FUNCTION_SCOPE, handle(scope_info, isolate));
     329      853442 :       if (scope_info->IsAsmModule()) {
     330             :         outer_scope->AsDeclarationScope()->set_is_asm_module();
     331             :       }
     332      240378 :     } else if (scope_info->scope_type() == EVAL_SCOPE) {
     333             :       outer_scope = new (zone)
     334       52840 :           DeclarationScope(zone, EVAL_SCOPE, handle(scope_info, isolate));
     335      213957 :     } else if (scope_info->scope_type() == CLASS_SCOPE) {
     336             :       outer_scope = new (zone) ClassScope(zone, handle(scope_info, isolate));
     337       60476 :     } else if (scope_info->scope_type() == BLOCK_SCOPE) {
     338       52171 :       if (scope_info->is_declaration_scope()) {
     339             :         outer_scope = new (zone)
     340       18283 :             DeclarationScope(zone, BLOCK_SCOPE, handle(scope_info, isolate));
     341             :       } else {
     342             :         outer_scope =
     343       86056 :             new (zone) Scope(zone, BLOCK_SCOPE, handle(scope_info, isolate));
     344             :       }
     345        8305 :     } else if (scope_info->scope_type() == MODULE_SCOPE) {
     346             :       outer_scope = new (zone)
     347             :           ModuleScope(isolate, handle(scope_info, isolate), ast_value_factory);
     348             :     } else {
     349             :       DCHECK_EQ(scope_info->scope_type(), CATCH_SCOPE);
     350             :       DCHECK_EQ(scope_info->ContextLocalCount(), 1);
     351             :       DCHECK_EQ(scope_info->ContextLocalMode(0), VariableMode::kVar);
     352             :       DCHECK_EQ(scope_info->ContextLocalInitFlag(0), kCreatedInitialized);
     353        5042 :       String name = scope_info->ContextLocalName(0);
     354             :       MaybeAssignedFlag maybe_assigned =
     355        5042 :           scope_info->ContextLocalMaybeAssignedFlag(0);
     356             :       outer_scope = new (zone)
     357             :           Scope(zone, ast_value_factory->GetString(handle(name, isolate)),
     358       15126 :                 maybe_assigned, handle(scope_info, isolate));
     359             :     }
     360     1108673 :     if (deserialization_mode == DeserializationMode::kScopesOnly) {
     361           0 :       outer_scope->scope_info_ = Handle<ScopeInfo>::null();
     362             :     }
     363     1108673 :     if (current_scope != nullptr) {
     364             :       outer_scope->AddInnerScope(current_scope);
     365             :     }
     366             :     current_scope = outer_scope;
     367     1108673 :     if (innermost_scope == nullptr) innermost_scope = current_scope;
     368     1108673 :     scope_info = scope_info->HasOuterScopeInfo() ? scope_info->OuterScopeInfo()
     369     1108672 :                                                  : ScopeInfo();
     370             :   }
     371             : 
     372     2043453 :   if (deserialization_mode == DeserializationMode::kIncludingVariables &&
     373             :       script_scope->scope_info_.is_null()) {
     374             :     Handle<ScriptContextTable> table(
     375     2063679 :         isolate->native_context()->script_context_table(), isolate);
     376      687893 :     Handle<Context> first = ScriptContextTable::GetContext(isolate, table, 0);
     377     1375786 :     Handle<ScopeInfo> scope_info(first->scope_info(), isolate);
     378             :     script_scope->SetScriptScopeInfo(scope_info);
     379             :   }
     380             : 
     381     1021726 :   if (innermost_scope == nullptr) return script_scope;
     382      867898 :   script_scope->AddInnerScope(current_scope);
     383      867898 :   return innermost_scope;
     384             : }
     385             : 
     386   154834575 : DeclarationScope* Scope::AsDeclarationScope() {
     387             :   DCHECK(is_declaration_scope());
     388   154834575 :   return static_cast<DeclarationScope*>(this);
     389             : }
     390             : 
     391           0 : const DeclarationScope* Scope::AsDeclarationScope() const {
     392             :   DCHECK(is_declaration_scope());
     393           0 :   return static_cast<const DeclarationScope*>(this);
     394             : }
     395             : 
     396       55331 : ModuleScope* Scope::AsModuleScope() {
     397             :   DCHECK(is_module_scope());
     398       55331 :   return static_cast<ModuleScope*>(this);
     399             : }
     400             : 
     401           0 : const ModuleScope* Scope::AsModuleScope() const {
     402             :   DCHECK(is_module_scope());
     403           0 :   return static_cast<const ModuleScope*>(this);
     404             : }
     405             : 
     406           0 : ClassScope* Scope::AsClassScope() {
     407             :   DCHECK(is_class_scope());
     408           0 :   return static_cast<ClassScope*>(this);
     409             : }
     410             : 
     411           0 : const ClassScope* Scope::AsClassScope() const {
     412             :   DCHECK(is_class_scope());
     413           0 :   return static_cast<const ClassScope*>(this);
     414             : }
     415             : 
     416       11637 : void DeclarationScope::DeclareSloppyBlockFunction(
     417             :     SloppyBlockFunctionStatement* sloppy_block_function) {
     418             :   sloppy_block_functions_.Add(sloppy_block_function);
     419       11637 : }
     420             : 
     421     5154785 : void DeclarationScope::HoistSloppyBlockFunctions(AstNodeFactory* factory) {
     422             :   DCHECK(is_sloppy(language_mode()));
     423             :   DCHECK(is_function_scope() || is_eval_scope() || is_script_scope() ||
     424             :          (is_block_scope() && outer_scope()->is_function_scope()));
     425             :   DCHECK(HasSimpleParameters() || is_block_scope() || is_being_lazily_parsed_);
     426             :   DCHECK_EQ(factory == nullptr, is_being_lazily_parsed_);
     427             : 
     428     5154785 :   if (sloppy_block_functions_.is_empty()) return;
     429             : 
     430             :   // In case of complex parameters the current scope is the body scope and the
     431             :   // parameters are stored in the outer scope.
     432       10275 :   Scope* parameter_scope = HasSimpleParameters() ? this : outer_scope_;
     433             :   DCHECK(parameter_scope->is_function_scope() || is_eval_scope() ||
     434             :          is_script_scope());
     435             : 
     436             :   DeclarationScope* decl_scope = this;
     437       11637 :   while (decl_scope->is_eval_scope()) {
     438             :     decl_scope = decl_scope->outer_scope()->GetDeclarationScope();
     439             :   }
     440             :   Scope* outer_scope = decl_scope->outer_scope();
     441             : 
     442             :   // For each variable which is used as a function declaration in a sloppy
     443             :   // block,
     444       21833 :   for (SloppyBlockFunctionStatement* sloppy_block_function :
     445       11558 :        sloppy_block_functions_) {
     446             :     const AstRawString* name = sloppy_block_function->name();
     447             : 
     448             :     // If the variable wouldn't conflict with a lexical declaration
     449             :     // or parameter,
     450             : 
     451             :     // Check if there's a conflict with a parameter.
     452             :     Variable* maybe_parameter = parameter_scope->LookupLocal(name);
     453       14343 :     if (maybe_parameter != nullptr && maybe_parameter->is_parameter()) {
     454             :       continue;
     455             :     }
     456             : 
     457             :     // Check if there's a conflict with a lexical declaration
     458             :     Scope* query_scope = sloppy_block_function->scope()->outer_scope();
     459             :     Variable* var = nullptr;
     460             :     bool should_hoist = true;
     461             : 
     462             :     // It is not sufficient to just do a Lookup on query_scope: for
     463             :     // example, that does not prevent hoisting of the function in
     464             :     // `{ let e; try {} catch (e) { function e(){} } }`
     465             :     do {
     466       16261 :       var = query_scope->LookupInScopeOrScopeInfo(name);
     467       19528 :       if (var != nullptr && IsLexicalVariableMode(var->mode())) {
     468             :         should_hoist = false;
     469             :         break;
     470             :       }
     471             :       query_scope = query_scope->outer_scope();
     472       14855 :     } while (query_scope != outer_scope);
     473             : 
     474       11365 :     if (!should_hoist) continue;
     475             : 
     476        9959 :     if (factory) {
     477             :       DCHECK(!is_being_lazily_parsed_);
     478             :       int pos = sloppy_block_function->position();
     479        7527 :       bool ok = true;
     480             :       bool was_added;
     481             :       auto declaration = factory->NewVariableDeclaration(pos);
     482             :       // Based on the preceding checks, it doesn't matter what we pass as
     483             :       // sloppy_mode_block_scope_function_redefinition.
     484             :       Variable* var = DeclareVariable(
     485             :           declaration, name, pos, VariableMode::kVar, NORMAL_VARIABLE,
     486             :           Variable::DefaultInitializationFlag(VariableMode::kVar), &was_added,
     487        7527 :           nullptr, &ok);
     488             :       DCHECK(ok);
     489             :       VariableProxy* source =
     490             :           factory->NewVariableProxy(sloppy_block_function->var());
     491             :       VariableProxy* target = factory->NewVariableProxy(var);
     492        7527 :       Assignment* assignment = factory->NewAssignment(
     493        7527 :           sloppy_block_function->init(), target, source, pos);
     494             :       assignment->set_lookup_hoisting_mode(LookupHoistingMode::kLegacySloppy);
     495             :       Statement* statement = factory->NewExpressionStatement(assignment, pos);
     496             :       sloppy_block_function->set_statement(statement);
     497             :     } else {
     498             :       DCHECK(is_being_lazily_parsed_);
     499             :       bool was_added;
     500        2432 :       Variable* var = DeclareVariableName(name, VariableMode::kVar, &was_added);
     501        2432 :       if (sloppy_block_function->init() == Token::ASSIGN)
     502             :         var->set_maybe_assigned();
     503             :     }
     504             :   }
     505             : }
     506             : 
     507     1818051 : bool DeclarationScope::Analyze(ParseInfo* info) {
     508             :   RuntimeCallTimerScope runtimeTimer(
     509             :       info->runtime_call_stats(),
     510             :       info->on_background_thread()
     511             :           ? RuntimeCallCounterId::kCompileBackgroundScopeAnalysis
     512     1818051 :           : RuntimeCallCounterId::kCompileScopeAnalysis);
     513             :   DCHECK_NOT_NULL(info->literal());
     514             :   DeclarationScope* scope = info->literal()->scope();
     515             : 
     516             :   base::Optional<AllowHandleDereference> allow_deref;
     517             :   if (!info->maybe_outer_scope_info().is_null()) {
     518             :     // Allow dereferences to the scope info if there is one.
     519             :     allow_deref.emplace();
     520             :   }
     521             : 
     522     2679107 :   if (scope->is_eval_scope() && is_sloppy(scope->language_mode())) {
     523      734968 :     AstNodeFactory factory(info->ast_value_factory(), info->zone());
     524      734968 :     scope->HoistSloppyBlockFunctions(&factory);
     525             :   }
     526             : 
     527             :   // We are compiling one of four cases:
     528             :   // 1) top-level code,
     529             :   // 2) a function/eval/module on the top-level
     530             :   // 3) a function/eval in a scope that was already resolved.
     531             :   DCHECK(scope->is_script_scope() || scope->outer_scope()->is_script_scope() ||
     532             :          scope->outer_scope()->already_resolved_);
     533             : 
     534             :   // The outer scope is never lazy.
     535             :   scope->set_should_eager_compile();
     536             : 
     537     1818051 :   if (scope->must_use_preparsed_scope_data_) {
     538             :     DCHECK_EQ(scope->scope_type_, ScopeType::FUNCTION_SCOPE);
     539             :     allow_deref.emplace();
     540       36544 :     info->consumed_preparse_data()->RestoreScopeAllocationData(scope);
     541             :   }
     542             : 
     543     1818051 :   if (!scope->AllocateVariables(info)) return false;
     544             : 
     545             : #ifdef DEBUG
     546             :   if (FLAG_print_scopes) {
     547             :     PrintF("Global scope:\n");
     548             :     scope->Print();
     549             :   }
     550             :   scope->CheckScopePositions();
     551             :   scope->CheckZones();
     552             : #endif
     553             : 
     554     1818047 :   return true;
     555             : }
     556             : 
     557     5303476 : void DeclarationScope::DeclareThis(AstValueFactory* ast_value_factory) {
     558             :   DCHECK(has_this_declaration());
     559             : 
     560     5303476 :   bool derived_constructor = IsDerivedConstructor(function_kind_);
     561             : 
     562             :   receiver_ = new (zone())
     563             :       Variable(this, ast_value_factory->this_string(),
     564             :                derived_constructor ? VariableMode::kConst : VariableMode::kVar,
     565             :                THIS_VARIABLE,
     566             :                derived_constructor ? kNeedsInitialization : kCreatedInitialized,
     567    10606962 :                kNotAssigned);
     568     5303481 : }
     569             : 
     570     4156434 : void DeclarationScope::DeclareArguments(AstValueFactory* ast_value_factory) {
     571             :   DCHECK(is_function_scope());
     572             :   DCHECK(!is_arrow_scope());
     573             : 
     574             :   // Declare 'arguments' variable which exists in all non arrow functions.  Note
     575             :   // that it might never be accessed, in which case it won't be allocated during
     576             :   // variable allocation.
     577             :   bool was_added;
     578             :   arguments_ =
     579     4156434 :       Declare(zone(), ast_value_factory->arguments_string(), VariableMode::kVar,
     580     4156478 :               NORMAL_VARIABLE, kCreatedInitialized, kNotAssigned, &was_added);
     581     4159239 :   if (!was_added && IsLexicalVariableMode(arguments_->mode())) {
     582             :     // Check if there's lexically declared variable named arguments to avoid
     583             :     // redeclaration. See ES#sec-functiondeclarationinstantiation, step 20.
     584         622 :     arguments_ = nullptr;
     585             :   }
     586     4156478 : }
     587             : 
     588     4590066 : void DeclarationScope::DeclareDefaultFunctionVariables(
     589             :     AstValueFactory* ast_value_factory) {
     590             :   DCHECK(is_function_scope());
     591             :   DCHECK(!is_arrow_scope());
     592             : 
     593     4590066 :   DeclareThis(ast_value_factory);
     594             :   bool was_added;
     595     4590070 :   new_target_ = Declare(zone(), ast_value_factory->new_target_string(),
     596             :                         VariableMode::kConst, NORMAL_VARIABLE,
     597     4590062 :                         kCreatedInitialized, kNotAssigned, &was_added);
     598             :   DCHECK(was_added);
     599             : 
     600    16836117 :   if (IsConciseMethod(function_kind_) || IsClassConstructor(function_kind_) ||
     601             :       IsAccessorFunction(function_kind_)) {
     602             :     EnsureRareData()->this_function = Declare(
     603             :         zone(), ast_value_factory->this_function_string(), VariableMode::kConst,
     604      945490 :         NORMAL_VARIABLE, kCreatedInitialized, kNotAssigned, &was_added);
     605             :     DCHECK(was_added);
     606             :   }
     607     4590067 : }
     608             : 
     609     1016824 : Variable* DeclarationScope::DeclareFunctionVar(const AstRawString* name,
     610             :                                                Scope* cache) {
     611             :   DCHECK(is_function_scope());
     612             :   DCHECK_NULL(function_);
     613     1016824 :   if (cache == nullptr) cache = this;
     614             :   DCHECK_NULL(cache->variables_.Lookup(name));
     615             :   VariableKind kind = is_sloppy(language_mode()) ? SLOPPY_FUNCTION_NAME_VARIABLE
     616     1016824 :                                                  : NORMAL_VARIABLE;
     617             :   function_ = new (zone())
     618     2033652 :       Variable(this, name, VariableMode::kConst, kind, kCreatedInitialized);
     619     1016826 :   if (calls_sloppy_eval()) {
     620         899 :     cache->NonLocal(name, VariableMode::kDynamic);
     621             :   } else {
     622     1015927 :     cache->variables_.Add(zone(), function_);
     623             :   }
     624     1016829 :   return function_;
     625             : }
     626             : 
     627      142482 : Variable* DeclarationScope::DeclareGeneratorObjectVar(
     628             :     const AstRawString* name) {
     629             :   DCHECK(is_function_scope() || is_module_scope());
     630             :   DCHECK_NULL(generator_object_var());
     631             : 
     632             :   Variable* result = EnsureRareData()->generator_object =
     633      142482 :       NewTemporary(name, kNotAssigned);
     634             :   result->set_is_used();
     635      142482 :   return result;
     636             : }
     637             : 
     638     5290237 : Scope* Scope::FinalizeBlockScope() {
     639             :   DCHECK(is_block_scope());
     640             : #ifdef DEBUG
     641             :   DCHECK_NE(sibling_, this);
     642             : #endif
     643             : 
     644    15083419 :   if (variables_.occupancy() > 0 ||
     645       70414 :       (is_declaration_scope() && AsDeclarationScope()->calls_sloppy_eval())) {
     646             :     return this;
     647             :   }
     648             : 
     649             :   DCHECK(!is_class_scope());
     650             : 
     651             :   // Remove this scope from outer scope.
     652             :   outer_scope()->RemoveInnerScope(this);
     653             : 
     654             :   // Reparent inner scopes.
     655     4500498 :   if (inner_scope_ != nullptr) {
     656             :     Scope* scope = inner_scope_;
     657      561935 :     scope->outer_scope_ = outer_scope();
     658      652033 :     while (scope->sibling_ != nullptr) {
     659             :       scope = scope->sibling_;
     660       45049 :       scope->outer_scope_ = outer_scope();
     661             :     }
     662      561935 :     scope->sibling_ = outer_scope()->inner_scope_;
     663      561935 :     outer_scope()->inner_scope_ = inner_scope_;
     664      561935 :     inner_scope_ = nullptr;
     665             :   }
     666             : 
     667             :   // Move unresolved variables
     668     4500498 :   if (!unresolved_list_.is_empty()) {
     669             :     outer_scope()->unresolved_list_.Prepend(std::move(unresolved_list_));
     670             :     unresolved_list_.Clear();
     671             :   }
     672             : 
     673     4500498 :   if (inner_scope_calls_eval_) outer_scope()->inner_scope_calls_eval_ = true;
     674             : 
     675             :   // No need to propagate scope_calls_eval_, since if it was relevant to
     676             :   // this scope we would have had to bail out at the top.
     677             :   DCHECK(!scope_calls_eval_ || !is_declaration_scope() ||
     678             :          !is_sloppy(language_mode()));
     679             : 
     680             :   // This block does not need a context.
     681     4500498 :   num_heap_slots_ = 0;
     682             : 
     683             :   // Mark scope as removed by making it its own sibling.
     684             : #ifdef DEBUG
     685             :   sibling_ = this;
     686             : #endif
     687             : 
     688     4500498 :   return nullptr;
     689             : }
     690             : 
     691           0 : void DeclarationScope::AddLocal(Variable* var) {
     692             :   DCHECK(!already_resolved_);
     693             :   // Temporaries are only placed in ClosureScopes.
     694             :   DCHECK_EQ(GetClosureScope(), this);
     695             :   locals_.Add(var);
     696           0 : }
     697             : 
     698      133518 : void Scope::Snapshot::Reparent(DeclarationScope* new_parent) {
     699             :   DCHECK(!IsCleared());
     700             :   DCHECK_EQ(new_parent, outer_scope_and_calls_eval_.GetPointer()->inner_scope_);
     701             :   DCHECK_EQ(new_parent->outer_scope_, outer_scope_and_calls_eval_.GetPointer());
     702             :   DCHECK_EQ(new_parent, new_parent->GetClosureScope());
     703             :   DCHECK_NULL(new_parent->inner_scope_);
     704             :   DCHECK(new_parent->unresolved_list_.is_empty());
     705      133518 :   Scope* inner_scope = new_parent->sibling_;
     706      133518 :   if (inner_scope != top_inner_scope_) {
     707        3644 :     for (; inner_scope->sibling() != top_inner_scope_;
     708             :          inner_scope = inner_scope->sibling()) {
     709           0 :       inner_scope->outer_scope_ = new_parent;
     710           0 :       if (inner_scope->inner_scope_calls_eval_) {
     711           0 :         new_parent->inner_scope_calls_eval_ = true;
     712             :       }
     713             :       DCHECK_NE(inner_scope, new_parent);
     714             :     }
     715        3644 :     inner_scope->outer_scope_ = new_parent;
     716        3644 :     if (inner_scope->inner_scope_calls_eval_) {
     717         128 :       new_parent->inner_scope_calls_eval_ = true;
     718             :     }
     719        3644 :     new_parent->inner_scope_ = new_parent->sibling_;
     720        3644 :     inner_scope->sibling_ = nullptr;
     721             :     // Reset the sibling rather than the inner_scope_ since we
     722             :     // want to keep new_parent there.
     723        3644 :     new_parent->sibling_ = top_inner_scope_;
     724             :   }
     725             : 
     726             :   Scope* outer_scope_ = outer_scope_and_calls_eval_.GetPointer();
     727             :   new_parent->unresolved_list_.MoveTail(&outer_scope_->unresolved_list_,
     728             :                                         top_unresolved_);
     729             : 
     730             :   // Move temporaries allocated for complex parameter initializers.
     731             :   DeclarationScope* outer_closure = outer_scope_->GetClosureScope();
     732      133518 :   for (auto it = top_local_; it != outer_closure->locals()->end(); ++it) {
     733          12 :     Variable* local = *it;
     734             :     DCHECK_EQ(VariableMode::kTemporary, local->mode());
     735             :     DCHECK_EQ(local->scope(), local->scope()->GetClosureScope());
     736             :     DCHECK_NE(local->scope(), new_parent);
     737             :     local->set_scope(new_parent);
     738             :   }
     739             :   new_parent->locals_.MoveTail(outer_closure->locals(), top_local_);
     740             :   outer_closure->locals_.Rewind(top_local_);
     741             : 
     742             :   // Move eval calls since Snapshot's creation into new_parent.
     743      133518 :   if (outer_scope_and_calls_eval_->scope_calls_eval_) {
     744         419 :     new_parent->scope_calls_eval_ = true;
     745         419 :     new_parent->inner_scope_calls_eval_ = true;
     746             :   }
     747             : 
     748             :   // We are in the arrow function case. The calls eval we may have recorded
     749             :   // is intended for the inner scope and we should simply restore the
     750             :   // original "calls eval" flag of the outer scope.
     751             :   RestoreEvalFlag();
     752             :   Clear();
     753      133518 : }
     754             : 
     755          91 : void Scope::ReplaceOuterScope(Scope* outer) {
     756             :   DCHECK_NOT_NULL(outer);
     757             :   DCHECK_NOT_NULL(outer_scope_);
     758             :   DCHECK(!already_resolved_);
     759          91 :   outer_scope_->RemoveInnerScope(this);
     760             :   outer->AddInnerScope(this);
     761             :   outer_scope_ = outer;
     762          91 : }
     763             : 
     764     2512449 : Variable* Scope::LookupInScopeInfo(const AstRawString* name, Scope* cache) {
     765             :   DCHECK(!scope_info_.is_null());
     766             :   DCHECK_NULL(cache->variables_.Lookup(name));
     767             :   DisallowHeapAllocation no_gc;
     768             : 
     769     2512449 :   String name_handle = *name->string();
     770             :   // The Scope is backed up by ScopeInfo. This means it cannot operate in a
     771             :   // heap-independent mode, and all strings must be internalized immediately. So
     772             :   // it's ok to get the Handle<String> here.
     773             :   bool found = false;
     774             : 
     775             :   VariableLocation location;
     776             :   int index;
     777             :   VariableMode mode;
     778             :   InitializationFlag init_flag;
     779             :   MaybeAssignedFlag maybe_assigned_flag;
     780             : 
     781             :   {
     782             :     location = VariableLocation::CONTEXT;
     783             :     index = ScopeInfo::ContextSlotIndex(*scope_info_, name_handle, &mode,
     784     2512449 :                                         &init_flag, &maybe_assigned_flag);
     785     2512454 :     found = index >= 0;
     786             :   }
     787             : 
     788     2512454 :   if (!found && is_module_scope()) {
     789             :     location = VariableLocation::MODULE;
     790        3982 :     index = scope_info_->ModuleIndex(name_handle, &mode, &init_flag,
     791        1991 :                                      &maybe_assigned_flag);
     792        1991 :     found = index != 0;
     793             :   }
     794             : 
     795     2512454 :   if (!found) {
     796     2047346 :     index = scope_info_->FunctionContextSlotIndex(name_handle);
     797     2047348 :     if (index < 0) return nullptr;  // Nowhere found.
     798        1041 :     Variable* var = AsDeclarationScope()->DeclareFunctionVar(name, cache);
     799             :     DCHECK_EQ(VariableMode::kConst, var->mode());
     800             :     var->AllocateTo(VariableLocation::CONTEXT, index);
     801        1041 :     return cache->variables_.Lookup(name);
     802             :   }
     803             : 
     804             :   if (!is_module_scope()) {
     805             :     DCHECK_NE(index, scope_info_->ReceiverContextSlotIndex());
     806             :   }
     807             : 
     808             :   bool was_added;
     809             :   Variable* var =
     810      465108 :       cache->variables_.Declare(zone(), this, name, mode, NORMAL_VARIABLE,
     811      465108 :                                 init_flag, maybe_assigned_flag, &was_added);
     812             :   DCHECK(was_added);
     813             :   var->AllocateTo(location, index);
     814      465105 :   return var;
     815             : }
     816             : 
     817     2939097 : Variable* DeclarationScope::DeclareParameter(const AstRawString* name,
     818             :                                              VariableMode mode,
     819             :                                              bool is_optional, bool is_rest,
     820             :                                              AstValueFactory* ast_value_factory,
     821             :                                              int position) {
     822             :   DCHECK(!already_resolved_);
     823             :   DCHECK(is_function_scope() || is_module_scope());
     824             :   DCHECK(!has_rest_);
     825             :   DCHECK(!is_optional || !is_rest);
     826             :   DCHECK(!is_being_lazily_parsed_);
     827             :   DCHECK(!was_lazily_parsed_);
     828             :   Variable* var;
     829     2939097 :   if (mode == VariableMode::kTemporary) {
     830      219630 :     var = NewTemporary(name);
     831             :   } else {
     832     2829283 :     var = LookupLocal(name);
     833             :     DCHECK_EQ(mode, VariableMode::kVar);
     834             :     DCHECK(var->is_parameter());
     835             :   }
     836     2939098 :   has_rest_ = is_rest;
     837     2939098 :   var->set_initializer_position(position);
     838     2939098 :   params_.Add(var, zone());
     839     2939098 :   if (!is_rest) ++num_parameters_;
     840     2939098 :   if (name == ast_value_factory->arguments_string()) {
     841        1454 :     has_arguments_parameter_ = true;
     842             :   }
     843             :   // Params are automatically marked as used to make sure that the debugger and
     844             :   // function.arguments sees them.
     845             :   // TODO(verwaest): Reevaluate whether we always need to do this, since
     846             :   // strict-mode function.arguments does not make the arguments available.
     847     2939098 :   var->set_is_used();
     848     2939098 :   return var;
     849             : }
     850             : 
     851     4012751 : void DeclarationScope::RecordParameter(bool is_rest) {
     852             :   DCHECK(!already_resolved_);
     853             :   DCHECK(is_function_scope() || is_module_scope());
     854             :   DCHECK(is_being_lazily_parsed_);
     855             :   DCHECK(!has_rest_);
     856     4012751 :   has_rest_ = is_rest;
     857     4012751 :   if (!is_rest) ++num_parameters_;
     858     4012751 : }
     859             : 
     860    24187814 : Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode,
     861             :                               VariableKind kind, bool* was_added,
     862             :                               InitializationFlag init_flag) {
     863             :   DCHECK(!already_resolved_);
     864             :   // This function handles VariableMode::kVar, VariableMode::kLet, and
     865             :   // VariableMode::kConst modes.  VariableMode::kDynamic variables are
     866             :   // introduced during variable allocation, and VariableMode::kTemporary
     867             :   // variables are allocated via NewTemporary().
     868             :   DCHECK(IsDeclaredVariableMode(mode));
     869             :   DCHECK_IMPLIES(GetDeclarationScope()->is_being_lazily_parsed(),
     870             :                  mode == VariableMode::kVar || mode == VariableMode::kLet ||
     871             :                      mode == VariableMode::kConst);
     872             :   DCHECK(!GetDeclarationScope()->was_lazily_parsed());
     873             :   Variable* var =
     874             :       Declare(zone(), name, mode, kind, init_flag, kNotAssigned, was_added);
     875             : 
     876             :   // Pessimistically assume that top-level variables will be assigned and used.
     877             :   //
     878             :   // Top-level variables in a script can be accessed by other scripts or even
     879             :   // become global properties. While this does not apply to top-level variables
     880             :   // in a module (assuming they are not exported), we must still mark these as
     881             :   // assigned because they might be accessed by a lazily parsed top-level
     882             :   // function, which, for efficiency, we preparse without variable tracking.
     883    24187588 :   if (is_script_scope() || is_module_scope()) {
     884     4163958 :     if (mode != VariableMode::kConst) var->set_maybe_assigned();
     885             :     var->set_is_used();
     886             :   }
     887             : 
     888    24187588 :   return var;
     889             : }
     890             : 
     891    15840078 : Variable* Scope::DeclareVariable(
     892             :     Declaration* declaration, const AstRawString* name, int pos,
     893             :     VariableMode mode, VariableKind kind, InitializationFlag init,
     894             :     bool* was_added, bool* sloppy_mode_block_scope_function_redefinition,
     895             :     bool* ok) {
     896             :   DCHECK(IsDeclaredVariableMode(mode));
     897             :   DCHECK(!already_resolved_);
     898             :   DCHECK(!GetDeclarationScope()->is_being_lazily_parsed());
     899             :   DCHECK(!GetDeclarationScope()->was_lazily_parsed());
     900             : 
     901    29902234 :   if (mode == VariableMode::kVar && !is_declaration_scope()) {
     902      806674 :     return GetDeclarationScope()->DeclareVariable(
     903             :         declaration, name, pos, mode, kind, init, was_added,
     904      403337 :         sloppy_mode_block_scope_function_redefinition, ok);
     905             :   }
     906             :   DCHECK(!is_catch_scope());
     907             :   DCHECK(!is_with_scope());
     908             :   DCHECK(is_declaration_scope() ||
     909             :          (IsLexicalVariableMode(mode) && is_block_scope()));
     910             : 
     911             :   DCHECK_NOT_NULL(name);
     912             : 
     913             :   Variable* var = LookupLocal(name);
     914             :   // Declare the variable in the declaration scope.
     915    15436773 :   *was_added = var == nullptr;
     916    15436773 :   if (V8_LIKELY(*was_added)) {
     917    14633570 :     if (V8_UNLIKELY(is_eval_scope() && is_sloppy(language_mode()) &&
     918             :                     mode == VariableMode::kVar)) {
     919             :       // In a var binding in a sloppy direct eval, pollute the enclosing scope
     920             :       // with this new binding by doing the following:
     921             :       // The proxy is bound to a lookup variable to force a dynamic declaration
     922             :       // using the DeclareEvalVar or DeclareEvalFunction runtime functions.
     923             :       DCHECK_EQ(NORMAL_VARIABLE, kind);
     924      307486 :       var = NonLocal(name, VariableMode::kDynamic);
     925             :       // Mark the var as used in case anyone outside the eval wants to use it.
     926             :       var->set_is_used();
     927             :     } else {
     928             :       // Declare the name.
     929    13514524 :       var = DeclareLocal(name, mode, kind, was_added, init);
     930             :       DCHECK(*was_added);
     931             :     }
     932             :   } else {
     933             :     var->set_maybe_assigned();
     934     3179648 :     if (V8_UNLIKELY(IsLexicalVariableMode(mode) ||
     935             :                     IsLexicalVariableMode(var->mode()))) {
     936             :       // The name was declared in this scope before; check for conflicting
     937             :       // re-declarations. We have a conflict if either of the declarations is
     938             :       // not a var (in script scope, we also have to ignore legacy const for
     939             :       // compatibility). There is similar code in runtime.cc in the Declare
     940             :       // functions. The function CheckConflictingVarDeclarations checks for
     941             :       // var and let bindings from different scopes whereas this is a check
     942             :       // for conflicting declarations within the same scope. This check also
     943             :       // covers the special case
     944             :       //
     945             :       // function () { let x; { var x; } }
     946             :       //
     947             :       // because the var declaration is hoisted to the function scope where
     948             :       // 'x' is already bound.
     949             :       //
     950             :       // In harmony we treat re-declarations as early errors. See ES5 16 for a
     951             :       // definition of early errors.
     952             :       //
     953             :       // Allow duplicate function decls for web compat, see bug 4693.
     954       64038 :       *ok = var->is_sloppy_block_function() &&
     955       64038 :             kind == SLOPPY_BLOCK_FUNCTION_VARIABLE;
     956       64038 :       *sloppy_mode_block_scope_function_redefinition = *ok;
     957             :     }
     958             :   }
     959             :   DCHECK_NOT_NULL(var);
     960             : 
     961             :   // We add a declaration node for every declaration. The compiler
     962             :   // will only generate code if necessary. In particular, declarations
     963             :   // for inner local variables that do not represent functions won't
     964             :   // result in any generated code.
     965             :   //
     966             :   // This will lead to multiple declaration nodes for the
     967             :   // same variable if it is declared several times. This is not a
     968             :   // semantic issue, but it may be a performance issue since it may
     969             :   // lead to repeated DeclareEvalVar or DeclareEvalFunction calls.
     970             :   decls_.Add(declaration);
     971             :   declaration->set_var(var);
     972    15436587 :   return var;
     973             : }
     974             : 
     975    11132730 : Variable* Scope::DeclareVariableName(const AstRawString* name,
     976             :                                      VariableMode mode, bool* was_added,
     977             :                                      VariableKind kind) {
     978             :   DCHECK(IsDeclaredVariableMode(mode));
     979             :   DCHECK(!already_resolved_);
     980             :   DCHECK(GetDeclarationScope()->is_being_lazily_parsed());
     981             : 
     982    20830277 :   if (mode == VariableMode::kVar && !is_declaration_scope()) {
     983     1138066 :     return GetDeclarationScope()->DeclareVariableName(name, mode, was_added,
     984      569033 :                                                       kind);
     985             :   }
     986             :   DCHECK(!is_with_scope());
     987             :   DCHECK(!is_eval_scope());
     988             :   DCHECK(is_declaration_scope() || IsLexicalVariableMode(mode));
     989             :   DCHECK(scope_info_.is_null());
     990             : 
     991             :   // Declare the variable in the declaration scope.
     992    10563697 :   Variable* var = DeclareLocal(name, mode, kind, was_added);
     993    10563751 :   if (!*was_added) {
     994     1737275 :     if (IsLexicalVariableMode(mode) || IsLexicalVariableMode(var->mode())) {
     995         321 :       if (!var->is_sloppy_block_function() ||
     996             :           kind != SLOPPY_BLOCK_FUNCTION_VARIABLE) {
     997             :         // Duplicate functions are allowed in the sloppy mode, but if this is
     998             :         // not a function declaration, it's an error. This is an error PreParser
     999             :         // hasn't previously detected.
    1000             :         return nullptr;
    1001             :       }
    1002             :       // Sloppy block function redefinition.
    1003             :     }
    1004             :     var->set_maybe_assigned();
    1005             :   }
    1006             :   var->set_is_used();
    1007    10563536 :   return var;
    1008             : }
    1009             : 
    1010      380626 : Variable* Scope::DeclareCatchVariableName(const AstRawString* name) {
    1011             :   DCHECK(!already_resolved_);
    1012             :   DCHECK(is_catch_scope());
    1013             :   DCHECK(scope_info_.is_null());
    1014             : 
    1015             :   bool was_added;
    1016             :   Variable* result = Declare(zone(), name, VariableMode::kVar, NORMAL_VARIABLE,
    1017             :                              kCreatedInitialized, kNotAssigned, &was_added);
    1018             :   DCHECK(was_added);
    1019      380635 :   return result;
    1020             : }
    1021             : 
    1022    50872566 : void Scope::AddUnresolved(VariableProxy* proxy) {
    1023             :   DCHECK(!already_resolved_);
    1024             :   DCHECK(!proxy->is_resolved());
    1025             :   unresolved_list_.Add(proxy);
    1026    50872566 : }
    1027             : 
    1028           0 : Variable* DeclarationScope::DeclareDynamicGlobal(const AstRawString* name,
    1029             :                                                  VariableKind kind,
    1030             :                                                  Scope* cache) {
    1031             :   DCHECK(is_script_scope());
    1032             :   bool was_added;
    1033     4968524 :   return cache->variables_.Declare(
    1034             :       zone(), this, name, VariableMode::kDynamicGlobal, kind,
    1035     4968524 :       kCreatedInitialized, kNotAssigned, &was_added);
    1036             :   // TODO(neis): Mark variable as maybe-assigned?
    1037             : }
    1038             : 
    1039        1289 : bool Scope::RemoveUnresolved(VariableProxy* var) {
    1040        1289 :   return unresolved_list_.Remove(var);
    1041             : }
    1042             : 
    1043       15738 : void Scope::DeleteUnresolved(VariableProxy* var) {
    1044             :   DCHECK(unresolved_list_.Contains(var));
    1045             :   var->mark_removed_from_unresolved();
    1046       15738 : }
    1047             : 
    1048     1241193 : Variable* Scope::NewTemporary(const AstRawString* name) {
    1049     1351008 :   return NewTemporary(name, kMaybeAssigned);
    1050             : }
    1051             : 
    1052     1493494 : Variable* Scope::NewTemporary(const AstRawString* name,
    1053             :                               MaybeAssignedFlag maybe_assigned) {
    1054             :   DeclarationScope* scope = GetClosureScope();
    1055             :   Variable* var = new (zone()) Variable(scope, name, VariableMode::kTemporary,
    1056             :                                         NORMAL_VARIABLE, kCreatedInitialized);
    1057             :   scope->AddLocal(var);
    1058     1493496 :   if (maybe_assigned == kMaybeAssigned) var->set_maybe_assigned();
    1059     1493496 :   return var;
    1060             : }
    1061             : 
    1062     6633977 : Declaration* DeclarationScope::CheckConflictingVarDeclarations() {
    1063     6633977 :   if (has_checked_syntax_) return nullptr;
    1064    19491038 :   for (Declaration* decl : decls_) {
    1065             :     // Lexical vs lexical conflicts within the same scope have already been
    1066             :     // captured in Parser::Declare. The only conflicts we still need to check
    1067             :     // are lexical vs nested var.
    1068    25205658 :     if (decl->IsVariableDeclaration() &&
    1069    12159117 :         decl->AsVariableDeclaration()->AsNested() != nullptr) {
    1070      939871 :       Scope* current = decl->AsVariableDeclaration()->AsNested()->scope();
    1071             :       DCHECK(decl->var()->mode() == VariableMode::kVar ||
    1072             :              decl->var()->mode() == VariableMode::kDynamic);
    1073             :       // Iterate through all scopes until the declaration scope.
    1074             :       do {
    1075             :         // There is a conflict if there exists a non-VAR binding.
    1076     1362105 :         if (current->is_catch_scope()) {
    1077             :           current = current->outer_scope();
    1078        2852 :           continue;
    1079             :         }
    1080             :         Variable* other_var = current->LookupLocal(decl->var()->raw_name());
    1081     1359253 :         if (other_var != nullptr) {
    1082             :           DCHECK(IsLexicalVariableMode(other_var->mode()));
    1083             :           return decl;
    1084             :         }
    1085             :         current = current->outer_scope();
    1086     1348976 :       } while (current != this);
    1087             :     }
    1088             :   }
    1089             : 
    1090     6444497 :   if (V8_LIKELY(!is_eval_scope())) return nullptr;
    1091      862833 :   if (!is_sloppy(language_mode())) return nullptr;
    1092             : 
    1093             :   // Var declarations in sloppy eval are hoisted to the first non-eval
    1094             :   // declaration scope. Check for conflicts between the eval scope that
    1095             :   // declaration scope.
    1096      735656 :   Scope* end = this;
    1097      735662 :   do {
    1098      735662 :     end = end->outer_scope_->GetDeclarationScope();
    1099             :   } while (end->is_eval_scope());
    1100      735656 :   end = end->outer_scope_;
    1101             : 
    1102     1036499 :   for (Declaration* decl : decls_) {
    1103      300996 :     if (IsLexicalVariableMode(decl->var()->mode())) continue;
    1104      289517 :     Scope* current = outer_scope_;
    1105             :     // Iterate through all scopes until and including the declaration scope.
    1106             :     do {
    1107             :       // There is a conflict if there exists a non-VAR binding up to the
    1108             :       // declaration scope in which this sloppy-eval runs.
    1109             :       Variable* other_var =
    1110      289726 :           current->LookupInScopeOrScopeInfo(decl->var()->raw_name());
    1111      290289 :       if (other_var != nullptr && IsLexicalVariableMode(other_var->mode())) {
    1112             :         DCHECK(!current->is_catch_scope());
    1113             :         return decl;
    1114             :       }
    1115             :       current = current->outer_scope();
    1116      289573 :     } while (current != end);
    1117             :   }
    1118             :   return nullptr;
    1119             : }
    1120             : 
    1121       85426 : const AstRawString* Scope::FindVariableDeclaredIn(Scope* scope,
    1122             :                                                   VariableMode mode_limit) {
    1123             :   const VariableMap& variables = scope->variables_;
    1124      885298 :   for (ZoneHashMap::Entry* p = variables.Start(); p != nullptr;
    1125             :        p = variables.Next(p)) {
    1126      400263 :     const AstRawString* name = static_cast<const AstRawString*>(p->key);
    1127             :     Variable* var = LookupLocal(name);
    1128      401754 :     if (var != nullptr && var->mode() <= mode_limit) return name;
    1129             :   }
    1130             :   return nullptr;
    1131             : }
    1132             : 
    1133      785310 : void DeclarationScope::DeserializeReceiver(AstValueFactory* ast_value_factory) {
    1134      785310 :   if (is_script_scope()) {
    1135             :     DCHECK_NOT_NULL(receiver_);
    1136             :     return;
    1137             :   }
    1138             :   DCHECK(has_this_declaration());
    1139      641690 :   DeclareThis(ast_value_factory);
    1140      641690 :   if (is_debug_evaluate_scope()) {
    1141       12241 :     receiver_->AllocateTo(VariableLocation::LOOKUP, -1);
    1142             :   } else {
    1143     1258898 :     receiver_->AllocateTo(VariableLocation::CONTEXT,
    1144             :                           scope_info_->ReceiverContextSlotIndex());
    1145             :   }
    1146             : }
    1147             : 
    1148     1818049 : bool DeclarationScope::AllocateVariables(ParseInfo* info) {
    1149             :   // Module variables must be allocated before variable resolution
    1150             :   // to ensure that UpdateNeedsHoleCheck() can detect import variables.
    1151     1818049 :   if (is_module_scope()) AsModuleScope()->AllocateModuleVariables();
    1152             : 
    1153     1818053 :   ClassScope* closest_class_scope = GetClassScope();
    1154     1971468 :   if (closest_class_scope != nullptr &&
    1155      153418 :       !closest_class_scope->ResolvePrivateNames(info)) {
    1156             :     DCHECK(info->pending_error_handler()->has_pending_error());
    1157             :     return false;
    1158             :   }
    1159             : 
    1160     1818035 :   if (!ResolveVariablesRecursively(info)) {
    1161             :     DCHECK(info->pending_error_handler()->has_pending_error());
    1162             :     return false;
    1163             :   }
    1164             : 
    1165             :   // // Don't allocate variables of preparsed scopes.
    1166     1818039 :   if (!was_lazily_parsed()) AllocateVariablesRecursively();
    1167             : 
    1168             :   return true;
    1169             : }
    1170             : 
    1171        4313 : bool Scope::HasThisReference() const {
    1172        7870 :   if (is_declaration_scope() && AsDeclarationScope()->has_this_reference()) {
    1173             :     return true;
    1174             :   }
    1175             : 
    1176        5062 :   for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
    1177        4426 :     if (!scope->is_declaration_scope() ||
    1178             :         !scope->AsDeclarationScope()->has_this_declaration()) {
    1179        2368 :       if (scope->HasThisReference()) return true;
    1180             :     }
    1181             :   }
    1182             : 
    1183             :   return false;
    1184             : }
    1185             : 
    1186     4190654 : bool Scope::AllowsLazyParsingWithoutUnresolvedVariables(
    1187             :     const Scope* outer) const {
    1188             :   // If none of the outer scopes need to decide whether to context allocate
    1189             :   // specific variables, we can preparse inner functions without unresolved
    1190             :   // variables. Otherwise we need to find unresolved variables to force context
    1191             :   // allocation of the matching declarations. We can stop at the outer scope for
    1192             :   // the parse, since context allocation of those variables is already
    1193             :   // guaranteed to be correct.
    1194     4190912 :   for (const Scope* s = this; s != outer; s = s->outer_scope_) {
    1195             :     // Eval forces context allocation on all outer scopes, so we don't need to
    1196             :     // look at those scopes. Sloppy eval makes top-level non-lexical variables
    1197             :     // dynamic, whereas strict-mode requires context allocation.
    1198     3151510 :     if (s->is_eval_scope()) return is_sloppy(s->language_mode());
    1199             :     // Catch scopes force context allocation of all variables.
    1200     2130318 :     if (s->is_catch_scope()) continue;
    1201             :     // With scopes do not introduce variables that need allocation.
    1202     2130318 :     if (s->is_with_scope()) continue;
    1203             :     DCHECK(s->is_module_scope() || s->is_block_scope() ||
    1204             :            s->is_function_scope());
    1205             :     return false;
    1206             :   }
    1207             :   return true;
    1208             : }
    1209             : 
    1210     3636820 : bool DeclarationScope::AllowsLazyCompilation() const {
    1211             :   // Functions which force eager compilation and class member initializer
    1212             :   // functions are not lazily compilable.
    1213     3636820 :   return !force_eager_compilation_ &&
    1214     3636820 :          !IsClassMembersInitializerFunction(function_kind());
    1215             : }
    1216             : 
    1217     2838126 : int Scope::ContextChainLength(Scope* scope) const {
    1218             :   int n = 0;
    1219     4318322 :   for (const Scope* s = this; s != scope; s = s->outer_scope_) {
    1220             :     DCHECK_NOT_NULL(s);  // scope must be in the scope chain
    1221      740098 :     if (s->NeedsContext()) n++;
    1222             :   }
    1223     2838126 :   return n;
    1224             : }
    1225             : 
    1226      355514 : int Scope::ContextChainLengthUntilOutermostSloppyEval() const {
    1227             :   int result = 0;
    1228             :   int length = 0;
    1229             : 
    1230     2547452 :   for (const Scope* s = this; s != nullptr; s = s->outer_scope()) {
    1231     1095969 :     if (!s->NeedsContext()) continue;
    1232      796663 :     length++;
    1233     1578374 :     if (s->is_declaration_scope() &&
    1234             :         s->AsDeclarationScope()->calls_sloppy_eval()) {
    1235             :       result = length;
    1236             :     }
    1237             :   }
    1238             : 
    1239      355514 :   return result;
    1240             : }
    1241             : 
    1242     2571912 : ClassScope* Scope::GetClassScope() {
    1243             :   Scope* scope = this;
    1244    14890887 :   while (scope != nullptr && !scope->is_class_scope()) {
    1245             :     scope = scope->outer_scope();
    1246             :   }
    1247     4392143 :   if (scope != nullptr && scope->is_class_scope()) {
    1248      375267 :     return scope->AsClassScope();
    1249             :   }
    1250             :   return nullptr;
    1251             : }
    1252             : 
    1253    17469757 : DeclarationScope* Scope::GetDeclarationScope() {
    1254             :   Scope* scope = this;
    1255    25015335 :   while (!scope->is_declaration_scope()) {
    1256             :     scope = scope->outer_scope();
    1257             :   }
    1258    17469757 :   return scope->AsDeclarationScope();
    1259             : }
    1260             : 
    1261           0 : const DeclarationScope* Scope::GetClosureScope() const {
    1262             :   const Scope* scope = this;
    1263           0 :   while (!scope->is_declaration_scope() || scope->is_block_scope()) {
    1264             :     scope = scope->outer_scope();
    1265             :   }
    1266           0 :   return scope->AsDeclarationScope();
    1267             : }
    1268             : 
    1269     9501099 : DeclarationScope* Scope::GetClosureScope() {
    1270             :   Scope* scope = this;
    1271    35127173 :   while (!scope->is_declaration_scope() || scope->is_block_scope()) {
    1272             :     scope = scope->outer_scope();
    1273             :   }
    1274     9501099 :   return scope->AsDeclarationScope();
    1275             : }
    1276             : 
    1277           0 : bool Scope::NeedsScopeInfo() const {
    1278             :   DCHECK(!already_resolved_);
    1279             :   DCHECK(GetClosureScope()->ShouldEagerCompile());
    1280             :   // The debugger expects all functions to have scope infos.
    1281             :   // TODO(jochen|yangguo): Remove this requirement.
    1282     2421923 :   if (is_function_scope()) return true;
    1283           0 :   return NeedsContext();
    1284             : }
    1285             : 
    1286       43944 : bool Scope::ShouldBanArguments() {
    1287       43944 :   return GetReceiverScope()->should_ban_arguments();
    1288             : }
    1289             : 
    1290     8954606 : DeclarationScope* Scope::GetReceiverScope() {
    1291             :   Scope* scope = this;
    1292    18694002 :   while (!scope->is_declaration_scope() ||
    1293     9047940 :          (!scope->is_script_scope() &&
    1294             :           !scope->AsDeclarationScope()->has_this_declaration())) {
    1295             :     scope = scope->outer_scope();
    1296             :   }
    1297     8954606 :   return scope->AsDeclarationScope();
    1298             : }
    1299             : 
    1300     2626530 : Scope* Scope::GetOuterScopeWithContext() {
    1301     2626530 :   Scope* scope = outer_scope_;
    1302     3556478 :   while (scope && !scope->NeedsContext()) {
    1303             :     scope = scope->outer_scope();
    1304             :   }
    1305     2626530 :   return scope;
    1306             : }
    1307             : 
    1308             : namespace {
    1309             : bool WasLazilyParsed(Scope* scope) {
    1310    21826727 :   return scope->is_declaration_scope() &&
    1311             :          scope->AsDeclarationScope()->was_lazily_parsed();
    1312             : }
    1313             : 
    1314             : }  // namespace
    1315             : 
    1316             : template <typename FunctionType>
    1317             : void Scope::ForEach(FunctionType callback) {
    1318             :   Scope* scope = this;
    1319             :   while (true) {
    1320    12068658 :     Iteration iteration = callback(scope);
    1321             :     // Try to descend into inner scopes first.
    1322    12068680 :     if ((iteration == Iteration::kDescend) && scope->inner_scope_ != nullptr) {
    1323             :       scope = scope->inner_scope_;
    1324             :     } else {
    1325             :       // Find the next outer scope with a sibling.
    1326    12068688 :       while (scope->sibling_ == nullptr) {
    1327     5199776 :         if (scope == this) return;
    1328     2996652 :         scope = scope->outer_scope_;
    1329             :       }
    1330     6868912 :       if (scope == this) return;
    1331             :       scope = scope->sibling_;
    1332             :     }
    1333             :   }
    1334             : }
    1335             : 
    1336       12578 : void Scope::CollectNonLocals(DeclarationScope* max_outer_scope,
    1337             :                              Isolate* isolate, ParseInfo* info,
    1338             :                              Handle<StringSet>* non_locals) {
    1339       90654 :   this->ForEach([max_outer_scope, isolate, info, non_locals](Scope* scope) {
    1340             :     // Module variables must be allocated before variable resolution
    1341             :     // to ensure that UpdateNeedsHoleCheck() can detect import variables.
    1342       17057 :     if (scope->is_module_scope()) {
    1343         228 :       scope->AsModuleScope()->AllocateModuleVariables();
    1344             :     }
    1345             : 
    1346             :     // Lazy parsed declaration scopes are already partially analyzed. If there
    1347             :     // are unresolved references remaining, they just need to be resolved in
    1348             :     // outer scopes.
    1349       17057 :     Scope* lookup = WasLazilyParsed(scope) ? scope->outer_scope() : scope;
    1350             : 
    1351       74421 :     for (VariableProxy* proxy : scope->unresolved_list_) {
    1352             :       DCHECK(!proxy->is_resolved());
    1353             :       Variable* var =
    1354       57364 :           Lookup<kParsedScope>(proxy, lookup, max_outer_scope->outer_scope());
    1355       57364 :       if (var == nullptr) {
    1356       16233 :         *non_locals = StringSet::Add(isolate, *non_locals, proxy->name());
    1357             :       } else {
    1358             :         // In this case we need to leave scopes in a way that they can be
    1359             :         // allocated. If we resolved variables from lazy parsed scopes, we need
    1360             :         // to context allocate the var.
    1361             :         scope->ResolveTo(info, proxy, var);
    1362       41131 :         if (!var->is_dynamic() && lookup != scope)
    1363             :           var->ForceContextAllocation();
    1364             :       }
    1365             :     }
    1366             : 
    1367             :     // Clear unresolved_list_ as it's in an inconsistent state.
    1368             :     scope->unresolved_list_.Clear();
    1369       17057 :     return Iteration::kDescend;
    1370             :   });
    1371       12578 : }
    1372             : 
    1373     1908312 : void Scope::AnalyzePartially(DeclarationScope* max_outer_scope,
    1374             :                              AstNodeFactory* ast_node_factory,
    1375             :                              UnresolvedList* new_unresolved_list) {
    1376             :   this->ForEach([max_outer_scope, ast_node_factory,
    1377    46201691 :                  new_unresolved_list](Scope* scope) {
    1378             :     DCHECK_IMPLIES(scope->is_declaration_scope(),
    1379             :                    !scope->AsDeclarationScope()->was_lazily_parsed());
    1380             : 
    1381    22889769 :     for (VariableProxy* proxy = scope->unresolved_list_.first();
    1382    26065043 :          proxy != nullptr; proxy = proxy->next_unresolved()) {
    1383             :       DCHECK(!proxy->is_resolved());
    1384             :       Variable* var =
    1385    22889527 :           Lookup<kParsedScope>(proxy, scope, max_outer_scope->outer_scope());
    1386    22889786 :       if (var == nullptr) {
    1387             :         // Don't copy unresolved references to the script scope, unless it's a
    1388             :         // reference to a private name or method. In that case keep it so we
    1389             :         // can fail later.
    1390     6827117 :         if (!max_outer_scope->outer_scope()->is_script_scope()) {
    1391             :           VariableProxy* copy = ast_node_factory->CopyVariableProxy(proxy);
    1392             :           new_unresolved_list->Add(copy);
    1393             :         }
    1394             :       } else {
    1395             :         var->set_is_used();
    1396    16062669 :         if (proxy->is_assigned()) var->set_maybe_assigned();
    1397             :       }
    1398             :     }
    1399             : 
    1400             :     // Clear unresolved_list_ as it's in an inconsistent state.
    1401             :     scope->unresolved_list_.Clear();
    1402     3175516 :     return Iteration::kDescend;
    1403             :   });
    1404     1908319 : }
    1405             : 
    1406       12578 : Handle<StringSet> DeclarationScope::CollectNonLocals(
    1407             :     Isolate* isolate, ParseInfo* info, Handle<StringSet> non_locals) {
    1408       12578 :   Scope::CollectNonLocals(this, isolate, info, &non_locals);
    1409       12578 :   return non_locals;
    1410             : }
    1411             : 
    1412     2614481 : void DeclarationScope::ResetAfterPreparsing(AstValueFactory* ast_value_factory,
    1413             :                                             bool aborted) {
    1414             :   DCHECK(is_function_scope());
    1415             : 
    1416             :   // Reset all non-trivial members.
    1417             :   params_.Clear();
    1418             :   decls_.Clear();
    1419             :   locals_.Clear();
    1420     2614481 :   inner_scope_ = nullptr;
    1421             :   unresolved_list_.Clear();
    1422             :   sloppy_block_functions_.Clear();
    1423     2614481 :   rare_data_ = nullptr;
    1424     2614481 :   has_rest_ = false;
    1425             : 
    1426             :   DCHECK_NE(zone_, ast_value_factory->zone());
    1427     2614481 :   zone_->ReleaseMemory();
    1428             : 
    1429     2614568 :   if (aborted) {
    1430             :     // Prepare scope for use in the outer zone.
    1431       49034 :     zone_ = ast_value_factory->zone();
    1432       49034 :     variables_.Reset(ZoneAllocationPolicy(zone_));
    1433       98068 :     if (!IsArrowFunction(function_kind_)) {
    1434       43288 :       has_simple_parameters_ = true;
    1435       43288 :       DeclareDefaultFunctionVariables(ast_value_factory);
    1436             :     }
    1437             :   } else {
    1438             :     // Make sure this scope isn't used for allocation anymore.
    1439     2565534 :     zone_ = nullptr;
    1440             :     variables_.Invalidate();
    1441             :   }
    1442             : 
    1443             : #ifdef DEBUG
    1444             :   needs_migration_ = false;
    1445             :   is_being_lazily_parsed_ = false;
    1446             : #endif
    1447             : 
    1448     2614568 :   was_lazily_parsed_ = !aborted;
    1449     2614568 : }
    1450             : 
    1451      280195 : bool Scope::IsSkippableFunctionScope() {
    1452             :   // Lazy non-arrow function scopes are skippable. Lazy functions are exactly
    1453             :   // those Scopes which have their own PreparseDataBuilder object. This
    1454             :   // logic ensures that the scope allocation data is consistent with the
    1455             :   // skippable function data (both agree on where the lazy function boundaries
    1456             :   // are).
    1457     3455699 :   if (!is_function_scope()) return false;
    1458             :   DeclarationScope* declaration_scope = AsDeclarationScope();
    1459     2784289 :   return !declaration_scope->is_arrow_scope() &&
    1460             :          declaration_scope->preparse_data_builder() != nullptr;
    1461             : }
    1462             : 
    1463     1908313 : void Scope::SavePreparseData(Parser* parser) {
    1464     5226464 :   this->ForEach([parser](Scope* scope) {
    1465     3175504 :     if (scope->IsSkippableFunctionScope()) {
    1466             :       scope->AsDeclarationScope()->SavePreparseDataForDeclarationScope(parser);
    1467             :     }
    1468     3175498 :     return Iteration::kDescend;
    1469             :   });
    1470     1908317 : }
    1471             : 
    1472           0 : void DeclarationScope::SavePreparseDataForDeclarationScope(Parser* parser) {
    1473     2050960 :   if (preparse_data_builder_ == nullptr) return;
    1474     2050959 :   preparse_data_builder_->SaveScopeAllocationData(this, parser);
    1475             : }
    1476             : 
    1477     2504644 : void DeclarationScope::AnalyzePartially(Parser* parser,
    1478             :                                         AstNodeFactory* ast_node_factory) {
    1479             :   DCHECK(!force_eager_compilation_);
    1480             :   UnresolvedList new_unresolved_list;
    1481     9992722 :   if (!IsArrowFunction(function_kind_) &&
    1482     3110357 :       (!outer_scope_->is_script_scope() ||
    1483     1263094 :        (preparse_data_builder_ != nullptr &&
    1484      631557 :         preparse_data_builder_->HasInnerFunctions()))) {
    1485             :     // Try to resolve unresolved variables for this Scope and migrate those
    1486             :     // which cannot be resolved inside. It doesn't make sense to try to resolve
    1487             :     // them in the outer Scopes here, because they are incomplete.
    1488     1908320 :     Scope::AnalyzePartially(this, ast_node_factory, &new_unresolved_list);
    1489             : 
    1490             :     // Migrate function_ to the right Zone.
    1491     1908333 :     if (function_ != nullptr) {
    1492      861771 :       function_ = ast_node_factory->CopyVariable(function_);
    1493             :     }
    1494             : 
    1495     1908324 :     SavePreparseData(parser);
    1496             :   }
    1497             : 
    1498             : #ifdef DEBUG
    1499             :   if (FLAG_print_scopes) {
    1500             :     PrintF("Inner function scope:\n");
    1501             :     Print();
    1502             :   }
    1503             : #endif
    1504             : 
    1505     2504631 :   ResetAfterPreparsing(ast_node_factory->ast_value_factory(), false);
    1506             : 
    1507             :   unresolved_list_ = std::move(new_unresolved_list);
    1508     2504744 : }
    1509             : 
    1510             : #ifdef DEBUG
    1511             : namespace {
    1512             : 
    1513             : const char* Header(ScopeType scope_type, FunctionKind function_kind,
    1514             :                    bool is_declaration_scope) {
    1515             :   switch (scope_type) {
    1516             :     case EVAL_SCOPE: return "eval";
    1517             :     // TODO(adamk): Should we print concise method scopes specially?
    1518             :     case FUNCTION_SCOPE:
    1519             :       if (IsGeneratorFunction(function_kind)) return "function*";
    1520             :       if (IsAsyncFunction(function_kind)) return "async function";
    1521             :       if (IsArrowFunction(function_kind)) return "arrow";
    1522             :       return "function";
    1523             :     case MODULE_SCOPE: return "module";
    1524             :     case SCRIPT_SCOPE: return "global";
    1525             :     case CATCH_SCOPE: return "catch";
    1526             :     case BLOCK_SCOPE: return is_declaration_scope ? "varblock" : "block";
    1527             :     case CLASS_SCOPE:
    1528             :       return "class";
    1529             :     case WITH_SCOPE: return "with";
    1530             :   }
    1531             :   UNREACHABLE();
    1532             : }
    1533             : 
    1534             : void Indent(int n, const char* str) { PrintF("%*s%s", n, "", str); }
    1535             : 
    1536             : void PrintName(const AstRawString* name) {
    1537             :   PrintF("%.*s", name->length(), name->raw_data());
    1538             : }
    1539             : 
    1540             : void PrintLocation(Variable* var) {
    1541             :   switch (var->location()) {
    1542             :     case VariableLocation::UNALLOCATED:
    1543             :       break;
    1544             :     case VariableLocation::PARAMETER:
    1545             :       PrintF("parameter[%d]", var->index());
    1546             :       break;
    1547             :     case VariableLocation::LOCAL:
    1548             :       PrintF("local[%d]", var->index());
    1549             :       break;
    1550             :     case VariableLocation::CONTEXT:
    1551             :       PrintF("context[%d]", var->index());
    1552             :       break;
    1553             :     case VariableLocation::LOOKUP:
    1554             :       PrintF("lookup");
    1555             :       break;
    1556             :     case VariableLocation::MODULE:
    1557             :       PrintF("module");
    1558             :       break;
    1559             :   }
    1560             : }
    1561             : 
    1562             : void PrintVar(int indent, Variable* var) {
    1563             :   Indent(indent, VariableMode2String(var->mode()));
    1564             :   PrintF(" ");
    1565             :   if (var->raw_name()->IsEmpty())
    1566             :     PrintF(".%p", reinterpret_cast<void*>(var));
    1567             :   else
    1568             :     PrintName(var->raw_name());
    1569             :   PrintF(";  // (%p) ", reinterpret_cast<void*>(var));
    1570             :   PrintLocation(var);
    1571             :   bool comma = !var->IsUnallocated();
    1572             :   if (var->has_forced_context_allocation()) {
    1573             :     if (comma) PrintF(", ");
    1574             :     PrintF("forced context allocation");
    1575             :     comma = true;
    1576             :   }
    1577             :   if (var->maybe_assigned() == kNotAssigned) {
    1578             :     if (comma) PrintF(", ");
    1579             :     PrintF("never assigned");
    1580             :     comma = true;
    1581             :   }
    1582             :   if (var->initialization_flag() == kNeedsInitialization &&
    1583             :       !var->binding_needs_init()) {
    1584             :     if (comma) PrintF(", ");
    1585             :     PrintF("hole initialization elided");
    1586             :   }
    1587             :   PrintF("\n");
    1588             : }
    1589             : 
    1590             : void PrintMap(int indent, const char* label, VariableMap* map, bool locals,
    1591             :               Variable* function_var) {
    1592             :   bool printed_label = false;
    1593             :   for (VariableMap::Entry* p = map->Start(); p != nullptr; p = map->Next(p)) {
    1594             :     Variable* var = reinterpret_cast<Variable*>(p->value);
    1595             :     if (var == function_var) continue;
    1596             :     bool local = !IsDynamicVariableMode(var->mode());
    1597             :     if ((locals ? local : !local) &&
    1598             :         (var->is_used() || !var->IsUnallocated())) {
    1599             :       if (!printed_label) {
    1600             :         Indent(indent, label);
    1601             :         printed_label = true;
    1602             :       }
    1603             :       PrintVar(indent, var);
    1604             :     }
    1605             :   }
    1606             : }
    1607             : 
    1608             : }  // anonymous namespace
    1609             : 
    1610             : void DeclarationScope::PrintParameters() {
    1611             :   PrintF(" (");
    1612             :   for (int i = 0; i < params_.length(); i++) {
    1613             :     if (i > 0) PrintF(", ");
    1614             :     const AstRawString* name = params_[i]->raw_name();
    1615             :     if (name->IsEmpty()) {
    1616             :       PrintF(".%p", reinterpret_cast<void*>(params_[i]));
    1617             :     } else {
    1618             :       PrintName(name);
    1619             :     }
    1620             :   }
    1621             :   PrintF(")");
    1622             : }
    1623             : 
    1624             : void Scope::Print(int n) {
    1625             :   int n0 = (n > 0 ? n : 0);
    1626             :   int n1 = n0 + 2;  // indentation
    1627             : 
    1628             :   // Print header.
    1629             :   FunctionKind function_kind = is_function_scope()
    1630             :                                    ? AsDeclarationScope()->function_kind()
    1631             :                                    : kNormalFunction;
    1632             :   Indent(n0, Header(scope_type_, function_kind, is_declaration_scope()));
    1633             :   if (scope_name_ != nullptr && !scope_name_->IsEmpty()) {
    1634             :     PrintF(" ");
    1635             :     PrintName(scope_name_);
    1636             :   }
    1637             : 
    1638             :   // Print parameters, if any.
    1639             :   Variable* function = nullptr;
    1640             :   if (is_function_scope()) {
    1641             :     AsDeclarationScope()->PrintParameters();
    1642             :     function = AsDeclarationScope()->function_var();
    1643             :   }
    1644             : 
    1645             :   PrintF(" { // (%p) (%d, %d)\n", reinterpret_cast<void*>(this),
    1646             :          start_position(), end_position());
    1647             :   if (is_hidden()) {
    1648             :     Indent(n1, "// is hidden\n");
    1649             :   }
    1650             : 
    1651             :   // Function name, if any (named function literals, only).
    1652             :   if (function != nullptr) {
    1653             :     Indent(n1, "// (local) function name: ");
    1654             :     PrintName(function->raw_name());
    1655             :     PrintF("\n");
    1656             :   }
    1657             : 
    1658             :   // Scope info.
    1659             :   if (is_strict(language_mode())) {
    1660             :     Indent(n1, "// strict mode scope\n");
    1661             :   }
    1662             :   if (IsAsmModule()) Indent(n1, "// scope is an asm module\n");
    1663             :   if (is_declaration_scope() && AsDeclarationScope()->calls_sloppy_eval()) {
    1664             :     Indent(n1, "// scope calls sloppy 'eval'\n");
    1665             :   }
    1666             :   if (is_declaration_scope() && AsDeclarationScope()->NeedsHomeObject()) {
    1667             :     Indent(n1, "// scope needs home object\n");
    1668             :   }
    1669             :   if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n");
    1670             :   if (is_declaration_scope()) {
    1671             :     DeclarationScope* scope = AsDeclarationScope();
    1672             :     if (scope->was_lazily_parsed()) Indent(n1, "// lazily parsed\n");
    1673             :     if (scope->ShouldEagerCompile()) Indent(n1, "// will be compiled\n");
    1674             :   }
    1675             :   if (num_stack_slots_ > 0) {
    1676             :     Indent(n1, "// ");
    1677             :     PrintF("%d stack slots\n", num_stack_slots_);
    1678             :   }
    1679             :   if (num_heap_slots_ > 0) {
    1680             :     Indent(n1, "// ");
    1681             :     PrintF("%d heap slots\n", num_heap_slots_);
    1682             :   }
    1683             : 
    1684             :   // Print locals.
    1685             :   if (function != nullptr) {
    1686             :     Indent(n1, "// function var:\n");
    1687             :     PrintVar(n1, function);
    1688             :   }
    1689             : 
    1690             :   // Print temporaries.
    1691             :   {
    1692             :     bool printed_header = false;
    1693             :     for (Variable* local : locals_) {
    1694             :       if (local->mode() != VariableMode::kTemporary) continue;
    1695             :       if (!printed_header) {
    1696             :         printed_header = true;
    1697             :         Indent(n1, "// temporary vars:\n");
    1698             :       }
    1699             :       PrintVar(n1, local);
    1700             :     }
    1701             :   }
    1702             : 
    1703             :   if (variables_.occupancy() > 0) {
    1704             :     PrintMap(n1, "// local vars:\n", &variables_, true, function);
    1705             :     PrintMap(n1, "// dynamic vars:\n", &variables_, false, function);
    1706             :   }
    1707             : 
    1708             :   if (is_class_scope()) {
    1709             :     ClassScope* class_scope = AsClassScope();
    1710             :     if (class_scope->rare_data_ != nullptr) {
    1711             :       PrintMap(n1, "// private name vars:\n",
    1712             :                &(class_scope->rare_data_->private_name_map), true, function);
    1713             :     }
    1714             :   }
    1715             : 
    1716             :   // Print inner scopes (disable by providing negative n).
    1717             :   if (n >= 0) {
    1718             :     for (Scope* scope = inner_scope_; scope != nullptr;
    1719             :          scope = scope->sibling_) {
    1720             :       PrintF("\n");
    1721             :       scope->Print(n1);
    1722             :     }
    1723             :   }
    1724             : 
    1725             :   Indent(n0, "}\n");
    1726             : }
    1727             : 
    1728             : void Scope::CheckScopePositions() {
    1729             :   this->ForEach([](Scope* scope) {
    1730             :     // Visible leaf scopes must have real positions.
    1731             :     if (!scope->is_hidden() && scope->inner_scope_ == nullptr) {
    1732             :       DCHECK_NE(kNoSourcePosition, scope->start_position());
    1733             :       DCHECK_NE(kNoSourcePosition, scope->end_position());
    1734             :     }
    1735             :     return Iteration::kDescend;
    1736             :   });
    1737             : }
    1738             : 
    1739             : void Scope::CheckZones() {
    1740             :   DCHECK(!needs_migration_);
    1741             :   this->ForEach([](Scope* scope) {
    1742             :     if (WasLazilyParsed(scope)) {
    1743             :       DCHECK_NULL(scope->zone());
    1744             :       DCHECK_NULL(scope->inner_scope_);
    1745             :       return Iteration::kContinue;
    1746             :     }
    1747             :     return Iteration::kDescend;
    1748             :   });
    1749             : }
    1750             : #endif  // DEBUG
    1751             : 
    1752      727014 : Variable* Scope::NonLocal(const AstRawString* name, VariableMode mode) {
    1753             :   // Declare a new non-local.
    1754             :   DCHECK(IsDynamicVariableMode(mode));
    1755             :   bool was_added;
    1756             :   Variable* var =
    1757      727014 :       variables_.Declare(zone(), this, name, mode, NORMAL_VARIABLE,
    1758      727014 :                          kCreatedInitialized, kNotAssigned, &was_added);
    1759             :   // Allocate it by giving it a dynamic lookup.
    1760             :   var->AllocateTo(VariableLocation::LOOKUP, -1);
    1761      727015 :   return var;
    1762             : }
    1763             : 
    1764             : // static
    1765             : template <Scope::ScopeLookupMode mode>
    1766    43980159 : Variable* Scope::Lookup(VariableProxy* proxy, Scope* scope,
    1767             :                         Scope* outer_scope_end, Scope* entry_point,
    1768             :                         bool force_context_allocation) {
    1769             :   if (mode == kDeserializedScope) {
    1770     2098008 :     Variable* var = entry_point->variables_.Lookup(proxy->raw_name());
    1771     2098012 :     if (var != nullptr) return var;
    1772             :   }
    1773             : 
    1774      502721 :   while (true) {
    1775             :     DCHECK_IMPLIES(mode == kParsedScope, !scope->is_debug_evaluate_scope_);
    1776             :     // Short-cut: whenever we find a debug-evaluate scope, just look everything
    1777             :     // up dynamically. Debug-evaluate doesn't properly create scope info for the
    1778             :     // lookups it does. It may not have a valid 'this' declaration, and anything
    1779             :     // accessed through debug-evaluate might invalidly resolve to
    1780             :     // stack-allocated variables.
    1781             :     // TODO(yangguo): Remove once debug-evaluate creates proper ScopeInfo for
    1782             :     // the scopes in which it's evaluating.
    1783     2240000 :     if (mode == kDeserializedScope &&
    1784     2240000 :         V8_UNLIKELY(scope->is_debug_evaluate_scope_)) {
    1785       10725 :       return entry_point->NonLocal(proxy->raw_name(), VariableMode::kDynamic);
    1786             :     }
    1787             : 
    1788             :     // Try to find the variable in this scope.
    1789             :     Variable* var = mode == kParsedScope ? scope->LookupLocal(proxy->raw_name())
    1790             :                                          : scope->LookupInScopeInfo(
    1791     2229275 :                                                proxy->raw_name(), entry_point);
    1792             : 
    1793             :     // We found a variable and we are done. (Even if there is an 'eval' in this
    1794             :     // scope which introduces the same variable again, the resulting variable
    1795             :     // remains the same.)
    1796    61460894 :     if (var != nullptr) {
    1797    39384729 :       if (mode == kParsedScope && force_context_allocation &&
    1798             :           !var->is_dynamic()) {
    1799             :         var->ForceContextAllocation();
    1800             :       }
    1801             :       return var;
    1802             :     }
    1803             : 
    1804    28874309 :     if (scope->outer_scope_ == outer_scope_end) break;
    1805             : 
    1806             :     DCHECK(!scope->is_script_scope());
    1807    20051778 :     if (V8_UNLIKELY(scope->is_with_scope())) {
    1808       46198 :       return LookupWith(proxy, scope, outer_scope_end, entry_point,
    1809       46198 :                         force_context_allocation);
    1810             :     }
    1811    35671104 :     if (V8_UNLIKELY(scope->is_declaration_scope() &&
    1812             :                     scope->AsDeclarationScope()->calls_sloppy_eval())) {
    1813      387262 :       return LookupSloppyEval(proxy, scope, outer_scope_end, entry_point,
    1814      387262 :                               force_context_allocation);
    1815             :     }
    1816             : 
    1817    19618318 :     force_context_allocation |= scope->is_function_scope();
    1818             :     scope = scope->outer_scope_;
    1819             :     // TODO(verwaest): Separate through AnalyzePartially.
    1820    19115597 :     if (mode == kParsedScope && !scope->scope_info_.is_null()) {
    1821     1777833 :       return Lookup<kDeserializedScope>(proxy, scope, outer_scope_end, scope);
    1822             :     }
    1823             :   }
    1824             : 
    1825             :   // We may just be trying to find all free variables. In that case, don't
    1826             :   // declare them in the outer scope.
    1827             :   // TODO(marja): Separate Lookup for preparsed scopes better.
    1828     7853477 :   if (mode == kParsedScope && !scope->is_script_scope()) {
    1829             :     return nullptr;
    1830             :   }
    1831             : 
    1832             :   // No binding has been found. Declare a variable on the global object.
    1833             :   return scope->AsDeclarationScope()->DeclareDynamicGlobal(
    1834             :       proxy->raw_name(), NORMAL_VARIABLE,
    1835     1978377 :       mode == kDeserializedScope ? entry_point : scope);
    1836             : }
    1837             : 
    1838             : template Variable* Scope::Lookup<Scope::kParsedScope>(
    1839             :     VariableProxy* proxy, Scope* scope, Scope* outer_scope_end,
    1840             :     Scope* entry_point, bool force_context_allocation);
    1841             : template Variable* Scope::Lookup<Scope::kDeserializedScope>(
    1842             :     VariableProxy* proxy, Scope* scope, Scope* outer_scope_end,
    1843             :     Scope* entry_point, bool force_context_allocation);
    1844             : 
    1845       46198 : Variable* Scope::LookupWith(VariableProxy* proxy, Scope* scope,
    1846             :                             Scope* outer_scope_end, Scope* entry_point,
    1847             :                             bool force_context_allocation) {
    1848             :   DCHECK(scope->is_with_scope());
    1849             : 
    1850             :   Variable* var =
    1851       46198 :       scope->outer_scope_->scope_info_.is_null()
    1852       44577 :           ? Lookup<kParsedScope>(proxy, scope->outer_scope_, outer_scope_end,
    1853             :                                  nullptr, force_context_allocation)
    1854             :           : Lookup<kDeserializedScope>(proxy, scope->outer_scope_,
    1855       90775 :                                        outer_scope_end, entry_point);
    1856             : 
    1857       46198 :   if (var == nullptr) return var;
    1858             : 
    1859             :   // The current scope is a with scope, so the variable binding can not be
    1860             :   // statically resolved. However, note that it was necessary to do a lookup
    1861             :   // in the outer scope anyway, because if a binding exists in an outer
    1862             :   // scope, the associated variable has to be marked as potentially being
    1863             :   // accessed from inside of an inner with scope (the property may not be in
    1864             :   // the 'with' object).
    1865       41039 :   if (!var->is_dynamic() && var->IsUnallocated()) {
    1866             :     DCHECK(!scope->already_resolved_);
    1867             :     var->set_is_used();
    1868             :     var->ForceContextAllocation();
    1869       11849 :     if (proxy->is_assigned()) var->set_maybe_assigned();
    1870             :   }
    1871       28950 :   if (entry_point != nullptr) entry_point->variables_.Remove(var);
    1872       28950 :   Scope* target = entry_point == nullptr ? scope : entry_point;
    1873       28950 :   return target->NonLocal(proxy->raw_name(), VariableMode::kDynamic);
    1874             : }
    1875             : 
    1876      387262 : Variable* Scope::LookupSloppyEval(VariableProxy* proxy, Scope* scope,
    1877             :                                   Scope* outer_scope_end, Scope* entry_point,
    1878             :                                   bool force_context_allocation) {
    1879             :   DCHECK(scope->is_declaration_scope() &&
    1880             :          scope->AsDeclarationScope()->calls_sloppy_eval());
    1881             : 
    1882             :   // If we're compiling eval, it's possible that the outer scope is the first
    1883             :   // ScopeInfo-backed scope.
    1884      387262 :   Scope* entry = entry_point == nullptr ? scope->outer_scope_ : entry_point;
    1885             :   Variable* var =
    1886      387262 :       scope->outer_scope_->scope_info_.is_null()
    1887       68706 :           ? Lookup<kParsedScope>(proxy, scope->outer_scope_, outer_scope_end,
    1888             :                                  nullptr, force_context_allocation)
    1889             :           : Lookup<kDeserializedScope>(proxy, scope->outer_scope_,
    1890      455968 :                                        outer_scope_end, entry);
    1891      387262 :   if (var == nullptr) return var;
    1892             : 
    1893             :   // A variable binding may have been found in an outer scope, but the current
    1894             :   // scope makes a sloppy 'eval' call, so the found variable may not be the
    1895             :   // correct one (the 'eval' may introduce a binding with the same name). In
    1896             :   // that case, change the lookup result to reflect this situation. Only
    1897             :   // scopes that can host var bindings (declaration scopes) need be considered
    1898             :   // here (this excludes block and catch scopes), and variable lookups at
    1899             :   // script scope are always dynamic.
    1900      380908 :   if (var->IsGlobalObjectProperty()) {
    1901      374459 :     Scope* target = entry_point == nullptr ? scope : entry_point;
    1902      374459 :     return target->NonLocal(proxy->raw_name(), VariableMode::kDynamicGlobal);
    1903             :   }
    1904             : 
    1905        6449 :   if (var->is_dynamic()) return var;
    1906             : 
    1907             :   Variable* invalidated = var;
    1908        4495 :   if (entry_point != nullptr) entry_point->variables_.Remove(invalidated);
    1909             : 
    1910        4495 :   Scope* target = entry_point == nullptr ? scope : entry_point;
    1911        4495 :   var = target->NonLocal(proxy->raw_name(), VariableMode::kDynamicLocal);
    1912             :   var->set_local_if_not_shadowed(invalidated);
    1913             : 
    1914        4495 :   return var;
    1915             : }
    1916             : 
    1917    18832175 : void Scope::ResolveVariable(ParseInfo* info, VariableProxy* proxy) {
    1918             :   DCHECK(info->script_scope()->is_script_scope());
    1919             :   DCHECK(!proxy->is_resolved());
    1920    18832175 :   Variable* var = Lookup<kParsedScope>(proxy, this, nullptr);
    1921             :   DCHECK_NOT_NULL(var);
    1922             :   ResolveTo(info, proxy, var);
    1923    18832170 : }
    1924             : 
    1925             : namespace {
    1926             : 
    1927             : void SetNeedsHoleCheck(Variable* var, VariableProxy* proxy) {
    1928             :   proxy->set_needs_hole_check();
    1929             :   var->ForceHoleInitialization();
    1930             : }
    1931             : 
    1932    18873575 : void UpdateNeedsHoleCheck(Variable* var, VariableProxy* proxy, Scope* scope) {
    1933    18877439 :   if (var->mode() == VariableMode::kDynamicLocal) {
    1934             :     // Dynamically introduced variables never need a hole check (since they're
    1935             :     // VariableMode::kVar bindings, either from var or function declarations),
    1936             :     // but the variable they shadow might need a hole check, which we want to do
    1937             :     // if we decide that no shadowing variable was dynamically introoduced.
    1938             :     DCHECK_EQ(kCreatedInitialized, var->initialization_flag());
    1939        3864 :     return UpdateNeedsHoleCheck(var->local_if_not_shadowed(), proxy, scope);
    1940             :   }
    1941             : 
    1942    18873575 :   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     1568795 :   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 VariableMode::kLet or
    1953             :   // VariableMode::kConst binding, both the Variable and the VariableProxy have
    1954             :   // the same declaration scope (i.e. they are both in global code, in the same
    1955             :   // function or in the same eval code), the VariableProxy is in the source
    1956             :   // physically located after the initializer of the variable, and that the
    1957             :   // 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     1567484 :   if (var->scope()->GetClosureScope() != scope->GetClosureScope()) {
    1970             :     return SetNeedsHoleCheck(var, proxy);
    1971             :   }
    1972             : 
    1973             :   // We should always have valid source positions.
    1974             :   DCHECK_NE(var->initializer_position(), kNoSourcePosition);
    1975             :   DCHECK_NE(proxy->position(), kNoSourcePosition);
    1976             : 
    1977      966750 :   if (var->scope()->is_nonlinear() ||
    1978             :       var->initializer_position() >= proxy->position()) {
    1979             :     return SetNeedsHoleCheck(var, proxy);
    1980             :   }
    1981             : }
    1982             : 
    1983             : }  // anonymous namespace
    1984             : 
    1985           0 : void Scope::ResolveTo(ParseInfo* info, VariableProxy* proxy, Variable* var) {
    1986             :   DCHECK_NOT_NULL(var);
    1987    18873714 :   UpdateNeedsHoleCheck(var, proxy, this);
    1988    18873456 :   proxy->BindTo(var);
    1989           0 : }
    1990             : 
    1991     6651595 : void Scope::ResolvePreparsedVariable(VariableProxy* proxy, Scope* scope,
    1992             :                                      Scope* end) {
    1993             :   // Resolve the variable in all parsed scopes to force context allocation.
    1994    15462053 :   for (; scope != end; scope = scope->outer_scope_) {
    1995             :     Variable* var = scope->LookupLocal(proxy->raw_name());
    1996     6668181 :     if (var != nullptr) {
    1997             :       var->set_is_used();
    1998     2264543 :       if (!var->is_dynamic()) {
    1999             :         var->ForceContextAllocation();
    2000     2262952 :         if (proxy->is_assigned()) var->set_maybe_assigned();
    2001             :         return;
    2002             :       }
    2003             :     }
    2004             :   }
    2005             : }
    2006             : 
    2007     5700617 : bool Scope::ResolveVariablesRecursively(ParseInfo* info) {
    2008             :   DCHECK(info->script_scope()->is_script_scope());
    2009             :   // Lazy parsed declaration scopes are already partially analyzed. If there are
    2010             :   // unresolved references remaining, they just need to be resolved in outer
    2011             :   // scopes.
    2012     5700617 :   if (WasLazilyParsed(this)) {
    2013             :     DCHECK_EQ(variables_.occupancy(), 0);
    2014     2474287 :     Scope* end = info->scope();
    2015             :     // Resolve in all parsed scopes except for the script scope.
    2016     2474284 :     if (!end->is_script_scope()) end = end->outer_scope();
    2017             : 
    2018     9125915 :     for (VariableProxy* proxy : unresolved_list_) {
    2019     6651627 :       ResolvePreparsedVariable(proxy, outer_scope(), end);
    2020             :     }
    2021             :   } else {
    2022             :     // Resolve unresolved variables for this scope.
    2023    22058527 :     for (VariableProxy* proxy : unresolved_list_) {
    2024    18832206 :       ResolveVariable(info, proxy);
    2025             :     }
    2026             : 
    2027             :     // Resolve unresolved variables for inner scopes.
    2028     7108871 :     for (Scope* scope = inner_scope_; scope != nullptr;
    2029             :          scope = scope->sibling_) {
    2030     3882567 :       if (!scope->ResolveVariablesRecursively(info)) return false;
    2031             :     }
    2032             :   }
    2033             :   return true;
    2034             : }
    2035             : 
    2036    19160657 : bool Scope::MustAllocate(Variable* var) {
    2037             :   DCHECK(var->location() != VariableLocation::MODULE);
    2038             :   // Give var a read/write use if there is a chance it might be accessed
    2039             :   // via an eval() call.  This is only possible if the variable has a
    2040             :   // visible name.
    2041    57441502 :   if (!var->raw_name()->IsEmpty() &&
    2042    35416211 :       (inner_scope_calls_eval_ || is_catch_scope() || is_script_scope())) {
    2043             :     var->set_is_used();
    2044     4192940 :     if (inner_scope_calls_eval_) var->set_maybe_assigned();
    2045             :   }
    2046             :   DCHECK(!var->has_forced_context_allocation() || var->is_used());
    2047             :   // Global variables do not need to be allocated.
    2048    36517728 :   return !var->IsGlobalObjectProperty() && var->is_used();
    2049             : }
    2050             : 
    2051             : 
    2052    11284705 : bool Scope::MustAllocateInContext(Variable* var) {
    2053             :   // If var is accessed from an inner scope, or if there is a possibility
    2054             :   // that it might be accessed from the current or an inner scope (through
    2055             :   // an eval() call or a runtime with lookup), it must be allocated in the
    2056             :   // context.
    2057             :   //
    2058             :   // Temporary variables are always stack-allocated.  Catch-bound variables are
    2059             :   // always context-allocated.
    2060    11284705 :   if (var->mode() == VariableMode::kTemporary) return false;
    2061    10027828 :   if (is_catch_scope()) return true;
    2062     9926125 :   if ((is_script_scope() || is_eval_scope()) &&
    2063             :       IsLexicalVariableMode(var->mode())) {
    2064             :     return true;
    2065             :   }
    2066     9250880 :   return var->has_forced_context_allocation() || inner_scope_calls_eval_;
    2067             : }
    2068             : 
    2069             : 
    2070     6391044 : void Scope::AllocateStackSlot(Variable* var) {
    2071     6779164 :   if (is_block_scope()) {
    2072      388120 :     outer_scope()->GetDeclarationScope()->AllocateStackSlot(var);
    2073             :   } else {
    2074     6391044 :     var->AllocateTo(VariableLocation::LOCAL, num_stack_slots_++);
    2075             :   }
    2076     6391044 : }
    2077             : 
    2078             : 
    2079             : void Scope::AllocateHeapSlot(Variable* var) {
    2080     2361607 :   var->AllocateTo(VariableLocation::CONTEXT, num_heap_slots_++);
    2081             : }
    2082             : 
    2083             : void DeclarationScope::AllocateParameterLocals() {
    2084             :   DCHECK(is_function_scope());
    2085             : 
    2086             :   bool has_mapped_arguments = false;
    2087     1604297 :   if (arguments_ != nullptr) {
    2088             :     DCHECK(!is_arrow_scope());
    2089     1085744 :     if (MustAllocate(arguments_) && !has_arguments_parameter_) {
    2090             :       // 'arguments' is used and does not refer to a function
    2091             :       // parameter of the same name. If the arguments object
    2092             :       // aliases formal parameters, we conservatively allocate
    2093             :       // them specially in the loop below.
    2094             :       has_mapped_arguments =
    2095      116785 :           GetArgumentsType() == CreateArgumentsType::kMappedArguments;
    2096             :     } else {
    2097             :       // 'arguments' is unused. Tell the code generator that it does not need to
    2098             :       // allocate the arguments object by nulling out arguments_.
    2099      968961 :       arguments_ = nullptr;
    2100             :     }
    2101             :   }
    2102             : 
    2103             :   // The same parameter may occur multiple times in the parameters_ list.
    2104             :   // If it does, and if it is not copied into the context object, it must
    2105             :   // receive the highest parameter index for that parameter; thus iteration
    2106             :   // order is relevant!
    2107     4097256 :   for (int i = num_parameters() - 1; i >= 0; --i) {
    2108     2492955 :     Variable* var = params_[i];
    2109             :     DCHECK_NOT_NULL(var);
    2110             :     DCHECK(!has_rest_ || var != rest_parameter());
    2111             :     DCHECK_EQ(this, var->scope());
    2112     2492955 :     if (has_mapped_arguments) {
    2113             :       var->set_is_used();
    2114             :       var->set_maybe_assigned();
    2115             :       var->ForceContextAllocation();
    2116             :     }
    2117             :     AllocateParameter(var, i);
    2118             :   }
    2119             : }
    2120             : 
    2121             : void DeclarationScope::AllocateParameter(Variable* var, int index) {
    2122     3629489 :   if (!MustAllocate(var)) return;
    2123     5397479 :   if (has_forced_context_allocation_for_parameters() ||
    2124     2698739 :       MustAllocateInContext(var)) {
    2125             :     DCHECK(var->IsUnallocated() || var->IsContextSlot());
    2126      163826 :     if (var->IsUnallocated()) AllocateHeapSlot(var);
    2127             :   } else {
    2128             :     DCHECK(var->IsUnallocated() || var->IsParameter());
    2129     2534914 :     if (var->IsUnallocated()) {
    2130             :       var->AllocateTo(VariableLocation::PARAMETER, index);
    2131             :     }
    2132             :   }
    2133             : }
    2134             : 
    2135             : void DeclarationScope::AllocateReceiver() {
    2136     2722401 :   if (!has_this_declaration()) return;
    2137             :   DCHECK_NOT_NULL(receiver());
    2138             :   DCHECK_EQ(receiver()->scope(), this);
    2139             :   AllocateParameter(receiver(), -1);
    2140             : }
    2141             : 
    2142    15547717 : void Scope::AllocateNonParameterLocal(Variable* var) {
    2143             :   DCHECK_EQ(var->scope(), this);
    2144    15547717 :   if (var->IsUnallocated() && MustAllocate(var)) {
    2145     8583922 :     if (MustAllocateInContext(var)) {
    2146             :       AllocateHeapSlot(var);
    2147             :       DCHECK_IMPLIES(is_catch_scope(),
    2148             :                      var->index() == Context::THROWN_OBJECT_INDEX);
    2149             :     } else {
    2150     6391045 :       AllocateStackSlot(var);
    2151             :     }
    2152             :   }
    2153    15547728 : }
    2154             : 
    2155             : void Scope::AllocateNonParameterLocalsAndDeclaredGlobals() {
    2156    37503341 :   for (Variable* local : locals_) {
    2157    15525335 :     AllocateNonParameterLocal(local);
    2158             :   }
    2159             : 
    2160     3226341 :   if (is_declaration_scope()) {
    2161             :     AsDeclarationScope()->AllocateLocals();
    2162             :   }
    2163             : }
    2164             : 
    2165             : void DeclarationScope::AllocateLocals() {
    2166             :   // For now, function_ must be allocated at the very end.  If it gets
    2167             :   // allocated in the context, it must be the last slot in the context,
    2168             :   // because of the current ScopeInfo implementation (see
    2169             :   // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor).
    2170     2722416 :   if (function_ != nullptr && MustAllocate(function_)) {
    2171       22393 :     AllocateNonParameterLocal(function_);
    2172             :   } else {
    2173     2700022 :     function_ = nullptr;
    2174             :   }
    2175             : 
    2176             :   DCHECK(!has_rest_ || !MustAllocate(rest_parameter()) ||
    2177             :          !rest_parameter()->IsUnallocated());
    2178             : 
    2179     2722414 :   if (new_target_ != nullptr && !MustAllocate(new_target_)) {
    2180     1008155 :     new_target_ = nullptr;
    2181             :   }
    2182             : 
    2183             :   NullifyRareVariableIf(RareVariable::kThisFunction,
    2184      170253 :                         [=](Variable* var) { return !MustAllocate(var); });
    2185             : }
    2186             : 
    2187        9130 : void ModuleScope::AllocateModuleVariables() {
    2188       10336 :   for (const auto& it : module()->regular_imports()) {
    2189        1206 :     Variable* var = LookupLocal(it.first);
    2190        1206 :     var->AllocateTo(VariableLocation::MODULE, it.second->cell_index);
    2191             :     DCHECK(!var->IsExport());
    2192             :   }
    2193             : 
    2194       27890 :   for (const auto& it : module()->regular_exports()) {
    2195       18760 :     Variable* var = LookupLocal(it.first);
    2196       18760 :     var->AllocateTo(VariableLocation::MODULE, it.second->cell_index);
    2197             :     DCHECK(var->IsExport());
    2198             :   }
    2199        9130 : }
    2200             : 
    2201     1818031 : void Scope::AllocateVariablesRecursively() {
    2202     5700572 :   this->ForEach([](Scope* scope) -> Iteration {
    2203             :     DCHECK(!scope->already_resolved_);
    2204     5700572 :     if (WasLazilyParsed(scope)) return Iteration::kContinue;
    2205             :     DCHECK_EQ(Context::MIN_CONTEXT_SLOTS, scope->num_heap_slots_);
    2206             : 
    2207             :     // Allocate variables for this scope.
    2208             :     // Parameters must be allocated first, if any.
    2209     3226321 :     if (scope->is_declaration_scope()) {
    2210     2722397 :       if (scope->is_function_scope()) {
    2211             :         scope->AsDeclarationScope()->AllocateParameterLocals();
    2212             :       }
    2213             :       scope->AsDeclarationScope()->AllocateReceiver();
    2214             :     }
    2215             :     scope->AllocateNonParameterLocalsAndDeclaredGlobals();
    2216             : 
    2217             :     // Force allocation of a context for this scope if necessary. For a 'with'
    2218             :     // scope and for a function scope that makes an 'eval' call we need a
    2219             :     // context, even if no local variables were statically allocated in the
    2220             :     // scope. Likewise for modules and function scopes representing asm.js
    2221             :     // modules. Also force a context, if the scope is stricter than the outer
    2222             :     // scope.
    2223             :     bool must_have_context =
    2224     6368509 :         scope->is_with_scope() || scope->is_module_scope() ||
    2225     3175519 :         scope->IsAsmModule() || scope->ForceContextForLanguageMode() ||
    2226     1600031 :         (scope->is_function_scope() &&
    2227     6316483 :          scope->AsDeclarationScope()->calls_sloppy_eval()) ||
    2228      360482 :         (scope->is_block_scope() && scope->is_declaration_scope() &&
    2229             :          scope->AsDeclarationScope()->calls_sloppy_eval());
    2230             : 
    2231             :     // If we didn't allocate any locals in the local context, then we only
    2232             :     // need the minimal number of slots if we must have a context.
    2233     3226342 :     if (scope->num_heap_slots_ == Context::MIN_CONTEXT_SLOTS &&
    2234             :         !must_have_context) {
    2235     2775440 :       scope->num_heap_slots_ = 0;
    2236             :     }
    2237             : 
    2238             :     // Allocation done.
    2239             :     DCHECK(scope->num_heap_slots_ == 0 ||
    2240             :            scope->num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS);
    2241             :     return Iteration::kDescend;
    2242             :   });
    2243     1818042 : }
    2244             : 
    2245     2421923 : void Scope::AllocateScopeInfosRecursively(Isolate* isolate,
    2246             :                                           MaybeHandle<ScopeInfo> outer_scope) {
    2247             :   DCHECK(scope_info_.is_null());
    2248     2421923 :   MaybeHandle<ScopeInfo> next_outer_scope = outer_scope;
    2249             : 
    2250     2421923 :   if (NeedsScopeInfo()) {
    2251     1270023 :     scope_info_ = ScopeInfo::Create(isolate, zone(), this, outer_scope);
    2252             :     // The ScopeInfo chain should mirror the context chain, so we only link to
    2253             :     // the next outer scope that needs a context.
    2254     1270020 :     if (NeedsContext()) next_outer_scope = scope_info_;
    2255             :   }
    2256             : 
    2257             :   // Allocate ScopeInfos for inner scopes.
    2258     5401548 :   for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
    2259     5632715 :     if (!scope->is_function_scope() ||
    2260             :         scope->AsDeclarationScope()->ShouldEagerCompile()) {
    2261      840890 :       scope->AllocateScopeInfosRecursively(isolate, next_outer_scope);
    2262             :     }
    2263             :   }
    2264     2421928 : }
    2265             : 
    2266             : // static
    2267     1581036 : void DeclarationScope::AllocateScopeInfos(ParseInfo* info, Isolate* isolate) {
    2268             :   DeclarationScope* scope = info->literal()->scope();
    2269     1581036 :   if (!scope->scope_info_.is_null()) return;  // Allocated by outer function.
    2270             : 
    2271     1581036 :   MaybeHandle<ScopeInfo> outer_scope;
    2272     1581036 :   if (scope->outer_scope_ != nullptr) {
    2273     1426595 :     outer_scope = scope->outer_scope_->scope_info_;
    2274             :   }
    2275             : 
    2276     1581036 :   scope->AllocateScopeInfosRecursively(isolate, outer_scope);
    2277             : 
    2278             :   // The debugger expects all shared function infos to contain a scope info.
    2279             :   // Since the top-most scope will end up in a shared function info, make sure
    2280             :   // it has one, even if it doesn't need a scope info.
    2281             :   // TODO(jochen|yangguo): Remove this requirement.
    2282     1581043 :   if (scope->scope_info_.is_null()) {
    2283             :     scope->scope_info_ =
    2284      956226 :         ScopeInfo::Create(isolate, scope->zone(), scope, outer_scope);
    2285             :   }
    2286             : 
    2287             :   // Ensuring that the outer script scope has a scope info avoids having
    2288             :   // special case for native contexts vs other contexts.
    2289     3162096 :   if (info->script_scope() && info->script_scope()->scope_info_.is_null()) {
    2290             :     info->script_scope()->scope_info_ =
    2291     1068998 :         handle(ScopeInfo::Empty(isolate), isolate);
    2292             :   }
    2293             : }
    2294             : 
    2295          90 : int Scope::ContextLocalCount() const {
    2296          90 :   if (num_heap_slots() == 0) return 0;
    2297             :   Variable* function =
    2298          55 :       is_function_scope() ? AsDeclarationScope()->function_var() : nullptr;
    2299             :   bool is_function_var_in_context =
    2300          55 :       function != nullptr && function->IsContextSlot();
    2301          55 :   return num_heap_slots() - Context::MIN_CONTEXT_SLOTS -
    2302          55 :          (is_function_var_in_context ? 1 : 0);
    2303             : }
    2304             : 
    2305       20111 : Variable* ClassScope::DeclarePrivateName(const AstRawString* name,
    2306             :                                          bool* was_added) {
    2307       40222 :   Variable* result = EnsureRareData()->private_name_map.Declare(
    2308             :       zone(), this, name, VariableMode::kConst, NORMAL_VARIABLE,
    2309             :       InitializationFlag::kNeedsInitialization,
    2310       20111 :       MaybeAssignedFlag::kMaybeAssigned, was_added);
    2311       20111 :   if (*was_added) {
    2312             :     locals_.Add(result);
    2313             :   }
    2314             :   result->ForceContextAllocation();
    2315       20111 :   return result;
    2316             : }
    2317             : 
    2318           0 : Variable* ClassScope::LookupLocalPrivateName(const AstRawString* name) {
    2319        2916 :   if (rare_data_ == nullptr) {
    2320             :     return nullptr;
    2321             :   }
    2322        2916 :   return rare_data_->private_name_map.Lookup(name);
    2323             : }
    2324             : 
    2325      369766 : UnresolvedList::Iterator ClassScope::GetUnresolvedPrivateNameTail() {
    2326      369766 :   if (rare_data_ == nullptr) {
    2327      367551 :     return UnresolvedList::Iterator();
    2328             :   }
    2329             :   return rare_data_->unresolved_private_names.end();
    2330             : }
    2331             : 
    2332        5789 : void ClassScope::ResetUnresolvedPrivateNameTail(UnresolvedList::Iterator tail) {
    2333        5789 :   if (rare_data_ == nullptr ||
    2334             :       rare_data_->unresolved_private_names.end() == tail) {
    2335             :     return;
    2336             :   }
    2337             : 
    2338             :   bool tail_is_empty = tail == UnresolvedList::Iterator();
    2339         480 :   if (tail_is_empty) {
    2340             :     // If the saved tail is empty, the list used to be empty, so clear it.
    2341             :     rare_data_->unresolved_private_names.Clear();
    2342             :   } else {
    2343             :     rare_data_->unresolved_private_names.Rewind(tail);
    2344             :   }
    2345             : }
    2346             : 
    2347      363582 : void ClassScope::MigrateUnresolvedPrivateNameTail(
    2348             :     AstNodeFactory* ast_node_factory, UnresolvedList::Iterator tail) {
    2349      363582 :   if (rare_data_ == nullptr ||
    2350             :       rare_data_->unresolved_private_names.end() == tail) {
    2351      362715 :     return;
    2352             :   }
    2353             :   UnresolvedList migrated_names;
    2354             : 
    2355             :   // If the saved tail is empty, the list used to be empty, so we should
    2356             :   // migrate everything after the head.
    2357             :   bool tail_is_empty = tail == UnresolvedList::Iterator();
    2358             :   UnresolvedList::Iterator it =
    2359         867 :       tail_is_empty ? rare_data_->unresolved_private_names.begin() : tail;
    2360             : 
    2361        1824 :   for (; it != rare_data_->unresolved_private_names.end(); ++it) {
    2362         957 :     VariableProxy* proxy = *it;
    2363             :     VariableProxy* copy = ast_node_factory->CopyVariableProxy(proxy);
    2364             :     migrated_names.Add(copy);
    2365             :   }
    2366             : 
    2367             :   // Replace with the migrated copies.
    2368         867 :   if (tail_is_empty) {
    2369             :     rare_data_->unresolved_private_names.Clear();
    2370             :   } else {
    2371             :     rare_data_->unresolved_private_names.Rewind(tail);
    2372             :   }
    2373         867 :   rare_data_->unresolved_private_names.Append(std::move(migrated_names));
    2374             : }
    2375             : 
    2376        5556 : void ClassScope::AddUnresolvedPrivateName(VariableProxy* proxy) {
    2377             :   // During a reparse, already_resolved_ may be true here, because
    2378             :   // the class scope is deserialized while the function scope inside may
    2379             :   // be new.
    2380             :   DCHECK(!proxy->is_resolved());
    2381             :   DCHECK(proxy->IsPrivateName());
    2382             :   EnsureRareData()->unresolved_private_names.Add(proxy);
    2383        5556 : }
    2384             : 
    2385         509 : Variable* ClassScope::LookupPrivateNameInScopeInfo(const AstRawString* name) {
    2386             :   DCHECK(!scope_info_.is_null());
    2387             :   DCHECK_NULL(LookupLocalPrivateName(name));
    2388             :   DisallowHeapAllocation no_gc;
    2389             : 
    2390         509 :   String name_handle = *name->string();
    2391             :   VariableMode mode;
    2392             :   InitializationFlag init_flag;
    2393             :   MaybeAssignedFlag maybe_assigned_flag;
    2394             :   int index = ScopeInfo::ContextSlotIndex(*scope_info_, name_handle, &mode,
    2395         509 :                                           &init_flag, &maybe_assigned_flag);
    2396         509 :   if (index < 0) {
    2397             :     return nullptr;
    2398             :   }
    2399             : 
    2400             :   DCHECK_EQ(mode, VariableMode::kConst);
    2401             :   DCHECK_EQ(init_flag, InitializationFlag::kNeedsInitialization);
    2402             :   DCHECK_EQ(maybe_assigned_flag, MaybeAssignedFlag::kMaybeAssigned);
    2403             : 
    2404             :   // Add the found private name to the map to speed up subsequent
    2405             :   // lookups for the same name.
    2406             :   bool was_added;
    2407         491 :   Variable* var = DeclarePrivateName(name, &was_added);
    2408             :   DCHECK(was_added);
    2409             :   var->AllocateTo(VariableLocation::CONTEXT, index);
    2410         491 :   return var;
    2411             : }
    2412             : 
    2413         524 : Variable* ClassScope::LookupPrivateName(VariableProxy* proxy) {
    2414             :   DCHECK(!proxy->is_resolved());
    2415             : 
    2416         524 :   for (Scope* scope = this; !scope->is_script_scope();
    2417             :        scope = scope->outer_scope_) {
    2418         524 :     if (!scope->is_class_scope()) continue;  // Only search in class scopes
    2419             :     ClassScope* class_scope = scope->AsClassScope();
    2420             :     // Try finding it in the private name map first, if it can't be found,
    2421             :     // try the deseralized scope info.
    2422             :     Variable* var = class_scope->LookupLocalPrivateName(proxy->raw_name());
    2423        1033 :     if (var == nullptr && !class_scope->scope_info_.is_null()) {
    2424         509 :       var = class_scope->LookupPrivateNameInScopeInfo(proxy->raw_name());
    2425             :     }
    2426             :     return var;
    2427             :   }
    2428             :   return nullptr;
    2429             : }
    2430             : 
    2431      153414 : bool ClassScope::ResolvePrivateNames(ParseInfo* info) {
    2432      153414 :   if (rare_data_ == nullptr ||
    2433             :       rare_data_->unresolved_private_names.is_empty()) {
    2434             :     return true;
    2435             :   }
    2436             : 
    2437             :   UnresolvedList& list = rare_data_->unresolved_private_names;
    2438        1015 :   for (VariableProxy* proxy : list) {
    2439         524 :     Variable* var = LookupPrivateName(proxy);
    2440         524 :     if (var == nullptr) {
    2441             :       Scanner::Location loc = proxy->location();
    2442             :       info->pending_error_handler()->ReportMessageAt(
    2443             :           loc.beg_pos, loc.end_pos,
    2444             :           MessageTemplate::kInvalidPrivateFieldResolution, proxy->raw_name(),
    2445          18 :           kSyntaxError);
    2446             :       return false;
    2447             :     } else {
    2448             :       var->set_is_used();
    2449         506 :       proxy->BindTo(var);
    2450             :     }
    2451             :   }
    2452             : 
    2453             :   // By now all unresolved private names should be resolved so
    2454             :   // clear the list.
    2455             :   list.Clear();
    2456         491 :   return true;
    2457             : }
    2458             : 
    2459      166534 : VariableProxy* ClassScope::ResolvePrivateNamesPartially() {
    2460      166534 :   if (rare_data_ == nullptr ||
    2461             :       rare_data_->unresolved_private_names.is_empty()) {
    2462             :     return nullptr;
    2463             :   }
    2464             : 
    2465             :   ClassScope* outer_class_scope =
    2466        2178 :       outer_scope_ == nullptr ? nullptr : outer_scope_->GetClassScope();
    2467        2178 :   UnresolvedList& unresolved = rare_data_->unresolved_private_names;
    2468             :   bool has_private_names = rare_data_->private_name_map.capacity() > 0;
    2469             : 
    2470             :   // If the class itself does not have private names, nor does it have
    2471             :   // an outer class scope, then we are certain any private name access
    2472             :   // inside cannot be resolved.
    2473        2178 :   if (!has_private_names && outer_class_scope == nullptr &&
    2474             :       !unresolved.is_empty()) {
    2475           0 :     return unresolved.first();
    2476             :   }
    2477             : 
    2478        2867 :   for (VariableProxy* proxy = unresolved.first(); proxy != nullptr;) {
    2479             :     DCHECK(proxy->IsPrivateName());
    2480             :     VariableProxy* next = proxy->next_unresolved();
    2481        2392 :     unresolved.Remove(proxy);
    2482             :     Variable* var = nullptr;
    2483             : 
    2484             :     // If we can find private name in the current class scope, we can bind
    2485             :     // them immediately because it's going to shadow any outer private names.
    2486        2392 :     if (has_private_names) {
    2487             :       var = LookupLocalPrivateName(proxy->raw_name());
    2488        2392 :       if (var != nullptr) {
    2489             :         var->set_is_used();
    2490         635 :         proxy->BindTo(var);
    2491             :       }
    2492             :     }
    2493             : 
    2494             :     // If the current scope does not have declared private names,
    2495             :     // try looking from the outer class scope later.
    2496        2392 :     if (var == nullptr) {
    2497             :       // There's no outer class scope so we are certain that the variable
    2498             :       // cannot be resolved later.
    2499        1757 :       if (outer_class_scope == nullptr) {
    2500             :         return proxy;
    2501             :       }
    2502             : 
    2503             :       // The private name may be found later in the outer class scope,
    2504             :       // so push it to the outer sopce.
    2505          54 :       outer_class_scope->AddUnresolvedPrivateName(proxy);
    2506             :     }
    2507             : 
    2508             :     proxy = next;
    2509             :   }
    2510             : 
    2511             :   DCHECK(unresolved.is_empty());
    2512             :   return nullptr;
    2513             : }
    2514             : 
    2515             : }  // namespace internal
    2516      121996 : }  // namespace v8

Generated by: LCOV version 1.10