LCOV - code coverage report
Current view: top level - src/ast - scopes.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 676 702 96.3 %
Date: 2019-02-19 Functions: 91 101 90.1 %

          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    39808369 : Variable* VariableMap::Declare(Zone* zone, Scope* scope,
      39    39808369 :                                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             :       ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->Hash(),
      49    79618144 :                                   ZoneAllocationPolicy(zone));
      50    39809775 :   *was_added = p->value == nullptr;
      51    39809775 :   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    38650833 :     p->value = variable;
      57             :   }
      58    39808677 :   return reinterpret_cast<Variable*>(p->value);
      59             : }
      60             : 
      61        3906 : void VariableMap::Remove(Variable* var) {
      62        3906 :   const AstRawString* name = var->raw_name();
      63        3906 :   ZoneHashMap::Remove(const_cast<AstRawString*>(name), name->Hash());
      64           0 : }
      65             : 
      66      995930 : void VariableMap::Add(Zone* zone, Variable* var) {
      67      995930 :   const AstRawString* name = var->raw_name();
      68             :   Entry* p =
      69             :       ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->Hash(),
      70     1991888 :                                   ZoneAllocationPolicy(zone));
      71             :   DCHECK_NULL(p->value);
      72             :   DCHECK_EQ(name, p->key);
      73      995958 :   p->value = var;
      74      995958 : }
      75             : 
      76    87736201 : Variable* VariableMap::Lookup(const AstRawString* name) {
      77    87736201 :   Entry* p = ZoneHashMap::Lookup(const_cast<AstRawString*>(name), name->Hash());
      78    87740183 :   if (p != nullptr) {
      79             :     DCHECK(reinterpret_cast<const AstRawString*>(p->key) == name);
      80             :     DCHECK_NOT_NULL(p->value);
      81    38612663 :     return reinterpret_cast<Variable*>(p->value);
      82             :   }
      83             :   return nullptr;
      84             : }
      85             : 
      86             : // ----------------------------------------------------------------------------
      87             : // Implementation of Scope
      88             : 
      89     2957967 : Scope::Scope(Zone* zone)
      90             :     : zone_(zone),
      91             :       outer_scope_(nullptr),
      92             :       variables_(zone),
      93     5915936 :       scope_type_(SCRIPT_SCOPE) {
      94             :   SetDefaults();
      95     2957969 : }
      96             : 
      97    12778630 : Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type)
      98             :     : zone_(zone),
      99             :       outer_scope_(outer_scope),
     100             :       variables_(zone),
     101    25557654 :       scope_type_(scope_type) {
     102             :   DCHECK_NE(SCRIPT_SCOPE, scope_type);
     103             :   SetDefaults();
     104             :   set_language_mode(outer_scope->language_mode());
     105    12779024 :   outer_scope_->AddInnerScope(this);
     106    12779024 : }
     107             : 
     108     2957966 : DeclarationScope::DeclarationScope(Zone* zone,
     109     2957946 :                                    AstValueFactory* ast_value_factory)
     110     5915916 :     : Scope(zone), function_kind_(kNormalFunction), params_(4, zone) {
     111             :   DCHECK_EQ(scope_type_, SCRIPT_SCOPE);
     112     2957950 :   SetDefaults();
     113             :   receiver_ = DeclareDynamicGlobal(ast_value_factory->this_string(),
     114     2957946 :                                    THIS_VARIABLE, this);
     115     2957917 : }
     116             : 
     117     6771202 : 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    13542862 :       params_(4, zone) {
     123             :   DCHECK_NE(scope_type, SCRIPT_SCOPE);
     124     6771660 :   SetDefaults();
     125     6771624 : }
     126             : 
     127       71705 : ModuleScope::ModuleScope(DeclarationScope* script_scope,
     128      143410 :                          AstValueFactory* ast_value_factory)
     129             :     : DeclarationScope(ast_value_factory->zone(), script_scope, MODULE_SCOPE,
     130       71705 :                        kModule) {
     131             :   Zone* zone = ast_value_factory->zone();
     132       71705 :   module_descriptor_ = new (zone) ModuleDescriptor(zone);
     133             :   set_language_mode(LanguageMode::kStrict);
     134       71705 :   DeclareThis(ast_value_factory);
     135       71705 : }
     136             : 
     137        3218 : ModuleScope::ModuleScope(Isolate* isolate, Handle<ScopeInfo> scope_info,
     138        6436 :                          AstValueFactory* avfactory)
     139        3218 :     : DeclarationScope(avfactory->zone(), MODULE_SCOPE, scope_info) {
     140             :   Zone* zone = avfactory->zone();
     141        6436 :   Handle<ModuleInfo> module_info(scope_info->ModuleDescriptorInfo(), isolate);
     142             : 
     143             :   set_language_mode(LanguageMode::kStrict);
     144        3218 :   module_descriptor_ = new (zone) ModuleDescriptor(zone);
     145             : 
     146             :   // Deserialize special exports.
     147        6436 :   Handle<FixedArray> special_exports(module_info->special_exports(), isolate);
     148        3218 :   for (int i = 0, n = special_exports->length(); i < n; ++i) {
     149             :     Handle<ModuleInfoEntry> serialized_entry(
     150             :         ModuleInfoEntry::cast(special_exports->get(i)), isolate);
     151             :     module_descriptor_->AddSpecialExport(
     152             :         ModuleDescriptor::Entry::Deserialize(isolate, avfactory,
     153           0 :                                              serialized_entry),
     154           0 :         avfactory->zone());
     155             :   }
     156             : 
     157             :   // Deserialize regular exports.
     158             :   module_descriptor_->DeserializeRegularExports(isolate, avfactory,
     159        3218 :                                                 module_info);
     160             : 
     161             :   // Deserialize namespace imports.
     162             :   Handle<FixedArray> namespace_imports(module_info->namespace_imports(),
     163        6436 :                                        isolate);
     164        3513 :   for (int i = 0, n = namespace_imports->length(); i < n; ++i) {
     165             :     Handle<ModuleInfoEntry> serialized_entry(
     166             :         ModuleInfoEntry::cast(namespace_imports->get(i)), isolate);
     167             :     module_descriptor_->AddNamespaceImport(
     168             :         ModuleDescriptor::Entry::Deserialize(isolate, avfactory,
     169         295 :                                              serialized_entry),
     170         295 :         avfactory->zone());
     171             :   }
     172             : 
     173             :   // Deserialize regular imports.
     174        6436 :   Handle<FixedArray> regular_imports(module_info->regular_imports(), isolate);
     175        5699 :   for (int i = 0, n = regular_imports->length(); i < n; ++i) {
     176             :     Handle<ModuleInfoEntry> serialized_entry(
     177             :         ModuleInfoEntry::cast(regular_imports->get(i)), isolate);
     178             :     module_descriptor_->AddRegularImport(ModuleDescriptor::Entry::Deserialize(
     179        2481 :         isolate, avfactory, serialized_entry));
     180             :   }
     181        3218 : }
     182             : 
     183     1068541 : Scope::Scope(Zone* zone, ScopeType scope_type, Handle<ScopeInfo> scope_info)
     184             :     : zone_(zone),
     185             :       outer_scope_(nullptr),
     186             :       variables_(zone),
     187             :       scope_info_(scope_info),
     188     2137084 :       scope_type_(scope_type) {
     189             :   DCHECK(!scope_info.is_null());
     190             :   SetDefaults();
     191             : #ifdef DEBUG
     192             :   already_resolved_ = true;
     193             : #endif
     194     1068544 :   if (scope_info->CallsSloppyEval()) scope_calls_eval_ = true;
     195     2137092 :   set_language_mode(scope_info->language_mode());
     196     1068546 :   num_heap_slots_ = scope_info->ContextLength();
     197             :   DCHECK_LE(Context::MIN_CONTEXT_SLOTS, num_heap_slots_);
     198             :   // We don't really need to use the preparsed scope data; this is just to
     199             :   // shorten the recursion in SetMustUsePreparseData.
     200     1068545 :   must_use_preparsed_scope_data_ = true;
     201     1068545 : }
     202             : 
     203      898115 : DeclarationScope::DeclarationScope(Zone* zone, ScopeType scope_type,
     204             :                                    Handle<ScopeInfo> scope_info)
     205             :     : Scope(zone, scope_type, scope_info),
     206     1796228 :       function_kind_(scope_info->function_kind()),
     207     3592457 :       params_(0, zone) {
     208             :   DCHECK_NE(scope_type, SCRIPT_SCOPE);
     209      898114 :   SetDefaults();
     210      898114 : }
     211             : 
     212        5294 : Scope::Scope(Zone* zone, const AstRawString* catch_variable_name,
     213             :              MaybeAssignedFlag maybe_assigned, Handle<ScopeInfo> scope_info)
     214             :     : zone_(zone),
     215             :       outer_scope_(nullptr),
     216             :       variables_(zone),
     217             :       scope_info_(scope_info),
     218       10588 :       scope_type_(CATCH_SCOPE) {
     219             :   SetDefaults();
     220             : #ifdef DEBUG
     221             :   already_resolved_ = true;
     222             : #endif
     223             :   // Cache the catch variable, even though it's also available via the
     224             :   // scope_info, as the parser expects that a catch scope always has the catch
     225             :   // variable as first and only variable.
     226             :   bool was_added;
     227             :   Variable* variable =
     228             :       Declare(zone, catch_variable_name, VariableMode::kVar, NORMAL_VARIABLE,
     229        5294 :               kCreatedInitialized, maybe_assigned, &was_added);
     230             :   DCHECK(was_added);
     231             :   AllocateHeapSlot(variable);
     232        5294 : }
     233             : 
     234    10627710 : void DeclarationScope::SetDefaults() {
     235    10627710 :   is_declaration_scope_ = true;
     236    10627710 :   has_simple_parameters_ = true;
     237    10627710 :   is_asm_module_ = false;
     238    10627710 :   force_eager_compilation_ = false;
     239    10627710 :   has_arguments_parameter_ = false;
     240    10627710 :   scope_uses_super_property_ = false;
     241    10627710 :   has_checked_syntax_ = false;
     242    10627710 :   has_this_reference_ = false;
     243             :   has_this_declaration_ =
     244    17058519 :       (is_function_scope() && !is_arrow_scope()) || is_module_scope();
     245    10627710 :   has_rest_ = false;
     246    10627710 :   receiver_ = nullptr;
     247    10627710 :   new_target_ = nullptr;
     248    10627710 :   function_ = nullptr;
     249    10627710 :   arguments_ = nullptr;
     250    10627710 :   rare_data_ = nullptr;
     251    10627710 :   should_eager_compile_ = false;
     252    10627710 :   was_lazily_parsed_ = false;
     253    10627710 :   is_skipped_function_ = false;
     254    10627710 :   preparse_data_builder_ = nullptr;
     255             : #ifdef DEBUG
     256             :   DeclarationScope* outer_declaration_scope =
     257             :       outer_scope_ ? outer_scope_->GetDeclarationScope() : nullptr;
     258             :   is_being_lazily_parsed_ =
     259             :       outer_declaration_scope ? outer_declaration_scope->is_being_lazily_parsed_
     260             :                               : false;
     261             : #endif
     262    10627710 : }
     263             : 
     264           0 : void Scope::SetDefaults() {
     265             : #ifdef DEBUG
     266             :   scope_name_ = nullptr;
     267             :   already_resolved_ = false;
     268             :   needs_migration_ = false;
     269             : #endif
     270    16810830 :   inner_scope_ = nullptr;
     271    16810830 :   sibling_ = nullptr;
     272             :   unresolved_list_.Clear();
     273             : 
     274    16810830 :   start_position_ = kNoSourcePosition;
     275    16810830 :   end_position_ = kNoSourcePosition;
     276             : 
     277    16810830 :   num_stack_slots_ = 0;
     278    16810830 :   num_heap_slots_ = Context::MIN_CONTEXT_SLOTS;
     279             : 
     280             :   set_language_mode(LanguageMode::kSloppy);
     281             : 
     282    16810830 :   scope_calls_eval_ = false;
     283    16810830 :   scope_nonlinear_ = false;
     284    16810830 :   is_hidden_ = false;
     285    16810830 :   is_debug_evaluate_scope_ = false;
     286             : 
     287    16810830 :   inner_scope_calls_eval_ = false;
     288    16810830 :   force_context_allocation_ = false;
     289    16810830 :   force_context_allocation_for_parameters_ = false;
     290             : 
     291    16810830 :   is_declaration_scope_ = false;
     292             : 
     293    16810830 :   must_use_preparsed_scope_data_ = false;
     294           0 : }
     295             : 
     296      430906 : bool Scope::HasSimpleParameters() {
     297             :   DeclarationScope* scope = GetClosureScope();
     298      585124 :   return !scope->is_function_scope() || scope->has_simple_parameters();
     299             : }
     300             : 
     301      716685 : void DeclarationScope::set_should_eager_compile() {
     302     2510641 :   should_eager_compile_ = !was_lazily_parsed_;
     303      716685 : }
     304             : 
     305        5847 : void DeclarationScope::set_is_asm_module() { is_asm_module_ = true; }
     306             : 
     307     1785664 : bool Scope::IsAsmModule() const {
     308     7440205 :   return is_function_scope() && AsDeclarationScope()->is_asm_module();
     309             : }
     310             : 
     311        6309 : bool Scope::ContainsAsmModule() const {
     312        6309 :   if (IsAsmModule()) return true;
     313             : 
     314             :   // Check inner scopes recursively
     315        2530 :   for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
     316             :     // Don't check inner functions which won't be eagerly compiled.
     317        4967 :     if (!scope->is_function_scope() ||
     318             :         scope->AsDeclarationScope()->ShouldEagerCompile()) {
     319        2106 :       if (scope->ContainsAsmModule()) return true;
     320             :     }
     321             :   }
     322             : 
     323             :   return false;
     324             : }
     325             : 
     326     1005066 : Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone,
     327             :                                     ScopeInfo scope_info,
     328             :                                     DeclarationScope* script_scope,
     329             :                                     AstValueFactory* ast_value_factory,
     330             :                                     DeserializationMode deserialization_mode) {
     331             :   // Reconstruct the outer scope chain from a closure's context chain.
     332             :   Scope* current_scope = nullptr;
     333             :   Scope* innermost_scope = nullptr;
     334             :   Scope* outer_scope = nullptr;
     335     3083971 :   while (!scope_info.is_null()) {
     336     1396860 :     if (scope_info->scope_type() == WITH_SCOPE) {
     337       14783 :       if (scope_info->IsDebugEvaluateScope()) {
     338             :         outer_scope = new (zone)
     339       25370 :             DeclarationScope(zone, FUNCTION_SCOPE, handle(scope_info, isolate));
     340             :         outer_scope->set_is_debug_evaluate_scope();
     341             :       } else {
     342             :         // For scope analysis, debug-evaluate is equivalent to a with scope.
     343             :         outer_scope =
     344        4196 :             new (zone) Scope(zone, WITH_SCOPE, handle(scope_info, isolate));
     345             :       }
     346             : 
     347     1382078 :     } else if (scope_info->scope_type() == SCRIPT_SCOPE) {
     348             :       // If we reach a script scope, it's the outermost scope. Install the
     349             :       // scope info of this script context onto the existing script scope to
     350             :       // avoid nesting script scopes.
     351      323023 :       if (deserialization_mode == DeserializationMode::kIncludingVariables) {
     352             :         script_scope->SetScriptScopeInfo(handle(scope_info, isolate));
     353             :       }
     354             :       DCHECK(!scope_info->HasOuterScopeInfo());
     355             :       break;
     356     1059056 :     } else if (scope_info->scope_type() == FUNCTION_SCOPE) {
     357             :       outer_scope = new (zone)
     358     1694158 :           DeclarationScope(zone, FUNCTION_SCOPE, handle(scope_info, isolate));
     359      847079 :       if (scope_info->IsAsmModule()) {
     360             :         outer_scope->AsDeclarationScope()->set_is_asm_module();
     361             :       }
     362      211977 :     } else if (scope_info->scope_type() == EVAL_SCOPE) {
     363             :       outer_scope = new (zone)
     364       52836 :           DeclarationScope(zone, EVAL_SCOPE, handle(scope_info, isolate));
     365      185558 :     } else if (scope_info->scope_type() == BLOCK_SCOPE) {
     366      177045 :       if (scope_info->is_declaration_scope()) {
     367             :         outer_scope = new (zone)
     368       17430 :             DeclarationScope(zone, BLOCK_SCOPE, handle(scope_info, isolate));
     369             :       } else {
     370             :         outer_scope =
     371      336663 :             new (zone) Scope(zone, BLOCK_SCOPE, handle(scope_info, isolate));
     372             :       }
     373        8512 :     } else if (scope_info->scope_type() == MODULE_SCOPE) {
     374             :       outer_scope = new (zone)
     375        6436 :           ModuleScope(isolate, handle(scope_info, isolate), ast_value_factory);
     376             :     } else {
     377             :       DCHECK_EQ(scope_info->scope_type(), CATCH_SCOPE);
     378             :       DCHECK_EQ(scope_info->ContextLocalCount(), 1);
     379             :       DCHECK_EQ(scope_info->ContextLocalMode(0), VariableMode::kVar);
     380             :       DCHECK_EQ(scope_info->ContextLocalInitFlag(0), kCreatedInitialized);
     381        5294 :       String name = scope_info->ContextLocalName(0);
     382             :       MaybeAssignedFlag maybe_assigned =
     383        5294 :           scope_info->ContextLocalMaybeAssignedFlag(0);
     384             :       outer_scope = new (zone)
     385             :           Scope(zone, ast_value_factory->GetString(handle(name, isolate)),
     386       15882 :                 maybe_assigned, handle(scope_info, isolate));
     387             :     }
     388     1073839 :     if (deserialization_mode == DeserializationMode::kScopesOnly) {
     389           0 :       outer_scope->scope_info_ = Handle<ScopeInfo>::null();
     390             :     }
     391     1073839 :     if (current_scope != nullptr) {
     392             :       outer_scope->AddInnerScope(current_scope);
     393             :     }
     394             :     current_scope = outer_scope;
     395     1073839 :     if (innermost_scope == nullptr) innermost_scope = current_scope;
     396     1073839 :     scope_info = scope_info->HasOuterScopeInfo() ? scope_info->OuterScopeInfo()
     397     1073837 :                                                  : ScopeInfo();
     398             :   }
     399             : 
     400     2010136 :   if (deserialization_mode == DeserializationMode::kIncludingVariables &&
     401             :       script_scope->scope_info_.is_null()) {
     402             :     Handle<ScriptContextTable> table(
     403     2046135 :         isolate->native_context()->script_context_table(), isolate);
     404      682045 :     Handle<Context> first = ScriptContextTable::GetContext(isolate, table, 0);
     405     1364090 :     Handle<ScopeInfo> scope_info(first->scope_info(), isolate);
     406             :     script_scope->SetScriptScopeInfo(scope_info);
     407             :   }
     408             : 
     409     1005068 :   if (innermost_scope == nullptr) return script_scope;
     410      849568 :   script_scope->AddInnerScope(current_scope);
     411      849568 :   return innermost_scope;
     412             : }
     413             : 
     414   150346443 : DeclarationScope* Scope::AsDeclarationScope() {
     415             :   DCHECK(is_declaration_scope());
     416   150346443 :   return static_cast<DeclarationScope*>(this);
     417             : }
     418             : 
     419           0 : const DeclarationScope* Scope::AsDeclarationScope() const {
     420             :   DCHECK(is_declaration_scope());
     421           0 :   return static_cast<const DeclarationScope*>(this);
     422             : }
     423             : 
     424       55221 : ModuleScope* Scope::AsModuleScope() {
     425             :   DCHECK(is_module_scope());
     426       55221 :   return static_cast<ModuleScope*>(this);
     427             : }
     428             : 
     429           0 : const ModuleScope* Scope::AsModuleScope() const {
     430             :   DCHECK(is_module_scope());
     431           0 :   return static_cast<const ModuleScope*>(this);
     432             : }
     433             : 
     434       11609 : void DeclarationScope::DeclareSloppyBlockFunction(
     435             :     SloppyBlockFunctionStatement* sloppy_block_function) {
     436             :   sloppy_block_functions_.Add(sloppy_block_function);
     437       11609 : }
     438             : 
     439     5107435 : void DeclarationScope::HoistSloppyBlockFunctions(AstNodeFactory* factory) {
     440             :   DCHECK(is_sloppy(language_mode()));
     441             :   DCHECK(is_function_scope() || is_eval_scope() || is_script_scope() ||
     442             :          (is_block_scope() && outer_scope()->is_function_scope()));
     443             :   DCHECK(HasSimpleParameters() || is_block_scope() || is_being_lazily_parsed_);
     444             :   DCHECK_EQ(factory == nullptr, is_being_lazily_parsed_);
     445             : 
     446    10154897 :   if (sloppy_block_functions_.is_empty()) return;
     447             : 
     448             :   // In case of complex parameters the current scope is the body scope and the
     449             :   // parameters are stored in the outer scope.
     450       10233 :   Scope* parameter_scope = HasSimpleParameters() ? this : outer_scope_;
     451             :   DCHECK(parameter_scope->is_function_scope() || is_eval_scope() ||
     452             :          is_script_scope());
     453             : 
     454             :   DeclarationScope* decl_scope = this;
     455       21828 :   while (decl_scope->is_eval_scope()) {
     456       23190 :     decl_scope = decl_scope->outer_scope()->GetDeclarationScope();
     457             :   }
     458             :   Scope* outer_scope = decl_scope->outer_scope();
     459             : 
     460             :   // For each variable which is used as a function declaration in a sloppy
     461             :   // block,
     462       60875 :   for (SloppyBlockFunctionStatement* sloppy_block_function :
     463       21736 :        sloppy_block_functions_) {
     464             :     const AstRawString* name = sloppy_block_function->name();
     465             : 
     466             :     // If the variable wouldn't conflict with a lexical declaration
     467             :     // or parameter,
     468             : 
     469             :     // Check if there's a conflict with a parameter.
     470             :     Variable* maybe_parameter = parameter_scope->LookupLocal(name);
     471       14280 :     if (maybe_parameter != nullptr && maybe_parameter->is_parameter()) {
     472             :       continue;
     473             :     }
     474             : 
     475             :     // Check if there's a conflict with a lexical declaration
     476       26102 :     Scope* query_scope = sloppy_block_function->scope()->outer_scope();
     477        3258 :     Variable* var = nullptr;
     478             :     bool should_hoist = true;
     479             : 
     480             :     // It is not sufficient to just do a Lookup on query_scope: for
     481             :     // example, that does not prevent hoisting of the function in
     482             :     // `{ let e; try {} catch (e) { function e(){} } }`
     483       14791 :     do {
     484       16197 :       var = query_scope->LookupInScopeOrScopeInfo(name);
     485       19455 :       if (var != nullptr && IsLexicalVariableMode(var->mode())) {
     486             :         should_hoist = false;
     487             :         break;
     488             :       }
     489             :       query_scope = query_scope->outer_scope();
     490             :     } while (query_scope != outer_scope);
     491             : 
     492       11311 :     if (!should_hoist) continue;
     493             : 
     494        9905 :     if (factory) {
     495             :       DCHECK(!is_being_lazily_parsed_);
     496        7497 :       int pos = sloppy_block_function->position();
     497        7497 :       bool ok = true;
     498             :       bool was_added;
     499             :       auto declaration = factory->NewVariableDeclaration(pos);
     500             :       // Based on the preceding checks, it doesn't matter what we pass as
     501             :       // sloppy_mode_block_scope_function_redefinition.
     502             :       Variable* var = DeclareVariable(
     503             :           declaration, name, pos, VariableMode::kVar, NORMAL_VARIABLE,
     504             :           Variable::DefaultInitializationFlag(VariableMode::kVar), &was_added,
     505        7497 :           nullptr, &ok);
     506             :       DCHECK(ok);
     507             :       VariableProxy* source =
     508             :           factory->NewVariableProxy(sloppy_block_function->var());
     509             :       VariableProxy* target = factory->NewVariableProxy(var);
     510             :       Assignment* assignment = factory->NewAssignment(
     511        7497 :           sloppy_block_function->init(), target, source, pos);
     512             :       assignment->set_lookup_hoisting_mode(LookupHoistingMode::kLegacySloppy);
     513             :       Statement* statement = factory->NewExpressionStatement(assignment, pos);
     514             :       sloppy_block_function->set_statement(statement);
     515             :     } else {
     516             :       DCHECK(is_being_lazily_parsed_);
     517             :       bool was_added;
     518        2408 :       Variable* var = DeclareVariableName(name, VariableMode::kVar, &was_added);
     519        2408 :       if (sloppy_block_function->init() == Token::ASSIGN)
     520             :         var->set_maybe_assigned();
     521             :     }
     522             :   }
     523             : }
     524             : 
     525     5381862 : bool DeclarationScope::Analyze(ParseInfo* info) {
     526             :   RuntimeCallTimerScope runtimeTimer(
     527             :       info->runtime_call_stats(),
     528             :       info->on_background_thread()
     529             :           ? RuntimeCallCounterId::kCompileBackgroundScopeAnalysis
     530     3587906 :           : RuntimeCallCounterId::kCompileScopeAnalysis);
     531             :   DCHECK_NOT_NULL(info->literal());
     532     1793956 :   DeclarationScope* scope = info->literal()->scope();
     533             : 
     534             :   base::Optional<AllowHandleDereference> allow_deref;
     535             :   if (!info->maybe_outer_scope_info().is_null()) {
     536             :     // Allow dereferences to the scope info if there is one.
     537             :     allow_deref.emplace();
     538             :   }
     539             : 
     540     2646654 :   if (scope->is_eval_scope() && is_sloppy(scope->language_mode())) {
     541      726710 :     AstNodeFactory factory(info->ast_value_factory(), info->zone());
     542      726710 :     scope->HoistSloppyBlockFunctions(&factory);
     543             :   }
     544             : 
     545             :   // We are compiling one of four cases:
     546             :   // 1) top-level code,
     547             :   // 2) a function/eval/module on the top-level
     548             :   // 3) a function/eval in a scope that was already resolved.
     549             :   DCHECK(scope->is_script_scope() || scope->outer_scope()->is_script_scope() ||
     550             :          scope->outer_scope()->already_resolved_);
     551             : 
     552             :   // The outer scope is never lazy.
     553             :   scope->set_should_eager_compile();
     554             : 
     555     1793956 :   if (scope->must_use_preparsed_scope_data_) {
     556             :     DCHECK_EQ(scope->scope_type_, ScopeType::FUNCTION_SCOPE);
     557             :     allow_deref.emplace();
     558       36349 :     info->consumed_preparse_data()->RestoreScopeAllocationData(scope);
     559             :   }
     560             : 
     561     1793956 :   if (!scope->AllocateVariables(info)) return false;
     562             : 
     563             : #ifdef DEBUG
     564             :   if (info->is_native() ? FLAG_print_builtin_scopes : FLAG_print_scopes) {
     565             :     PrintF("Global scope:\n");
     566             :     scope->Print();
     567             :   }
     568             :   scope->CheckScopePositions();
     569             :   scope->CheckZones();
     570             : #endif
     571             : 
     572     1793784 :   return true;
     573             : }
     574             : 
     575    10438866 : void DeclarationScope::DeclareThis(AstValueFactory* ast_value_factory) {
     576             :   DCHECK(has_this_declaration());
     577             : 
     578     5219433 :   bool derived_constructor = IsDerivedConstructor(function_kind_);
     579             : 
     580     5219433 :   receiver_ = new (zone())
     581             :       Variable(this, ast_value_factory->this_string(),
     582             :                derived_constructor ? VariableMode::kConst : VariableMode::kVar,
     583             :                THIS_VARIABLE,
     584             :                derived_constructor ? kNeedsInitialization : kCreatedInitialized,
     585    10438934 :                kNotAssigned);
     586     5219467 : }
     587             : 
     588     4074728 : void DeclarationScope::DeclareArguments(AstValueFactory* ast_value_factory) {
     589             :   DCHECK(is_function_scope());
     590             :   DCHECK(!is_arrow_scope());
     591             : 
     592             :   // Declare 'arguments' variable which exists in all non arrow functions.  Note
     593             :   // that it might never be accessed, in which case it won't be allocated during
     594             :   // variable allocation.
     595             :   bool was_added;
     596             :   arguments_ =
     597             :       Declare(zone(), ast_value_factory->arguments_string(), VariableMode::kVar,
     598     4074728 :               NORMAL_VARIABLE, kCreatedInitialized, kNotAssigned, &was_added);
     599     4077561 :   if (!was_added && IsLexicalVariableMode(arguments_->mode())) {
     600             :     // Check if there's lexically declared variable named arguments to avoid
     601             :     // redeclaration. See ES#sec-functiondeclarationinstantiation, step 20.
     602         622 :     arguments_ = nullptr;
     603             :   }
     604     4074800 : }
     605             : 
     606     4509483 : void DeclarationScope::DeclareDefaultFunctionVariables(
     607     6336226 :     AstValueFactory* ast_value_factory) {
     608             :   DCHECK(is_function_scope());
     609             :   DCHECK(!is_arrow_scope());
     610             : 
     611     4509483 :   DeclareThis(ast_value_factory);
     612             :   bool was_added;
     613             :   new_target_ = Declare(zone(), ast_value_factory->new_target_string(),
     614             :                         VariableMode::kConst, NORMAL_VARIABLE,
     615     5422852 :                         kCreatedInitialized, kNotAssigned, &was_added);
     616             :   DCHECK(was_added);
     617             : 
     618    16574872 :   if (IsConciseMethod(function_kind_) || IsClassConstructor(function_kind_) ||
     619             :       IsAccessorFunction(function_kind_)) {
     620             :     EnsureRareData()->this_function = Declare(
     621             :         zone(), ast_value_factory->this_function_string(), VariableMode::kConst,
     622      913369 :         NORMAL_VARIABLE, kCreatedInitialized, kNotAssigned, &was_added);
     623             :     DCHECK(was_added);
     624             :   }
     625     4509474 : }
     626             : 
     627      996835 : Variable* DeclarationScope::DeclareFunctionVar(const AstRawString* name,
     628             :                                                Scope* cache) {
     629             :   DCHECK(is_function_scope());
     630             :   DCHECK_NULL(function_);
     631      996835 :   if (cache == nullptr) cache = this;
     632             :   DCHECK_NULL(cache->variables_.Lookup(name));
     633     1992764 :   VariableKind kind = is_sloppy(language_mode()) ? SLOPPY_FUNCTION_NAME_VARIABLE
     634      996835 :                                                  : NORMAL_VARIABLE;
     635             :   function_ = new (zone())
     636     1993656 :       Variable(this, name, VariableMode::kConst, kind, kCreatedInitialized);
     637      996828 :   if (calls_sloppy_eval()) {
     638         899 :     cache->NonLocal(name, VariableMode::kDynamic);
     639             :   } else {
     640      995929 :     cache->variables_.Add(zone(), function_);
     641             :   }
     642      996857 :   return function_;
     643             : }
     644             : 
     645      142688 : Variable* DeclarationScope::DeclareGeneratorObjectVar(
     646      142688 :     const AstRawString* name) {
     647             :   DCHECK(is_function_scope() || is_module_scope());
     648             :   DCHECK_NULL(generator_object_var());
     649             : 
     650             :   Variable* result = EnsureRareData()->generator_object =
     651      142689 :       NewTemporary(name, kNotAssigned);
     652             :   result->set_is_used();
     653      142688 :   return result;
     654             : }
     655             : 
     656    14761245 : Scope* Scope::FinalizeBlockScope() {
     657             :   DCHECK(is_block_scope());
     658             : #ifdef DEBUG
     659             :   DCHECK_NE(sibling_, this);
     660             : #endif
     661             : 
     662    14678873 :   if (variables_.occupancy() > 0 ||
     663       68171 :       (is_declaration_scope() && AsDeclarationScope()->calls_sloppy_eval())) {
     664             :     return this;
     665             :   }
     666             : 
     667             :   // Remove this scope from outer scope.
     668             :   outer_scope()->RemoveInnerScope(this);
     669             : 
     670             :   // Reparent inner scopes.
     671     4379370 :   if (inner_scope_ != nullptr) {
     672             :     Scope* scope = inner_scope_;
     673      541976 :     scope->outer_scope_ = outer_scope();
     674     1125857 :     while (scope->sibling_ != nullptr) {
     675             :       scope = scope->sibling_;
     676       41905 :       scope->outer_scope_ = outer_scope();
     677             :     }
     678      541976 :     scope->sibling_ = outer_scope()->inner_scope_;
     679      541976 :     outer_scope()->inner_scope_ = inner_scope_;
     680      541976 :     inner_scope_ = nullptr;
     681             :   }
     682             : 
     683             :   // Move unresolved variables
     684     4379370 :   if (!unresolved_list_.is_empty()) {
     685             :     outer_scope()->unresolved_list_.Prepend(std::move(unresolved_list_));
     686             :     unresolved_list_.Clear();
     687             :   }
     688             : 
     689     4474844 :   if (inner_scope_calls_eval_) outer_scope()->inner_scope_calls_eval_ = true;
     690             : 
     691             :   // No need to propagate scope_calls_eval_, since if it was relevant to
     692             :   // this scope we would have had to bail out at the top.
     693             :   DCHECK(!scope_calls_eval_ || !is_declaration_scope() ||
     694             :          !is_sloppy(language_mode()));
     695             : 
     696             :   // This block does not need a context.
     697     4379370 :   num_heap_slots_ = 0;
     698             : 
     699             :   // Mark scope as removed by making it its own sibling.
     700             : #ifdef DEBUG
     701             :   sibling_ = this;
     702             : #endif
     703             : 
     704     4379370 :   return nullptr;
     705             : }
     706             : 
     707           0 : void DeclarationScope::AddLocal(Variable* var) {
     708             :   DCHECK(!already_resolved_);
     709             :   // Temporaries are only placed in ClosureScopes.
     710             :   DCHECK_EQ(GetClosureScope(), this);
     711             :   locals_.Add(var);
     712           0 : }
     713             : 
     714      132572 : void Scope::Snapshot::Reparent(DeclarationScope* new_parent) {
     715             :   DCHECK(!IsCleared());
     716             :   DCHECK_EQ(new_parent, outer_scope_and_calls_eval_.GetPointer()->inner_scope_);
     717             :   DCHECK_EQ(new_parent->outer_scope_, outer_scope_and_calls_eval_.GetPointer());
     718             :   DCHECK_EQ(new_parent, new_parent->GetClosureScope());
     719             :   DCHECK_NULL(new_parent->inner_scope_);
     720             :   DCHECK(new_parent->unresolved_list_.is_empty());
     721      132572 :   Scope* inner_scope = new_parent->sibling_;
     722      132572 :   if (inner_scope != top_inner_scope_) {
     723        3644 :     for (; inner_scope->sibling() != top_inner_scope_;
     724             :          inner_scope = inner_scope->sibling()) {
     725           0 :       inner_scope->outer_scope_ = new_parent;
     726           0 :       if (inner_scope->inner_scope_calls_eval_) {
     727           0 :         new_parent->inner_scope_calls_eval_ = true;
     728             :       }
     729             :       DCHECK_NE(inner_scope, new_parent);
     730             :     }
     731        3644 :     inner_scope->outer_scope_ = new_parent;
     732        3644 :     if (inner_scope->inner_scope_calls_eval_) {
     733         128 :       new_parent->inner_scope_calls_eval_ = true;
     734             :     }
     735        3644 :     new_parent->inner_scope_ = new_parent->sibling_;
     736        3644 :     inner_scope->sibling_ = nullptr;
     737             :     // Reset the sibling rather than the inner_scope_ since we
     738             :     // want to keep new_parent there.
     739        3644 :     new_parent->sibling_ = top_inner_scope_;
     740             :   }
     741             : 
     742             :   Scope* outer_scope_ = outer_scope_and_calls_eval_.GetPointer();
     743             :   new_parent->unresolved_list_.MoveTail(&outer_scope_->unresolved_list_,
     744             :                                         top_unresolved_);
     745             : 
     746             :   // Move temporaries allocated for complex parameter initializers.
     747             :   DeclarationScope* outer_closure = outer_scope_->GetClosureScope();
     748      265156 :   for (auto it = top_local_; it != outer_closure->locals()->end(); ++it) {
     749          12 :     Variable* local = *it;
     750             :     DCHECK_EQ(VariableMode::kTemporary, local->mode());
     751             :     DCHECK_EQ(local->scope(), local->scope()->GetClosureScope());
     752             :     DCHECK_NE(local->scope(), new_parent);
     753             :     local->set_scope(new_parent);
     754             :   }
     755             :   new_parent->locals_.MoveTail(outer_closure->locals(), top_local_);
     756             :   outer_closure->locals_.Rewind(top_local_);
     757             : 
     758             :   // Move eval calls since Snapshot's creation into new_parent.
     759      132572 :   if (outer_scope_and_calls_eval_->scope_calls_eval_) {
     760         419 :     new_parent->scope_calls_eval_ = true;
     761         419 :     new_parent->inner_scope_calls_eval_ = true;
     762             :   }
     763             : 
     764             :   // We are in the arrow function case. The calls eval we may have recorded
     765             :   // is intended for the inner scope and we should simply restore the
     766             :   // original "calls eval" flag of the outer scope.
     767             :   RestoreEvalFlag();
     768             :   Clear();
     769      132572 : }
     770             : 
     771          91 : void Scope::ReplaceOuterScope(Scope* outer) {
     772             :   DCHECK_NOT_NULL(outer);
     773             :   DCHECK_NOT_NULL(outer_scope_);
     774             :   DCHECK(!already_resolved_);
     775          91 :   outer_scope_->RemoveInnerScope(this);
     776             :   outer->AddInnerScope(this);
     777             :   outer_scope_ = outer;
     778          91 : }
     779             : 
     780     4906822 : Variable* Scope::LookupInScopeInfo(const AstRawString* name, Scope* cache) {
     781             :   DCHECK(!scope_info_.is_null());
     782             :   DCHECK_NULL(cache->variables_.Lookup(name));
     783             :   DisallowHeapAllocation no_gc;
     784             : 
     785     2453197 :   String name_handle = *name->string();
     786             :   // The Scope is backed up by ScopeInfo. This means it cannot operate in a
     787             :   // heap-independent mode, and all strings must be internalized immediately. So
     788             :   // it's ok to get the Handle<String> here.
     789             :   bool found = false;
     790             : 
     791             :   VariableLocation location;
     792             :   int index;
     793             :   VariableMode mode;
     794             :   InitializationFlag init_flag;
     795             :   MaybeAssignedFlag maybe_assigned_flag;
     796             : 
     797             :   {
     798             :     location = VariableLocation::CONTEXT;
     799             :     index = ScopeInfo::ContextSlotIndex(*scope_info_, name_handle, &mode,
     800     2453198 :                                         &init_flag, &maybe_assigned_flag);
     801     2453199 :     found = index >= 0;
     802             :   }
     803             : 
     804     4459132 :   if (!found && is_module_scope()) {
     805             :     location = VariableLocation::MODULE;
     806             :     index = scope_info_->ModuleIndex(name_handle, &mode, &init_flag,
     807        1981 :                                      &maybe_assigned_flag);
     808        1981 :     found = index != 0;
     809             :   }
     810             : 
     811     2453199 :   if (!found) {
     812     2005506 :     index = scope_info_->FunctionContextSlotIndex(name_handle);
     813     2005505 :     if (index < 0) return nullptr;  // Nowhere found.
     814        1040 :     Variable* var = AsDeclarationScope()->DeclareFunctionVar(name, cache);
     815             :     DCHECK_EQ(VariableMode::kConst, var->mode());
     816             :     var->AllocateTo(VariableLocation::CONTEXT, index);
     817        1040 :     return cache->variables_.Lookup(name);
     818             :   }
     819             : 
     820             :   if (!is_module_scope()) {
     821             :     DCHECK_NE(index, scope_info_->ReceiverContextSlotIndex());
     822             :   }
     823             : 
     824             :   bool was_added;
     825             :   Variable* var =
     826             :       cache->variables_.Declare(zone(), this, name, mode, NORMAL_VARIABLE,
     827      895390 :                                 init_flag, maybe_assigned_flag, &was_added);
     828             :   DCHECK(was_added);
     829             :   var->AllocateTo(location, index);
     830      447694 :   return var;
     831             : }
     832             : 
     833     2916459 : Variable* DeclarationScope::DeclareParameter(const AstRawString* name,
     834             :                                              VariableMode mode,
     835             :                                              bool is_optional, bool is_rest,
     836     2916472 :                                              AstValueFactory* ast_value_factory,
     837             :                                              int position) {
     838             :   DCHECK(!already_resolved_);
     839             :   DCHECK(is_function_scope() || is_module_scope());
     840             :   DCHECK(!has_rest_);
     841             :   DCHECK(!is_optional || !is_rest);
     842             :   DCHECK(!is_being_lazily_parsed_);
     843             :   DCHECK(!was_lazily_parsed_);
     844             :   Variable* var;
     845     2916459 :   if (mode == VariableMode::kTemporary) {
     846     3141360 :     var = NewTemporary(name);
     847             :   } else {
     848     2804020 :     var = LookupLocal(name);
     849             :     DCHECK_EQ(mode, VariableMode::kVar);
     850             :     DCHECK(var->is_parameter());
     851             :   }
     852     2916467 :   has_rest_ = is_rest;
     853     2916467 :   var->set_initializer_position(position);
     854     2916467 :   params_.Add(var, zone());
     855     2916472 :   if (!is_rest) ++num_parameters_;
     856     2916472 :   if (name == ast_value_factory->arguments_string()) {
     857        1454 :     has_arguments_parameter_ = true;
     858             :   }
     859             :   // Params are automatically marked as used to make sure that the debugger and
     860             :   // function.arguments sees them.
     861             :   // TODO(verwaest): Reevaluate whether we always need to do this, since
     862             :   // strict-mode function.arguments does not make the arguments available.
     863     2916472 :   var->set_is_used();
     864     2916472 :   return var;
     865             : }
     866             : 
     867     3918536 : void DeclarationScope::RecordParameter(bool is_rest) {
     868             :   DCHECK(!already_resolved_);
     869             :   DCHECK(is_function_scope() || is_module_scope());
     870             :   DCHECK(is_being_lazily_parsed_);
     871             :   DCHECK(!has_rest_);
     872     3918536 :   has_rest_ = is_rest;
     873     3918536 :   if (!is_rest) ++num_parameters_;
     874     3918536 : }
     875             : 
     876    23850270 : Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode,
     877             :                               VariableKind kind, bool* was_added,
     878    47701042 :                               InitializationFlag init_flag) {
     879             :   DCHECK(!already_resolved_);
     880             :   // This function handles VariableMode::kVar, VariableMode::kLet, and
     881             :   // VariableMode::kConst modes.  VariableMode::kDynamic variables are
     882             :   // introduced during variable allocation, and VariableMode::kTemporary
     883             :   // variables are allocated via NewTemporary().
     884             :   DCHECK(IsDeclaredVariableMode(mode));
     885             :   DCHECK_IMPLIES(GetDeclarationScope()->is_being_lazily_parsed(),
     886             :                  mode == VariableMode::kVar || mode == VariableMode::kLet ||
     887             :                      mode == VariableMode::kConst);
     888             :   DCHECK(!GetDeclarationScope()->was_lazily_parsed());
     889             :   Variable* var =
     890    47700540 :       Declare(zone(), name, mode, kind, init_flag, kNotAssigned, was_added);
     891             : 
     892             :   // Pessimistically assume that top-level variables will be assigned and used.
     893             :   //
     894             :   // Top-level variables in a script can be accessed by other scripts or even
     895             :   // become global properties. While this does not apply to top-level variables
     896             :   // in a module (assuming they are not exported), we must still mark these as
     897             :   // assigned because they might be accessed by a lazily parsed top-level
     898             :   // function, which, for efficiency, we preparse without variable tracking.
     899    23850772 :   if (is_script_scope() || is_module_scope()) {
     900     4045911 :     if (mode != VariableMode::kConst) var->set_maybe_assigned();
     901             :     var->set_is_used();
     902             :   }
     903             : 
     904    23850772 :   return var;
     905             : }
     906             : 
     907    15667950 : Variable* Scope::DeclareVariable(
     908             :     Declaration* declaration, const AstRawString* name, int pos,
     909             :     VariableMode mode, VariableKind kind, InitializationFlag init,
     910             :     bool* was_added, bool* sloppy_mode_block_scope_function_redefinition,
     911    13652639 :     bool* ok) {
     912             :   DCHECK(IsDeclaredVariableMode(mode));
     913             :   DCHECK(!already_resolved_);
     914             :   DCHECK(!GetDeclarationScope()->is_being_lazily_parsed());
     915             :   DCHECK(!GetDeclarationScope()->was_lazily_parsed());
     916             : 
     917    29648589 :   if (mode == VariableMode::kVar && !is_declaration_scope()) {
     918             :     return GetDeclarationScope()->DeclareVariable(
     919             :         declaration, name, pos, mode, kind, init, was_added,
     920      801036 :         sloppy_mode_block_scope_function_redefinition, ok);
     921             :   }
     922             :   DCHECK(!is_catch_scope());
     923             :   DCHECK(!is_with_scope());
     924             :   DCHECK(is_declaration_scope() ||
     925             :          (IsLexicalVariableMode(mode) && is_block_scope()));
     926             : 
     927             :   DCHECK_NOT_NULL(name);
     928             : 
     929             :   Variable* var = LookupLocal(name);
     930             :   // Declare the variable in the declaration scope.
     931    15267552 :   *was_added = var == nullptr;
     932    15267552 :   if (V8_LIKELY(*was_added)) {
     933    14464086 :     if (V8_UNLIKELY(is_eval_scope() && is_sloppy(language_mode()) &&
     934             :                     mode == VariableMode::kVar)) {
     935             :       // In a var binding in a sloppy direct eval, pollute the enclosing scope
     936             :       // with this new binding by doing the following:
     937             :       // The proxy is bound to a lookup variable to force a dynamic declaration
     938             :       // using the DeclareEvalVar or DeclareEvalFunction runtime functions.
     939             :       DCHECK_EQ(NORMAL_VARIABLE, kind);
     940      307430 :       var = NonLocal(name, VariableMode::kDynamic);
     941             :       // Mark the var as used in case anyone outside the eval wants to use it.
     942             :       var->set_is_used();
     943             :     } else {
     944             :       // Declare the name.
     945    13345209 :       var = DeclareLocal(name, mode, kind, was_added, init);
     946             :       DCHECK(*was_added);
     947             :     }
     948             :   } else {
     949             :     var->set_maybe_assigned();
     950     3179528 :     if (V8_UNLIKELY(IsLexicalVariableMode(mode) ||
     951             :                     IsLexicalVariableMode(var->mode()))) {
     952             :       // The name was declared in this scope before; check for conflicting
     953             :       // re-declarations. We have a conflict if either of the declarations is
     954             :       // not a var (in script scope, we also have to ignore legacy const for
     955             :       // compatibility). There is similar code in runtime.cc in the Declare
     956             :       // functions. The function CheckConflictingVarDeclarations checks for
     957             :       // var and let bindings from different scopes whereas this is a check
     958             :       // for conflicting declarations within the same scope. This check also
     959             :       // covers the special case
     960             :       //
     961             :       // function () { let x; { var x; } }
     962             :       //
     963             :       // because the var declaration is hoisted to the function scope where
     964             :       // 'x' is already bound.
     965             :       //
     966             :       // In harmony we treat re-declarations as early errors. See ES5 16 for a
     967             :       // definition of early errors.
     968             :       //
     969             :       // Allow duplicate function decls for web compat, see bug 4693.
     970       64459 :       *ok = var->is_sloppy_block_function() &&
     971       64459 :             kind == SLOPPY_BLOCK_FUNCTION_VARIABLE;
     972       64459 :       *sloppy_mode_block_scope_function_redefinition = *ok;
     973             :     }
     974             :   }
     975             :   DCHECK_NOT_NULL(var);
     976             : 
     977             :   // We add a declaration node for every declaration. The compiler
     978             :   // will only generate code if necessary. In particular, declarations
     979             :   // for inner local variables that do not represent functions won't
     980             :   // result in any generated code.
     981             :   //
     982             :   // This will lead to multiple declaration nodes for the
     983             :   // same variable if it is declared several times. This is not a
     984             :   // semantic issue, but it may be a performance issue since it may
     985             :   // lead to repeated DeclareEvalVar or DeclareEvalFunction calls.
     986             :   decls_.Add(declaration);
     987             :   declaration->set_var(var);
     988    15267655 :   return var;
     989             : }
     990             : 
     991    10955744 : Variable* Scope::DeclareVariableName(const AstRawString* name,
     992             :                                      VariableMode mode, bool* was_added,
     993             :                                      VariableKind kind) {
     994             :   DCHECK(IsDeclaredVariableMode(mode));
     995             :   DCHECK(!already_resolved_);
     996             :   DCHECK(GetDeclarationScope()->is_being_lazily_parsed());
     997             : 
     998    20506341 :   if (mode == VariableMode::kVar && !is_declaration_scope()) {
     999             :     return GetDeclarationScope()->DeclareVariableName(name, mode, was_added,
    1000     1120546 :                                                       kind);
    1001             :   }
    1002             :   DCHECK(!is_with_scope());
    1003             :   DCHECK(!is_eval_scope());
    1004             :   DCHECK(is_declaration_scope() || IsLexicalVariableMode(mode));
    1005             :   DCHECK(scope_info_.is_null());
    1006             : 
    1007             :   // Declare the variable in the declaration scope.
    1008    11263160 :   Variable* var = DeclareLocal(name, mode, kind, was_added);
    1009    10395972 :   if (!*was_added) {
    1010     1736076 :     if (IsLexicalVariableMode(mode) || IsLexicalVariableMode(var->mode())) {
    1011         712 :       if (!var->is_sloppy_block_function() ||
    1012             :           kind != SLOPPY_BLOCK_FUNCTION_VARIABLE) {
    1013             :         // Duplicate functions are allowed in the sloppy mode, but if this is
    1014             :         // not a function declaration, it's an error. This is an error PreParser
    1015             :         // hasn't previously detected.
    1016             :         return nullptr;
    1017             :       }
    1018             :       // Sloppy block function redefinition.
    1019             :     }
    1020             :     var->set_maybe_assigned();
    1021             :   }
    1022             :   var->set_is_used();
    1023    10395366 :   return var;
    1024             : }
    1025             : 
    1026      365645 : Variable* Scope::DeclareCatchVariableName(const AstRawString* name) {
    1027             :   DCHECK(!already_resolved_);
    1028             :   DCHECK(is_catch_scope());
    1029             :   DCHECK(scope_info_.is_null());
    1030             : 
    1031             :   bool was_added;
    1032             :   Variable* result = Declare(zone(), name, VariableMode::kVar, NORMAL_VARIABLE,
    1033      365645 :                              kCreatedInitialized, kNotAssigned, &was_added);
    1034             :   DCHECK(was_added);
    1035      365813 :   return result;
    1036             : }
    1037             : 
    1038    50041632 : void Scope::AddUnresolved(VariableProxy* proxy) {
    1039             :   DCHECK(!already_resolved_);
    1040             :   DCHECK(!proxy->is_resolved());
    1041             :   unresolved_list_.Add(proxy);
    1042    50040895 : }
    1043             : 
    1044     4919671 : Variable* DeclarationScope::DeclareDynamicGlobal(const AstRawString* name,
    1045             :                                                  VariableKind kind,
    1046             :                                                  Scope* cache) {
    1047             :   DCHECK(is_script_scope());
    1048             :   bool was_added;
    1049             :   return cache->variables_.Declare(
    1050             :       zone(), this, name, VariableMode::kDynamicGlobal, kind,
    1051     4919671 :       kCreatedInitialized, kNotAssigned, &was_added);
    1052             :   // TODO(neis): Mark variable as maybe-assigned?
    1053             : }
    1054             : 
    1055        1289 : bool Scope::RemoveUnresolved(VariableProxy* var) {
    1056        1289 :   return unresolved_list_.Remove(var);
    1057             : }
    1058             : 
    1059       15713 : void Scope::DeleteUnresolved(VariableProxy* var) {
    1060             :   DCHECK(unresolved_list_.Contains(var));
    1061             :   var->mark_removed_from_unresolved();
    1062       15713 : }
    1063             : 
    1064     1228083 : Variable* Scope::NewTemporary(const AstRawString* name) {
    1065     1340529 :   return NewTemporary(name, kMaybeAssigned);
    1066             : }
    1067             : 
    1068     1483228 : Variable* Scope::NewTemporary(const AstRawString* name,
    1069     1483228 :                               MaybeAssignedFlag maybe_assigned) {
    1070             :   DeclarationScope* scope = GetClosureScope();
    1071             :   Variable* var = new (zone()) Variable(scope, name, VariableMode::kTemporary,
    1072             :                                         NORMAL_VARIABLE, kCreatedInitialized);
    1073             :   scope->AddLocal(var);
    1074     1483229 :   if (maybe_assigned == kMaybeAssigned) var->set_maybe_assigned();
    1075     1483229 :   return var;
    1076             : }
    1077             : 
    1078     6534902 : Declaration* DeclarationScope::CheckConflictingVarDeclarations() {
    1079     6534902 :   if (has_checked_syntax_) return nullptr;
    1080    26881484 :   for (Declaration* decl : decls_) {
    1081             :     // Lexical vs lexical conflicts within the same scope have already been
    1082             :     // captured in Parser::Declare. The only conflicts we still need to check
    1083             :     // are lexical vs nested var.
    1084    24795263 :     if (decl->IsVariableDeclaration() &&
    1085    11957906 :         decl->AsVariableDeclaration()->AsNested() != nullptr) {
    1086     3184715 :       Scope* current = decl->AsVariableDeclaration()->AsNested()->scope();
    1087             :       DCHECK(decl->var()->mode() == VariableMode::kVar ||
    1088             :              decl->var()->mode() == VariableMode::kDynamic);
    1089             :       // Iterate through all scopes until the declaration scope.
    1090     1327853 :       do {
    1091             :         // There is a conflict if there exists a non-VAR binding.
    1092     1340984 :         if (current->is_catch_scope()) {
    1093             :           current = current->outer_scope();
    1094        2780 :           continue;
    1095             :         }
    1096     1338204 :         Variable* other_var = current->LookupLocal(decl->var()->raw_name());
    1097     1338200 :         if (other_var != nullptr) {
    1098             :           DCHECK(IsLexicalVariableMode(other_var->mode()));
    1099             :           return decl;
    1100             :         }
    1101             :         current = current->outer_scope();
    1102     7674054 :       } while (current != this);
    1103             :     }
    1104             :   }
    1105             : 
    1106     6346201 :   if (V8_LIKELY(!is_eval_scope())) return nullptr;
    1107      854475 :   if (!is_sloppy(language_mode())) return nullptr;
    1108             : 
    1109             :   // Var declarations in sloppy eval are hoisted to the first non-eval
    1110             :   // declaration scope. Check for conflicts between the eval scope that
    1111             :   // declaration scope.
    1112     1454802 :   Scope* end = this;
    1113      727404 :   do {
    1114      727404 :     end = end->outer_scope_->GetDeclarationScope();
    1115             :   } while (end->is_eval_scope());
    1116      727398 :   end = end->outer_scope_;
    1117             : 
    1118     2045173 :   for (Declaration* decl : decls_) {
    1119      601778 :     if (IsLexicalVariableMode(decl->var()->mode())) continue;
    1120      578922 :     Scope* current = outer_scope_;
    1121             :     // Iterate through all scopes until and including the declaration scope.
    1122      289488 :     do {
    1123             :       // There is a conflict if there exists a non-VAR binding up to the
    1124             :       // declaration scope in which this sloppy-eval runs.
    1125         560 :       Variable* other_var =
    1126      289641 :           current->LookupInScopeOrScopeInfo(decl->var()->raw_name());
    1127      290201 :       if (other_var != nullptr && IsLexicalVariableMode(other_var->mode())) {
    1128             :         DCHECK(!current->is_catch_scope());
    1129             :         return decl;
    1130             :       }
    1131             :       current = current->outer_scope();
    1132             :     } while (current != end);
    1133             :   }
    1134             :   return nullptr;
    1135             : }
    1136             : 
    1137       87363 : const AstRawString* Scope::FindVariableDeclaredIn(Scope* scope,
    1138             :                                                   VariableMode mode_limit) {
    1139             :   const VariableMap& variables = scope->variables_;
    1140      573819 :   for (ZoneHashMap::Entry* p = variables.Start(); p != nullptr;
    1141             :        p = variables.Next(p)) {
    1142      399414 :     const AstRawString* name = static_cast<const AstRawString*>(p->key);
    1143        1491 :     Variable* var = LookupLocal(name);
    1144      400908 :     if (var != nullptr && var->mode() <= mode_limit) return name;
    1145             :   }
    1146             :   return nullptr;
    1147             : }
    1148             : 
    1149      778424 : void DeclarationScope::DeserializeReceiver(AstValueFactory* ast_value_factory) {
    1150      778424 :   if (is_script_scope()) {
    1151             :     DCHECK_NOT_NULL(receiver_);
    1152      778424 :     return;
    1153             :   }
    1154             :   DCHECK(has_this_declaration());
    1155      638247 :   DeclareThis(ast_value_factory);
    1156      638247 :   if (is_debug_evaluate_scope()) {
    1157       12169 :     receiver_->AllocateTo(VariableLocation::LOOKUP, -1);
    1158             :   } else {
    1159             :     receiver_->AllocateTo(VariableLocation::CONTEXT,
    1160     1252156 :                           scope_info_->ReceiverContextSlotIndex());
    1161             :   }
    1162             : }
    1163             : 
    1164     1793949 : bool DeclarationScope::AllocateVariables(ParseInfo* info) {
    1165             :   // Module variables must be allocated before variable resolution
    1166             :   // to ensure that UpdateNeedsHoleCheck() can detect import variables.
    1167     1793949 :   if (is_module_scope()) AsModuleScope()->AllocateModuleVariables();
    1168             : 
    1169     1793949 :   if (!ResolveVariablesRecursively(info)) {
    1170             :     DCHECK(info->pending_error_handler()->has_pending_error());
    1171             :     return false;
    1172             :   }
    1173             : 
    1174             :   // // Don't allocate variables of preparsed scopes.
    1175     1793775 :   if (!was_lazily_parsed()) AllocateVariablesRecursively();
    1176             : 
    1177             :   return true;
    1178             : }
    1179             : 
    1180        4183 : bool Scope::HasThisReference() const {
    1181        7610 :   if (is_declaration_scope() && AsDeclarationScope()->has_this_reference()) {
    1182             :     return true;
    1183             :   }
    1184             : 
    1185        4932 :   for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
    1186        4426 :     if (!scope->is_declaration_scope() ||
    1187             :         !scope->AsDeclarationScope()->has_this_declaration()) {
    1188        2368 :       if (scope->HasThisReference()) return true;
    1189             :     }
    1190             :   }
    1191             : 
    1192             :   return false;
    1193             : }
    1194             : 
    1195     4113353 : bool Scope::AllowsLazyParsingWithoutUnresolvedVariables(
    1196             :     const Scope* outer) const {
    1197             :   // If none of the outer scopes need to decide whether to context allocate
    1198             :   // specific variables, we can preparse inner functions without unresolved
    1199             :   // variables. Otherwise we need to find unresolved variables to force context
    1200             :   // allocation of the matching declarations. We can stop at the outer scope for
    1201             :   // the parse, since context allocation of those variables is already
    1202             :   // guaranteed to be correct.
    1203     4113482 :   for (const Scope* s = this; s != outer; s = s->outer_scope_) {
    1204             :     // Eval forces context allocation on all outer scopes, so we don't need to
    1205             :     // look at those scopes. Sloppy eval makes top-level non-lexical variables
    1206             :     // dynamic, whereas strict-mode requires context allocation.
    1207     3086477 :     if (s->is_eval_scope()) return is_sloppy(s->language_mode());
    1208             :     // Catch scopes force context allocation of all variables.
    1209     2075405 :     if (s->is_catch_scope()) continue;
    1210             :     // With scopes do not introduce variables that need allocation.
    1211     2075413 :     if (s->is_with_scope()) continue;
    1212             :     DCHECK(s->is_module_scope() || s->is_block_scope() ||
    1213             :            s->is_function_scope());
    1214             :     return false;
    1215             :   }
    1216             :   return true;
    1217             : }
    1218             : 
    1219     7152304 : bool DeclarationScope::AllowsLazyCompilation() const {
    1220             :   // Functions which force eager compilation and class member initializer
    1221             :   // functions are not lazily compilable.
    1222     7152304 :   return !force_eager_compilation_ &&
    1223     3576899 :          !IsClassMembersInitializerFunction(function_kind());
    1224             : }
    1225             : 
    1226     2699139 : int Scope::ContextChainLength(Scope* scope) const {
    1227             :   int n = 0;
    1228     3405932 :   for (const Scope* s = this; s != scope; s = s->outer_scope_) {
    1229             :     DCHECK_NOT_NULL(s);  // scope must be in the scope chain
    1230      706793 :     if (s->NeedsContext()) n++;
    1231             :   }
    1232     2699139 :   return n;
    1233             : }
    1234             : 
    1235      354324 : int Scope::ContextChainLengthUntilOutermostSloppyEval() const {
    1236             :   int result = 0;
    1237             :   int length = 0;
    1238             : 
    1239     1446674 :   for (const Scope* s = this; s != nullptr; s = s->outer_scope()) {
    1240     1092350 :     if (!s->NeedsContext()) continue;
    1241      793818 :     length++;
    1242     1572851 :     if (s->is_declaration_scope() &&
    1243             :         s->AsDeclarationScope()->calls_sloppy_eval()) {
    1244             :       result = length;
    1245             :     }
    1246             :   }
    1247             : 
    1248      354324 :   return result;
    1249             : }
    1250             : 
    1251    17290071 : DeclarationScope* Scope::GetDeclarationScope() {
    1252     5305022 :   Scope* scope = this;
    1253    41946155 :   while (!scope->is_declaration_scope()) {
    1254             :     scope = scope->outer_scope();
    1255             :   }
    1256    17290071 :   return scope->AsDeclarationScope();
    1257             : }
    1258             : 
    1259           0 : const DeclarationScope* Scope::GetClosureScope() const {
    1260           0 :   const Scope* scope = this;
    1261           0 :   while (!scope->is_declaration_scope() || scope->is_block_scope()) {
    1262             :     scope = scope->outer_scope();
    1263             :   }
    1264           0 :   return scope->AsDeclarationScope();
    1265             : }
    1266             : 
    1267     9319250 : DeclarationScope* Scope::GetClosureScope() {
    1268    19640220 :   Scope* scope = this;
    1269    43276146 :   while (!scope->is_declaration_scope() || scope->is_block_scope()) {
    1270             :     scope = scope->outer_scope();
    1271             :   }
    1272     9319250 :   return scope->AsDeclarationScope();
    1273             : }
    1274             : 
    1275     2384967 : bool Scope::NeedsScopeInfo() const {
    1276             :   DCHECK(!already_resolved_);
    1277             :   DCHECK(GetClosureScope()->ShouldEagerCompile());
    1278             :   // The debugger expects all functions to have scope infos.
    1279             :   // TODO(jochen|yangguo): Remove this requirement.
    1280     2384967 :   if (is_function_scope()) return true;
    1281           0 :   return NeedsContext();
    1282             : }
    1283             : 
    1284       43358 : bool Scope::ShouldBanArguments() {
    1285       43358 :   return GetReceiverScope()->should_ban_arguments();
    1286             : }
    1287             : 
    1288     8789244 : DeclarationScope* Scope::GetReceiverScope() {
    1289     9393770 :   Scope* scope = this;
    1290    36172451 :   while (!scope->is_declaration_scope() ||
    1291     8882146 :          (!scope->is_script_scope() &&
    1292             :           !scope->AsDeclarationScope()->has_this_declaration())) {
    1293             :     scope = scope->outer_scope();
    1294             :   }
    1295     8789244 :   return scope->AsDeclarationScope();
    1296             : }
    1297             : 
    1298     2577042 : Scope* Scope::GetOuterScopeWithContext() {
    1299     3495217 :   Scope* scope = outer_scope_;
    1300     9177822 :   while (scope && !scope->NeedsContext()) {
    1301             :     scope = scope->outer_scope();
    1302             :   }
    1303     2577042 :   return scope;
    1304             : }
    1305             : 
    1306             : namespace {
    1307             : bool WasLazilyParsed(Scope* scope) {
    1308    21463088 :   return scope->is_declaration_scope() &&
    1309             :          scope->AsDeclarationScope()->was_lazily_parsed();
    1310             : }
    1311             : 
    1312             : }  // namespace
    1313             : 
    1314             : template <typename FunctionType>
    1315             : void Scope::ForEach(FunctionType callback) {
    1316             :   Scope* scope = this;
    1317             :   while (true) {
    1318    11814049 :     Iteration iteration = callback(scope);
    1319             :     // Try to descend into inner scopes first.
    1320    11814197 :     if ((iteration == Iteration::kDescend) && scope->inner_scope_ != nullptr) {
    1321             :       scope = scope->inner_scope_;
    1322             :     } else {
    1323             :       // Find the next outer scope with a sibling.
    1324    11814096 :       while (scope->sibling_ == nullptr) {
    1325     5118363 :         if (scope == this) return;
    1326     2943815 :         scope = scope->outer_scope_;
    1327             :       }
    1328     6695733 :       if (scope == this) return;
    1329             :       scope = scope->sibling_;
    1330             :     }
    1331             :   }
    1332             : }
    1333             : 
    1334       12376 : void Scope::CollectNonLocals(DeclarationScope* max_outer_scope,
    1335             :                              Isolate* isolate, ParseInfo* info,
    1336             :                              Handle<StringSet>* non_locals) {
    1337       17604 :   this->ForEach([max_outer_scope, isolate, info, non_locals](Scope* scope) {
    1338             :     // Module variables must be allocated before variable resolution
    1339             :     // to ensure that UpdateNeedsHoleCheck() can detect import variables.
    1340       16855 :     if (scope->is_module_scope()) {
    1341         228 :       scope->AsModuleScope()->AllocateModuleVariables();
    1342             :     }
    1343             : 
    1344             :     // Lazy parsed declaration scopes are already partially analyzed. If there
    1345             :     // are unresolved references remaining, they just need to be resolved in
    1346             :     // outer scopes.
    1347       16855 :     Scope* lookup = WasLazilyParsed(scope) ? scope->outer_scope() : scope;
    1348             : 
    1349       91070 :     for (VariableProxy* proxy : scope->unresolved_list_) {
    1350             :       DCHECK(!proxy->is_resolved());
    1351             :       Variable* var =
    1352       57360 :           Lookup<kParsedScope>(proxy, lookup, max_outer_scope->outer_scope());
    1353       57360 :       if (var == nullptr) {
    1354       16229 :         *non_locals = StringSet::Add(isolate, *non_locals, proxy->name());
    1355             :       } else {
    1356             :         // In this case we need to leave scopes in a way that they can be
    1357             :         // allocated. If we resolved variables from lazy parsed scopes, we need
    1358             :         // to context allocate the var.
    1359             :         scope->ResolveTo(info, proxy, var);
    1360       41131 :         if (!var->is_dynamic() && lookup != scope)
    1361             :           var->ForceContextAllocation();
    1362             :       }
    1363             :     }
    1364             : 
    1365             :     // Clear unresolved_list_ as it's in an inconsistent state.
    1366             :     scope->unresolved_list_.Clear();
    1367       16855 :     return Iteration::kDescend;
    1368             :   });
    1369       12376 : }
    1370             : 
    1371     1858868 : void Scope::AnalyzePartially(DeclarationScope* max_outer_scope,
    1372             :                              AstNodeFactory* ast_node_factory,
    1373             :                              UnresolvedList* new_unresolved_list) {
    1374             :   this->ForEach([max_outer_scope, ast_node_factory,
    1375     3097729 :                  new_unresolved_list](Scope* scope) {
    1376             :     DCHECK_IMPLIES(scope->is_declaration_scope(),
    1377             :                    !scope->AsDeclarationScope()->was_lazily_parsed());
    1378             : 
    1379    41094247 :     for (VariableProxy* proxy = scope->unresolved_list_.first();
    1380             :          proxy != nullptr; proxy = proxy->next_unresolved()) {
    1381             :       DCHECK(!proxy->is_resolved());
    1382             :       Variable* var =
    1383    29007092 :           Lookup<kParsedScope>(proxy, scope, max_outer_scope->outer_scope());
    1384    22334386 :       if (var == nullptr) {
    1385             :         // Don't copy unresolved references to the script scope, unless it's a
    1386             :         // reference to a private name or method. In that case keep it so we
    1387             :         // can fail later.
    1388    13516488 :         if (!max_outer_scope->outer_scope()->is_script_scope() ||
    1389      171567 :             proxy->IsPrivateName()) {
    1390     6503327 :           VariableProxy* copy = ast_node_factory->CopyVariableProxy(proxy);
    1391     6503441 :           new_unresolved_list->Add(copy);
    1392             :         }
    1393             :       } else {
    1394             :         var->set_is_used();
    1395    15661933 :         if (proxy->is_assigned()) var->set_maybe_assigned();
    1396             :       }
    1397             :     }
    1398             : 
    1399             :     // Clear unresolved_list_ as it's in an inconsistent state.
    1400             :     scope->unresolved_list_.Clear();
    1401     3097675 :     return Iteration::kDescend;
    1402             :   });
    1403     1858910 : }
    1404             : 
    1405       12376 : Handle<StringSet> DeclarationScope::CollectNonLocals(
    1406             :     Isolate* isolate, ParseInfo* info, Handle<StringSet> non_locals) {
    1407       12376 :   Scope::CollectNonLocals(this, isolate, info, &non_locals);
    1408       12376 :   return non_locals;
    1409             : }
    1410             : 
    1411     2607355 : void DeclarationScope::ResetAfterPreparsing(AstValueFactory* ast_value_factory,
    1412             :                                             bool aborted) {
    1413             :   DCHECK(is_function_scope());
    1414             : 
    1415             :   // Reset all non-trivial members.
    1416             :   params_.Clear();
    1417             :   decls_.Clear();
    1418             :   locals_.Clear();
    1419     2559260 :   inner_scope_ = nullptr;
    1420             :   unresolved_list_.Clear();
    1421             :   sloppy_block_functions_.Clear();
    1422     2559260 :   rare_data_ = nullptr;
    1423     2559260 :   has_rest_ = false;
    1424             : 
    1425             :   DCHECK_NE(zone_, ast_value_factory->zone());
    1426     2559260 :   zone_->ReleaseMemory();
    1427             : 
    1428     2559642 :   if (aborted) {
    1429             :     // Prepare scope for use in the outer zone.
    1430       48095 :     zone_ = ast_value_factory->zone();
    1431       48095 :     variables_.Reset(ZoneAllocationPolicy(zone_));
    1432       96190 :     if (!IsArrowFunction(function_kind_)) {
    1433       42418 :       has_simple_parameters_ = true;
    1434       42418 :       DeclareDefaultFunctionVariables(ast_value_factory);
    1435             :     }
    1436             :   } else {
    1437             :     // Make sure this scope isn't used for allocation anymore.
    1438     2511547 :     zone_ = nullptr;
    1439             :     variables_.Invalidate();
    1440             :   }
    1441             : 
    1442             : #ifdef DEBUG
    1443             :   needs_migration_ = false;
    1444             :   is_being_lazily_parsed_ = false;
    1445             : #endif
    1446             : 
    1447     2559642 :   was_lazily_parsed_ = !aborted;
    1448     2559642 : }
    1449             : 
    1450     3375835 : bool Scope::IsSkippableFunctionScope() {
    1451             :   // Lazy non-arrow function scopes are skippable. Lazy functions are exactly
    1452             :   // those Scopes which have their own PreparseDataBuilder object. This
    1453             :   // logic ensures that the scope allocation data is consistent with the
    1454             :   // skippable function data (both agree on where the lazy function boundaries
    1455             :   // are).
    1456     3375835 :   if (!is_function_scope()) return false;
    1457     2159098 :   DeclarationScope* declaration_scope = AsDeclarationScope();
    1458     4881720 :   return !declaration_scope->is_arrow_scope() &&
    1459      227073 :          declaration_scope->preparse_data_builder() != nullptr;
    1460             : }
    1461             : 
    1462     1858737 : void Scope::SavePreparseData(Parser* parser) {
    1463     3097361 :   this->ForEach([parser](Scope* scope) {
    1464     3097361 :     if (scope->IsSkippableFunctionScope()) {
    1465     2000633 :       scope->AsDeclarationScope()->SavePreparseDataForDeclarationScope(parser);
    1466             :     }
    1467     3097298 :     return Iteration::kDescend;
    1468             :   });
    1469     1858832 : }
    1470             : 
    1471           0 : void DeclarationScope::SavePreparseDataForDeclarationScope(Parser* parser) {
    1472     2000633 :   if (preparse_data_builder_ == nullptr) return;
    1473     2000648 :   preparse_data_builder_->SaveScopeAllocationData(this, parser);
    1474             : }
    1475             : 
    1476     2450736 : void DeclarationScope::AnalyzePartially(Parser* parser,
    1477     3294875 :                                         AstNodeFactory* ast_node_factory) {
    1478             :   DCHECK(!force_eager_compilation_);
    1479             :   UnresolvedList new_unresolved_list;
    1480     9778791 :   if (!IsArrowFunction(function_kind_) &&
    1481     3055222 :       (!outer_scope_->is_script_scope() ||
    1482     1257039 :        (preparse_data_builder_ != nullptr &&
    1483      628576 :         preparse_data_builder_->HasInnerFunctions()))) {
    1484             :     // Try to resolve unresolved variables for this Scope and migrate those
    1485             :     // which cannot be resolved inside. It doesn't make sense to try to resolve
    1486             :     // them in the outer Scopes here, because they are incomplete.
    1487     1858945 :     Scope::AnalyzePartially(this, ast_node_factory, &new_unresolved_list);
    1488             : 
    1489             :     // Migrate function_ to the right Zone.
    1490     1858912 :     if (function_ != nullptr) {
    1491      844226 :       function_ = ast_node_factory->CopyVariable(function_);
    1492             :     }
    1493             : 
    1494     1858868 :     SavePreparseData(parser);
    1495             :   }
    1496             : 
    1497             : #ifdef DEBUG
    1498             :   if (FLAG_print_scopes) {
    1499             :     PrintF("Inner function scope:\n");
    1500             :     Print();
    1501             :   }
    1502             : #endif
    1503             : 
    1504     2450605 :   ResetAfterPreparsing(ast_node_factory->ast_value_factory(), false);
    1505             : 
    1506             :   unresolved_list_ = std::move(new_unresolved_list);
    1507     2451158 : }
    1508             : 
    1509             : #ifdef DEBUG
    1510             : namespace {
    1511             : 
    1512             : const char* Header(ScopeType scope_type, FunctionKind function_kind,
    1513             :                    bool is_declaration_scope) {
    1514             :   switch (scope_type) {
    1515             :     case EVAL_SCOPE: return "eval";
    1516             :     // TODO(adamk): Should we print concise method scopes specially?
    1517             :     case FUNCTION_SCOPE:
    1518             :       if (IsGeneratorFunction(function_kind)) return "function*";
    1519             :       if (IsAsyncFunction(function_kind)) return "async function";
    1520             :       if (IsArrowFunction(function_kind)) return "arrow";
    1521             :       return "function";
    1522             :     case MODULE_SCOPE: return "module";
    1523             :     case SCRIPT_SCOPE: return "global";
    1524             :     case CATCH_SCOPE: return "catch";
    1525             :     case BLOCK_SCOPE: return is_declaration_scope ? "varblock" : "block";
    1526             :     case WITH_SCOPE: return "with";
    1527             :   }
    1528             :   UNREACHABLE();
    1529             : }
    1530             : 
    1531             : void Indent(int n, const char* str) { PrintF("%*s%s", n, "", str); }
    1532             : 
    1533             : void PrintName(const AstRawString* name) {
    1534             :   PrintF("%.*s", name->length(), name->raw_data());
    1535             : }
    1536             : 
    1537             : void PrintLocation(Variable* var) {
    1538             :   switch (var->location()) {
    1539             :     case VariableLocation::UNALLOCATED:
    1540             :       break;
    1541             :     case VariableLocation::PARAMETER:
    1542             :       PrintF("parameter[%d]", var->index());
    1543             :       break;
    1544             :     case VariableLocation::LOCAL:
    1545             :       PrintF("local[%d]", var->index());
    1546             :       break;
    1547             :     case VariableLocation::CONTEXT:
    1548             :       PrintF("context[%d]", var->index());
    1549             :       break;
    1550             :     case VariableLocation::LOOKUP:
    1551             :       PrintF("lookup");
    1552             :       break;
    1553             :     case VariableLocation::MODULE:
    1554             :       PrintF("module");
    1555             :       break;
    1556             :   }
    1557             : }
    1558             : 
    1559             : void PrintVar(int indent, Variable* var) {
    1560             :   Indent(indent, VariableMode2String(var->mode()));
    1561             :   PrintF(" ");
    1562             :   if (var->raw_name()->IsEmpty())
    1563             :     PrintF(".%p", reinterpret_cast<void*>(var));
    1564             :   else
    1565             :     PrintName(var->raw_name());
    1566             :   PrintF(";  // (%p) ", reinterpret_cast<void*>(var));
    1567             :   PrintLocation(var);
    1568             :   bool comma = !var->IsUnallocated();
    1569             :   if (var->has_forced_context_allocation()) {
    1570             :     if (comma) PrintF(", ");
    1571             :     PrintF("forced context allocation");
    1572             :     comma = true;
    1573             :   }
    1574             :   if (var->maybe_assigned() == kNotAssigned) {
    1575             :     if (comma) PrintF(", ");
    1576             :     PrintF("never assigned");
    1577             :     comma = true;
    1578             :   }
    1579             :   if (var->initialization_flag() == kNeedsInitialization &&
    1580             :       !var->binding_needs_init()) {
    1581             :     if (comma) PrintF(", ");
    1582             :     PrintF("hole initialization elided");
    1583             :   }
    1584             :   PrintF("\n");
    1585             : }
    1586             : 
    1587             : void PrintMap(int indent, const char* label, VariableMap* map, bool locals,
    1588             :               Variable* function_var) {
    1589             :   bool printed_label = false;
    1590             :   for (VariableMap::Entry* p = map->Start(); p != nullptr; p = map->Next(p)) {
    1591             :     Variable* var = reinterpret_cast<Variable*>(p->value);
    1592             :     if (var == function_var) continue;
    1593             :     bool local = !IsDynamicVariableMode(var->mode());
    1594             :     if ((locals ? local : !local) &&
    1595             :         (var->is_used() || !var->IsUnallocated())) {
    1596             :       if (!printed_label) {
    1597             :         Indent(indent, label);
    1598             :         printed_label = true;
    1599             :       }
    1600             :       PrintVar(indent, var);
    1601             :     }
    1602             :   }
    1603             : }
    1604             : 
    1605             : }  // anonymous namespace
    1606             : 
    1607             : void DeclarationScope::PrintParameters() {
    1608             :   PrintF(" (");
    1609             :   for (int i = 0; i < params_.length(); i++) {
    1610             :     if (i > 0) PrintF(", ");
    1611             :     const AstRawString* name = params_[i]->raw_name();
    1612             :     if (name->IsEmpty()) {
    1613             :       PrintF(".%p", reinterpret_cast<void*>(params_[i]));
    1614             :     } else {
    1615             :       PrintName(name);
    1616             :     }
    1617             :   }
    1618             :   PrintF(")");
    1619             : }
    1620             : 
    1621             : void Scope::Print(int n) {
    1622             :   int n0 = (n > 0 ? n : 0);
    1623             :   int n1 = n0 + 2;  // indentation
    1624             : 
    1625             :   // Print header.
    1626             :   FunctionKind function_kind = is_function_scope()
    1627             :                                    ? AsDeclarationScope()->function_kind()
    1628             :                                    : kNormalFunction;
    1629             :   Indent(n0, Header(scope_type_, function_kind, is_declaration_scope()));
    1630             :   if (scope_name_ != nullptr && !scope_name_->IsEmpty()) {
    1631             :     PrintF(" ");
    1632             :     PrintName(scope_name_);
    1633             :   }
    1634             : 
    1635             :   // Print parameters, if any.
    1636             :   Variable* function = nullptr;
    1637             :   if (is_function_scope()) {
    1638             :     AsDeclarationScope()->PrintParameters();
    1639             :     function = AsDeclarationScope()->function_var();
    1640             :   }
    1641             : 
    1642             :   PrintF(" { // (%p) (%d, %d)\n", reinterpret_cast<void*>(this),
    1643             :          start_position(), end_position());
    1644             :   if (is_hidden()) {
    1645             :     Indent(n1, "// is hidden\n");
    1646             :   }
    1647             : 
    1648             :   // Function name, if any (named function literals, only).
    1649             :   if (function != nullptr) {
    1650             :     Indent(n1, "// (local) function name: ");
    1651             :     PrintName(function->raw_name());
    1652             :     PrintF("\n");
    1653             :   }
    1654             : 
    1655             :   // Scope info.
    1656             :   if (is_strict(language_mode())) {
    1657             :     Indent(n1, "// strict mode scope\n");
    1658             :   }
    1659             :   if (IsAsmModule()) Indent(n1, "// scope is an asm module\n");
    1660             :   if (is_declaration_scope() && AsDeclarationScope()->calls_sloppy_eval()) {
    1661             :     Indent(n1, "// scope calls sloppy 'eval'\n");
    1662             :   }
    1663             :   if (is_declaration_scope() && AsDeclarationScope()->NeedsHomeObject()) {
    1664             :     Indent(n1, "// scope needs home object\n");
    1665             :   }
    1666             :   if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n");
    1667             :   if (is_declaration_scope()) {
    1668             :     DeclarationScope* scope = AsDeclarationScope();
    1669             :     if (scope->was_lazily_parsed()) Indent(n1, "// lazily parsed\n");
    1670             :     if (scope->ShouldEagerCompile()) Indent(n1, "// will be compiled\n");
    1671             :   }
    1672             :   if (num_stack_slots_ > 0) {
    1673             :     Indent(n1, "// ");
    1674             :     PrintF("%d stack slots\n", num_stack_slots_);
    1675             :   }
    1676             :   if (num_heap_slots_ > 0) {
    1677             :     Indent(n1, "// ");
    1678             :     PrintF("%d heap slots\n", num_heap_slots_);
    1679             :   }
    1680             : 
    1681             :   // Print locals.
    1682             :   if (function != nullptr) {
    1683             :     Indent(n1, "// function var:\n");
    1684             :     PrintVar(n1, function);
    1685             :   }
    1686             : 
    1687             :   // Print temporaries.
    1688             :   {
    1689             :     bool printed_header = false;
    1690             :     for (Variable* local : locals_) {
    1691             :       if (local->mode() != VariableMode::kTemporary) continue;
    1692             :       if (!printed_header) {
    1693             :         printed_header = true;
    1694             :         Indent(n1, "// temporary vars:\n");
    1695             :       }
    1696             :       PrintVar(n1, local);
    1697             :     }
    1698             :   }
    1699             : 
    1700             :   if (variables_.occupancy() > 0) {
    1701             :     PrintMap(n1, "// local vars:\n", &variables_, true, function);
    1702             :     PrintMap(n1, "// dynamic vars:\n", &variables_, false, function);
    1703             :   }
    1704             : 
    1705             :   // Print inner scopes (disable by providing negative n).
    1706             :   if (n >= 0) {
    1707             :     for (Scope* scope = inner_scope_; scope != nullptr;
    1708             :          scope = scope->sibling_) {
    1709             :       PrintF("\n");
    1710             :       scope->Print(n1);
    1711             :     }
    1712             :   }
    1713             : 
    1714             :   Indent(n0, "}\n");
    1715             : }
    1716             : 
    1717             : void Scope::CheckScopePositions() {
    1718             :   this->ForEach([](Scope* scope) {
    1719             :     // Visible leaf scopes must have real positions.
    1720             :     if (!scope->is_hidden() && scope->inner_scope_ == nullptr) {
    1721             :       DCHECK_NE(kNoSourcePosition, scope->start_position());
    1722             :       DCHECK_NE(kNoSourcePosition, scope->end_position());
    1723             :     }
    1724             :     return Iteration::kDescend;
    1725             :   });
    1726             : }
    1727             : 
    1728             : void Scope::CheckZones() {
    1729             :   DCHECK(!needs_migration_);
    1730             :   this->ForEach([](Scope* scope) {
    1731             :     if (WasLazilyParsed(scope)) {
    1732             :       DCHECK_NULL(scope->zone());
    1733             :       DCHECK_NULL(scope->inner_scope_);
    1734             :       return Iteration::kContinue;
    1735             :     }
    1736             :     return Iteration::kDescend;
    1737             :   });
    1738             : }
    1739             : #endif  // DEBUG
    1740             : 
    1741      725622 : Variable* Scope::NonLocal(const AstRawString* name, VariableMode mode) {
    1742             :   // Declare a new non-local.
    1743             :   DCHECK(IsDynamicVariableMode(mode));
    1744             :   bool was_added;
    1745             :   Variable* var =
    1746             :       variables_.Declare(zone(), this, name, mode, NORMAL_VARIABLE,
    1747      725622 :                          kCreatedInitialized, kNotAssigned, &was_added);
    1748             :   // Allocate it by giving it a dynamic lookup.
    1749             :   var->AllocateTo(VariableLocation::LOOKUP, -1);
    1750      725618 :   return var;
    1751             : }
    1752             : 
    1753             : // static
    1754             : template <Scope::ScopeLookupMode mode>
    1755    43910408 : Variable* Scope::Lookup(VariableProxy* proxy, Scope* scope,
    1756             :                         Scope* outer_scope_end, Scope* entry_point,
    1757             :                         bool force_context_allocation) {
    1758             :   if (mode == kDeserializedScope) {
    1759     2068071 :     Variable* var = entry_point->variables_.Lookup(proxy->raw_name());
    1760     2068072 :     if (var != nullptr) return var;
    1761             :   }
    1762             : 
    1763             :   while (true) {
    1764             :     DCHECK_IMPLIES(mode == kParsedScope, !scope->is_debug_evaluate_scope_);
    1765             :     // Short-cut: whenever we find a debug-evaluate scope, just look everything
    1766             :     // up dynamically. Debug-evaluate doesn't properly create scope info for the
    1767             :     // lookups it does. It may not have a valid 'this' declaration, and anything
    1768             :     // accessed through debug-evaluate might invalidly resolve to
    1769             :     // stack-allocated variables.
    1770             :     // TODO(yangguo): Remove once debug-evaluate creates proper ScopeInfo for
    1771             :     // the scopes in which it's evaluating.
    1772     2180751 :     if (mode == kDeserializedScope &&
    1773     2180751 :         V8_UNLIKELY(scope->is_debug_evaluate_scope_)) {
    1774       10672 :       return entry_point->NonLocal(proxy->raw_name(), VariableMode::kDynamic);
    1775             :     }
    1776             : 
    1777             :     // Try to find the variable in this scope.
    1778             :     Variable* var = mode == kParsedScope ? scope->LookupLocal(proxy->raw_name())
    1779             :                                          : scope->LookupInScopeInfo(
    1780     2170079 :                                                proxy->raw_name(), entry_point);
    1781             : 
    1782             :     // We found a variable and we are done. (Even if there is an 'eval' in this
    1783             :     // scope which introduces the same variable again, the resulting variable
    1784             :     // remains the same.)
    1785    60132591 :     if (var != nullptr) {
    1786    38728764 :       if (mode == kParsedScope && force_context_allocation &&
    1787             :           !var->is_dynamic()) {
    1788             :         var->ForceContextAllocation();
    1789             :       }
    1790    31511643 :       return var;
    1791             :     }
    1792             : 
    1793    28172797 :     if (scope->outer_scope_ == outer_scope_end) break;
    1794             : 
    1795             :     DCHECK(!scope->is_script_scope());
    1796    19519986 :     if (V8_UNLIKELY(scope->is_with_scope())) {
    1797             :       return LookupWith(proxy, scope, outer_scope_end, entry_point,
    1798       46205 :                         force_context_allocation);
    1799             :     }
    1800    34963351 :     if (V8_UNLIKELY(scope->is_declaration_scope() &&
    1801             :                     scope->AsDeclarationScope()->calls_sloppy_eval())) {
    1802             :       return LookupSloppyEval(proxy, scope, outer_scope_end, entry_point,
    1803      385962 :                               force_context_allocation);
    1804             :     }
    1805             : 
    1806    19087819 :     force_context_allocation |= scope->is_function_scope();
    1807             :     scope = scope->outer_scope_;
    1808             :     // TODO(verwaest): Separate through AnalyzePartially.
    1809    18619374 :     if (mode == kParsedScope && !scope->scope_info_.is_null()) {
    1810     1748881 :       return Lookup<kDeserializedScope>(proxy, scope, outer_scope_end, scope);
    1811             :     }
    1812             :   }
    1813             : 
    1814             :   // We may just be trying to find all free variables. In that case, don't
    1815             :   // declare them in the outer scope.
    1816             :   // TODO(marja): Separate Lookup for preparsed scopes better.
    1817     7690495 :   if (mode == kParsedScope && !scope->is_script_scope()) {
    1818             :     return nullptr;
    1819             :   }
    1820     1961868 :   if (V8_UNLIKELY(proxy->IsPrivateName())) return nullptr;
    1821             : 
    1822             :   // No binding has been found. Declare a variable on the global object.
    1823             :   return scope->AsDeclarationScope()->DeclareDynamicGlobal(
    1824             :       proxy->raw_name(), NORMAL_VARIABLE,
    1825     2430179 :       mode == kDeserializedScope ? entry_point : scope);
    1826             : }
    1827             : 
    1828             : template Variable* Scope::Lookup<Scope::kParsedScope>(
    1829             :     VariableProxy* proxy, Scope* scope, Scope* outer_scope_end,
    1830             :     Scope* entry_point, bool force_context_allocation);
    1831             : template Variable* Scope::Lookup<Scope::kDeserializedScope>(
    1832             :     VariableProxy* proxy, Scope* scope, Scope* outer_scope_end,
    1833             :     Scope* entry_point, bool force_context_allocation);
    1834             : 
    1835       58053 : Variable* Scope::LookupWith(VariableProxy* proxy, Scope* scope,
    1836             :                             Scope* outer_scope_end, Scope* entry_point,
    1837             :                             bool force_context_allocation) {
    1838             :   DCHECK(scope->is_with_scope());
    1839             : 
    1840             :   Variable* var =
    1841       46204 :       scope->outer_scope_->scope_info_.is_null()
    1842             :           ? Lookup<kParsedScope>(proxy, scope->outer_scope_, outer_scope_end,
    1843       44573 :                                  nullptr, force_context_allocation)
    1844             :           : Lookup<kDeserializedScope>(proxy, scope->outer_scope_,
    1845       90777 :                                        outer_scope_end, entry_point);
    1846             : 
    1847       46204 :   if (var == nullptr) return var;
    1848             : 
    1849             :   // The current scope is a with scope, so the variable binding can not be
    1850             :   // statically resolved. However, note that it was necessary to do a lookup
    1851             :   // in the outer scope anyway, because if a binding exists in an outer
    1852             :   // scope, the associated variable has to be marked as potentially being
    1853             :   // accessed from inside of an inner with scope (the property may not be in
    1854             :   // the 'with' object).
    1855       41052 :   if (!var->is_dynamic() && var->IsUnallocated()) {
    1856             :     DCHECK(!scope->already_resolved_);
    1857             :     var->set_is_used();
    1858             :     var->ForceContextAllocation();
    1859       11849 :     if (proxy->is_assigned()) var->set_maybe_assigned();
    1860             :   }
    1861       28958 :   if (entry_point != nullptr) entry_point->variables_.Remove(var);
    1862       28958 :   Scope* target = entry_point == nullptr ? scope : entry_point;
    1863       28958 :   return target->NonLocal(proxy->raw_name(), VariableMode::kDynamic);
    1864             : }
    1865             : 
    1866      385962 : Variable* Scope::LookupSloppyEval(VariableProxy* proxy, Scope* scope,
    1867             :                                   Scope* outer_scope_end, Scope* entry_point,
    1868             :                                   bool force_context_allocation) {
    1869             :   DCHECK(scope->is_declaration_scope() &&
    1870             :          scope->AsDeclarationScope()->calls_sloppy_eval());
    1871             : 
    1872             :   // If we're compiling eval, it's possible that the outer scope is the first
    1873             :   // ScopeInfo-backed scope.
    1874      385962 :   Scope* entry = entry_point == nullptr ? scope->outer_scope_ : entry_point;
    1875             :   Variable* var =
    1876      385962 :       scope->outer_scope_->scope_info_.is_null()
    1877             :           ? Lookup<kParsedScope>(proxy, scope->outer_scope_, outer_scope_end,
    1878       68401 :                                  nullptr, force_context_allocation)
    1879             :           : Lookup<kDeserializedScope>(proxy, scope->outer_scope_,
    1880      454363 :                                        outer_scope_end, entry);
    1881      385962 :   if (var == nullptr) return var;
    1882             : 
    1883             :   // A variable binding may have been found in an outer scope, but the current
    1884             :   // scope makes a sloppy 'eval' call, so the found variable may not be the
    1885             :   // correct one (the 'eval' may introduce a binding with the same name). In
    1886             :   // that case, change the lookup result to reflect this situation. Only
    1887             :   // scopes that can host var bindings (declaration scopes) need be considered
    1888             :   // here (this excludes block and catch scopes), and variable lookups at
    1889             :   // script scope are always dynamic.
    1890      379614 :   if (var->IsGlobalObjectProperty()) {
    1891      373237 :     Scope* target = entry_point == nullptr ? scope : entry_point;
    1892      373237 :     return target->NonLocal(proxy->raw_name(), VariableMode::kDynamicGlobal);
    1893             :   }
    1894             : 
    1895        6377 :   if (var->is_dynamic()) return var;
    1896             : 
    1897             :   Variable* invalidated = var;
    1898        4426 :   if (entry_point != nullptr) entry_point->variables_.Remove(invalidated);
    1899             : 
    1900        4426 :   Scope* target = entry_point == nullptr ? scope : entry_point;
    1901        4426 :   var = target->NonLocal(proxy->raw_name(), VariableMode::kDynamicLocal);
    1902             :   var->set_local_if_not_shadowed(invalidated);
    1903             : 
    1904        4426 :   return var;
    1905             : }
    1906             : 
    1907    18585288 : bool Scope::ResolveVariable(ParseInfo* info, VariableProxy* proxy) {
    1908             :   DCHECK(info->script_scope()->is_script_scope());
    1909             :   DCHECK(!proxy->is_resolved());
    1910    18585288 :   Variable* var = Lookup<kParsedScope>(proxy, this, nullptr);
    1911    18585308 :   if (var == nullptr) {
    1912             :     DCHECK(proxy->IsPrivateName());
    1913             :     info->pending_error_handler()->ReportMessageAt(
    1914         133 :         proxy->position(), proxy->position() + 1,
    1915             :         MessageTemplate::kInvalidPrivateFieldResolution, proxy->raw_name(),
    1916         133 :         kSyntaxError);
    1917         133 :     return false;
    1918             :   }
    1919             :   ResolveTo(info, proxy, var);
    1920    18585194 :   return true;
    1921             : }
    1922             : 
    1923             : namespace {
    1924             : 
    1925             : void SetNeedsHoleCheck(Variable* var, VariableProxy* proxy) {
    1926             :   proxy->set_needs_hole_check();
    1927             :   var->ForceHoleInitialization();
    1928             : }
    1929             : 
    1930    20993282 : void UpdateNeedsHoleCheck(Variable* var, VariableProxy* proxy, Scope* scope) {
    1931    18630121 :   if (var->mode() == VariableMode::kDynamicLocal) {
    1932             :     // Dynamically introduced variables never need a hole check (since they're
    1933             :     // VariableMode::kVar bindings, either from var or function declarations),
    1934             :     // but the variable they shadow might need a hole check, which we want to do
    1935             :     // if we decide that no shadowing variable was dynamically introoduced.
    1936             :     DCHECK_EQ(kCreatedInitialized, var->initialization_flag());
    1937        3761 :     return UpdateNeedsHoleCheck(var->local_if_not_shadowed(), proxy, scope);
    1938             :   }
    1939             : 
    1940    18626360 :   if (var->initialization_flag() == kCreatedInitialized) return;
    1941             : 
    1942             :   // It's impossible to eliminate module import hole checks here, because it's
    1943             :   // unknown at compilation time whether the binding referred to in the
    1944             :   // exporting module itself requires hole checks.
    1945     1478756 :   if (var->location() == VariableLocation::MODULE && !var->IsExport()) {
    1946             :     return SetNeedsHoleCheck(var, proxy);
    1947             :   }
    1948             : 
    1949             :   // Check if the binding really needs an initialization check. The check
    1950             :   // can be skipped in the following situation: we have a VariableMode::kLet or
    1951             :   // VariableMode::kConst binding, both the Variable and the VariableProxy have
    1952             :   // the same declaration scope (i.e. they are both in global code, in the same
    1953             :   // function or in the same eval code), the VariableProxy is in the source
    1954             :   // physically located after the initializer of the variable, and that the
    1955             :   // initializer cannot be skipped due to a nonlinear scope.
    1956             :   //
    1957             :   // The condition on the closure scopes is a conservative check for
    1958             :   // nested functions that access a binding and are called before the
    1959             :   // binding is initialized:
    1960             :   //   function() { f(); let x = 1; function f() { x = 2; } }
    1961             :   //
    1962             :   // The check cannot be skipped on non-linear scopes, namely switch
    1963             :   // scopes, to ensure tests are done in cases like the following:
    1964             :   //   switch (1) { case 0: let x = 2; case 1: f(x); }
    1965             :   // The scope of the variable needs to be checked, in case the use is
    1966             :   // in a sub-block which may be linear.
    1967     1475360 :   if (var->scope()->GetClosureScope() != scope->GetClosureScope()) {
    1968             :     return SetNeedsHoleCheck(var, proxy);
    1969             :   }
    1970             : 
    1971             :   // We should always have valid source positions.
    1972             :   DCHECK_NE(var->initializer_position(), kNoSourcePosition);
    1973             :   DCHECK_NE(proxy->position(), kNoSourcePosition);
    1974             : 
    1975     1775713 :   if (var->scope()->is_nonlinear() ||
    1976      887801 :       var->initializer_position() >= proxy->position()) {
    1977             :     return SetNeedsHoleCheck(var, proxy);
    1978             :   }
    1979             : }
    1980             : 
    1981             : }  // anonymous namespace
    1982             : 
    1983           0 : void Scope::ResolveTo(ParseInfo* info, VariableProxy* proxy, Variable* var) {
    1984             : #ifdef DEBUG
    1985             :   if (info->is_native()) {
    1986             :     // To avoid polluting the global object in native scripts
    1987             :     //  - Variables must not be allocated to the global scope.
    1988             :     DCHECK_NOT_NULL(outer_scope());
    1989             :     //  - Variables must be bound locally or unallocated.
    1990             :     if (var->IsGlobalObjectProperty()) {
    1991             :       // The following variable name may be minified. If so, disable
    1992             :       // minification in js2c.py for better output.
    1993             :       Handle<String> name = proxy->raw_name()->string();
    1994             :       FATAL("Unbound variable: '%s' in native script.",
    1995             :             name->ToCString().get());
    1996             :     }
    1997             :     VariableLocation location = var->location();
    1998             :     DCHECK(location == VariableLocation::LOCAL ||
    1999             :            location == VariableLocation::CONTEXT ||
    2000             :            location == VariableLocation::PARAMETER ||
    2001             :            location == VariableLocation::UNALLOCATED);
    2002             :   }
    2003             : #endif
    2004             : 
    2005             :   DCHECK_NOT_NULL(var);
    2006    18626306 :   UpdateNeedsHoleCheck(var, proxy, this);
    2007    18626485 :   proxy->BindTo(var);
    2008           0 : }
    2009             : 
    2010     8726545 : bool Scope::ResolvePreparsedVariable(VariableProxy* proxy, Scope* scope,
    2011             :                                      Scope* end) {
    2012             :   // Resolve the variable in all parsed scopes to force context allocation.
    2013    10788059 :   for (; scope != end; scope = scope->outer_scope_) {
    2014             :     Variable* var = scope->LookupLocal(proxy->raw_name());
    2015     6517317 :     if (var != nullptr) {
    2016             :       var->set_is_used();
    2017     2228726 :       if (!var->is_dynamic()) {
    2018             :         var->ForceContextAllocation();
    2019     2227031 :         if (proxy->is_assigned()) var->set_maybe_assigned();
    2020             :       }
    2021             :       return true;
    2022             :     }
    2023             :   }
    2024             : 
    2025     4271781 :   if (!proxy->IsPrivateName()) return true;
    2026             : 
    2027             :   // If we're resolving a private name, throw an exception of we didn't manage
    2028             :   // to resolve. In case of eval, also look in all outer scope-info backed
    2029             :   // scopes except for the script scope. Don't throw an exception if a reference
    2030             :   // was found.
    2031             :   Scope* start = scope;
    2032          46 :   for (; !scope->is_script_scope(); scope = scope->outer_scope_) {
    2033           0 :     if (scope->LookupInScopeInfo(proxy->raw_name(), start) != nullptr) {
    2034             :       return true;
    2035             :     }
    2036             :   }
    2037             : 
    2038             :   return false;
    2039             : }
    2040             : 
    2041    12101800 : bool Scope::ResolveVariablesRecursively(ParseInfo* info) {
    2042             :   DCHECK(info->script_scope()->is_script_scope());
    2043             :   // Lazy parsed declaration scopes are already partially analyzed. If there are
    2044             :   // unresolved references remaining, they just need to be resolved in outer
    2045             :   // scopes.
    2046     5602385 :   if (WasLazilyParsed(this)) {
    2047             :     DCHECK_EQ(variables_.occupancy(), 0);
    2048     2669713 :     Scope* end = info->scope();
    2049             :     // Resolve in all parsed scopes except for the script scope.
    2050     2420521 :     if (!end->is_script_scope()) end = end->outer_scope();
    2051             : 
    2052    11340405 :     for (VariableProxy* proxy : unresolved_list_) {
    2053     6499415 :       if (!ResolvePreparsedVariable(proxy, outer_scope(), end)) {
    2054             :         info->pending_error_handler()->ReportMessageAt(
    2055          46 :             proxy->position(), proxy->position() + 1,
    2056             :             MessageTemplate::kInvalidPrivateFieldResolution, proxy->raw_name(),
    2057          46 :             kSyntaxError);
    2058             :         DCHECK(proxy->IsPrivateName());
    2059             :         return false;
    2060             :       }
    2061             :     }
    2062             :   } else {
    2063             :     // Resolve unresolved variables for this scope.
    2064    24948934 :     for (VariableProxy* proxy : unresolved_list_) {
    2065    18585385 :       if (!ResolveVariable(info, proxy)) return false;
    2066             :     }
    2067             : 
    2068             :     // Resolve unresolved variables for inner scopes.
    2069     6989914 :     for (Scope* scope = inner_scope_; scope != nullptr;
    2070             :          scope = scope->sibling_) {
    2071     3808375 :       if (!scope->ResolveVariablesRecursively(info)) return false;
    2072             :     }
    2073             :   }
    2074             :   return true;
    2075             : }
    2076             : 
    2077    51827126 : bool Scope::MustAllocate(Variable* var) {
    2078             :   DCHECK(var->location() != VariableLocation::MODULE);
    2079             :   // Give var a read/write use if there is a chance it might be accessed
    2080             :   // via an eval() call.  This is only possible if the variable has a
    2081             :   // visible name.
    2082    37631452 :   if (!var->raw_name()->IsEmpty() &&
    2083    15970188 :       (inner_scope_calls_eval_ || is_catch_scope() || is_script_scope())) {
    2084             :     var->set_is_used();
    2085     4060761 :     if (inner_scope_calls_eval_) var->set_maybe_assigned();
    2086             :   }
    2087             :   DCHECK(!var->has_forced_context_allocation() || var->is_used());
    2088             :   // Global variables do not need to be allocated.
    2089    35856938 :   return !var->IsGlobalObjectProperty() && var->is_used();
    2090             : }
    2091             : 
    2092             : 
    2093    20904858 : bool Scope::MustAllocateInContext(Variable* var) {
    2094             :   // If var is accessed from an inner scope, or if there is a possibility
    2095             :   // that it might be accessed from the current or an inner scope (through
    2096             :   // an eval() call or a runtime with lookup), it must be allocated in the
    2097             :   // context.
    2098             :   //
    2099             :   // Temporary variables are always stack-allocated.  Catch-bound variables are
    2100             :   // always context-allocated.
    2101    11075517 :   if (var->mode() == VariableMode::kTemporary) return false;
    2102     9829341 :   if (is_catch_scope()) return true;
    2103     9733583 :   if ((is_script_scope() || is_eval_scope()) &&
    2104             :       IsLexicalVariableMode(var->mode())) {
    2105             :     return true;
    2106             :   }
    2107     9136333 :   return var->has_forced_context_allocation() || inner_scope_calls_eval_;
    2108             : }
    2109             : 
    2110             : 
    2111     6687446 : void Scope::AllocateStackSlot(Variable* var) {
    2112     6687446 :   if (is_block_scope()) {
    2113      371434 :     outer_scope()->GetDeclarationScope()->AllocateStackSlot(var);
    2114             :   } else {
    2115     6316012 :     var->AllocateTo(VariableLocation::LOCAL, num_stack_slots_++);
    2116             :   }
    2117     6316012 : }
    2118             : 
    2119             : 
    2120             : void Scope::AllocateHeapSlot(Variable* var) {
    2121     2260024 :   var->AllocateTo(VariableLocation::CONTEXT, num_heap_slots_++);
    2122             : }
    2123             : 
    2124     1584482 : void DeclarationScope::AllocateParameterLocals() {
    2125             :   DCHECK(is_function_scope());
    2126             : 
    2127             :   bool has_mapped_arguments = false;
    2128     1584481 :   if (arguments_ != nullptr) {
    2129             :     DCHECK(!is_arrow_scope());
    2130     1064694 :     if (MustAllocate(arguments_) && !has_arguments_parameter_) {
    2131             :       // 'arguments' is used and does not refer to a function
    2132             :       // parameter of the same name. If the arguments object
    2133             :       // aliases formal parameters, we conservatively allocate
    2134             :       // them specially in the loop below.
    2135             :       has_mapped_arguments =
    2136      115248 :           GetArgumentsType() == CreateArgumentsType::kMappedArguments;
    2137             :     } else {
    2138             :       // 'arguments' is unused. Tell the code generator that it does not need to
    2139             :       // allocate the arguments object by nulling out arguments_.
    2140      949447 :       arguments_ = nullptr;
    2141             :     }
    2142             :   }
    2143             : 
    2144             :   // The same parameter may occur multiple times in the parameters_ list.
    2145             :   // If it does, and if it is not copied into the context object, it must
    2146             :   // receive the highest parameter index for that parameter; thus iteration
    2147             :   // order is relevant!
    2148     4052330 :   for (int i = num_parameters() - 1; i >= 0; --i) {
    2149     2467845 :     Variable* var = params_[i];
    2150             :     DCHECK_NOT_NULL(var);
    2151             :     DCHECK(!has_rest_ || var != rest_parameter());
    2152             :     DCHECK_EQ(this, var->scope());
    2153     2467848 :     if (has_mapped_arguments) {
    2154       18108 :       var->set_is_used();
    2155       18108 :       var->set_maybe_assigned();
    2156       18108 :       var->ForceContextAllocation();
    2157             :     }
    2158             :     AllocateParameter(var, i);
    2159             :   }
    2160             : }
    2161             : 
    2162             : void DeclarationScope::AllocateParameter(Variable* var, int index) {
    2163     3585608 :   if (!MustAllocate(var)) return;
    2164     5329710 :   if (has_forced_context_allocation_for_parameters() ||
    2165     2664852 :       MustAllocateInContext(var)) {
    2166             :     DCHECK(var->IsUnallocated() || var->IsContextSlot());
    2167      162252 :     if (var->IsUnallocated()) AllocateHeapSlot(var);
    2168             :   } else {
    2169             :     DCHECK(var->IsUnallocated() || var->IsParameter());
    2170     2502606 :     if (var->IsUnallocated()) {
    2171     2498070 :       var->AllocateTo(VariableLocation::PARAMETER, index);
    2172             :     }
    2173             :   }
    2174             : }
    2175             : 
    2176     1117755 : void DeclarationScope::AllocateReceiver() {
    2177     2692757 :   if (!has_this_declaration()) return;
    2178             :   DCHECK_NOT_NULL(receiver());
    2179             :   DCHECK_EQ(receiver()->scope(), this);
    2180     1117755 :   AllocateParameter(receiver(), -1);
    2181             : }
    2182             : 
    2183    15269788 : void Scope::AllocateNonParameterLocal(Variable* var) {
    2184             :   DCHECK_EQ(var->scope(), this);
    2185    15269788 :   if (var->IsUnallocated() && MustAllocate(var)) {
    2186     8408615 :     if (MustAllocateInContext(var)) {
    2187             :       AllocateHeapSlot(var);
    2188             :       DCHECK_IMPLIES(is_catch_scope(),
    2189             :                      var->index() == Context::THROWN_OBJECT_INDEX);
    2190             :     } else {
    2191     6316015 :       AllocateStackSlot(var);
    2192             :     }
    2193             :   }
    2194    15269836 : }
    2195             : 
    2196             : void Scope::AllocateNonParameterLocalsAndDeclaredGlobals() {
    2197    18429262 :   for (Variable* local : locals_) {
    2198    15247694 :     AllocateNonParameterLocal(local);
    2199             :   }
    2200             : 
    2201     3181570 :   if (is_declaration_scope()) {
    2202     2692767 :     AsDeclarationScope()->AllocateLocals();
    2203             :   }
    2204             : }
    2205             : 
    2206     2692774 : void DeclarationScope::AllocateLocals() {
    2207             :   // For now, function_ must be allocated at the very end.  If it gets
    2208             :   // allocated in the context, it must be the last slot in the context,
    2209             :   // because of the current ScopeInfo implementation (see
    2210             :   // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor).
    2211     2692761 :   if (function_ != nullptr && MustAllocate(function_)) {
    2212       22117 :     AllocateNonParameterLocal(function_);
    2213             :   } else {
    2214     2670643 :     function_ = nullptr;
    2215             :   }
    2216             : 
    2217             :   DCHECK(!has_rest_ || !MustAllocate(rest_parameter()) ||
    2218             :          !rest_parameter()->IsUnallocated());
    2219             : 
    2220     2692772 :   if (new_target_ != nullptr && !MustAllocate(new_target_)) {
    2221      987629 :     new_target_ = nullptr;
    2222             :   }
    2223             : 
    2224             :   NullifyRareVariableIf(RareVariable::kThisFunction,
    2225      164450 :                         [=](Variable* var) { return !MustAllocate(var); });
    2226             : }
    2227             : 
    2228       18230 : void ModuleScope::AllocateModuleVariables() {
    2229       19436 :   for (const auto& it : module()->regular_imports()) {
    2230        1206 :     Variable* var = LookupLocal(it.first);
    2231        1206 :     var->AllocateTo(VariableLocation::MODULE, it.second->cell_index);
    2232             :     DCHECK(!var->IsExport());
    2233             :   }
    2234             : 
    2235       36950 :   for (const auto& it : module()->regular_exports()) {
    2236       18720 :     Variable* var = LookupLocal(it.first);
    2237       18720 :     var->AllocateTo(VariableLocation::MODULE, it.second->cell_index);
    2238             :     DCHECK(var->IsExport());
    2239             :   }
    2240        9115 : }
    2241             : 
    2242     1793772 : void Scope::AllocateVariablesRecursively() {
    2243    11476446 :   this->ForEach([](Scope* scope) -> Iteration {
    2244             :     DCHECK(!scope->already_resolved_);
    2245     5602111 :     if (WasLazilyParsed(scope)) return Iteration::kContinue;
    2246             :     DCHECK_EQ(Context::MIN_CONTEXT_SLOTS, scope->num_heap_slots_);
    2247             : 
    2248             :     // Allocate variables for this scope.
    2249             :     // Parameters must be allocated first, if any.
    2250     3181563 :     if (scope->is_declaration_scope()) {
    2251     2692761 :       if (scope->is_function_scope()) {
    2252             :         scope->AsDeclarationScope()->AllocateParameterLocals();
    2253             :       }
    2254             :       scope->AsDeclarationScope()->AllocateReceiver();
    2255             :     }
    2256             :     scope->AllocateNonParameterLocalsAndDeclaredGlobals();
    2257             : 
    2258             :     // Force allocation of a context for this scope if necessary. For a 'with'
    2259             :     // scope and for a function scope that makes an 'eval' call we need a
    2260             :     // context, even if no local variables were statically allocated in the
    2261             :     // scope. Likewise for modules and function scopes representing asm.js
    2262             :     // modules. Also force a context, if the scope is stricter than the outer
    2263             :     // scope.
    2264             :     bool must_have_context =
    2265     6279007 :         scope->is_with_scope() || scope->is_module_scope() ||
    2266     3130814 :         scope->IsAsmModule() || scope->ForceContextForLanguageMode() ||
    2267     1580237 :         (scope->is_function_scope() &&
    2268     6228133 :          scope->AsDeclarationScope()->calls_sloppy_eval()) ||
    2269      354443 :         (scope->is_block_scope() && scope->is_declaration_scope() &&
    2270             :          scope->AsDeclarationScope()->calls_sloppy_eval());
    2271             : 
    2272             :     // If we didn't allocate any locals in the local context, then we only
    2273             :     // need the minimal number of slots if we must have a context.
    2274     3181574 :     if (scope->num_heap_slots_ == Context::MIN_CONTEXT_SLOTS &&
    2275             :         !must_have_context) {
    2276     2740075 :       scope->num_heap_slots_ = 0;
    2277             :     }
    2278             : 
    2279             :     // Allocation done.
    2280             :     DCHECK(scope->num_heap_slots_ == 0 ||
    2281             :            scope->num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS);
    2282             :     return Iteration::kDescend;
    2283             :   });
    2284     1793783 : }
    2285             : 
    2286     2384967 : void Scope::AllocateScopeInfosRecursively(Isolate* isolate,
    2287     1244675 :                                           MaybeHandle<ScopeInfo> outer_scope) {
    2288             :   DCHECK(scope_info_.is_null());
    2289     2384967 :   MaybeHandle<ScopeInfo> next_outer_scope = outer_scope;
    2290             : 
    2291     2384967 :   if (NeedsScopeInfo()) {
    2292     1244675 :     scope_info_ = ScopeInfo::Create(isolate, zone(), this, outer_scope);
    2293             :     // The ScopeInfo chain should mirror the context chain, so we only link to
    2294             :     // the next outer scope that needs a context.
    2295     1244676 :     if (NeedsContext()) next_outer_scope = scope_info_;
    2296             :   }
    2297             : 
    2298             :   // Allocate ScopeInfos for inner scopes.
    2299     5306341 :   for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
    2300     5524606 :     if (!scope->is_function_scope() ||
    2301             :         scope->AsDeclarationScope()->ShouldEagerCompile()) {
    2302      827152 :       scope->AllocateScopeInfosRecursively(isolate, next_outer_scope);
    2303             :     }
    2304             :   }
    2305     2384968 : }
    2306             : 
    2307             : // static
    2308     3115636 : void DeclarationScope::AllocateScopeInfos(ParseInfo* info, Isolate* isolate) {
    2309     1557814 :   DeclarationScope* scope = info->literal()->scope();
    2310     1557814 :   if (!scope->scope_info_.is_null()) return;  // Allocated by outer function.
    2311             : 
    2312     1557814 :   MaybeHandle<ScopeInfo> outer_scope;
    2313     1557814 :   if (scope->outer_scope_ != nullptr) {
    2314     1405421 :     outer_scope = scope->outer_scope_->scope_info_;
    2315             :   }
    2316             : 
    2317     2503957 :   scope->AllocateScopeInfosRecursively(isolate, outer_scope);
    2318             : 
    2319             :   // The debugger expects all shared function infos to contain a scope info.
    2320             :   // Since the top-most scope will end up in a shared function info, make sure
    2321             :   // it has one, even if it doesn't need a scope info.
    2322             :   // TODO(jochen|yangguo): Remove this requirement.
    2323     1557820 :   if (scope->scope_info_.is_null()) {
    2324             :     scope->scope_info_ =
    2325      946143 :         ScopeInfo::Create(isolate, scope->zone(), scope, outer_scope);
    2326             :   }
    2327             : 
    2328             :   // Ensuring that the outer script scope has a scope info avoids having
    2329             :   // special case for native contexts vs other contexts.
    2330     3115644 :   if (info->script_scope() && info->script_scope()->scope_info_.is_null()) {
    2331             :     info->script_scope()->scope_info_ =
    2332     1059935 :         handle(ScopeInfo::Empty(isolate), isolate);
    2333             :   }
    2334             : }
    2335             : 
    2336         145 : int Scope::ContextLocalCount() const {
    2337          90 :   if (num_heap_slots() == 0) return 0;
    2338             :   Variable* function =
    2339          55 :       is_function_scope() ? AsDeclarationScope()->function_var() : nullptr;
    2340             :   bool is_function_var_in_context =
    2341          55 :       function != nullptr && function->IsContextSlot();
    2342          55 :   return num_heap_slots() - Context::MIN_CONTEXT_SLOTS -
    2343          55 :          (is_function_var_in_context ? 1 : 0);
    2344             : }
    2345             : 
    2346             : }  // namespace internal
    2347      178779 : }  // namespace v8

Generated by: LCOV version 1.10