LCOV - code coverage report
Current view: top level - src/ast - scopes.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 617 647 95.4 %
Date: 2019-03-21 Functions: 86 99 86.9 %

          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    40192551 : 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    80384916 :       ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->Hash(),
      49             :                                   ZoneAllocationPolicy(zone));
      50    40192365 :   *was_added = p->value == nullptr;
      51    40192365 :   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    39033339 :     p->value = variable;
      57             :   }
      58    40191900 :   return reinterpret_cast<Variable*>(p->value);
      59             : }
      60             : 
      61           0 : void VariableMap::Remove(Variable* var) {
      62             :   const AstRawString* name = var->raw_name();
      63        3904 :   ZoneHashMap::Remove(const_cast<AstRawString*>(name), name->Hash());
      64           0 : }
      65             : 
      66     1005835 : void VariableMap::Add(Zone* zone, Variable* var) {
      67             :   const AstRawString* name = var->raw_name();
      68             :   Entry* p =
      69     1005839 :       ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->Hash(),
      70             :                                   ZoneAllocationPolicy(zone));
      71             :   DCHECK_NULL(p->value);
      72             :   DCHECK_EQ(name, p->key);
      73     1005839 :   p->value = var;
      74     1005839 : }
      75             : 
      76    88795627 : Variable* VariableMap::Lookup(const AstRawString* name) {
      77             :   Entry* p = ZoneHashMap::Lookup(const_cast<AstRawString*>(name), name->Hash());
      78    88795627 :   if (p != nullptr) {
      79             :     DCHECK(reinterpret_cast<const AstRawString*>(p->key) == name);
      80             :     DCHECK_NOT_NULL(p->value);
      81    39017493 :     return reinterpret_cast<Variable*>(p->value);
      82             :   }
      83             :   return nullptr;
      84             : }
      85             : 
      86             : // ----------------------------------------------------------------------------
      87             : // Implementation of Scope
      88             : 
      89     2974419 : Scope::Scope(Zone* zone)
      90             :     : zone_(zone),
      91             :       outer_scope_(nullptr),
      92             :       variables_(zone),
      93     5948836 :       scope_type_(SCRIPT_SCOPE) {
      94             :   SetDefaults();
      95     2974417 : }
      96             : 
      97    12902644 : Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type)
      98             :     : zone_(zone),
      99             :       outer_scope_(outer_scope),
     100             :       variables_(zone),
     101    25805340 :       scope_type_(scope_type) {
     102             :   DCHECK_NE(SCRIPT_SCOPE, scope_type);
     103             :   SetDefaults();
     104             :   set_language_mode(outer_scope->language_mode());
     105    12902696 :   outer_scope_->AddInnerScope(this);
     106    12902696 : }
     107             : 
     108     2974420 : DeclarationScope::DeclarationScope(Zone* zone,
     109             :                                    AstValueFactory* ast_value_factory)
     110     5948835 :     : Scope(zone), function_kind_(kNormalFunction), params_(4, zone) {
     111             :   DCHECK_EQ(scope_type_, SCRIPT_SCOPE);
     112     2974415 :   SetDefaults();
     113             :   receiver_ = DeclareDynamicGlobal(ast_value_factory->this_string(),
     114     2974419 :                                    THIS_VARIABLE, this);
     115     2974419 : }
     116             : 
     117     6822103 : 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    13644254 :       params_(4, zone) {
     123             :   DCHECK_NE(scope_type, SCRIPT_SCOPE);
     124     6822151 :   SetDefaults();
     125     6822139 : }
     126             : 
     127       71720 : ModuleScope::ModuleScope(DeclarationScope* script_scope,
     128             :                          AstValueFactory* avfactory)
     129             :     : DeclarationScope(avfactory->zone(), script_scope, MODULE_SCOPE, kModule),
     130             :       module_descriptor_(new (avfactory->zone())
     131      143440 :                              ModuleDescriptor(avfactory->zone())) {
     132             :   set_language_mode(LanguageMode::kStrict);
     133       71720 :   DeclareThis(avfactory);
     134       71720 : }
     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     1078372 : Scope::Scope(Zone* zone, ScopeType scope_type, Handle<ScopeInfo> scope_info)
     144             :     : zone_(zone),
     145             :       outer_scope_(nullptr),
     146             :       variables_(zone),
     147             :       scope_info_(scope_info),
     148     2156745 :       scope_type_(scope_type) {
     149             :   DCHECK(!scope_info.is_null());
     150             :   SetDefaults();
     151             : #ifdef DEBUG
     152             :   already_resolved_ = true;
     153             : #endif
     154     1078373 :   if (scope_info->CallsSloppyEval()) scope_calls_eval_ = true;
     155     2156745 :   set_language_mode(scope_info->language_mode());
     156     1078373 :   num_heap_slots_ = scope_info->ContextLength();
     157             :   DCHECK_LE(Context::MIN_CONTEXT_SLOTS, num_heap_slots_);
     158             :   // We don't really need to use the preparsed scope data; this is just to
     159             :   // shorten the recursion in SetMustUsePreparseData.
     160     1078373 :   must_use_preparsed_scope_data_ = true;
     161     1078373 : }
     162             : 
     163      900849 : DeclarationScope::DeclarationScope(Zone* zone, ScopeType scope_type,
     164             :                                    Handle<ScopeInfo> scope_info)
     165             :     : Scope(zone, scope_type, scope_info),
     166     1801698 :       function_kind_(scope_info->function_kind()),
     167     3603396 :       params_(0, zone) {
     168             :   DCHECK_NE(scope_type, SCRIPT_SCOPE);
     169      900849 :   SetDefaults();
     170      900849 : }
     171             : 
     172        5334 : Scope::Scope(Zone* zone, const AstRawString* catch_variable_name,
     173             :              MaybeAssignedFlag maybe_assigned, Handle<ScopeInfo> scope_info)
     174             :     : zone_(zone),
     175             :       outer_scope_(nullptr),
     176             :       variables_(zone),
     177             :       scope_info_(scope_info),
     178       10668 :       scope_type_(CATCH_SCOPE) {
     179             :   SetDefaults();
     180             : #ifdef DEBUG
     181             :   already_resolved_ = true;
     182             : #endif
     183             :   // Cache the catch variable, even though it's also available via the
     184             :   // scope_info, as the parser expects that a catch scope always has the catch
     185             :   // variable as first and only variable.
     186             :   bool was_added;
     187             :   Variable* variable =
     188             :       Declare(zone, catch_variable_name, VariableMode::kVar, NORMAL_VARIABLE,
     189             :               kCreatedInitialized, maybe_assigned, &was_added);
     190             :   DCHECK(was_added);
     191             :   AllocateHeapSlot(variable);
     192        5334 : }
     193             : 
     194    10697392 : void DeclarationScope::SetDefaults() {
     195    10697392 :   is_declaration_scope_ = true;
     196    10697392 :   has_simple_parameters_ = true;
     197    10697392 :   is_asm_module_ = false;
     198    10697392 :   force_eager_compilation_ = false;
     199    10697392 :   has_arguments_parameter_ = false;
     200    10697392 :   scope_uses_super_property_ = false;
     201    10697392 :   has_checked_syntax_ = false;
     202    10697392 :   has_this_reference_ = false;
     203             :   has_this_declaration_ =
     204    17183261 :       (is_function_scope() && !is_arrow_scope()) || is_module_scope();
     205    10697392 :   has_rest_ = false;
     206    10697392 :   receiver_ = nullptr;
     207    10697392 :   new_target_ = nullptr;
     208    10697392 :   function_ = nullptr;
     209    10697392 :   arguments_ = nullptr;
     210    10697392 :   rare_data_ = nullptr;
     211    10697392 :   should_eager_compile_ = false;
     212    10697392 :   was_lazily_parsed_ = false;
     213    10697392 :   is_skipped_function_ = false;
     214    10697392 :   preparse_data_builder_ = nullptr;
     215             : #ifdef DEBUG
     216             :   DeclarationScope* outer_declaration_scope =
     217             :       outer_scope_ ? outer_scope_->GetDeclarationScope() : nullptr;
     218             :   is_being_lazily_parsed_ =
     219             :       outer_declaration_scope ? outer_declaration_scope->is_being_lazily_parsed_
     220             :                               : false;
     221             : #endif
     222    10697392 : }
     223             : 
     224           0 : void Scope::SetDefaults() {
     225             : #ifdef DEBUG
     226             :   scope_name_ = nullptr;
     227             :   already_resolved_ = false;
     228             :   needs_migration_ = false;
     229             : #endif
     230    16960820 :   inner_scope_ = nullptr;
     231    16960820 :   sibling_ = nullptr;
     232             :   unresolved_list_.Clear();
     233             : 
     234    16960820 :   start_position_ = kNoSourcePosition;
     235    16960820 :   end_position_ = kNoSourcePosition;
     236             : 
     237    16960820 :   num_stack_slots_ = 0;
     238    16960820 :   num_heap_slots_ = Context::MIN_CONTEXT_SLOTS;
     239             : 
     240             :   set_language_mode(LanguageMode::kSloppy);
     241             : 
     242    16960820 :   scope_calls_eval_ = false;
     243    16960820 :   scope_nonlinear_ = false;
     244    16960820 :   is_hidden_ = false;
     245    16960820 :   is_debug_evaluate_scope_ = false;
     246             : 
     247    16960820 :   inner_scope_calls_eval_ = false;
     248    16960820 :   force_context_allocation_ = false;
     249    16960820 :   force_context_allocation_for_parameters_ = false;
     250             : 
     251    16960820 :   is_declaration_scope_ = false;
     252             : 
     253    16960820 :   must_use_preparsed_scope_data_ = false;
     254           0 : }
     255             : 
     256      420773 : bool Scope::HasSimpleParameters() {
     257             :   DeclarationScope* scope = GetClosureScope();
     258      585358 :   return !scope->is_function_scope() || scope->has_simple_parameters();
     259             : }
     260             : 
     261      717408 : void DeclarationScope::set_should_eager_compile() {
     262     2522106 :   should_eager_compile_ = !was_lazily_parsed_;
     263      717408 : }
     264             : 
     265        5870 : void DeclarationScope::set_is_asm_module() { is_asm_module_ = true; }
     266             : 
     267     1788095 : bool Scope::IsAsmModule() const {
     268     7487439 :   return is_function_scope() && AsDeclarationScope()->is_asm_module();
     269             : }
     270             : 
     271        6335 : bool Scope::ContainsAsmModule() const {
     272        6335 :   if (IsAsmModule()) return true;
     273             : 
     274             :   // Check inner scopes recursively
     275        2531 :   for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
     276             :     // Don't check inner functions which won't be eagerly compiled.
     277        4971 :     if (!scope->is_function_scope() ||
     278             :         scope->AsDeclarationScope()->ShouldEagerCompile()) {
     279        2108 :       if (scope->ContainsAsmModule()) return true;
     280             :     }
     281             :   }
     282             : 
     283             :   return false;
     284             : }
     285             : 
     286     1014547 : Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone,
     287             :                                     ScopeInfo scope_info,
     288             :                                     DeclarationScope* script_scope,
     289             :                                     AstValueFactory* ast_value_factory,
     290             :                                     DeserializationMode deserialization_mode) {
     291             :   // Reconstruct the outer scope chain from a closure's context chain.
     292             :   Scope* current_scope = nullptr;
     293             :   Scope* innermost_scope = nullptr;
     294             :   Scope* outer_scope = nullptr;
     295     2098254 :   while (!scope_info.is_null()) {
     296     1413882 :     if (scope_info->scope_type() == WITH_SCOPE) {
     297       14837 :       if (scope_info->IsDebugEvaluateScope()) {
     298             :         outer_scope = new (zone)
     299       25478 :             DeclarationScope(zone, FUNCTION_SCOPE, handle(scope_info, isolate));
     300             :         outer_scope->set_is_debug_evaluate_scope();
     301             :       } else {
     302             :         // For scope analysis, debug-evaluate is equivalent to a with scope.
     303             :         outer_scope =
     304        4196 :             new (zone) Scope(zone, WITH_SCOPE, handle(scope_info, isolate));
     305             :       }
     306             : 
     307     1399046 :     } else if (scope_info->scope_type() == SCRIPT_SCOPE) {
     308             :       // If we reach a script scope, it's the outermost scope. Install the
     309             :       // scope info of this script context onto the existing script scope to
     310             :       // avoid nesting script scopes.
     311      330177 :       if (deserialization_mode == DeserializationMode::kIncludingVariables) {
     312             :         script_scope->SetScriptScopeInfo(handle(scope_info, isolate));
     313             :       }
     314             :       DCHECK(!scope_info->HasOuterScopeInfo());
     315             :       break;
     316     1068869 :     } else if (scope_info->scope_type() == FUNCTION_SCOPE) {
     317             :       outer_scope = new (zone)
     318     1698644 :           DeclarationScope(zone, FUNCTION_SCOPE, handle(scope_info, isolate));
     319      849322 :       if (scope_info->IsAsmModule()) {
     320             :         outer_scope->AsDeclarationScope()->set_is_asm_module();
     321             :       }
     322      219547 :     } else if (scope_info->scope_type() == EVAL_SCOPE) {
     323             :       outer_scope = new (zone)
     324       52836 :           DeclarationScope(zone, EVAL_SCOPE, handle(scope_info, isolate));
     325      193130 :     } else if (scope_info->scope_type() == BLOCK_SCOPE) {
     326      184533 :       if (scope_info->is_declaration_scope()) {
     327             :         outer_scope = new (zone)
     328       18214 :             DeclarationScope(zone, BLOCK_SCOPE, handle(scope_info, isolate));
     329             :       } else {
     330             :         outer_scope =
     331      350853 :             new (zone) Scope(zone, BLOCK_SCOPE, handle(scope_info, isolate));
     332             :       }
     333        8597 :     } else if (scope_info->scope_type() == MODULE_SCOPE) {
     334             :       outer_scope = new (zone)
     335             :           ModuleScope(isolate, handle(scope_info, isolate), ast_value_factory);
     336             :     } else {
     337             :       DCHECK_EQ(scope_info->scope_type(), CATCH_SCOPE);
     338             :       DCHECK_EQ(scope_info->ContextLocalCount(), 1);
     339             :       DCHECK_EQ(scope_info->ContextLocalMode(0), VariableMode::kVar);
     340             :       DCHECK_EQ(scope_info->ContextLocalInitFlag(0), kCreatedInitialized);
     341        5334 :       String name = scope_info->ContextLocalName(0);
     342             :       MaybeAssignedFlag maybe_assigned =
     343        5334 :           scope_info->ContextLocalMaybeAssignedFlag(0);
     344             :       outer_scope = new (zone)
     345             :           Scope(zone, ast_value_factory->GetString(handle(name, isolate)),
     346       16002 :                 maybe_assigned, handle(scope_info, isolate));
     347             :     }
     348     1083708 :     if (deserialization_mode == DeserializationMode::kScopesOnly) {
     349           0 :       outer_scope->scope_info_ = Handle<ScopeInfo>::null();
     350             :     }
     351     1083708 :     if (current_scope != nullptr) {
     352             :       outer_scope->AddInnerScope(current_scope);
     353             :     }
     354             :     current_scope = outer_scope;
     355     1083708 :     if (innermost_scope == nullptr) innermost_scope = current_scope;
     356     1083708 :     scope_info = scope_info->HasOuterScopeInfo() ? scope_info->OuterScopeInfo()
     357     1083706 :                                                  : ScopeInfo();
     358             :   }
     359             : 
     360     2029098 :   if (deserialization_mode == DeserializationMode::kIncludingVariables &&
     361             :       script_scope->scope_info_.is_null()) {
     362             :     Handle<ScriptContextTable> table(
     363     2053116 :         isolate->native_context()->script_context_table(), isolate);
     364      684372 :     Handle<Context> first = ScriptContextTable::GetContext(isolate, table, 0);
     365     1368744 :     Handle<ScopeInfo> scope_info(first->scope_info(), isolate);
     366             :     script_scope->SetScriptScopeInfo(scope_info);
     367             :   }
     368             : 
     369     1014549 :   if (innermost_scope == nullptr) return script_scope;
     370      858432 :   script_scope->AddInnerScope(current_scope);
     371      858432 :   return innermost_scope;
     372             : }
     373             : 
     374   147977565 : DeclarationScope* Scope::AsDeclarationScope() {
     375             :   DCHECK(is_declaration_scope());
     376   147977565 :   return static_cast<DeclarationScope*>(this);
     377             : }
     378             : 
     379           0 : const DeclarationScope* Scope::AsDeclarationScope() const {
     380             :   DCHECK(is_declaration_scope());
     381           0 :   return static_cast<const DeclarationScope*>(this);
     382             : }
     383             : 
     384       55331 : ModuleScope* Scope::AsModuleScope() {
     385             :   DCHECK(is_module_scope());
     386       55331 :   return static_cast<ModuleScope*>(this);
     387             : }
     388             : 
     389           0 : const ModuleScope* Scope::AsModuleScope() const {
     390             :   DCHECK(is_module_scope());
     391           0 :   return static_cast<const ModuleScope*>(this);
     392             : }
     393             : 
     394       11584 : void DeclarationScope::DeclareSloppyBlockFunction(
     395             :     SloppyBlockFunctionStatement* sloppy_block_function) {
     396             :   sloppy_block_functions_.Add(sloppy_block_function);
     397       11584 : }
     398             : 
     399     5106002 : void DeclarationScope::HoistSloppyBlockFunctions(AstNodeFactory* factory) {
     400             :   DCHECK(is_sloppy(language_mode()));
     401             :   DCHECK(is_function_scope() || is_eval_scope() || is_script_scope() ||
     402             :          (is_block_scope() && outer_scope()->is_function_scope()));
     403             :   DCHECK(HasSimpleParameters() || is_block_scope() || is_being_lazily_parsed_);
     404             :   DCHECK_EQ(factory == nullptr, is_being_lazily_parsed_);
     405             : 
     406     5106002 :   if (sloppy_block_functions_.is_empty()) return;
     407             : 
     408             :   // In case of complex parameters the current scope is the body scope and the
     409             :   // parameters are stored in the outer scope.
     410       20498 :   Scope* parameter_scope = HasSimpleParameters() ? this : outer_scope_;
     411             :   DCHECK(parameter_scope->is_function_scope() || is_eval_scope() ||
     412             :          is_script_scope());
     413             : 
     414             :   DeclarationScope* decl_scope = this;
     415       11611 :   while (decl_scope->is_eval_scope()) {
     416             :     decl_scope = decl_scope->outer_scope()->GetDeclarationScope();
     417             :   }
     418             :   Scope* outer_scope = decl_scope->outer_scope();
     419             : 
     420             :   // For each variable which is used as a function declaration in a sloppy
     421             :   // block,
     422       21755 :   for (SloppyBlockFunctionStatement* sloppy_block_function :
     423       11505 :        sloppy_block_functions_) {
     424             :     const AstRawString* name = sloppy_block_function->name();
     425             : 
     426             :     // If the variable wouldn't conflict with a lexical declaration
     427             :     // or parameter,
     428             : 
     429             :     // Check if there's a conflict with a parameter.
     430             :     Variable* maybe_parameter = parameter_scope->LookupLocal(name);
     431       14290 :     if (maybe_parameter != nullptr && maybe_parameter->is_parameter()) {
     432             :       continue;
     433             :     }
     434             : 
     435             :     // Check if there's a conflict with a lexical declaration
     436             :     Scope* query_scope = sloppy_block_function->scope()->outer_scope();
     437             :     Variable* var = nullptr;
     438             :     bool should_hoist = true;
     439             : 
     440             :     // It is not sufficient to just do a Lookup on query_scope: for
     441             :     // example, that does not prevent hoisting of the function in
     442             :     // `{ let e; try {} catch (e) { function e(){} } }`
     443             :     do {
     444       16198 :       var = query_scope->LookupInScopeOrScopeInfo(name);
     445       19465 :       if (var != nullptr && IsLexicalVariableMode(var->mode())) {
     446             :         should_hoist = false;
     447             :         break;
     448             :       }
     449             :       query_scope = query_scope->outer_scope();
     450       14792 :     } while (query_scope != outer_scope);
     451             : 
     452       11312 :     if (!should_hoist) continue;
     453             : 
     454        9906 :     if (factory) {
     455             :       DCHECK(!is_being_lazily_parsed_);
     456             :       int pos = sloppy_block_function->position();
     457        7480 :       bool ok = true;
     458             :       bool was_added;
     459             :       auto declaration = factory->NewVariableDeclaration(pos);
     460             :       // Based on the preceding checks, it doesn't matter what we pass as
     461             :       // sloppy_mode_block_scope_function_redefinition.
     462             :       Variable* var = DeclareVariable(
     463             :           declaration, name, pos, VariableMode::kVar, NORMAL_VARIABLE,
     464             :           Variable::DefaultInitializationFlag(VariableMode::kVar), &was_added,
     465        7480 :           nullptr, &ok);
     466             :       DCHECK(ok);
     467             :       VariableProxy* source =
     468             :           factory->NewVariableProxy(sloppy_block_function->var());
     469             :       VariableProxy* target = factory->NewVariableProxy(var);
     470        7481 :       Assignment* assignment = factory->NewAssignment(
     471        7481 :           sloppy_block_function->init(), target, source, pos);
     472             :       assignment->set_lookup_hoisting_mode(LookupHoistingMode::kLegacySloppy);
     473             :       Statement* statement = factory->NewExpressionStatement(assignment, pos);
     474             :       sloppy_block_function->set_statement(statement);
     475             :     } else {
     476             :       DCHECK(is_being_lazily_parsed_);
     477             :       bool was_added;
     478        2426 :       Variable* var = DeclareVariableName(name, VariableMode::kVar, &was_added);
     479        2426 :       if (sloppy_block_function->init() == Token::ASSIGN)
     480             :         var->set_maybe_assigned();
     481             :     }
     482             :   }
     483             : }
     484             : 
     485     1804696 : bool DeclarationScope::Analyze(ParseInfo* info) {
     486             :   RuntimeCallTimerScope runtimeTimer(
     487             :       info->runtime_call_stats(),
     488             :       info->on_background_thread()
     489             :           ? RuntimeCallCounterId::kCompileBackgroundScopeAnalysis
     490     1804696 :           : RuntimeCallCounterId::kCompileScopeAnalysis);
     491             :   DCHECK_NOT_NULL(info->literal());
     492             :   DeclarationScope* scope = info->literal()->scope();
     493             : 
     494             :   base::Optional<AllowHandleDereference> allow_deref;
     495             :   if (!info->maybe_outer_scope_info().is_null()) {
     496             :     // Allow dereferences to the scope info if there is one.
     497             :     allow_deref.emplace();
     498             :   }
     499             : 
     500     2656237 :   if (scope->is_eval_scope() && is_sloppy(scope->language_mode())) {
     501      725536 :     AstNodeFactory factory(info->ast_value_factory(), info->zone());
     502      725536 :     scope->HoistSloppyBlockFunctions(&factory);
     503             :   }
     504             : 
     505             :   // We are compiling one of four cases:
     506             :   // 1) top-level code,
     507             :   // 2) a function/eval/module on the top-level
     508             :   // 3) a function/eval in a scope that was already resolved.
     509             :   DCHECK(scope->is_script_scope() || scope->outer_scope()->is_script_scope() ||
     510             :          scope->outer_scope()->already_resolved_);
     511             : 
     512             :   // The outer scope is never lazy.
     513             :   scope->set_should_eager_compile();
     514             : 
     515     1804698 :   if (scope->must_use_preparsed_scope_data_) {
     516             :     DCHECK_EQ(scope->scope_type_, ScopeType::FUNCTION_SCOPE);
     517             :     allow_deref.emplace();
     518       36471 :     info->consumed_preparse_data()->RestoreScopeAllocationData(scope);
     519             :   }
     520             : 
     521     1804698 :   if (!scope->AllocateVariables(info)) return false;
     522             : 
     523             : #ifdef DEBUG
     524             :   if (info->is_native() ? FLAG_print_builtin_scopes : FLAG_print_scopes) {
     525             :     PrintF("Global scope:\n");
     526             :     scope->Print();
     527             :   }
     528             :   scope->CheckScopePositions();
     529             :   scope->CheckZones();
     530             : #endif
     531             : 
     532     1804529 :   return true;
     533             : }
     534             : 
     535     5264578 : void DeclarationScope::DeclareThis(AstValueFactory* ast_value_factory) {
     536             :   DCHECK(has_this_declaration());
     537             : 
     538     5264578 :   bool derived_constructor = IsDerivedConstructor(function_kind_);
     539             : 
     540             :   receiver_ = new (zone())
     541             :       Variable(this, ast_value_factory->this_string(),
     542             :                derived_constructor ? VariableMode::kConst : VariableMode::kVar,
     543             :                THIS_VARIABLE,
     544             :                derived_constructor ? kNeedsInitialization : kCreatedInitialized,
     545    10529168 :                kNotAssigned);
     546     5264584 : }
     547             : 
     548     4121273 : void DeclarationScope::DeclareArguments(AstValueFactory* ast_value_factory) {
     549             :   DCHECK(is_function_scope());
     550             :   DCHECK(!is_arrow_scope());
     551             : 
     552             :   // Declare 'arguments' variable which exists in all non arrow functions.  Note
     553             :   // that it might never be accessed, in which case it won't be allocated during
     554             :   // variable allocation.
     555             :   bool was_added;
     556             :   arguments_ =
     557     4121273 :       Declare(zone(), ast_value_factory->arguments_string(), VariableMode::kVar,
     558     4121295 :               NORMAL_VARIABLE, kCreatedInitialized, kNotAssigned, &was_added);
     559     4124056 :   if (!was_added && IsLexicalVariableMode(arguments_->mode())) {
     560             :     // Check if there's lexically declared variable named arguments to avoid
     561             :     // redeclaration. See ES#sec-functiondeclarationinstantiation, step 20.
     562         622 :     arguments_ = nullptr;
     563             :   }
     564     4121295 : }
     565             : 
     566     4554179 : void DeclarationScope::DeclareDefaultFunctionVariables(
     567             :     AstValueFactory* ast_value_factory) {
     568             :   DCHECK(is_function_scope());
     569             :   DCHECK(!is_arrow_scope());
     570             : 
     571     4554179 :   DeclareThis(ast_value_factory);
     572             :   bool was_added;
     573     4554177 :   new_target_ = Declare(zone(), ast_value_factory->new_target_string(),
     574             :                         VariableMode::kConst, NORMAL_VARIABLE,
     575     4554186 :                         kCreatedInitialized, kNotAssigned, &was_added);
     576             :   DCHECK(was_added);
     577             : 
     578    16705815 :   if (IsConciseMethod(function_kind_) || IsClassConstructor(function_kind_) ||
     579             :       IsAccessorFunction(function_kind_)) {
     580             :     EnsureRareData()->this_function = Declare(
     581             :         zone(), ast_value_factory->this_function_string(), VariableMode::kConst,
     582      938694 :         NORMAL_VARIABLE, kCreatedInitialized, kNotAssigned, &was_added);
     583             :     DCHECK(was_added);
     584             :   }
     585     4554187 : }
     586             : 
     587     1006733 : Variable* DeclarationScope::DeclareFunctionVar(const AstRawString* name,
     588             :                                                Scope* cache) {
     589             :   DCHECK(is_function_scope());
     590             :   DCHECK_NULL(function_);
     591     1006733 :   if (cache == nullptr) cache = this;
     592             :   DCHECK_NULL(cache->variables_.Lookup(name));
     593             :   VariableKind kind = is_sloppy(language_mode()) ? SLOPPY_FUNCTION_NAME_VARIABLE
     594     1006733 :                                                  : NORMAL_VARIABLE;
     595             :   function_ = new (zone())
     596     2013470 :       Variable(this, name, VariableMode::kConst, kind, kCreatedInitialized);
     597     1006735 :   if (calls_sloppy_eval()) {
     598         900 :     cache->NonLocal(name, VariableMode::kDynamic);
     599             :   } else {
     600     1005835 :     cache->variables_.Add(zone(), function_);
     601             :   }
     602     1006739 :   return function_;
     603             : }
     604             : 
     605      142965 : Variable* DeclarationScope::DeclareGeneratorObjectVar(
     606             :     const AstRawString* name) {
     607             :   DCHECK(is_function_scope() || is_module_scope());
     608             :   DCHECK_NULL(generator_object_var());
     609             : 
     610             :   Variable* result = EnsureRareData()->generator_object =
     611      142965 :       NewTemporary(name, kNotAssigned);
     612             :   result->set_is_used();
     613      142965 :   return result;
     614             : }
     615             : 
     616     5214143 : Scope* Scope::FinalizeBlockScope() {
     617             :   DCHECK(is_block_scope());
     618             : #ifdef DEBUG
     619             :   DCHECK_NE(sibling_, this);
     620             : #endif
     621             : 
     622    14862403 :   if (variables_.occupancy() > 0 ||
     623       69872 :       (is_declaration_scope() && AsDeclarationScope()->calls_sloppy_eval())) {
     624             :     return this;
     625             :   }
     626             : 
     627             :   // Remove this scope from outer scope.
     628             :   outer_scope()->RemoveInnerScope(this);
     629             : 
     630             :   // Reparent inner scopes.
     631     4431702 :   if (inner_scope_ != nullptr) {
     632             :     Scope* scope = inner_scope_;
     633      557275 :     scope->outer_scope_ = outer_scope();
     634      646975 :     while (scope->sibling_ != nullptr) {
     635             :       scope = scope->sibling_;
     636       44850 :       scope->outer_scope_ = outer_scope();
     637             :     }
     638      557275 :     scope->sibling_ = outer_scope()->inner_scope_;
     639      557275 :     outer_scope()->inner_scope_ = inner_scope_;
     640      557275 :     inner_scope_ = nullptr;
     641             :   }
     642             : 
     643             :   // Move unresolved variables
     644     4431702 :   if (!unresolved_list_.is_empty()) {
     645             :     outer_scope()->unresolved_list_.Prepend(std::move(unresolved_list_));
     646             :     unresolved_list_.Clear();
     647             :   }
     648             : 
     649     4431702 :   if (inner_scope_calls_eval_) outer_scope()->inner_scope_calls_eval_ = true;
     650             : 
     651             :   // No need to propagate scope_calls_eval_, since if it was relevant to
     652             :   // this scope we would have had to bail out at the top.
     653             :   DCHECK(!scope_calls_eval_ || !is_declaration_scope() ||
     654             :          !is_sloppy(language_mode()));
     655             : 
     656             :   // This block does not need a context.
     657     4431702 :   num_heap_slots_ = 0;
     658             : 
     659             :   // Mark scope as removed by making it its own sibling.
     660             : #ifdef DEBUG
     661             :   sibling_ = this;
     662             : #endif
     663             : 
     664     4431702 :   return nullptr;
     665             : }
     666             : 
     667           0 : void DeclarationScope::AddLocal(Variable* var) {
     668             :   DCHECK(!already_resolved_);
     669             :   // Temporaries are only placed in ClosureScopes.
     670             :   DCHECK_EQ(GetClosureScope(), this);
     671             :   locals_.Add(var);
     672           0 : }
     673             : 
     674      133195 : void Scope::Snapshot::Reparent(DeclarationScope* new_parent) {
     675             :   DCHECK(!IsCleared());
     676             :   DCHECK_EQ(new_parent, outer_scope_and_calls_eval_.GetPointer()->inner_scope_);
     677             :   DCHECK_EQ(new_parent->outer_scope_, outer_scope_and_calls_eval_.GetPointer());
     678             :   DCHECK_EQ(new_parent, new_parent->GetClosureScope());
     679             :   DCHECK_NULL(new_parent->inner_scope_);
     680             :   DCHECK(new_parent->unresolved_list_.is_empty());
     681      133195 :   Scope* inner_scope = new_parent->sibling_;
     682      133195 :   if (inner_scope != top_inner_scope_) {
     683        3644 :     for (; inner_scope->sibling() != top_inner_scope_;
     684             :          inner_scope = inner_scope->sibling()) {
     685           0 :       inner_scope->outer_scope_ = new_parent;
     686           0 :       if (inner_scope->inner_scope_calls_eval_) {
     687           0 :         new_parent->inner_scope_calls_eval_ = true;
     688             :       }
     689             :       DCHECK_NE(inner_scope, new_parent);
     690             :     }
     691        3644 :     inner_scope->outer_scope_ = new_parent;
     692        3644 :     if (inner_scope->inner_scope_calls_eval_) {
     693         128 :       new_parent->inner_scope_calls_eval_ = true;
     694             :     }
     695        3644 :     new_parent->inner_scope_ = new_parent->sibling_;
     696        3644 :     inner_scope->sibling_ = nullptr;
     697             :     // Reset the sibling rather than the inner_scope_ since we
     698             :     // want to keep new_parent there.
     699        3644 :     new_parent->sibling_ = top_inner_scope_;
     700             :   }
     701             : 
     702             :   Scope* outer_scope_ = outer_scope_and_calls_eval_.GetPointer();
     703             :   new_parent->unresolved_list_.MoveTail(&outer_scope_->unresolved_list_,
     704             :                                         top_unresolved_);
     705             : 
     706             :   // Move temporaries allocated for complex parameter initializers.
     707             :   DeclarationScope* outer_closure = outer_scope_->GetClosureScope();
     708      133195 :   for (auto it = top_local_; it != outer_closure->locals()->end(); ++it) {
     709          12 :     Variable* local = *it;
     710             :     DCHECK_EQ(VariableMode::kTemporary, local->mode());
     711             :     DCHECK_EQ(local->scope(), local->scope()->GetClosureScope());
     712             :     DCHECK_NE(local->scope(), new_parent);
     713             :     local->set_scope(new_parent);
     714             :   }
     715             :   new_parent->locals_.MoveTail(outer_closure->locals(), top_local_);
     716             :   outer_closure->locals_.Rewind(top_local_);
     717             : 
     718             :   // Move eval calls since Snapshot's creation into new_parent.
     719      133195 :   if (outer_scope_and_calls_eval_->scope_calls_eval_) {
     720         419 :     new_parent->scope_calls_eval_ = true;
     721         419 :     new_parent->inner_scope_calls_eval_ = true;
     722             :   }
     723             : 
     724             :   // We are in the arrow function case. The calls eval we may have recorded
     725             :   // is intended for the inner scope and we should simply restore the
     726             :   // original "calls eval" flag of the outer scope.
     727             :   RestoreEvalFlag();
     728             :   Clear();
     729      133195 : }
     730             : 
     731          91 : void Scope::ReplaceOuterScope(Scope* outer) {
     732             :   DCHECK_NOT_NULL(outer);
     733             :   DCHECK_NOT_NULL(outer_scope_);
     734             :   DCHECK(!already_resolved_);
     735          91 :   outer_scope_->RemoveInnerScope(this);
     736             :   outer->AddInnerScope(this);
     737             :   outer_scope_ = outer;
     738          91 : }
     739             : 
     740     2495979 : Variable* Scope::LookupInScopeInfo(const AstRawString* name, Scope* cache) {
     741             :   DCHECK(!scope_info_.is_null());
     742             :   DCHECK_NULL(cache->variables_.Lookup(name));
     743             :   DisallowHeapAllocation no_gc;
     744             : 
     745     2495979 :   String name_handle = *name->string();
     746             :   // The Scope is backed up by ScopeInfo. This means it cannot operate in a
     747             :   // heap-independent mode, and all strings must be internalized immediately. So
     748             :   // it's ok to get the Handle<String> here.
     749             :   bool found = false;
     750             : 
     751             :   VariableLocation location;
     752             :   int index;
     753             :   VariableMode mode;
     754             :   InitializationFlag init_flag;
     755             :   MaybeAssignedFlag maybe_assigned_flag;
     756             : 
     757             :   {
     758             :     location = VariableLocation::CONTEXT;
     759             :     index = ScopeInfo::ContextSlotIndex(*scope_info_, name_handle, &mode,
     760     2495979 :                                         &init_flag, &maybe_assigned_flag);
     761     2495982 :     found = index >= 0;
     762             :   }
     763             : 
     764     2495982 :   if (!found && is_module_scope()) {
     765             :     location = VariableLocation::MODULE;
     766        3982 :     index = scope_info_->ModuleIndex(name_handle, &mode, &init_flag,
     767        1991 :                                      &maybe_assigned_flag);
     768        1991 :     found = index != 0;
     769             :   }
     770             : 
     771     2495982 :   if (!found) {
     772     2033368 :     index = scope_info_->FunctionContextSlotIndex(name_handle);
     773     2033368 :     if (index < 0) return nullptr;  // Nowhere found.
     774        1040 :     Variable* var = AsDeclarationScope()->DeclareFunctionVar(name, cache);
     775             :     DCHECK_EQ(VariableMode::kConst, var->mode());
     776             :     var->AllocateTo(VariableLocation::CONTEXT, index);
     777        1040 :     return cache->variables_.Lookup(name);
     778             :   }
     779             : 
     780             :   if (!is_module_scope()) {
     781             :     DCHECK_NE(index, scope_info_->ReceiverContextSlotIndex());
     782             :   }
     783             : 
     784             :   bool was_added;
     785             :   Variable* var =
     786      462614 :       cache->variables_.Declare(zone(), this, name, mode, NORMAL_VARIABLE,
     787      462614 :                                 init_flag, maybe_assigned_flag, &was_added);
     788             :   DCHECK(was_added);
     789             :   var->AllocateTo(location, index);
     790      462615 :   return var;
     791             : }
     792             : 
     793     2923060 : Variable* DeclarationScope::DeclareParameter(const AstRawString* name,
     794             :                                              VariableMode mode,
     795             :                                              bool is_optional, bool is_rest,
     796             :                                              AstValueFactory* ast_value_factory,
     797             :                                              int position) {
     798             :   DCHECK(!already_resolved_);
     799             :   DCHECK(is_function_scope() || is_module_scope());
     800             :   DCHECK(!has_rest_);
     801             :   DCHECK(!is_optional || !is_rest);
     802             :   DCHECK(!is_being_lazily_parsed_);
     803             :   DCHECK(!was_lazily_parsed_);
     804             :   Variable* var;
     805     2923060 :   if (mode == VariableMode::kTemporary) {
     806      219700 :     var = NewTemporary(name);
     807             :   } else {
     808     2813212 :     var = LookupLocal(name);
     809             :     DCHECK_EQ(mode, VariableMode::kVar);
     810             :     DCHECK(var->is_parameter());
     811             :   }
     812     2923062 :   has_rest_ = is_rest;
     813     2923062 :   var->set_initializer_position(position);
     814     2923062 :   params_.Add(var, zone());
     815     2923056 :   if (!is_rest) ++num_parameters_;
     816     2923056 :   if (name == ast_value_factory->arguments_string()) {
     817        1454 :     has_arguments_parameter_ = true;
     818             :   }
     819             :   // Params are automatically marked as used to make sure that the debugger and
     820             :   // function.arguments sees them.
     821             :   // TODO(verwaest): Reevaluate whether we always need to do this, since
     822             :   // strict-mode function.arguments does not make the arguments available.
     823     2923056 :   var->set_is_used();
     824     2923056 :   return var;
     825             : }
     826             : 
     827     3974957 : void DeclarationScope::RecordParameter(bool is_rest) {
     828             :   DCHECK(!already_resolved_);
     829             :   DCHECK(is_function_scope() || is_module_scope());
     830             :   DCHECK(is_being_lazily_parsed_);
     831             :   DCHECK(!has_rest_);
     832     3974957 :   has_rest_ = is_rest;
     833     3974957 :   if (!is_rest) ++num_parameters_;
     834     3974957 : }
     835             : 
     836    24070249 : Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode,
     837             :                               VariableKind kind, bool* was_added,
     838             :                               InitializationFlag init_flag) {
     839             :   DCHECK(!already_resolved_);
     840             :   // This function handles VariableMode::kVar, VariableMode::kLet, and
     841             :   // VariableMode::kConst modes.  VariableMode::kDynamic variables are
     842             :   // introduced during variable allocation, and VariableMode::kTemporary
     843             :   // variables are allocated via NewTemporary().
     844             :   DCHECK(IsDeclaredVariableMode(mode));
     845             :   DCHECK_IMPLIES(GetDeclarationScope()->is_being_lazily_parsed(),
     846             :                  mode == VariableMode::kVar || mode == VariableMode::kLet ||
     847             :                      mode == VariableMode::kConst);
     848             :   DCHECK(!GetDeclarationScope()->was_lazily_parsed());
     849             :   Variable* var =
     850             :       Declare(zone(), name, mode, kind, init_flag, kNotAssigned, was_added);
     851             : 
     852             :   // Pessimistically assume that top-level variables will be assigned and used.
     853             :   //
     854             :   // Top-level variables in a script can be accessed by other scripts or even
     855             :   // become global properties. While this does not apply to top-level variables
     856             :   // in a module (assuming they are not exported), we must still mark these as
     857             :   // assigned because they might be accessed by a lazily parsed top-level
     858             :   // function, which, for efficiency, we preparse without variable tracking.
     859    24069931 :   if (is_script_scope() || is_module_scope()) {
     860     4124731 :     if (mode != VariableMode::kConst) var->set_maybe_assigned();
     861             :     var->set_is_used();
     862             :   }
     863             : 
     864    24069931 :   return var;
     865             : }
     866             : 
     867    15780866 : Variable* Scope::DeclareVariable(
     868             :     Declaration* declaration, const AstRawString* name, int pos,
     869             :     VariableMode mode, VariableKind kind, InitializationFlag init,
     870             :     bool* was_added, bool* sloppy_mode_block_scope_function_redefinition,
     871             :     bool* ok) {
     872             :   DCHECK(IsDeclaredVariableMode(mode));
     873             :   DCHECK(!already_resolved_);
     874             :   DCHECK(!GetDeclarationScope()->is_being_lazily_parsed());
     875             :   DCHECK(!GetDeclarationScope()->was_lazily_parsed());
     876             : 
     877    29802417 :   if (mode == VariableMode::kVar && !is_declaration_scope()) {
     878      805618 :     return GetDeclarationScope()->DeclareVariable(
     879             :         declaration, name, pos, mode, kind, init, was_added,
     880      402809 :         sloppy_mode_block_scope_function_redefinition, ok);
     881             :   }
     882             :   DCHECK(!is_catch_scope());
     883             :   DCHECK(!is_with_scope());
     884             :   DCHECK(is_declaration_scope() ||
     885             :          (IsLexicalVariableMode(mode) && is_block_scope()));
     886             : 
     887             :   DCHECK_NOT_NULL(name);
     888             : 
     889             :   Variable* var = LookupLocal(name);
     890             :   // Declare the variable in the declaration scope.
     891    15378061 :   *was_added = var == nullptr;
     892    15378061 :   if (V8_LIKELY(*was_added)) {
     893    14574449 :     if (V8_UNLIKELY(is_eval_scope() && is_sloppy(language_mode()) &&
     894             :                     mode == VariableMode::kVar)) {
     895             :       // In a var binding in a sloppy direct eval, pollute the enclosing scope
     896             :       // with this new binding by doing the following:
     897             :       // The proxy is bound to a lookup variable to force a dynamic declaration
     898             :       // using the DeclareEvalVar or DeclareEvalFunction runtime functions.
     899             :       DCHECK_EQ(NORMAL_VARIABLE, kind);
     900      307410 :       var = NonLocal(name, VariableMode::kDynamic);
     901             :       // Mark the var as used in case anyone outside the eval wants to use it.
     902             :       var->set_is_used();
     903             :     } else {
     904             :       // Declare the name.
     905    13455588 :       var = DeclareLocal(name, mode, kind, was_added, init);
     906             :       DCHECK(*was_added);
     907             :     }
     908             :   } else {
     909             :     var->set_maybe_assigned();
     910     3179848 :     if (V8_UNLIKELY(IsLexicalVariableMode(mode) ||
     911             :                     IsLexicalVariableMode(var->mode()))) {
     912             :       // The name was declared in this scope before; check for conflicting
     913             :       // re-declarations. We have a conflict if either of the declarations is
     914             :       // not a var (in script scope, we also have to ignore legacy const for
     915             :       // compatibility). There is similar code in runtime.cc in the Declare
     916             :       // functions. The function CheckConflictingVarDeclarations checks for
     917             :       // var and let bindings from different scopes whereas this is a check
     918             :       // for conflicting declarations within the same scope. This check also
     919             :       // covers the special case
     920             :       //
     921             :       // function () { let x; { var x; } }
     922             :       //
     923             :       // because the var declaration is hoisted to the function scope where
     924             :       // 'x' is already bound.
     925             :       //
     926             :       // In harmony we treat re-declarations as early errors. See ES5 16 for a
     927             :       // definition of early errors.
     928             :       //
     929             :       // Allow duplicate function decls for web compat, see bug 4693.
     930       64438 :       *ok = var->is_sloppy_block_function() &&
     931       64438 :             kind == SLOPPY_BLOCK_FUNCTION_VARIABLE;
     932       64438 :       *sloppy_mode_block_scope_function_redefinition = *ok;
     933             :     }
     934             :   }
     935             :   DCHECK_NOT_NULL(var);
     936             : 
     937             :   // We add a declaration node for every declaration. The compiler
     938             :   // will only generate code if necessary. In particular, declarations
     939             :   // for inner local variables that do not represent functions won't
     940             :   // result in any generated code.
     941             :   //
     942             :   // This will lead to multiple declaration nodes for the
     943             :   // same variable if it is declared several times. This is not a
     944             :   // semantic issue, but it may be a performance issue since it may
     945             :   // lead to repeated DeclareEvalVar or DeclareEvalFunction calls.
     946             :   decls_.Add(declaration);
     947             :   declaration->set_var(var);
     948    15377849 :   return var;
     949             : }
     950             : 
     951    11070214 : Variable* Scope::DeclareVariableName(const AstRawString* name,
     952             :                                      VariableMode mode, bool* was_added,
     953             :                                      VariableKind kind) {
     954             :   DCHECK(IsDeclaredVariableMode(mode));
     955             :   DCHECK(!already_resolved_);
     956             :   DCHECK(GetDeclarationScope()->is_being_lazily_parsed());
     957             : 
     958    20710273 :   if (mode == VariableMode::kVar && !is_declaration_scope()) {
     959     1130988 :     return GetDeclarationScope()->DeclareVariableName(name, mode, was_added,
     960      565494 :                                                       kind);
     961             :   }
     962             :   DCHECK(!is_with_scope());
     963             :   DCHECK(!is_eval_scope());
     964             :   DCHECK(is_declaration_scope() || IsLexicalVariableMode(mode));
     965             :   DCHECK(scope_info_.is_null());
     966             : 
     967             :   // Declare the variable in the declaration scope.
     968    10504720 :   Variable* var = DeclareLocal(name, mode, kind, was_added);
     969    10504720 :   if (!*was_added) {
     970     1736967 :     if (IsLexicalVariableMode(mode) || IsLexicalVariableMode(var->mode())) {
     971         721 :       if (!var->is_sloppy_block_function() ||
     972             :           kind != SLOPPY_BLOCK_FUNCTION_VARIABLE) {
     973             :         // Duplicate functions are allowed in the sloppy mode, but if this is
     974             :         // not a function declaration, it's an error. This is an error PreParser
     975             :         // hasn't previously detected.
     976             :         return nullptr;
     977             :       }
     978             :       // Sloppy block function redefinition.
     979             :     }
     980             :     var->set_maybe_assigned();
     981             :   }
     982             :   var->set_is_used();
     983    10504105 :   return var;
     984             : }
     985             : 
     986      368579 : Variable* Scope::DeclareCatchVariableName(const AstRawString* name) {
     987             :   DCHECK(!already_resolved_);
     988             :   DCHECK(is_catch_scope());
     989             :   DCHECK(scope_info_.is_null());
     990             : 
     991             :   bool was_added;
     992             :   Variable* result = Declare(zone(), name, VariableMode::kVar, NORMAL_VARIABLE,
     993             :                              kCreatedInitialized, kNotAssigned, &was_added);
     994             :   DCHECK(was_added);
     995      368584 :   return result;
     996             : }
     997             : 
     998    50540277 : void Scope::AddUnresolved(VariableProxy* proxy) {
     999             :   DCHECK(!already_resolved_);
    1000             :   DCHECK(!proxy->is_resolved());
    1001             :   unresolved_list_.Add(proxy);
    1002    50540277 : }
    1003             : 
    1004           0 : Variable* DeclarationScope::DeclareDynamicGlobal(const AstRawString* name,
    1005             :                                                  VariableKind kind,
    1006             :                                                  Scope* cache) {
    1007             :   DCHECK(is_script_scope());
    1008             :   bool was_added;
    1009     4947218 :   return cache->variables_.Declare(
    1010             :       zone(), this, name, VariableMode::kDynamicGlobal, kind,
    1011     4947218 :       kCreatedInitialized, kNotAssigned, &was_added);
    1012             :   // TODO(neis): Mark variable as maybe-assigned?
    1013             : }
    1014             : 
    1015        1289 : bool Scope::RemoveUnresolved(VariableProxy* var) {
    1016        1289 :   return unresolved_list_.Remove(var);
    1017             : }
    1018             : 
    1019       15713 : void Scope::DeleteUnresolved(VariableProxy* var) {
    1020             :   DCHECK(unresolved_list_.Contains(var));
    1021             :   var->mark_removed_from_unresolved();
    1022       15713 : }
    1023             : 
    1024     1230524 : Variable* Scope::NewTemporary(const AstRawString* name) {
    1025     1340374 :   return NewTemporary(name, kMaybeAssigned);
    1026             : }
    1027             : 
    1028     1483342 : Variable* Scope::NewTemporary(const AstRawString* name,
    1029             :                               MaybeAssignedFlag maybe_assigned) {
    1030             :   DeclarationScope* scope = GetClosureScope();
    1031             :   Variable* var = new (zone()) Variable(scope, name, VariableMode::kTemporary,
    1032             :                                         NORMAL_VARIABLE, kCreatedInitialized);
    1033             :   scope->AddLocal(var);
    1034     1483339 :   if (maybe_assigned == kMaybeAssigned) var->set_maybe_assigned();
    1035     1483339 :   return var;
    1036             : }
    1037             : 
    1038     6587297 : Declaration* DeclarationScope::CheckConflictingVarDeclarations() {
    1039     6587297 :   if (has_checked_syntax_) return nullptr;
    1040    19377814 :   for (Declaration* decl : decls_) {
    1041             :     // Lexical vs lexical conflicts within the same scope have already been
    1042             :     // captured in Parser::Declare. The only conflicts we still need to check
    1043             :     // are lexical vs nested var.
    1044    25077896 :     if (decl->IsVariableDeclaration() &&
    1045    12097598 :         decl->AsVariableDeclaration()->AsNested() != nullptr) {
    1046      935784 :       Scope* current = decl->AsVariableDeclaration()->AsNested()->scope();
    1047             :       DCHECK(decl->var()->mode() == VariableMode::kVar ||
    1048             :              decl->var()->mode() == VariableMode::kDynamic);
    1049             :       // Iterate through all scopes until the declaration scope.
    1050             :       do {
    1051             :         // There is a conflict if there exists a non-VAR binding.
    1052     1356111 :         if (current->is_catch_scope()) {
    1053             :           current = current->outer_scope();
    1054        2780 :           continue;
    1055             :         }
    1056             :         Variable* other_var = current->LookupLocal(decl->var()->raw_name());
    1057     1353331 :         if (other_var != nullptr) {
    1058             :           DCHECK(IsLexicalVariableMode(other_var->mode()));
    1059             :           return decl;
    1060             :         }
    1061             :         current = current->outer_scope();
    1062     1342982 :       } while (current != this);
    1063             :     }
    1064             :   }
    1065             : 
    1066     6397516 :   if (V8_LIKELY(!is_eval_scope())) return nullptr;
    1067      853316 :   if (!is_sloppy(language_mode())) return nullptr;
    1068             : 
    1069             :   // Var declarations in sloppy eval are hoisted to the first non-eval
    1070             :   // declaration scope. Check for conflicts between the eval scope that
    1071             :   // declaration scope.
    1072      726224 :   Scope* end = this;
    1073      726230 :   do {
    1074      726230 :     end = end->outer_scope_->GetDeclarationScope();
    1075             :   } while (end->is_eval_scope());
    1076      726224 :   end = end->outer_scope_;
    1077             : 
    1078     1026977 :   for (Declaration* decl : decls_) {
    1079      300906 :     if (IsLexicalVariableMode(decl->var()->mode())) continue;
    1080      289441 :     Scope* current = outer_scope_;
    1081             :     // Iterate through all scopes until and including the declaration scope.
    1082             :     do {
    1083             :       // There is a conflict if there exists a non-VAR binding up to the
    1084             :       // declaration scope in which this sloppy-eval runs.
    1085             :       Variable* other_var =
    1086      289648 :           current->LookupInScopeOrScopeInfo(decl->var()->raw_name());
    1087      290208 :       if (other_var != nullptr && IsLexicalVariableMode(other_var->mode())) {
    1088             :         DCHECK(!current->is_catch_scope());
    1089             :         return decl;
    1090             :       }
    1091             :       current = current->outer_scope();
    1092      289495 :     } while (current != end);
    1093             :   }
    1094             :   return nullptr;
    1095             : }
    1096             : 
    1097       84383 : const AstRawString* Scope::FindVariableDeclaredIn(Scope* scope,
    1098             :                                                   VariableMode mode_limit) {
    1099             :   const VariableMap& variables = scope->variables_;
    1100      873847 :   for (ZoneHashMap::Entry* p = variables.Start(); p != nullptr;
    1101             :        p = variables.Next(p)) {
    1102      395059 :     const AstRawString* name = static_cast<const AstRawString*>(p->key);
    1103             :     Variable* var = LookupLocal(name);
    1104      396550 :     if (var != nullptr && var->mode() <= mode_limit) return name;
    1105             :   }
    1106             :   return nullptr;
    1107             : }
    1108             : 
    1109      779616 : void DeclarationScope::DeserializeReceiver(AstValueFactory* ast_value_factory) {
    1110      779616 :   if (is_script_scope()) {
    1111             :     DCHECK_NOT_NULL(receiver_);
    1112             :     return;
    1113             :   }
    1114             :   DCHECK(has_this_declaration());
    1115      638680 :   DeclareThis(ast_value_factory);
    1116      638680 :   if (is_debug_evaluate_scope()) {
    1117       12223 :     receiver_->AllocateTo(VariableLocation::LOOKUP, -1);
    1118             :   } else {
    1119     1252914 :     receiver_->AllocateTo(VariableLocation::CONTEXT,
    1120             :                           scope_info_->ReceiverContextSlotIndex());
    1121             :   }
    1122             : }
    1123             : 
    1124     1804695 : bool DeclarationScope::AllocateVariables(ParseInfo* info) {
    1125             :   // Module variables must be allocated before variable resolution
    1126             :   // to ensure that UpdateNeedsHoleCheck() can detect import variables.
    1127     1804695 :   if (is_module_scope()) AsModuleScope()->AllocateModuleVariables();
    1128             : 
    1129     1804695 :   if (!ResolveVariablesRecursively(info)) {
    1130             :     DCHECK(info->pending_error_handler()->has_pending_error());
    1131             :     return false;
    1132             :   }
    1133             : 
    1134             :   // // Don't allocate variables of preparsed scopes.
    1135     1804523 :   if (!was_lazily_parsed()) AllocateVariablesRecursively();
    1136             : 
    1137             :   return true;
    1138             : }
    1139             : 
    1140        4313 : bool Scope::HasThisReference() const {
    1141        7870 :   if (is_declaration_scope() && AsDeclarationScope()->has_this_reference()) {
    1142             :     return true;
    1143             :   }
    1144             : 
    1145        5062 :   for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
    1146        4426 :     if (!scope->is_declaration_scope() ||
    1147             :         !scope->AsDeclarationScope()->has_this_declaration()) {
    1148        2368 :       if (scope->HasThisReference()) return true;
    1149             :     }
    1150             :   }
    1151             : 
    1152             :   return false;
    1153             : }
    1154             : 
    1155     4158567 : bool Scope::AllowsLazyParsingWithoutUnresolvedVariables(
    1156             :     const Scope* outer) const {
    1157             :   // If none of the outer scopes need to decide whether to context allocate
    1158             :   // specific variables, we can preparse inner functions without unresolved
    1159             :   // variables. Otherwise we need to find unresolved variables to force context
    1160             :   // allocation of the matching declarations. We can stop at the outer scope for
    1161             :   // the parse, since context allocation of those variables is already
    1162             :   // guaranteed to be correct.
    1163     4158825 :   for (const Scope* s = this; s != outer; s = s->outer_scope_) {
    1164             :     // Eval forces context allocation on all outer scopes, so we don't need to
    1165             :     // look at those scopes. Sloppy eval makes top-level non-lexical variables
    1166             :     // dynamic, whereas strict-mode requires context allocation.
    1167     3116768 :     if (s->is_eval_scope()) return is_sloppy(s->language_mode());
    1168             :     // Catch scopes force context allocation of all variables.
    1169     2108574 :     if (s->is_catch_scope()) continue;
    1170             :     // With scopes do not introduce variables that need allocation.
    1171     2108574 :     if (s->is_with_scope()) continue;
    1172             :     DCHECK(s->is_module_scope() || s->is_block_scope() ||
    1173             :            s->is_function_scope());
    1174             :     return false;
    1175             :   }
    1176             :   return true;
    1177             : }
    1178             : 
    1179     3602688 : bool DeclarationScope::AllowsLazyCompilation() const {
    1180             :   // Functions which force eager compilation and class member initializer
    1181             :   // functions are not lazily compilable.
    1182     3602688 :   return !force_eager_compilation_ &&
    1183     3602688 :          !IsClassMembersInitializerFunction(function_kind());
    1184             : }
    1185             : 
    1186     2800009 : int Scope::ContextChainLength(Scope* scope) const {
    1187             :   int n = 0;
    1188     4273489 :   for (const Scope* s = this; s != scope; s = s->outer_scope_) {
    1189             :     DCHECK_NOT_NULL(s);  // scope must be in the scope chain
    1190      736740 :     if (s->NeedsContext()) n++;
    1191             :   }
    1192     2800009 :   return n;
    1193             : }
    1194             : 
    1195      354574 : int Scope::ContextChainLengthUntilOutermostSloppyEval() const {
    1196             :   int result = 0;
    1197             :   int length = 0;
    1198             : 
    1199     2540798 :   for (const Scope* s = this; s != nullptr; s = s->outer_scope()) {
    1200     1093112 :     if (!s->NeedsContext()) continue;
    1201      794580 :     length++;
    1202     1574365 :     if (s->is_declaration_scope() &&
    1203             :         s->AsDeclarationScope()->calls_sloppy_eval()) {
    1204             :       result = length;
    1205             :     }
    1206             :   }
    1207             : 
    1208      354574 :   return result;
    1209             : }
    1210             : 
    1211    17384062 : DeclarationScope* Scope::GetDeclarationScope() {
    1212             :   Scope* scope = this;
    1213    24860355 :   while (!scope->is_declaration_scope()) {
    1214             :     scope = scope->outer_scope();
    1215             :   }
    1216    17384062 :   return scope->AsDeclarationScope();
    1217             : }
    1218             : 
    1219           0 : const DeclarationScope* Scope::GetClosureScope() const {
    1220             :   const Scope* scope = this;
    1221           0 :   while (!scope->is_declaration_scope() || scope->is_block_scope()) {
    1222             :     scope = scope->outer_scope();
    1223             :   }
    1224           0 :   return scope->AsDeclarationScope();
    1225             : }
    1226             : 
    1227     9504413 : DeclarationScope* Scope::GetClosureScope() {
    1228             :   Scope* scope = this;
    1229    19630893 :   while (!scope->is_declaration_scope() || scope->is_block_scope()) {
    1230             :     scope = scope->outer_scope();
    1231             :   }
    1232     9504413 :   return scope->AsDeclarationScope();
    1233             : }
    1234             : 
    1235           0 : bool Scope::NeedsScopeInfo() const {
    1236             :   DCHECK(!already_resolved_);
    1237             :   DCHECK(GetClosureScope()->ShouldEagerCompile());
    1238             :   // The debugger expects all functions to have scope infos.
    1239             :   // TODO(jochen|yangguo): Remove this requirement.
    1240     2397073 :   if (is_function_scope()) return true;
    1241           0 :   return NeedsContext();
    1242             : }
    1243             : 
    1244       43337 : bool Scope::ShouldBanArguments() {
    1245       43337 :   return GetReceiverScope()->should_ban_arguments();
    1246             : }
    1247             : 
    1248     9006589 : DeclarationScope* Scope::GetReceiverScope() {
    1249             :   Scope* scope = this;
    1250    18754912 :   while (!scope->is_declaration_scope() ||
    1251     9101312 :          (!scope->is_script_scope() &&
    1252             :           !scope->AsDeclarationScope()->has_this_declaration())) {
    1253             :     scope = scope->outer_scope();
    1254             :   }
    1255     9006589 :   return scope->AsDeclarationScope();
    1256             : }
    1257             : 
    1258     2602735 : Scope* Scope::GetOuterScopeWithContext() {
    1259     2602735 :   Scope* scope = outer_scope_;
    1260     3521897 :   while (scope && !scope->NeedsContext()) {
    1261             :     scope = scope->outer_scope();
    1262             :   }
    1263     2602735 :   return scope;
    1264             : }
    1265             : 
    1266             : namespace {
    1267             : bool WasLazilyParsed(Scope* scope) {
    1268    21648310 :   return scope->is_declaration_scope() &&
    1269             :          scope->AsDeclarationScope()->was_lazily_parsed();
    1270             : }
    1271             : 
    1272             : }  // namespace
    1273             : 
    1274             : template <typename FunctionType>
    1275             : void Scope::ForEach(FunctionType callback) {
    1276             :   Scope* scope = this;
    1277             :   while (true) {
    1278    11957099 :     Iteration iteration = callback(scope);
    1279             :     // Try to descend into inner scopes first.
    1280    11957144 :     if ((iteration == Iteration::kDescend) && scope->inner_scope_ != nullptr) {
    1281             :       scope = scope->inner_scope_;
    1282             :     } else {
    1283             :       // Find the next outer scope with a sibling.
    1284    11957144 :       while (scope->sibling_ == nullptr) {
    1285     5154400 :         if (scope == this) return;
    1286     2966231 :         scope = scope->outer_scope_;
    1287             :       }
    1288     6802744 :       if (scope == this) return;
    1289             :       scope = scope->sibling_;
    1290             :     }
    1291             :   }
    1292             : }
    1293             : 
    1294       12560 : void Scope::CollectNonLocals(DeclarationScope* max_outer_scope,
    1295             :                              Isolate* isolate, ParseInfo* info,
    1296             :                              Handle<StringSet>* non_locals) {
    1297       90636 :   this->ForEach([max_outer_scope, isolate, info, non_locals](Scope* scope) {
    1298             :     // Module variables must be allocated before variable resolution
    1299             :     // to ensure that UpdateNeedsHoleCheck() can detect import variables.
    1300       17039 :     if (scope->is_module_scope()) {
    1301         228 :       scope->AsModuleScope()->AllocateModuleVariables();
    1302             :     }
    1303             : 
    1304             :     // Lazy parsed declaration scopes are already partially analyzed. If there
    1305             :     // are unresolved references remaining, they just need to be resolved in
    1306             :     // outer scopes.
    1307       17039 :     Scope* lookup = WasLazilyParsed(scope) ? scope->outer_scope() : scope;
    1308             : 
    1309       74403 :     for (VariableProxy* proxy : scope->unresolved_list_) {
    1310             :       DCHECK(!proxy->is_resolved());
    1311             :       Variable* var =
    1312       57364 :           Lookup<kParsedScope>(proxy, lookup, max_outer_scope->outer_scope());
    1313       57364 :       if (var == nullptr) {
    1314       16233 :         *non_locals = StringSet::Add(isolate, *non_locals, proxy->name());
    1315             :       } else {
    1316             :         // In this case we need to leave scopes in a way that they can be
    1317             :         // allocated. If we resolved variables from lazy parsed scopes, we need
    1318             :         // to context allocate the var.
    1319             :         scope->ResolveTo(info, proxy, var);
    1320       41131 :         if (!var->is_dynamic() && lookup != scope)
    1321             :           var->ForceContextAllocation();
    1322             :       }
    1323             :     }
    1324             : 
    1325             :     // Clear unresolved_list_ as it's in an inconsistent state.
    1326             :     scope->unresolved_list_.Clear();
    1327       17039 :     return Iteration::kDescend;
    1328             :   });
    1329       12560 : }
    1330             : 
    1331     1889597 : void Scope::AnalyzePartially(DeclarationScope* max_outer_scope,
    1332             :                              AstNodeFactory* ast_node_factory,
    1333             :                              UnresolvedList* new_unresolved_list) {
    1334             :   this->ForEach([max_outer_scope, ast_node_factory,
    1335    45709087 :                  new_unresolved_list](Scope* scope) {
    1336             :     DCHECK_IMPLIES(scope->is_declaration_scope(),
    1337             :                    !scope->AsDeclarationScope()->was_lazily_parsed());
    1338             : 
    1339    22645578 :     for (VariableProxy* proxy = scope->unresolved_list_.first();
    1340    25789110 :          proxy != nullptr; proxy = proxy->next_unresolved()) {
    1341             :       DCHECK(!proxy->is_resolved());
    1342             :       Variable* var =
    1343    22645400 :           Lookup<kParsedScope>(proxy, scope, max_outer_scope->outer_scope());
    1344    22645601 :       if (var == nullptr) {
    1345             :         // Don't copy unresolved references to the script scope, unless it's a
    1346             :         // reference to a private name or method. In that case keep it so we
    1347             :         // can fail later.
    1348     6926936 :         if (!max_outer_scope->outer_scope()->is_script_scope() ||
    1349      172576 :             proxy->IsPrivateName()) {
    1350             :           VariableProxy* copy = ast_node_factory->CopyVariableProxy(proxy);
    1351             :           new_unresolved_list->Add(copy);
    1352             :         }
    1353             :       } else {
    1354             :         var->set_is_used();
    1355    15891238 :         if (proxy->is_assigned()) var->set_maybe_assigned();
    1356             :       }
    1357             :     }
    1358             : 
    1359             :     // Clear unresolved_list_ as it's in an inconsistent state.
    1360             :     scope->unresolved_list_.Clear();
    1361     3143710 :     return Iteration::kDescend;
    1362             :   });
    1363     1889587 : }
    1364             : 
    1365       12560 : Handle<StringSet> DeclarationScope::CollectNonLocals(
    1366             :     Isolate* isolate, ParseInfo* info, Handle<StringSet> non_locals) {
    1367       12560 :   Scope::CollectNonLocals(this, isolate, info, &non_locals);
    1368       12560 :   return non_locals;
    1369             : }
    1370             : 
    1371     2592082 : void DeclarationScope::ResetAfterPreparsing(AstValueFactory* ast_value_factory,
    1372             :                                             bool aborted) {
    1373             :   DCHECK(is_function_scope());
    1374             : 
    1375             :   // Reset all non-trivial members.
    1376             :   params_.Clear();
    1377             :   decls_.Clear();
    1378             :   locals_.Clear();
    1379     2592082 :   inner_scope_ = nullptr;
    1380             :   unresolved_list_.Clear();
    1381             :   sloppy_block_functions_.Clear();
    1382     2592082 :   rare_data_ = nullptr;
    1383     2592082 :   has_rest_ = false;
    1384             : 
    1385             :   DCHECK_NE(zone_, ast_value_factory->zone());
    1386     2592082 :   zone_->ReleaseMemory();
    1387             : 
    1388     2592157 :   if (aborted) {
    1389             :     // Prepare scope for use in the outer zone.
    1390       48875 :     zone_ = ast_value_factory->zone();
    1391       48875 :     variables_.Reset(ZoneAllocationPolicy(zone_));
    1392       97750 :     if (!IsArrowFunction(function_kind_)) {
    1393       43128 :       has_simple_parameters_ = true;
    1394       43128 :       DeclareDefaultFunctionVariables(ast_value_factory);
    1395             :     }
    1396             :   } else {
    1397             :     // Make sure this scope isn't used for allocation anymore.
    1398     2543282 :     zone_ = nullptr;
    1399             :     variables_.Invalidate();
    1400             :   }
    1401             : 
    1402             : #ifdef DEBUG
    1403             :   needs_migration_ = false;
    1404             :   is_being_lazily_parsed_ = false;
    1405             : #endif
    1406             : 
    1407     2592157 :   was_lazily_parsed_ = !aborted;
    1408     2592157 : }
    1409             : 
    1410      279481 : bool Scope::IsSkippableFunctionScope() {
    1411             :   // Lazy non-arrow function scopes are skippable. Lazy functions are exactly
    1412             :   // those Scopes which have their own PreparseDataBuilder object. This
    1413             :   // logic ensures that the scope allocation data is consistent with the
    1414             :   // skippable function data (both agree on where the lazy function boundaries
    1415             :   // are).
    1416     3423166 :   if (!is_function_scope()) return false;
    1417             :   DeclarationScope* declaration_scope = AsDeclarationScope();
    1418     2759974 :   return !declaration_scope->is_arrow_scope() &&
    1419             :          declaration_scope->preparse_data_builder() != nullptr;
    1420             : }
    1421             : 
    1422     1889548 : void Scope::SavePreparseData(Parser* parser) {
    1423     5175560 :   this->ForEach([parser](Scope* scope) {
    1424     3143685 :     if (scope->IsSkippableFunctionScope()) {
    1425             :       scope->AsDeclarationScope()->SavePreparseDataForDeclarationScope(parser);
    1426             :     }
    1427     3143680 :     return Iteration::kDescend;
    1428             :   });
    1429     1889596 : }
    1430             : 
    1431           0 : void DeclarationScope::SavePreparseDataForDeclarationScope(Parser* parser) {
    1432     2031875 :   if (preparse_data_builder_ == nullptr) return;
    1433     2031878 :   preparse_data_builder_->SaveScopeAllocationData(this, parser);
    1434             : }
    1435             : 
    1436     2482546 : void DeclarationScope::AnalyzePartially(Parser* parser,
    1437             :                                         AstNodeFactory* ast_node_factory) {
    1438             :   DCHECK(!force_eager_compilation_);
    1439             :   UnresolvedList new_unresolved_list;
    1440     9905992 :   if (!IsArrowFunction(function_kind_) &&
    1441     3088089 :       (!outer_scope_->is_script_scope() ||
    1442     1259449 :        (preparse_data_builder_ != nullptr &&
    1443      629732 :         preparse_data_builder_->HasInnerFunctions()))) {
    1444             :     // Try to resolve unresolved variables for this Scope and migrate those
    1445             :     // which cannot be resolved inside. It doesn't make sense to try to resolve
    1446             :     // them in the outer Scopes here, because they are incomplete.
    1447     1889608 :     Scope::AnalyzePartially(this, ast_node_factory, &new_unresolved_list);
    1448             : 
    1449             :     // Migrate function_ to the right Zone.
    1450     1889604 :     if (function_ != nullptr) {
    1451      852953 :       function_ = ast_node_factory->CopyVariable(function_);
    1452             :     }
    1453             : 
    1454     1889599 :     SavePreparseData(parser);
    1455             :   }
    1456             : 
    1457             : #ifdef DEBUG
    1458             :   if (FLAG_print_scopes) {
    1459             :     PrintF("Inner function scope:\n");
    1460             :     Print();
    1461             :   }
    1462             : #endif
    1463             : 
    1464     2482521 :   ResetAfterPreparsing(ast_node_factory->ast_value_factory(), false);
    1465             : 
    1466             :   unresolved_list_ = std::move(new_unresolved_list);
    1467     2482613 : }
    1468             : 
    1469             : #ifdef DEBUG
    1470             : namespace {
    1471             : 
    1472             : const char* Header(ScopeType scope_type, FunctionKind function_kind,
    1473             :                    bool is_declaration_scope) {
    1474             :   switch (scope_type) {
    1475             :     case EVAL_SCOPE: return "eval";
    1476             :     // TODO(adamk): Should we print concise method scopes specially?
    1477             :     case FUNCTION_SCOPE:
    1478             :       if (IsGeneratorFunction(function_kind)) return "function*";
    1479             :       if (IsAsyncFunction(function_kind)) return "async function";
    1480             :       if (IsArrowFunction(function_kind)) return "arrow";
    1481             :       return "function";
    1482             :     case MODULE_SCOPE: return "module";
    1483             :     case SCRIPT_SCOPE: return "global";
    1484             :     case CATCH_SCOPE: return "catch";
    1485             :     case BLOCK_SCOPE: return is_declaration_scope ? "varblock" : "block";
    1486             :     case WITH_SCOPE: return "with";
    1487             :   }
    1488             :   UNREACHABLE();
    1489             : }
    1490             : 
    1491             : void Indent(int n, const char* str) { PrintF("%*s%s", n, "", str); }
    1492             : 
    1493             : void PrintName(const AstRawString* name) {
    1494             :   PrintF("%.*s", name->length(), name->raw_data());
    1495             : }
    1496             : 
    1497             : void PrintLocation(Variable* var) {
    1498             :   switch (var->location()) {
    1499             :     case VariableLocation::UNALLOCATED:
    1500             :       break;
    1501             :     case VariableLocation::PARAMETER:
    1502             :       PrintF("parameter[%d]", var->index());
    1503             :       break;
    1504             :     case VariableLocation::LOCAL:
    1505             :       PrintF("local[%d]", var->index());
    1506             :       break;
    1507             :     case VariableLocation::CONTEXT:
    1508             :       PrintF("context[%d]", var->index());
    1509             :       break;
    1510             :     case VariableLocation::LOOKUP:
    1511             :       PrintF("lookup");
    1512             :       break;
    1513             :     case VariableLocation::MODULE:
    1514             :       PrintF("module");
    1515             :       break;
    1516             :   }
    1517             : }
    1518             : 
    1519             : void PrintVar(int indent, Variable* var) {
    1520             :   Indent(indent, VariableMode2String(var->mode()));
    1521             :   PrintF(" ");
    1522             :   if (var->raw_name()->IsEmpty())
    1523             :     PrintF(".%p", reinterpret_cast<void*>(var));
    1524             :   else
    1525             :     PrintName(var->raw_name());
    1526             :   PrintF(";  // (%p) ", reinterpret_cast<void*>(var));
    1527             :   PrintLocation(var);
    1528             :   bool comma = !var->IsUnallocated();
    1529             :   if (var->has_forced_context_allocation()) {
    1530             :     if (comma) PrintF(", ");
    1531             :     PrintF("forced context allocation");
    1532             :     comma = true;
    1533             :   }
    1534             :   if (var->maybe_assigned() == kNotAssigned) {
    1535             :     if (comma) PrintF(", ");
    1536             :     PrintF("never assigned");
    1537             :     comma = true;
    1538             :   }
    1539             :   if (var->initialization_flag() == kNeedsInitialization &&
    1540             :       !var->binding_needs_init()) {
    1541             :     if (comma) PrintF(", ");
    1542             :     PrintF("hole initialization elided");
    1543             :   }
    1544             :   PrintF("\n");
    1545             : }
    1546             : 
    1547             : void PrintMap(int indent, const char* label, VariableMap* map, bool locals,
    1548             :               Variable* function_var) {
    1549             :   bool printed_label = false;
    1550             :   for (VariableMap::Entry* p = map->Start(); p != nullptr; p = map->Next(p)) {
    1551             :     Variable* var = reinterpret_cast<Variable*>(p->value);
    1552             :     if (var == function_var) continue;
    1553             :     bool local = !IsDynamicVariableMode(var->mode());
    1554             :     if ((locals ? local : !local) &&
    1555             :         (var->is_used() || !var->IsUnallocated())) {
    1556             :       if (!printed_label) {
    1557             :         Indent(indent, label);
    1558             :         printed_label = true;
    1559             :       }
    1560             :       PrintVar(indent, var);
    1561             :     }
    1562             :   }
    1563             : }
    1564             : 
    1565             : }  // anonymous namespace
    1566             : 
    1567             : void DeclarationScope::PrintParameters() {
    1568             :   PrintF(" (");
    1569             :   for (int i = 0; i < params_.length(); i++) {
    1570             :     if (i > 0) PrintF(", ");
    1571             :     const AstRawString* name = params_[i]->raw_name();
    1572             :     if (name->IsEmpty()) {
    1573             :       PrintF(".%p", reinterpret_cast<void*>(params_[i]));
    1574             :     } else {
    1575             :       PrintName(name);
    1576             :     }
    1577             :   }
    1578             :   PrintF(")");
    1579             : }
    1580             : 
    1581             : void Scope::Print(int n) {
    1582             :   int n0 = (n > 0 ? n : 0);
    1583             :   int n1 = n0 + 2;  // indentation
    1584             : 
    1585             :   // Print header.
    1586             :   FunctionKind function_kind = is_function_scope()
    1587             :                                    ? AsDeclarationScope()->function_kind()
    1588             :                                    : kNormalFunction;
    1589             :   Indent(n0, Header(scope_type_, function_kind, is_declaration_scope()));
    1590             :   if (scope_name_ != nullptr && !scope_name_->IsEmpty()) {
    1591             :     PrintF(" ");
    1592             :     PrintName(scope_name_);
    1593             :   }
    1594             : 
    1595             :   // Print parameters, if any.
    1596             :   Variable* function = nullptr;
    1597             :   if (is_function_scope()) {
    1598             :     AsDeclarationScope()->PrintParameters();
    1599             :     function = AsDeclarationScope()->function_var();
    1600             :   }
    1601             : 
    1602             :   PrintF(" { // (%p) (%d, %d)\n", reinterpret_cast<void*>(this),
    1603             :          start_position(), end_position());
    1604             :   if (is_hidden()) {
    1605             :     Indent(n1, "// is hidden\n");
    1606             :   }
    1607             : 
    1608             :   // Function name, if any (named function literals, only).
    1609             :   if (function != nullptr) {
    1610             :     Indent(n1, "// (local) function name: ");
    1611             :     PrintName(function->raw_name());
    1612             :     PrintF("\n");
    1613             :   }
    1614             : 
    1615             :   // Scope info.
    1616             :   if (is_strict(language_mode())) {
    1617             :     Indent(n1, "// strict mode scope\n");
    1618             :   }
    1619             :   if (IsAsmModule()) Indent(n1, "// scope is an asm module\n");
    1620             :   if (is_declaration_scope() && AsDeclarationScope()->calls_sloppy_eval()) {
    1621             :     Indent(n1, "// scope calls sloppy 'eval'\n");
    1622             :   }
    1623             :   if (is_declaration_scope() && AsDeclarationScope()->NeedsHomeObject()) {
    1624             :     Indent(n1, "// scope needs home object\n");
    1625             :   }
    1626             :   if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n");
    1627             :   if (is_declaration_scope()) {
    1628             :     DeclarationScope* scope = AsDeclarationScope();
    1629             :     if (scope->was_lazily_parsed()) Indent(n1, "// lazily parsed\n");
    1630             :     if (scope->ShouldEagerCompile()) Indent(n1, "// will be compiled\n");
    1631             :   }
    1632             :   if (num_stack_slots_ > 0) {
    1633             :     Indent(n1, "// ");
    1634             :     PrintF("%d stack slots\n", num_stack_slots_);
    1635             :   }
    1636             :   if (num_heap_slots_ > 0) {
    1637             :     Indent(n1, "// ");
    1638             :     PrintF("%d heap slots\n", num_heap_slots_);
    1639             :   }
    1640             : 
    1641             :   // Print locals.
    1642             :   if (function != nullptr) {
    1643             :     Indent(n1, "// function var:\n");
    1644             :     PrintVar(n1, function);
    1645             :   }
    1646             : 
    1647             :   // Print temporaries.
    1648             :   {
    1649             :     bool printed_header = false;
    1650             :     for (Variable* local : locals_) {
    1651             :       if (local->mode() != VariableMode::kTemporary) continue;
    1652             :       if (!printed_header) {
    1653             :         printed_header = true;
    1654             :         Indent(n1, "// temporary vars:\n");
    1655             :       }
    1656             :       PrintVar(n1, local);
    1657             :     }
    1658             :   }
    1659             : 
    1660             :   if (variables_.occupancy() > 0) {
    1661             :     PrintMap(n1, "// local vars:\n", &variables_, true, function);
    1662             :     PrintMap(n1, "// dynamic vars:\n", &variables_, false, function);
    1663             :   }
    1664             : 
    1665             :   // Print inner scopes (disable by providing negative n).
    1666             :   if (n >= 0) {
    1667             :     for (Scope* scope = inner_scope_; scope != nullptr;
    1668             :          scope = scope->sibling_) {
    1669             :       PrintF("\n");
    1670             :       scope->Print(n1);
    1671             :     }
    1672             :   }
    1673             : 
    1674             :   Indent(n0, "}\n");
    1675             : }
    1676             : 
    1677             : void Scope::CheckScopePositions() {
    1678             :   this->ForEach([](Scope* scope) {
    1679             :     // Visible leaf scopes must have real positions.
    1680             :     if (!scope->is_hidden() && scope->inner_scope_ == nullptr) {
    1681             :       DCHECK_NE(kNoSourcePosition, scope->start_position());
    1682             :       DCHECK_NE(kNoSourcePosition, scope->end_position());
    1683             :     }
    1684             :     return Iteration::kDescend;
    1685             :   });
    1686             : }
    1687             : 
    1688             : void Scope::CheckZones() {
    1689             :   DCHECK(!needs_migration_);
    1690             :   this->ForEach([](Scope* scope) {
    1691             :     if (WasLazilyParsed(scope)) {
    1692             :       DCHECK_NULL(scope->zone());
    1693             :       DCHECK_NULL(scope->inner_scope_);
    1694             :       return Iteration::kContinue;
    1695             :     }
    1696             :     return Iteration::kDescend;
    1697             :   });
    1698             : }
    1699             : #endif  // DEBUG
    1700             : 
    1701      725917 : Variable* Scope::NonLocal(const AstRawString* name, VariableMode mode) {
    1702             :   // Declare a new non-local.
    1703             :   DCHECK(IsDynamicVariableMode(mode));
    1704             :   bool was_added;
    1705             :   Variable* var =
    1706      725917 :       variables_.Declare(zone(), this, name, mode, NORMAL_VARIABLE,
    1707      725917 :                          kCreatedInitialized, kNotAssigned, &was_added);
    1708             :   // Allocate it by giving it a dynamic lookup.
    1709             :   var->AllocateTo(VariableLocation::LOOKUP, -1);
    1710      725917 :   return var;
    1711             : }
    1712             : 
    1713             : // static
    1714             : template <Scope::ScopeLookupMode mode>
    1715    43662394 : Variable* Scope::Lookup(VariableProxy* proxy, Scope* scope,
    1716             :                         Scope* outer_scope_end, Scope* entry_point,
    1717             :                         bool force_context_allocation) {
    1718             :   if (mode == kDeserializedScope) {
    1719     2092698 :     Variable* var = entry_point->variables_.Lookup(proxy->raw_name());
    1720     2092698 :     if (var != nullptr) return var;
    1721             :   }
    1722             : 
    1723      488877 :   while (true) {
    1724             :     DCHECK_IMPLIES(mode == kParsedScope, !scope->is_debug_evaluate_scope_);
    1725             :     // Short-cut: whenever we find a debug-evaluate scope, just look everything
    1726             :     // up dynamically. Debug-evaluate doesn't properly create scope info for the
    1727             :     // lookups it does. It may not have a valid 'this' declaration, and anything
    1728             :     // accessed through debug-evaluate might invalidly resolve to
    1729             :     // stack-allocated variables.
    1730             :     // TODO(yangguo): Remove once debug-evaluate creates proper ScopeInfo for
    1731             :     // the scopes in which it's evaluating.
    1732     2223574 :     if (mode == kDeserializedScope &&
    1733     2223574 :         V8_UNLIKELY(scope->is_debug_evaluate_scope_)) {
    1734       10716 :       return entry_point->NonLocal(proxy->raw_name(), VariableMode::kDynamic);
    1735             :     }
    1736             : 
    1737             :     // Try to find the variable in this scope.
    1738             :     Variable* var = mode == kParsedScope ? scope->LookupLocal(proxy->raw_name())
    1739             :                                          : scope->LookupInScopeInfo(
    1740     2212858 :                                                proxy->raw_name(), entry_point);
    1741             : 
    1742             :     // We found a variable and we are done. (Even if there is an 'eval' in this
    1743             :     // scope which introduces the same variable again, the resulting variable
    1744             :     // remains the same.)
    1745    60982629 :     if (var != nullptr) {
    1746    39136297 :       if (mode == kParsedScope && force_context_allocation &&
    1747             :           !var->is_dynamic()) {
    1748             :         var->ForceContextAllocation();
    1749             :       }
    1750             :       return var;
    1751             :     }
    1752             : 
    1753    28629879 :     if (scope->outer_scope_ == outer_scope_end) break;
    1754             : 
    1755             :     DCHECK(!scope->is_script_scope());
    1756    19885271 :     if (V8_UNLIKELY(scope->is_with_scope())) {
    1757       46207 :       return LookupWith(proxy, scope, outer_scope_end, entry_point,
    1758       46207 :                         force_context_allocation);
    1759             :     }
    1760    35431366 :     if (V8_UNLIKELY(scope->is_declaration_scope() &&
    1761             :                     scope->AsDeclarationScope()->calls_sloppy_eval())) {
    1762      386230 :       return LookupSloppyEval(proxy, scope, outer_scope_end, entry_point,
    1763      386230 :                               force_context_allocation);
    1764             :     }
    1765             : 
    1766    19452834 :     force_context_allocation |= scope->is_function_scope();
    1767             :     scope = scope->outer_scope_;
    1768             :     // TODO(verwaest): Separate through AnalyzePartially.
    1769    18963957 :     if (mode == kParsedScope && !scope->scope_info_.is_null()) {
    1770     1773278 :       return Lookup<kDeserializedScope>(proxy, scope, outer_scope_end, scope);
    1771             :     }
    1772             :   }
    1773             : 
    1774             :   // We may just be trying to find all free variables. In that case, don't
    1775             :   // declare them in the outer scope.
    1776             :   // TODO(marja): Separate Lookup for preparsed scopes better.
    1777     7774864 :   if (mode == kParsedScope && !scope->is_script_scope()) {
    1778             :     return nullptr;
    1779             :   }
    1780     1972933 :   if (V8_UNLIKELY(proxy->IsPrivateName())) return nullptr;
    1781             : 
    1782             :   // No binding has been found. Declare a variable on the global object.
    1783             :   return scope->AsDeclarationScope()->DeclareDynamicGlobal(
    1784             :       proxy->raw_name(), NORMAL_VARIABLE,
    1785     1972801 :       mode == kDeserializedScope ? entry_point : scope);
    1786             : }
    1787             : 
    1788             : template Variable* Scope::Lookup<Scope::kParsedScope>(
    1789             :     VariableProxy* proxy, Scope* scope, Scope* outer_scope_end,
    1790             :     Scope* entry_point, bool force_context_allocation);
    1791             : template Variable* Scope::Lookup<Scope::kDeserializedScope>(
    1792             :     VariableProxy* proxy, Scope* scope, Scope* outer_scope_end,
    1793             :     Scope* entry_point, bool force_context_allocation);
    1794             : 
    1795       46207 : Variable* Scope::LookupWith(VariableProxy* proxy, Scope* scope,
    1796             :                             Scope* outer_scope_end, Scope* entry_point,
    1797             :                             bool force_context_allocation) {
    1798             :   DCHECK(scope->is_with_scope());
    1799             : 
    1800             :   Variable* var =
    1801       46207 :       scope->outer_scope_->scope_info_.is_null()
    1802       44576 :           ? Lookup<kParsedScope>(proxy, scope->outer_scope_, outer_scope_end,
    1803             :                                  nullptr, force_context_allocation)
    1804             :           : Lookup<kDeserializedScope>(proxy, scope->outer_scope_,
    1805       90783 :                                        outer_scope_end, entry_point);
    1806             : 
    1807       46207 :   if (var == nullptr) return var;
    1808             : 
    1809             :   // The current scope is a with scope, so the variable binding can not be
    1810             :   // statically resolved. However, note that it was necessary to do a lookup
    1811             :   // in the outer scope anyway, because if a binding exists in an outer
    1812             :   // scope, the associated variable has to be marked as potentially being
    1813             :   // accessed from inside of an inner with scope (the property may not be in
    1814             :   // the 'with' object).
    1815       41054 :   if (!var->is_dynamic() && var->IsUnallocated()) {
    1816             :     DCHECK(!scope->already_resolved_);
    1817             :     var->set_is_used();
    1818             :     var->ForceContextAllocation();
    1819       11849 :     if (proxy->is_assigned()) var->set_maybe_assigned();
    1820             :   }
    1821       28960 :   if (entry_point != nullptr) entry_point->variables_.Remove(var);
    1822       28960 :   Scope* target = entry_point == nullptr ? scope : entry_point;
    1823       28960 :   return target->NonLocal(proxy->raw_name(), VariableMode::kDynamic);
    1824             : }
    1825             : 
    1826      386230 : Variable* Scope::LookupSloppyEval(VariableProxy* proxy, Scope* scope,
    1827             :                                   Scope* outer_scope_end, Scope* entry_point,
    1828             :                                   bool force_context_allocation) {
    1829             :   DCHECK(scope->is_declaration_scope() &&
    1830             :          scope->AsDeclarationScope()->calls_sloppy_eval());
    1831             : 
    1832             :   // If we're compiling eval, it's possible that the outer scope is the first
    1833             :   // ScopeInfo-backed scope.
    1834      386230 :   Scope* entry = entry_point == nullptr ? scope->outer_scope_ : entry_point;
    1835             :   Variable* var =
    1836      386230 :       scope->outer_scope_->scope_info_.is_null()
    1837       68440 :           ? Lookup<kParsedScope>(proxy, scope->outer_scope_, outer_scope_end,
    1838             :                                  nullptr, force_context_allocation)
    1839             :           : Lookup<kDeserializedScope>(proxy, scope->outer_scope_,
    1840      454670 :                                        outer_scope_end, entry);
    1841      386230 :   if (var == nullptr) return var;
    1842             : 
    1843             :   // A variable binding may have been found in an outer scope, but the current
    1844             :   // scope makes a sloppy 'eval' call, so the found variable may not be the
    1845             :   // correct one (the 'eval' may introduce a binding with the same name). In
    1846             :   // that case, change the lookup result to reflect this situation. Only
    1847             :   // scopes that can host var bindings (declaration scopes) need be considered
    1848             :   // here (this excludes block and catch scopes), and variable lookups at
    1849             :   // script scope are always dynamic.
    1850      379882 :   if (var->IsGlobalObjectProperty()) {
    1851      373497 :     Scope* target = entry_point == nullptr ? scope : entry_point;
    1852      373497 :     return target->NonLocal(proxy->raw_name(), VariableMode::kDynamicGlobal);
    1853             :   }
    1854             : 
    1855        6385 :   if (var->is_dynamic()) return var;
    1856             : 
    1857             :   Variable* invalidated = var;
    1858        4434 :   if (entry_point != nullptr) entry_point->variables_.Remove(invalidated);
    1859             : 
    1860        4434 :   Scope* target = entry_point == nullptr ? scope : entry_point;
    1861        4434 :   var = target->NonLocal(proxy->raw_name(), VariableMode::kDynamicLocal);
    1862             :   var->set_local_if_not_shadowed(invalidated);
    1863             : 
    1864        4434 :   return var;
    1865             : }
    1866             : 
    1867    18761712 : bool Scope::ResolveVariable(ParseInfo* info, VariableProxy* proxy) {
    1868             :   DCHECK(info->script_scope()->is_script_scope());
    1869             :   DCHECK(!proxy->is_resolved());
    1870    18761712 :   Variable* var = Lookup<kParsedScope>(proxy, this, nullptr);
    1871    18762058 :   if (var == nullptr) {
    1872             :     DCHECK(proxy->IsPrivateName());
    1873         128 :     info->pending_error_handler()->ReportMessageAt(
    1874             :         proxy->position(), proxy->position() + 1,
    1875             :         MessageTemplate::kInvalidPrivateFieldResolution, proxy->raw_name(),
    1876         128 :         kSyntaxError);
    1877         128 :     return false;
    1878             :   }
    1879             :   ResolveTo(info, proxy, var);
    1880    18761654 :   return true;
    1881             : }
    1882             : 
    1883             : namespace {
    1884             : 
    1885             : void SetNeedsHoleCheck(Variable* var, VariableProxy* proxy) {
    1886             :   proxy->set_needs_hole_check();
    1887             :   var->ForceHoleInitialization();
    1888             : }
    1889             : 
    1890    18802996 : void UpdateNeedsHoleCheck(Variable* var, VariableProxy* proxy, Scope* scope) {
    1891    18806775 :   if (var->mode() == VariableMode::kDynamicLocal) {
    1892             :     // Dynamically introduced variables never need a hole check (since they're
    1893             :     // VariableMode::kVar bindings, either from var or function declarations),
    1894             :     // but the variable they shadow might need a hole check, which we want to do
    1895             :     // if we decide that no shadowing variable was dynamically introoduced.
    1896             :     DCHECK_EQ(kCreatedInitialized, var->initialization_flag());
    1897        3779 :     return UpdateNeedsHoleCheck(var->local_if_not_shadowed(), proxy, scope);
    1898             :   }
    1899             : 
    1900    18802996 :   if (var->initialization_flag() == kCreatedInitialized) return;
    1901             : 
    1902             :   // It's impossible to eliminate module import hole checks here, because it's
    1903             :   // unknown at compilation time whether the binding referred to in the
    1904             :   // exporting module itself requires hole checks.
    1905     1554552 :   if (var->location() == VariableLocation::MODULE && !var->IsExport()) {
    1906             :     return SetNeedsHoleCheck(var, proxy);
    1907             :   }
    1908             : 
    1909             :   // Check if the binding really needs an initialization check. The check
    1910             :   // can be skipped in the following situation: we have a VariableMode::kLet or
    1911             :   // VariableMode::kConst binding, both the Variable and the VariableProxy have
    1912             :   // the same declaration scope (i.e. they are both in global code, in the same
    1913             :   // function or in the same eval code), the VariableProxy is in the source
    1914             :   // physically located after the initializer of the variable, and that the
    1915             :   // initializer cannot be skipped due to a nonlinear scope.
    1916             :   //
    1917             :   // The condition on the closure scopes is a conservative check for
    1918             :   // nested functions that access a binding and are called before the
    1919             :   // binding is initialized:
    1920             :   //   function() { f(); let x = 1; function f() { x = 2; } }
    1921             :   //
    1922             :   // The check cannot be skipped on non-linear scopes, namely switch
    1923             :   // scopes, to ensure tests are done in cases like the following:
    1924             :   //   switch (1) { case 0: let x = 2; case 1: f(x); }
    1925             :   // The scope of the variable needs to be checked, in case the use is
    1926             :   // in a sub-block which may be linear.
    1927     1553241 :   if (var->scope()->GetClosureScope() != scope->GetClosureScope()) {
    1928             :     return SetNeedsHoleCheck(var, proxy);
    1929             :   }
    1930             : 
    1931             :   // We should always have valid source positions.
    1932             :   DCHECK_NE(var->initializer_position(), kNoSourcePosition);
    1933             :   DCHECK_NE(proxy->position(), kNoSourcePosition);
    1934             : 
    1935      952257 :   if (var->scope()->is_nonlinear() ||
    1936             :       var->initializer_position() >= proxy->position()) {
    1937             :     return SetNeedsHoleCheck(var, proxy);
    1938             :   }
    1939             : }
    1940             : 
    1941             : }  // anonymous namespace
    1942             : 
    1943           0 : void Scope::ResolveTo(ParseInfo* info, VariableProxy* proxy, Variable* var) {
    1944             : #ifdef DEBUG
    1945             :   if (info->is_native()) {
    1946             :     // To avoid polluting the global object in native scripts
    1947             :     //  - Variables must not be allocated to the global scope.
    1948             :     DCHECK_NOT_NULL(outer_scope());
    1949             :     //  - Variables must be bound locally or unallocated.
    1950             :     if (var->IsGlobalObjectProperty()) {
    1951             :       // The following variable name may be minified. If so, disable
    1952             :       // minification in js2c.py for better output.
    1953             :       Handle<String> name = proxy->raw_name()->string();
    1954             :       FATAL("Unbound variable: '%s' in native script.",
    1955             :             name->ToCString().get());
    1956             :     }
    1957             :     VariableLocation location = var->location();
    1958             :     DCHECK(location == VariableLocation::LOCAL ||
    1959             :            location == VariableLocation::CONTEXT ||
    1960             :            location == VariableLocation::PARAMETER ||
    1961             :            location == VariableLocation::UNALLOCATED);
    1962             :   }
    1963             : #endif
    1964             : 
    1965             :   DCHECK_NOT_NULL(var);
    1966    18803061 :   UpdateNeedsHoleCheck(var, proxy, this);
    1967    18802996 :   proxy->BindTo(var);
    1968           0 : }
    1969             : 
    1970     6579854 : bool Scope::ResolvePreparsedVariable(VariableProxy* proxy, Scope* scope,
    1971             :                                      Scope* end) {
    1972             :   // Resolve the variable in all parsed scopes to force context allocation.
    1973    15279594 :   for (; scope != end; scope = scope->outer_scope_) {
    1974             :     Variable* var = scope->LookupLocal(proxy->raw_name());
    1975     6596303 :     if (var != nullptr) {
    1976             :       var->set_is_used();
    1977     2246433 :       if (!var->is_dynamic()) {
    1978             :         var->ForceContextAllocation();
    1979     2244737 :         if (proxy->is_assigned()) var->set_maybe_assigned();
    1980             :       }
    1981             :       return true;
    1982             :     }
    1983             :   }
    1984             : 
    1985     4333400 :   if (!proxy->IsPrivateName()) return true;
    1986             : 
    1987             :   // If we're resolving a private name, throw an exception of we didn't manage
    1988             :   // to resolve. In case of eval, also look in all outer scope-info backed
    1989             :   // scopes except for the script scope. Don't throw an exception if a reference
    1990             :   // was found.
    1991             :   Scope* start = scope;
    1992          46 :   for (; !scope->is_script_scope(); scope = scope->outer_scope_) {
    1993           0 :     if (scope->LookupInScopeInfo(proxy->raw_name(), start) != nullptr) {
    1994             :       return true;
    1995             :     }
    1996             :   }
    1997             : 
    1998             :   return false;
    1999             : }
    2000             : 
    2001     5653037 : bool Scope::ResolveVariablesRecursively(ParseInfo* info) {
    2002             :   DCHECK(info->script_scope()->is_script_scope());
    2003             :   // Lazy parsed declaration scopes are already partially analyzed. If there are
    2004             :   // unresolved references remaining, they just need to be resolved in outer
    2005             :   // scopes.
    2006     5653037 :   if (WasLazilyParsed(this)) {
    2007             :     DCHECK_EQ(variables_.occupancy(), 0);
    2008     2452222 :     Scope* end = info->scope();
    2009             :     // Resolve in all parsed scopes except for the script scope.
    2010     2452217 :     if (!end->is_script_scope()) end = end->outer_scope();
    2011             : 
    2012     9031884 :     for (VariableProxy* proxy : unresolved_list_) {
    2013     6579686 :       if (!ResolvePreparsedVariable(proxy, outer_scope(), end)) {
    2014          46 :         info->pending_error_handler()->ReportMessageAt(
    2015             :             proxy->position(), proxy->position() + 1,
    2016             :             MessageTemplate::kInvalidPrivateFieldResolution, proxy->raw_name(),
    2017          46 :             kSyntaxError);
    2018             :         DCHECK(proxy->IsPrivateName());
    2019             :         return false;
    2020             :       }
    2021             :     }
    2022             :   } else {
    2023             :     // Resolve unresolved variables for this scope.
    2024    21962454 :     for (VariableProxy* proxy : unresolved_list_) {
    2025    18761759 :       if (!ResolveVariable(info, proxy)) return false;
    2026             :     }
    2027             : 
    2028             :     // Resolve unresolved variables for inner scopes.
    2029     7048878 :     for (Scope* scope = inner_scope_; scope != nullptr;
    2030             :          scope = scope->sibling_) {
    2031     3848348 :       if (!scope->ResolveVariablesRecursively(info)) return false;
    2032             :     }
    2033             :   }
    2034             :   return true;
    2035             : }
    2036             : 
    2037    19019047 : bool Scope::MustAllocate(Variable* var) {
    2038             :   DCHECK(var->location() != VariableLocation::MODULE);
    2039             :   // Give var a read/write use if there is a chance it might be accessed
    2040             :   // via an eval() call.  This is only possible if the variable has a
    2041             :   // visible name.
    2042    57016770 :   if (!var->raw_name()->IsEmpty() &&
    2043    35154003 :       (inner_scope_calls_eval_ || is_catch_scope() || is_script_scope())) {
    2044             :     var->set_is_used();
    2045     4141236 :     if (inner_scope_calls_eval_) var->set_maybe_assigned();
    2046             :   }
    2047             :   DCHECK(!var->has_forced_context_allocation() || var->is_used());
    2048             :   // Global variables do not need to be allocated.
    2049    36248094 :   return !var->IsGlobalObjectProperty() && var->is_used();
    2050             : }
    2051             : 
    2052             : 
    2053    11213482 : bool Scope::MustAllocateInContext(Variable* var) {
    2054             :   // If var is accessed from an inner scope, or if there is a possibility
    2055             :   // that it might be accessed from the current or an inner scope (through
    2056             :   // an eval() call or a runtime with lookup), it must be allocated in the
    2057             :   // context.
    2058             :   //
    2059             :   // Temporary variables are always stack-allocated.  Catch-bound variables are
    2060             :   // always context-allocated.
    2061    11213482 :   if (var->mode() == VariableMode::kTemporary) return false;
    2062     9967310 :   if (is_catch_scope()) return true;
    2063     9870648 :   if ((is_script_scope() || is_eval_scope()) &&
    2064             :       IsLexicalVariableMode(var->mode())) {
    2065             :     return true;
    2066             :   }
    2067     9219019 :   return var->has_forced_context_allocation() || inner_scope_calls_eval_;
    2068             : }
    2069             : 
    2070             : 
    2071           0 : void Scope::AllocateStackSlot(Variable* var) {
    2072     6760507 :   if (is_block_scope()) {
    2073      386802 :     outer_scope()->GetDeclarationScope()->AllocateStackSlot(var);
    2074             :   } else {
    2075     6373705 :     var->AllocateTo(VariableLocation::LOCAL, num_stack_slots_++);
    2076             :   }
    2077           0 : }
    2078             : 
    2079             : 
    2080             : void Scope::AllocateHeapSlot(Variable* var) {
    2081     2324446 :   var->AllocateTo(VariableLocation::CONTEXT, num_heap_slots_++);
    2082             : }
    2083             : 
    2084             : void DeclarationScope::AllocateParameterLocals() {
    2085             :   DCHECK(is_function_scope());
    2086             : 
    2087             :   bool has_mapped_arguments = false;
    2088     1595297 :   if (arguments_ != nullptr) {
    2089             :     DCHECK(!is_arrow_scope());
    2090     1074703 :     if (MustAllocate(arguments_) && !has_arguments_parameter_) {
    2091             :       // 'arguments' is used and does not refer to a function
    2092             :       // parameter of the same name. If the arguments object
    2093             :       // aliases formal parameters, we conservatively allocate
    2094             :       // them specially in the loop below.
    2095             :       has_mapped_arguments =
    2096      115921 :           GetArgumentsType() == CreateArgumentsType::kMappedArguments;
    2097             :     } else {
    2098             :       // 'arguments' is unused. Tell the code generator that it does not need to
    2099             :       // allocate the arguments object by nulling out arguments_.
    2100      958776 :       arguments_ = nullptr;
    2101             :     }
    2102             :   }
    2103             : 
    2104             :   // The same parameter may occur multiple times in the parameters_ list.
    2105             :   // If it does, and if it is not copied into the context object, it must
    2106             :   // receive the highest parameter index for that parameter; thus iteration
    2107             :   // order is relevant!
    2108     4072152 :   for (int i = num_parameters() - 1; i >= 0; --i) {
    2109     2476861 :     Variable* var = params_[i];
    2110             :     DCHECK_NOT_NULL(var);
    2111             :     DCHECK(!has_rest_ || var != rest_parameter());
    2112             :     DCHECK_EQ(this, var->scope());
    2113     2476861 :     if (has_mapped_arguments) {
    2114             :       var->set_is_used();
    2115             :       var->set_maybe_assigned();
    2116             :       var->ForceContextAllocation();
    2117             :     }
    2118             :     AllocateParameter(var, i);
    2119             :   }
    2120             : }
    2121             : 
    2122             : void DeclarationScope::AllocateParameter(Variable* var, int index) {
    2123     3602177 :   if (!MustAllocate(var)) return;
    2124     5363381 :   if (has_forced_context_allocation_for_parameters() ||
    2125     2681691 :       MustAllocateInContext(var)) {
    2126             :     DCHECK(var->IsUnallocated() || var->IsContextSlot());
    2127      163191 :     if (var->IsUnallocated()) AllocateHeapSlot(var);
    2128             :   } else {
    2129             :     DCHECK(var->IsUnallocated() || var->IsParameter());
    2130     2518499 :     if (var->IsUnallocated()) {
    2131             :       var->AllocateTo(VariableLocation::PARAMETER, index);
    2132             :     }
    2133             :   }
    2134             : }
    2135             : 
    2136             : void DeclarationScope::AllocateReceiver() {
    2137     2702876 :   if (!has_this_declaration()) return;
    2138             :   DCHECK_NOT_NULL(receiver());
    2139             :   DCHECK_EQ(receiver()->scope(), this);
    2140             :   AllocateParameter(receiver(), -1);
    2141             : }
    2142             : 
    2143    15441791 : void Scope::AllocateNonParameterLocal(Variable* var) {
    2144             :   DCHECK_EQ(var->scope(), this);
    2145    15441791 :   if (var->IsUnallocated() && MustAllocate(var)) {
    2146     8529739 :     if (MustAllocateInContext(var)) {
    2147             :       AllocateHeapSlot(var);
    2148             :       DCHECK_IMPLIES(is_catch_scope(),
    2149             :                      var->index() == Context::THROWN_OBJECT_INDEX);
    2150             :     } else {
    2151             :       AllocateStackSlot(var);
    2152             :     }
    2153             :   }
    2154    15441818 : }
    2155             : 
    2156             : void Scope::AllocateNonParameterLocalsAndDeclaredGlobals() {
    2157    37240029 :   for (Variable* local : locals_) {
    2158    15419527 :     AllocateNonParameterLocal(local);
    2159             :   }
    2160             : 
    2161     3200481 :   if (is_declaration_scope()) {
    2162             :     AsDeclarationScope()->AllocateLocals();
    2163             :   }
    2164             : }
    2165             : 
    2166             : void DeclarationScope::AllocateLocals() {
    2167             :   // For now, function_ must be allocated at the very end.  If it gets
    2168             :   // allocated in the context, it must be the last slot in the context,
    2169             :   // because of the current ScopeInfo implementation (see
    2170             :   // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor).
    2171     2702883 :   if (function_ != nullptr && MustAllocate(function_)) {
    2172       22274 :     AllocateNonParameterLocal(function_);
    2173             :   } else {
    2174     2680610 :     function_ = nullptr;
    2175             :   }
    2176             : 
    2177             :   DCHECK(!has_rest_ || !MustAllocate(rest_parameter()) ||
    2178             :          !rest_parameter()->IsUnallocated());
    2179             : 
    2180     2702899 :   if (new_target_ != nullptr && !MustAllocate(new_target_)) {
    2181      997220 :     new_target_ = nullptr;
    2182             :   }
    2183             : 
    2184             :   NullifyRareVariableIf(RareVariable::kThisFunction,
    2185      169460 :                         [=](Variable* var) { return !MustAllocate(var); });
    2186             : }
    2187             : 
    2188        9130 : void ModuleScope::AllocateModuleVariables() {
    2189       10336 :   for (const auto& it : module()->regular_imports()) {
    2190        1206 :     Variable* var = LookupLocal(it.first);
    2191        1206 :     var->AllocateTo(VariableLocation::MODULE, it.second->cell_index);
    2192             :     DCHECK(!var->IsExport());
    2193             :   }
    2194             : 
    2195       27890 :   for (const auto& it : module()->regular_exports()) {
    2196       18760 :     Variable* var = LookupLocal(it.first);
    2197       18760 :     var->AllocateTo(VariableLocation::MODULE, it.second->cell_index);
    2198             :     DCHECK(var->IsExport());
    2199             :   }
    2200        9130 : }
    2201             : 
    2202     1804521 : void Scope::AllocateVariablesRecursively() {
    2203     5652662 :   this->ForEach([](Scope* scope) -> Iteration {
    2204             :     DCHECK(!scope->already_resolved_);
    2205     5652662 :     if (WasLazilyParsed(scope)) return Iteration::kContinue;
    2206             :     DCHECK_EQ(Context::MIN_CONTEXT_SLOTS, scope->num_heap_slots_);
    2207             : 
    2208             :     // Allocate variables for this scope.
    2209             :     // Parameters must be allocated first, if any.
    2210     3200481 :     if (scope->is_declaration_scope()) {
    2211     2702882 :       if (scope->is_function_scope()) {
    2212             :         scope->AsDeclarationScope()->AllocateParameterLocals();
    2213             :       }
    2214             :       scope->AsDeclarationScope()->AllocateReceiver();
    2215             :     }
    2216             :     scope->AllocateNonParameterLocalsAndDeclaredGlobals();
    2217             : 
    2218             :     // Force allocation of a context for this scope if necessary. For a 'with'
    2219             :     // scope and for a function scope that makes an 'eval' call we need a
    2220             :     // context, even if no local variables were statically allocated in the
    2221             :     // scope. Likewise for modules and function scopes representing asm.js
    2222             :     // modules. Also force a context, if the scope is stricter than the outer
    2223             :     // scope.
    2224             :     bool must_have_context =
    2225     6316790 :         scope->is_with_scope() || scope->is_module_scope() ||
    2226     3149682 :         scope->IsAsmModule() || scope->ForceContextForLanguageMode() ||
    2227     1591029 :         (scope->is_function_scope() &&
    2228     6265098 :          scope->AsDeclarationScope()->calls_sloppy_eval()) ||
    2229      359413 :         (scope->is_block_scope() && scope->is_declaration_scope() &&
    2230             :          scope->AsDeclarationScope()->calls_sloppy_eval());
    2231             : 
    2232             :     // If we didn't allocate any locals in the local context, then we only
    2233             :     // need the minimal number of slots if we must have a context.
    2234     3200488 :     if (scope->num_heap_slots_ == Context::MIN_CONTEXT_SLOTS &&
    2235             :         !must_have_context) {
    2236     2755981 :       scope->num_heap_slots_ = 0;
    2237             :     }
    2238             : 
    2239             :     // Allocation done.
    2240             :     DCHECK(scope->num_heap_slots_ == 0 ||
    2241             :            scope->num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS);
    2242             :     return Iteration::kDescend;
    2243             :   });
    2244     1804528 : }
    2245             : 
    2246     2397073 : void Scope::AllocateScopeInfosRecursively(Isolate* isolate,
    2247             :                                           MaybeHandle<ScopeInfo> outer_scope) {
    2248             :   DCHECK(scope_info_.is_null());
    2249     2397073 :   MaybeHandle<ScopeInfo> next_outer_scope = outer_scope;
    2250             : 
    2251     2397073 :   if (NeedsScopeInfo()) {
    2252     1255594 :     scope_info_ = ScopeInfo::Create(isolate, zone(), this, outer_scope);
    2253             :     // The ScopeInfo chain should mirror the context chain, so we only link to
    2254             :     // the next outer scope that needs a context.
    2255     1255595 :     if (NeedsContext()) next_outer_scope = scope_info_;
    2256             :   }
    2257             : 
    2258             :   // Allocate ScopeInfos for inner scopes.
    2259     5347320 :   for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
    2260     5579547 :     if (!scope->is_function_scope() ||
    2261             :         scope->AsDeclarationScope()->ShouldEagerCompile()) {
    2262      829356 :       scope->AllocateScopeInfosRecursively(isolate, next_outer_scope);
    2263             :     }
    2264             :   }
    2265     2397076 : }
    2266             : 
    2267             : // static
    2268     1567720 : void DeclarationScope::AllocateScopeInfos(ParseInfo* info, Isolate* isolate) {
    2269             :   DeclarationScope* scope = info->literal()->scope();
    2270     1567720 :   if (!scope->scope_info_.is_null()) return;  // Allocated by outer function.
    2271             : 
    2272     1567720 :   MaybeHandle<ScopeInfo> outer_scope;
    2273     1567720 :   if (scope->outer_scope_ != nullptr) {
    2274     1414075 :     outer_scope = scope->outer_scope_->scope_info_;
    2275             :   }
    2276             : 
    2277     1567720 :   scope->AllocateScopeInfosRecursively(isolate, outer_scope);
    2278             : 
    2279             :   // The debugger expects all shared function infos to contain a scope info.
    2280             :   // Since the top-most scope will end up in a shared function info, make sure
    2281             :   // it has one, even if it doesn't need a scope info.
    2282             :   // TODO(jochen|yangguo): Remove this requirement.
    2283     1567723 :   if (scope->scope_info_.is_null()) {
    2284             :     scope->scope_info_ =
    2285      946094 :         ScopeInfo::Create(isolate, scope->zone(), scope, outer_scope);
    2286             :   }
    2287             : 
    2288             :   // Ensuring that the outer script scope has a scope info avoids having
    2289             :   // special case for native contexts vs other contexts.
    2290     3135449 :   if (info->script_scope() && info->script_scope()->scope_info_.is_null()) {
    2291             :     info->script_scope()->scope_info_ =
    2292     1058388 :         handle(ScopeInfo::Empty(isolate), isolate);
    2293             :   }
    2294             : }
    2295             : 
    2296          90 : int Scope::ContextLocalCount() const {
    2297          90 :   if (num_heap_slots() == 0) return 0;
    2298             :   Variable* function =
    2299          55 :       is_function_scope() ? AsDeclarationScope()->function_var() : nullptr;
    2300             :   bool is_function_var_in_context =
    2301          55 :       function != nullptr && function->IsContextSlot();
    2302          55 :   return num_heap_slots() - Context::MIN_CONTEXT_SLOTS -
    2303          55 :          (is_function_var_in_context ? 1 : 0);
    2304             : }
    2305             : 
    2306             : }  // namespace internal
    2307      120216 : }  // namespace v8

Generated by: LCOV version 1.10