LCOV - code coverage report
Current view: top level - src/ast - scopes.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 718 751 95.6 %
Date: 2017-04-26 Functions: 92 106 86.8 %

          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/bootstrapper.h"
      12             : #include "src/counters.h"
      13             : #include "src/messages.h"
      14             : #include "src/objects-inl.h"
      15             : #include "src/objects/module-info.h"
      16             : #include "src/objects/scope-info.h"
      17             : #include "src/parsing/parse-info.h"
      18             : #include "src/parsing/preparsed-scope-data.h"
      19             : 
      20             : namespace v8 {
      21             : namespace internal {
      22             : 
      23             : namespace {
      24             : void* kDummyPreParserVariable = reinterpret_cast<void*>(0x1);
      25             : void* kDummyPreParserLexicalVariable = reinterpret_cast<void*>(0x2);
      26             : 
      27        5035 : bool IsLexical(Variable* variable) {
      28        5092 :   if (variable == kDummyPreParserLexicalVariable) return true;
      29        5078 :   if (variable == kDummyPreParserVariable) return false;
      30             :   return IsLexicalVariableMode(variable->mode());
      31             : }
      32             : 
      33             : }  // namespace
      34             : 
      35             : // ----------------------------------------------------------------------------
      36             : // Implementation of LocalsMap
      37             : //
      38             : // Note: We are storing the handle locations as key values in the hash map.
      39             : //       When inserting a new variable via Declare(), we rely on the fact that
      40             : //       the handle location remains alive for the duration of that variable
      41             : //       use. Because a Variable holding a handle with the same location exists
      42             : //       this is ensured.
      43             : 
      44           0 : VariableMap::VariableMap(Zone* zone)
      45           0 :     : ZoneHashMap(8, ZoneAllocationPolicy(zone)) {}
      46             : 
      47    59272772 : Variable* VariableMap::Declare(Zone* zone, Scope* scope,
      48    59272772 :                                const AstRawString* name, VariableMode mode,
      49             :                                VariableKind kind,
      50             :                                InitializationFlag initialization_flag,
      51             :                                MaybeAssignedFlag maybe_assigned_flag,
      52             :                                bool* added) {
      53             :   // AstRawStrings are unambiguous, i.e., the same string is always represented
      54             :   // by the same AstRawString*.
      55             :   // FIXME(marja): fix the type of Lookup.
      56             :   Entry* p =
      57             :       ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->hash(),
      58   118545561 :                                   ZoneAllocationPolicy(zone));
      59    59272789 :   if (added) *added = p->value == nullptr;
      60    59272789 :   if (p->value == nullptr) {
      61             :     // The variable has not been declared yet -> insert it.
      62             :     DCHECK_EQ(name, p->key);
      63             :     p->value = new (zone) Variable(scope, name, mode, kind, initialization_flag,
      64    59258147 :                                    maybe_assigned_flag);
      65             :   }
      66    59272731 :   return reinterpret_cast<Variable*>(p->value);
      67             : }
      68             : 
      69     1409420 : Variable* VariableMap::DeclareName(Zone* zone, const AstRawString* name,
      70             :                                    VariableMode mode) {
      71             :   Entry* p =
      72             :       ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->hash(),
      73     2818840 :                                   ZoneAllocationPolicy(zone));
      74     1409420 :   if (p->value == nullptr) {
      75             :     // The variable has not been declared yet -> insert it.
      76             :     DCHECK_EQ(name, p->key);
      77             :     p->value =
      78     1379070 :         mode == VAR ? kDummyPreParserVariable : kDummyPreParserLexicalVariable;
      79             :   }
      80     1409420 :   return reinterpret_cast<Variable*>(p->value);
      81             : }
      82             : 
      83          29 : void VariableMap::Remove(Variable* var) {
      84          29 :   const AstRawString* name = var->raw_name();
      85          29 :   ZoneHashMap::Remove(const_cast<AstRawString*>(name), name->hash());
      86           0 : }
      87             : 
      88      873841 : void VariableMap::Add(Zone* zone, Variable* var) {
      89      873841 :   const AstRawString* name = var->raw_name();
      90             :   Entry* p =
      91             :       ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->hash(),
      92     1747690 :                                   ZoneAllocationPolicy(zone));
      93             :   DCHECK_NULL(p->value);
      94             :   DCHECK_EQ(name, p->key);
      95      873849 :   p->value = var;
      96      873849 : }
      97             : 
      98   161898190 : Variable* VariableMap::Lookup(const AstRawString* name) {
      99   161898190 :   Entry* p = ZoneHashMap::Lookup(const_cast<AstRawString*>(name), name->hash());
     100   161898200 :   if (p != NULL) {
     101             :     DCHECK(reinterpret_cast<const AstRawString*>(p->key) == name);
     102             :     DCHECK(p->value != NULL);
     103   105094389 :     return reinterpret_cast<Variable*>(p->value);
     104             :   }
     105             :   return NULL;
     106             : }
     107             : 
     108           0 : void SloppyBlockFunctionMap::Delegate::set_statement(Statement* statement) {
     109        7902 :   if (statement_ != nullptr) {
     110             :     statement_->set_statement(statement);
     111             :   }
     112           0 : }
     113             : 
     114           0 : SloppyBlockFunctionMap::SloppyBlockFunctionMap(Zone* zone)
     115       10807 :     : ZoneHashMap(8, ZoneAllocationPolicy(zone)), count_(0) {}
     116             : 
     117       24054 : void SloppyBlockFunctionMap::Declare(Zone* zone, const AstRawString* name,
     118             :                                      Scope* scope,
     119             :                                      SloppyBlockFunctionStatement* statement) {
     120       12027 :   auto* delegate = new (zone) Delegate(scope, statement, count_++);
     121             :   // AstRawStrings are unambiguous, i.e., the same string is always represented
     122             :   // by the same AstRawString*.
     123             :   Entry* p =
     124             :       ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->hash(),
     125       24054 :                                   ZoneAllocationPolicy(zone));
     126       12027 :   delegate->set_next(static_cast<SloppyBlockFunctionMap::Delegate*>(p->value));
     127       12027 :   p->value = delegate;
     128       12027 : }
     129             : 
     130             : // ----------------------------------------------------------------------------
     131             : // Implementation of Scope
     132             : 
     133     5590110 : Scope::Scope(Zone* zone)
     134             :     : zone_(zone),
     135             :       outer_scope_(nullptr),
     136             :       variables_(zone),
     137    11180211 :       scope_type_(SCRIPT_SCOPE) {
     138             :   SetDefaults();
     139     5590101 : }
     140             : 
     141    20992343 : Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type)
     142             :     : zone_(zone),
     143             :       outer_scope_(outer_scope),
     144             :       variables_(zone),
     145    41984670 :       scope_type_(scope_type) {
     146             :   DCHECK_NE(SCRIPT_SCOPE, scope_type);
     147             :   SetDefaults();
     148             :   set_language_mode(outer_scope->language_mode());
     149             :   force_context_allocation_ =
     150    33182976 :       !is_function_scope() && outer_scope->has_forced_context_allocation();
     151    20992327 :   outer_scope_->AddInnerScope(this);
     152    20992327 : }
     153             : 
     154   138202857 : Scope::Snapshot::Snapshot(Scope* scope)
     155             :     : outer_scope_(scope),
     156             :       top_inner_scope_(scope->inner_scope_),
     157             :       top_unresolved_(scope->unresolved_),
     158   138202857 :       top_local_(scope->GetClosureScope()->locals_.end()),
     159   138202857 :       top_decl_(scope->GetClosureScope()->decls_.end()),
     160   414608571 :       outer_scope_calls_eval_(scope->scope_calls_eval_) {
     161             :   // Reset in order to record eval calls during this Snapshot's lifetime.
     162   138202857 :   outer_scope_->scope_calls_eval_ = false;
     163   138202857 : }
     164             : 
     165   138202718 : Scope::Snapshot::~Snapshot() {
     166             :   // Restore previous calls_eval bit if needed.
     167   138202718 :   if (outer_scope_calls_eval_) {
     168      453247 :     outer_scope_->scope_calls_eval_ = true;
     169             :   }
     170   138202718 : }
     171             : 
     172     5590111 : DeclarationScope::DeclarationScope(Zone* zone,
     173     5590125 :                                    AstValueFactory* ast_value_factory)
     174     5590111 :     : Scope(zone), function_kind_(kNormalFunction), params_(4, zone) {
     175             :   DCHECK_EQ(scope_type_, SCRIPT_SCOPE);
     176             :   SetDefaults();
     177             : 
     178             :   // Make sure that if we don't find the global 'this', it won't be declared as
     179             :   // a regular dynamic global by predeclaring it with the right variable kind.
     180     5590125 :   DeclareDynamicGlobal(ast_value_factory->this_string(), THIS_VARIABLE);
     181     5590113 : }
     182             : 
     183    10325866 : DeclarationScope::DeclarationScope(Zone* zone, Scope* outer_scope,
     184             :                                    ScopeType scope_type,
     185             :                                    FunctionKind function_kind)
     186             :     : Scope(zone, outer_scope, scope_type),
     187             :       function_kind_(function_kind),
     188    10325866 :       params_(4, zone) {
     189             :   DCHECK_NE(scope_type, SCRIPT_SCOPE);
     190             :   SetDefaults();
     191    20651736 :   asm_function_ = outer_scope_->IsAsmModule();
     192    10325868 : }
     193             : 
     194       28202 : ModuleScope::ModuleScope(DeclarationScope* script_scope,
     195       56404 :                          AstValueFactory* ast_value_factory)
     196             :     : DeclarationScope(ast_value_factory->zone(), script_scope, MODULE_SCOPE,
     197       28202 :                        kModule) {
     198             :   Zone* zone = ast_value_factory->zone();
     199       28202 :   module_descriptor_ = new (zone) ModuleDescriptor(zone);
     200             :   set_language_mode(STRICT);
     201       28202 :   DeclareThis(ast_value_factory);
     202       28202 : }
     203             : 
     204        5406 : ModuleScope::ModuleScope(Handle<ScopeInfo> scope_info,
     205       11056 :                          AstValueFactory* avfactory)
     206        5406 :     : DeclarationScope(avfactory->zone(), MODULE_SCOPE, scope_info) {
     207             :   Zone* zone = avfactory->zone();
     208             :   Isolate* isolate = scope_info->GetIsolate();
     209        5406 :   Handle<ModuleInfo> module_info(scope_info->ModuleDescriptorInfo(), isolate);
     210             : 
     211             :   set_language_mode(STRICT);
     212        5406 :   module_descriptor_ = new (zone) ModuleDescriptor(zone);
     213             : 
     214             :   // Deserialize special exports.
     215             :   Handle<FixedArray> special_exports(module_info->special_exports(), isolate);
     216        5406 :   for (int i = 0, n = special_exports->length(); i < n; ++i) {
     217             :     Handle<ModuleInfoEntry> serialized_entry(
     218             :         ModuleInfoEntry::cast(special_exports->get(i)), isolate);
     219             :     module_descriptor_->AddSpecialExport(
     220             :         ModuleDescriptor::Entry::Deserialize(isolate, avfactory,
     221           0 :                                              serialized_entry),
     222           0 :         avfactory->zone());
     223             :   }
     224             : 
     225             :   // Deserialize regular exports.
     226             :   module_descriptor_->DeserializeRegularExports(isolate, avfactory,
     227        5406 :                                                 module_info);
     228             : 
     229             :   // Deserialize namespace imports.
     230             :   Handle<FixedArray> namespace_imports(module_info->namespace_imports(),
     231             :                                        isolate);
     232        5650 :   for (int i = 0, n = namespace_imports->length(); i < n; ++i) {
     233             :     Handle<ModuleInfoEntry> serialized_entry(
     234             :         ModuleInfoEntry::cast(namespace_imports->get(i)), isolate);
     235             :     module_descriptor_->AddNamespaceImport(
     236             :         ModuleDescriptor::Entry::Deserialize(isolate, avfactory,
     237         244 :                                              serialized_entry),
     238         244 :         avfactory->zone());
     239             :   }
     240             : 
     241             :   // Deserialize regular imports.
     242             :   Handle<FixedArray> regular_imports(module_info->regular_imports(), isolate);
     243        8028 :   for (int i = 0, n = regular_imports->length(); i < n; ++i) {
     244             :     Handle<ModuleInfoEntry> serialized_entry(
     245             :         ModuleInfoEntry::cast(regular_imports->get(i)), isolate);
     246             :     module_descriptor_->AddRegularImport(ModuleDescriptor::Entry::Deserialize(
     247        2622 :         isolate, avfactory, serialized_entry));
     248             :   }
     249        5406 : }
     250             : 
     251     3494379 : Scope::Scope(Zone* zone, ScopeType scope_type, Handle<ScopeInfo> scope_info)
     252             :     : zone_(zone),
     253             :       outer_scope_(nullptr),
     254             :       variables_(zone),
     255             :       scope_info_(scope_info),
     256     6988757 :       scope_type_(scope_type) {
     257             :   DCHECK(!scope_info.is_null());
     258             :   SetDefaults();
     259             : #ifdef DEBUG
     260             :   already_resolved_ = true;
     261             : #endif
     262     3494378 :   if (scope_info->CallsEval()) RecordEvalCall();
     263     3494378 :   set_language_mode(scope_info->language_mode());
     264     3494378 :   num_heap_slots_ = scope_info->ContextLength();
     265             :   DCHECK_LE(Context::MIN_CONTEXT_SLOTS, num_heap_slots_);
     266             :   // We don't really need to use the preparsed scope data; this is just to
     267             :   // shorten the recursion in SetMustUsePreParsedScopeData.
     268     3494378 :   must_use_preparsed_scope_data_ = true;
     269     3494378 : }
     270             : 
     271     3342985 : DeclarationScope::DeclarationScope(Zone* zone, ScopeType scope_type,
     272             :                                    Handle<ScopeInfo> scope_info)
     273             :     : Scope(zone, scope_type, scope_info),
     274     3342984 :       function_kind_(scope_info->function_kind()),
     275     6685969 :       params_(0, zone) {
     276             :   DCHECK_NE(scope_type, SCRIPT_SCOPE);
     277             :   SetDefaults();
     278     3342984 : }
     279             : 
     280        4694 : Scope::Scope(Zone* zone, const AstRawString* catch_variable_name,
     281             :              MaybeAssignedFlag maybe_assigned, Handle<ScopeInfo> scope_info)
     282             :     : zone_(zone),
     283             :       outer_scope_(nullptr),
     284             :       variables_(zone),
     285             :       scope_info_(scope_info),
     286        9388 :       scope_type_(CATCH_SCOPE) {
     287             :   SetDefaults();
     288             : #ifdef DEBUG
     289             :   already_resolved_ = true;
     290             : #endif
     291             :   // Cache the catch variable, even though it's also available via the
     292             :   // scope_info, as the parser expects that a catch scope always has the catch
     293             :   // variable as first and only variable.
     294             :   Variable* variable = Declare(zone, catch_variable_name, VAR, NORMAL_VARIABLE,
     295        4694 :                                kCreatedInitialized, maybe_assigned);
     296             :   AllocateHeapSlot(variable);
     297        4694 : }
     298             : 
     299           0 : void DeclarationScope::SetDefaults() {
     300    19258977 :   is_declaration_scope_ = true;
     301    19258977 :   has_simple_parameters_ = true;
     302    19258977 :   asm_module_ = false;
     303    19258977 :   asm_function_ = false;
     304    19258977 :   force_eager_compilation_ = false;
     305    19258977 :   has_arguments_parameter_ = false;
     306    19258977 :   scope_uses_super_property_ = false;
     307    19258977 :   has_rest_ = false;
     308    19258977 :   sloppy_block_function_map_ = nullptr;
     309    19258977 :   receiver_ = nullptr;
     310    19258977 :   new_target_ = nullptr;
     311    19258977 :   function_ = nullptr;
     312    19258977 :   arguments_ = nullptr;
     313           0 :   rare_data_ = nullptr;
     314    19258977 :   should_eager_compile_ = false;
     315    19258977 :   was_lazily_parsed_ = false;
     316    19258977 :   is_skipped_function_ = false;
     317             : #ifdef DEBUG
     318             :   DeclarationScope* outer_declaration_scope =
     319             :       outer_scope_ ? outer_scope_->GetDeclarationScope() : nullptr;
     320             :   is_being_lazily_parsed_ =
     321             :       outer_declaration_scope ? outer_declaration_scope->is_being_lazily_parsed_
     322             :                               : false;
     323             : #endif
     324           0 : }
     325             : 
     326           0 : void Scope::SetDefaults() {
     327             : #ifdef DEBUG
     328             :   scope_name_ = nullptr;
     329             :   already_resolved_ = false;
     330             :   needs_migration_ = false;
     331             : #endif
     332    30081500 :   inner_scope_ = nullptr;
     333    30081500 :   sibling_ = nullptr;
     334    30081500 :   unresolved_ = nullptr;
     335             : 
     336    30081500 :   start_position_ = kNoSourcePosition;
     337    30081500 :   end_position_ = kNoSourcePosition;
     338             : 
     339    30081500 :   num_stack_slots_ = 0;
     340    30081500 :   num_heap_slots_ = Context::MIN_CONTEXT_SLOTS;
     341             : 
     342             :   set_language_mode(SLOPPY);
     343             : 
     344    30081500 :   scope_calls_eval_ = false;
     345    30081500 :   scope_nonlinear_ = false;
     346    30081500 :   is_hidden_ = false;
     347    30081500 :   is_debug_evaluate_scope_ = false;
     348             : 
     349    30081500 :   inner_scope_calls_eval_ = false;
     350    30081500 :   force_context_allocation_ = false;
     351             : 
     352    30081500 :   is_declaration_scope_ = false;
     353             : 
     354    30081500 :   must_use_preparsed_scope_data_ = false;
     355           0 : }
     356             : 
     357      543562 : bool Scope::HasSimpleParameters() {
     358             :   DeclarationScope* scope = GetClosureScope();
     359      755607 :   return !scope->is_function_scope() || scope->has_simple_parameters();
     360             : }
     361             : 
     362     5458771 : bool DeclarationScope::ShouldEagerCompile() const {
     363    11303438 :   return force_eager_compilation_ || should_eager_compile_;
     364             : }
     365             : 
     366     1096877 : void DeclarationScope::set_should_eager_compile() {
     367     3973454 :   should_eager_compile_ = !was_lazily_parsed_;
     368     1096877 : }
     369             : 
     370       11102 : void DeclarationScope::set_asm_module() {
     371       23467 :   asm_module_ = true;
     372             :   // Mark any existing inner function scopes as asm function scopes.
     373       23467 :   for (Scope* inner = inner_scope_; inner != nullptr; inner = inner->sibling_) {
     374           0 :     if (inner->is_function_scope()) {
     375             :       inner->AsDeclarationScope()->set_asm_function();
     376             :     }
     377             :   }
     378       11102 : }
     379             : 
     380    13256618 : bool Scope::IsAsmModule() const {
     381    36756634 :   return is_function_scope() && AsDeclarationScope()->asm_module();
     382             : }
     383             : 
     384          30 : bool Scope::IsAsmFunction() const {
     385          60 :   return is_function_scope() && AsDeclarationScope()->asm_function();
     386             : }
     387             : 
     388     3241202 : Scope* Scope::DeserializeScopeChain(Zone* zone, ScopeInfo* scope_info,
     389             :                                     DeclarationScope* script_scope,
     390             :                                     AstValueFactory* ast_value_factory,
     391             :                                     DeserializationMode deserialization_mode) {
     392             :   // Reconstruct the outer scope chain from a closure's context chain.
     393             :   Scope* current_scope = nullptr;
     394             :   Scope* innermost_scope = nullptr;
     395             :   Scope* outer_scope = nullptr;
     396     9981477 :   while (scope_info) {
     397     4021321 :     if (scope_info->scope_type() == WITH_SCOPE) {
     398             :       // For scope analysis, debug-evaluate is equivalent to a with scope.
     399       76836 :       outer_scope = new (zone) Scope(zone, WITH_SCOPE, handle(scope_info));
     400             : 
     401             :       // TODO(yangguo): Remove once debug-evaluate properly keeps track of the
     402             :       // function scope in which we are evaluating.
     403       38418 :       if (scope_info->IsDebugEvaluateScope()) {
     404             :         outer_scope->set_is_debug_evaluate_scope();
     405             :       }
     406     3982903 :     } else if (scope_info->scope_type() == SCRIPT_SCOPE) {
     407             :       // If we reach a script scope, it's the outermost scope. Install the
     408             :       // scope info of this script context onto the existing script scope to
     409             :       // avoid nesting script scopes.
     410      522248 :       if (deserialization_mode == DeserializationMode::kIncludingVariables) {
     411             :         script_scope->SetScriptScopeInfo(handle(scope_info));
     412             :       }
     413             :       DCHECK(!scope_info->HasOuterScopeInfo());
     414             :       break;
     415     3460655 :     } else if (scope_info->scope_type() == FUNCTION_SCOPE) {
     416             :       outer_scope =
     417     6629790 :           new (zone) DeclarationScope(zone, FUNCTION_SCOPE, handle(scope_info));
     418     3314894 :       if (scope_info->IsAsmFunction())
     419             :         outer_scope->AsDeclarationScope()->set_asm_function();
     420     3314894 :       if (scope_info->IsAsmModule())
     421             :         outer_scope->AsDeclarationScope()->set_asm_module();
     422      145760 :     } else if (scope_info->scope_type() == EVAL_SCOPE) {
     423             :       outer_scope =
     424       19816 :           new (zone) DeclarationScope(zone, EVAL_SCOPE, handle(scope_info));
     425      135852 :     } else if (scope_info->scope_type() == BLOCK_SCOPE) {
     426      125752 :       if (scope_info->is_declaration_scope()) {
     427             :         outer_scope =
     428       25552 :             new (zone) DeclarationScope(zone, BLOCK_SCOPE, handle(scope_info));
     429             :       } else {
     430      225952 :         outer_scope = new (zone) Scope(zone, BLOCK_SCOPE, handle(scope_info));
     431             :       }
     432       10100 :     } else if (scope_info->scope_type() == MODULE_SCOPE) {
     433             :       outer_scope =
     434       10812 :           new (zone) ModuleScope(handle(scope_info), ast_value_factory);
     435             :     } else {
     436             :       DCHECK_EQ(scope_info->scope_type(), CATCH_SCOPE);
     437             :       DCHECK_EQ(scope_info->LocalCount(), 1);
     438             :       DCHECK_EQ(scope_info->ContextLocalCount(), 1);
     439             :       DCHECK_EQ(scope_info->ContextLocalMode(0), VAR);
     440             :       DCHECK_EQ(scope_info->ContextLocalInitFlag(0), kCreatedInitialized);
     441        4694 :       String* name = scope_info->ContextLocalName(0);
     442             :       MaybeAssignedFlag maybe_assigned =
     443        4694 :           scope_info->ContextLocalMaybeAssignedFlag(0);
     444             :       outer_scope =
     445             :           new (zone) Scope(zone, ast_value_factory->GetString(handle(name)),
     446       14082 :                            maybe_assigned, handle(scope_info));
     447             :     }
     448     3499072 :     if (deserialization_mode == DeserializationMode::kScopesOnly) {
     449     1857617 :       outer_scope->scope_info_ = Handle<ScopeInfo>::null();
     450             :     }
     451     3499072 :     if (current_scope != nullptr) {
     452             :       outer_scope->AddInnerScope(current_scope);
     453             :     }
     454             :     current_scope = outer_scope;
     455     3499072 :     if (innermost_scope == nullptr) innermost_scope = current_scope;
     456     3499072 :     scope_info = scope_info->HasOuterScopeInfo() ? scope_info->OuterScopeInfo()
     457     3499073 :                                                  : nullptr;
     458             :   }
     459             : 
     460     3241202 :   if (innermost_scope == nullptr) return script_scope;
     461     3005380 :   script_scope->AddInnerScope(current_scope);
     462     3005380 :   return innermost_scope;
     463             : }
     464             : 
     465   152779109 : DeclarationScope* Scope::AsDeclarationScope() {
     466             :   DCHECK(is_declaration_scope());
     467   152779109 :   return static_cast<DeclarationScope*>(this);
     468             : }
     469             : 
     470           0 : const DeclarationScope* Scope::AsDeclarationScope() const {
     471             :   DCHECK(is_declaration_scope());
     472           0 :   return static_cast<const DeclarationScope*>(this);
     473             : }
     474             : 
     475       25354 : ModuleScope* Scope::AsModuleScope() {
     476             :   DCHECK(is_module_scope());
     477       25354 :   return static_cast<ModuleScope*>(this);
     478             : }
     479             : 
     480           0 : const ModuleScope* Scope::AsModuleScope() const {
     481             :   DCHECK(is_module_scope());
     482           0 :   return static_cast<const ModuleScope*>(this);
     483             : }
     484             : 
     485     4325730 : int Scope::num_parameters() const {
     486     8651460 :   return is_declaration_scope() ? AsDeclarationScope()->num_parameters() : 0;
     487             : }
     488             : 
     489       12027 : void DeclarationScope::DeclareSloppyBlockFunction(
     490             :     const AstRawString* name, Scope* scope,
     491             :     SloppyBlockFunctionStatement* statement) {
     492       12027 :   if (sloppy_block_function_map_ == nullptr) {
     493             :     sloppy_block_function_map_ =
     494             :         new (zone()->New(sizeof(SloppyBlockFunctionMap)))
     495       21614 :             SloppyBlockFunctionMap(zone());
     496             :   }
     497       12027 :   sloppy_block_function_map_->Declare(zone(), name, scope, statement);
     498       12027 : }
     499             : 
     500     5556521 : void DeclarationScope::HoistSloppyBlockFunctions(AstNodeFactory* factory) {
     501             :   DCHECK(is_sloppy(language_mode()));
     502             :   DCHECK(is_function_scope() || is_eval_scope() || is_script_scope() ||
     503             :          (is_block_scope() && outer_scope()->is_function_scope()));
     504             :   DCHECK(HasSimpleParameters() || is_block_scope() || is_being_lazily_parsed_);
     505             :   DCHECK_EQ(factory == nullptr, is_being_lazily_parsed_);
     506             : 
     507             :   SloppyBlockFunctionMap* map = sloppy_block_function_map();
     508    11058303 :   if (map == nullptr) return;
     509             : 
     510       10683 :   const bool has_simple_parameters = HasSimpleParameters();
     511             : 
     512             :   // The declarations need to be added in the order they were seen,
     513             :   // so accumulate declared names sorted by index.
     514             :   ZoneMap<int, const AstRawString*> names_to_declare(zone());
     515             : 
     516             :   // For each variable which is used as a function declaration in a sloppy
     517             :   // block,
     518       32910 :   for (ZoneHashMap::Entry* p = map->Start(); p != nullptr; p = map->Next(p)) {
     519       11544 :     const AstRawString* name = static_cast<AstRawString*>(p->key);
     520             : 
     521             :     // If the variable wouldn't conflict with a lexical declaration
     522             :     // or parameter,
     523             : 
     524             :     // Check if there's a conflict with a parameter.
     525             :     // This depends on the fact that functions always have a scope solely to
     526             :     // hold complex parameters, and the names local to that scope are
     527             :     // precisely the names of the parameters. IsDeclaredParameter(name) does
     528             :     // not hold for names declared by complex parameters, nor are those
     529             :     // bindings necessarily declared lexically, so we have to check for them
     530             :     // explicitly. On the other hand, if there are not complex parameters,
     531             :     // it is sufficient to just check IsDeclaredParameter.
     532       11544 :     if (!has_simple_parameters) {
     533         186 :       if (outer_scope_->LookupLocal(name) != nullptr) {
     534             :         continue;
     535             :       }
     536             :     } else {
     537       11358 :       if (IsDeclaredParameter(name)) {
     538             :         continue;
     539             :       }
     540             :     }
     541             : 
     542             :     bool declaration_queued = false;
     543             : 
     544             :     // Write in assignments to var for each block-scoped function declaration
     545       11326 :     auto delegates = static_cast<SloppyBlockFunctionMap::Delegate*>(p->value);
     546             : 
     547             :     DeclarationScope* decl_scope = this;
     548       24563 :     while (decl_scope->is_eval_scope()) {
     549       26474 :       decl_scope = decl_scope->outer_scope()->GetDeclarationScope();
     550             :     }
     551             :     Scope* outer_scope = decl_scope->outer_scope();
     552             : 
     553       40299 :     for (SloppyBlockFunctionMap::Delegate* delegate = delegates;
     554             :          delegate != nullptr; delegate = delegate->next()) {
     555             :       // Check if there's a conflict with a lexical declaration
     556       25214 :       Scope* query_scope = delegate->scope()->outer_scope();
     557             :       Variable* var = nullptr;
     558             :       bool should_hoist = true;
     559             : 
     560             :       // Note that we perform this loop for each delegate named 'name',
     561             :       // which may duplicate work if those delegates share scopes.
     562             :       // It is not sufficient to just do a Lookup on query_scope: for
     563             :       // example, that does not prevent hoisting of the function in
     564             :       // `{ let e; try {} catch (e) { function e(){} } }`
     565       13452 :       do {
     566       15483 :         var = query_scope->LookupLocal(name);
     567       18960 :         if (var != nullptr && IsLexical(var)) {
     568             :           should_hoist = false;
     569             :           break;
     570             :         }
     571             :         query_scope = query_scope->outer_scope();
     572             :       } while (query_scope != outer_scope);
     573             : 
     574       11762 :       if (!should_hoist) continue;
     575             : 
     576        9731 :       if (!declaration_queued) {
     577             :         declaration_queued = true;
     578        9309 :         names_to_declare.insert({delegate->index(), name});
     579             :       }
     580             : 
     581        9731 :       if (factory) {
     582             :         DCHECK(!is_being_lazily_parsed_);
     583             :         Expression* assignment = factory->NewAssignment(
     584        7902 :             Token::ASSIGN, NewUnresolved(factory, name),
     585       15804 :             delegate->scope()->NewUnresolved(factory, name), kNoSourcePosition);
     586             :         Statement* statement =
     587             :             factory->NewExpressionStatement(assignment, kNoSourcePosition);
     588             :         delegate->set_statement(statement);
     589             :       }
     590             :     }
     591             :   }
     592             : 
     593       10683 :   if (names_to_declare.empty()) return;
     594             : 
     595       26217 :   for (const auto& index_and_name : names_to_declare) {
     596        9309 :     const AstRawString* name = index_and_name.second;
     597        9309 :     if (factory) {
     598             :       DCHECK(!is_being_lazily_parsed_);
     599             :       VariableProxy* proxy = factory->NewVariableProxy(name, NORMAL_VARIABLE);
     600             :       auto declaration =
     601             :           factory->NewVariableDeclaration(proxy, this, kNoSourcePosition);
     602             :       // Based on the preceding checks, it doesn't matter what we pass as
     603             :       // allow_harmony_restrictive_generators and
     604             :       // sloppy_mode_block_scope_function_redefinition.
     605        7620 :       bool ok = true;
     606             :       DeclareVariable(declaration, VAR,
     607             :                       Variable::DefaultInitializationFlag(VAR), false, nullptr,
     608        7620 :                       &ok);
     609             :       DCHECK(ok);
     610             :     } else {
     611             :       DCHECK(is_being_lazily_parsed_);
     612        1689 :       Variable* var = DeclareVariableName(name, VAR);
     613        3236 :       if (var != kDummyPreParserVariable &&
     614        1547 :           var != kDummyPreParserLexicalVariable) {
     615             :         DCHECK(FLAG_experimental_preparser_scope_analysis);
     616             :         var->set_maybe_assigned();
     617             :       }
     618             :     }
     619             :   }
     620             : }
     621             : 
     622    12763656 : void DeclarationScope::Analyze(ParseInfo* info, Isolate* isolate,
     623             :                                AnalyzeMode mode) {
     624             :   RuntimeCallTimerScope runtimeTimer(isolate,
     625     2876573 :                                      &RuntimeCallStats::CompileScopeAnalysis);
     626             :   DCHECK(info->literal() != NULL);
     627     2876576 :   DeclarationScope* scope = info->literal()->scope();
     628             :   DCHECK(scope->scope_info_.is_null());
     629             : 
     630             :   Handle<ScopeInfo> outer_scope_info;
     631     2876576 :   if (info->maybe_outer_scope_info().ToHandle(&outer_scope_info)) {
     632     4418008 :     if (scope->outer_scope()) {
     633             :       DeclarationScope* script_scope = new (info->zone())
     634     1541431 :           DeclarationScope(info->zone(), info->ast_value_factory());
     635             :       info->set_script_scope(script_scope);
     636             :       scope->ReplaceOuterScope(Scope::DeserializeScopeChain(
     637             :           info->zone(), *outer_scope_info, script_scope,
     638             :           info->ast_value_factory(),
     639     1541431 :           Scope::DeserializationMode::kIncludingVariables));
     640             :     } else {
     641             :       DCHECK_EQ(outer_scope_info->scope_type(), SCRIPT_SCOPE);
     642             :       scope->SetScriptScopeInfo(outer_scope_info);
     643             :     }
     644             :   }
     645             : 
     646     4114378 :   if (scope->is_eval_scope() && is_sloppy(scope->language_mode())) {
     647             :     AstNodeFactory factory(info->ast_value_factory());
     648     1051060 :     scope->HoistSloppyBlockFunctions(&factory);
     649             :   }
     650             : 
     651             :   // We are compiling one of four cases:
     652             :   // 1) top-level code,
     653             :   // 2) a function/eval/module on the top-level
     654             :   // 3) a function/eval in a scope that was already resolved.
     655             :   // 4) an asm.js function
     656             :   DCHECK(scope->scope_type() == SCRIPT_SCOPE ||
     657             :          scope->outer_scope()->scope_type() == SCRIPT_SCOPE ||
     658             :          scope->outer_scope()->already_resolved_ ||
     659             :          (info->asm_function_scope() && scope->is_function_scope()));
     660             : 
     661             :   // The outer scope is never lazy.
     662             :   scope->set_should_eager_compile();
     663             : 
     664     2876577 :   if (scope->must_use_preparsed_scope_data_) {
     665             :     DCHECK(FLAG_experimental_preparser_scope_analysis);
     666             :     DCHECK_NOT_NULL(info->preparsed_scope_data());
     667             :     DCHECK_EQ(scope->scope_type_, ScopeType::FUNCTION_SCOPE);
     668          14 :     info->preparsed_scope_data()->RestoreData(scope);
     669             :   }
     670             : 
     671     2876577 :   scope->AllocateVariables(info, isolate, mode);
     672             : 
     673             :   // Ensuring that the outer script scope has a scope info avoids having
     674             :   // special case for native contexts vs other contexts.
     675     2876585 :   if (info->script_scope()->scope_info_.is_null()) {
     676     4551822 :     info->script_scope()->scope_info_ = handle(ScopeInfo::Empty(isolate));
     677             :   }
     678             : 
     679             : #ifdef DEBUG
     680             :   if (info->script_is_native() ? FLAG_print_builtin_scopes
     681             :                                : FLAG_print_scopes) {
     682             :     PrintF("Global scope:\n");
     683             :     scope->Print();
     684             :   }
     685             :   scope->CheckScopePositions();
     686             :   scope->CheckZones();
     687             : #endif
     688     2876585 : }
     689             : 
     690    16159932 : void DeclarationScope::DeclareThis(AstValueFactory* ast_value_factory) {
     691             :   DCHECK(!already_resolved_);
     692             :   DCHECK(is_declaration_scope());
     693             :   DCHECK(has_this_declaration());
     694             : 
     695     8079966 :   bool derived_constructor = IsDerivedConstructor(function_kind_);
     696             :   Variable* var =
     697             :       Declare(zone(), ast_value_factory->this_string(),
     698             :               derived_constructor ? CONST : VAR, THIS_VARIABLE,
     699    16159932 :               derived_constructor ? kNeedsInitialization : kCreatedInitialized);
     700     8079966 :   receiver_ = var;
     701     8079966 : }
     702             : 
     703    13779997 : void DeclarationScope::DeclareArguments(AstValueFactory* ast_value_factory) {
     704             :   DCHECK(is_function_scope());
     705             :   DCHECK(!is_arrow_scope());
     706             : 
     707    13779997 :   arguments_ = LookupLocal(ast_value_factory->arguments_string());
     708     6890810 :   if (arguments_ == nullptr) {
     709             :     // Declare 'arguments' variable which exists in all non arrow functions.
     710             :     // Note that it might never be accessed, in which case it won't be
     711             :     // allocated during variable allocation.
     712     6889195 :     arguments_ = Declare(zone(), ast_value_factory->arguments_string(), VAR);
     713        1615 :   } else if (IsLexical(arguments_)) {
     714             :     // Check if there's lexically declared variable named arguments to avoid
     715             :     // redeclaration. See ES#sec-functiondeclarationinstantiation, step 20.
     716         615 :     arguments_ = nullptr;
     717             :   }
     718     6890805 : }
     719             : 
     720     8051767 : void DeclarationScope::DeclareDefaultFunctionVariables(
     721     9407861 :     AstValueFactory* ast_value_factory) {
     722             :   DCHECK(is_function_scope());
     723             :   DCHECK(!is_arrow_scope());
     724             : 
     725     8051767 :   DeclareThis(ast_value_factory);
     726     8729813 :   new_target_ = Declare(zone(), ast_value_factory->new_target_string(), CONST);
     727             : 
     728    31098655 :   if (IsConciseMethod(function_kind_) || IsClassConstructor(function_kind_) ||
     729             :       IsAccessorFunction(function_kind_)) {
     730             :     EnsureRareData()->this_function =
     731      678048 :         Declare(zone(), ast_value_factory->this_function_string(), CONST);
     732             :   }
     733     8051766 : }
     734             : 
     735      940123 : Variable* DeclarationScope::DeclareFunctionVar(const AstRawString* name) {
     736             :   DCHECK(is_function_scope());
     737             :   DCHECK_NULL(function_);
     738             :   DCHECK_NULL(variables_.Lookup(name));
     739     1813937 :   VariableKind kind = is_sloppy(language_mode()) ? SLOPPY_FUNCTION_NAME_VARIABLE
     740      940123 :                                                  : NORMAL_VARIABLE;
     741             :   function_ =
     742      940134 :       new (zone()) Variable(this, name, CONST, kind, kCreatedInitialized);
     743      940130 :   if (calls_sloppy_eval()) {
     744       66316 :     NonLocal(name, DYNAMIC);
     745             :   } else {
     746      873814 :     variables_.Add(zone(), function_);
     747             :   }
     748      940136 :   return function_;
     749             : }
     750             : 
     751      110847 : Variable* DeclarationScope::DeclareGeneratorObjectVar(
     752      110847 :     const AstRawString* name) {
     753             :   DCHECK(is_function_scope() || is_module_scope());
     754             :   DCHECK_NULL(generator_object_var());
     755             : 
     756             :   Variable* result = EnsureRareData()->generator_object =
     757      110847 :       NewTemporary(name, kNotAssigned);
     758             :   result->set_is_used();
     759      110847 :   return result;
     760             : }
     761             : 
     762       32344 : Variable* DeclarationScope::DeclarePromiseVar(const AstRawString* name) {
     763             :   DCHECK(is_function_scope());
     764             :   DCHECK_NULL(promise_var());
     765       64688 :   Variable* result = EnsureRareData()->promise = NewTemporary(name);
     766             :   result->set_is_used();
     767       32344 :   return result;
     768             : }
     769             : 
     770       11386 : Variable* DeclarationScope::DeclareAsyncGeneratorAwaitVar(
     771       11386 :     const AstRawString* name) {
     772             :   DCHECK(is_function_scope());
     773             :   DCHECK_NULL(async_generator_await_var());
     774       22772 :   Variable* result = EnsureRareData()->promise = NewTemporary(name);
     775             :   DCHECK_NULL(promise_var());  // promise is alias for generator await var
     776             :   result->set_is_used();
     777       11386 :   return result;
     778             : }
     779             : 
     780      111119 : bool Scope::HasBeenRemoved() const {
     781      111119 :   if (sibling() == this) {
     782             :     DCHECK_NULL(inner_scope_);
     783             :     DCHECK(is_block_scope());
     784             :     return true;
     785             :   }
     786           0 :   return false;
     787             : }
     788             : 
     789       73529 : Scope* Scope::GetUnremovedScope() {
     790       37590 :   Scope* scope = this;
     791      295767 :   while (scope != nullptr && scope->HasBeenRemoved()) {
     792             :     scope = scope->outer_scope();
     793             :   }
     794             :   DCHECK_NOT_NULL(scope);
     795       73529 :   return scope;
     796             : }
     797             : 
     798    34734055 : Scope* Scope::FinalizeBlockScope() {
     799             :   DCHECK(is_block_scope());
     800             :   DCHECK(!HasBeenRemoved());
     801             : 
     802    27778350 :   if (variables_.occupancy() > 0 ||
     803       69537 :       (is_declaration_scope() && calls_sloppy_eval())) {
     804             :     return this;
     805             :   }
     806             : 
     807             :   // Remove this scope from outer scope.
     808             :   outer_scope()->RemoveInnerScope(this);
     809             : 
     810             :   // Reparent inner scopes.
     811     8946210 :   if (inner_scope_ != nullptr) {
     812             :     Scope* scope = inner_scope_;
     813      674968 :     scope->outer_scope_ = outer_scope();
     814     1570376 :     while (scope->sibling_ != nullptr) {
     815             :       scope = scope->sibling_;
     816      220440 :       scope->outer_scope_ = outer_scope();
     817             :     }
     818      674968 :     scope->sibling_ = outer_scope()->inner_scope_;
     819      674968 :     outer_scope()->inner_scope_ = inner_scope_;
     820      674968 :     inner_scope_ = nullptr;
     821             :   }
     822             : 
     823             :   // Move unresolved variables
     824     8946210 :   if (unresolved_ != nullptr) {
     825     6768837 :     if (outer_scope()->unresolved_ != nullptr) {
     826    50317270 :       VariableProxy* unresolved = unresolved_;
     827    50317270 :       while (unresolved->next_unresolved() != nullptr) {
     828             :         unresolved = unresolved->next_unresolved();
     829             :       }
     830             :       unresolved->set_next_unresolved(outer_scope()->unresolved_);
     831             :     }
     832     6768837 :     outer_scope()->unresolved_ = unresolved_;
     833     6768837 :     unresolved_ = nullptr;
     834             :   }
     835             : 
     836     9235965 :   if (scope_calls_eval_) outer_scope()->scope_calls_eval_ = true;
     837     9246185 :   if (inner_scope_calls_eval_) outer_scope()->inner_scope_calls_eval_ = true;
     838             : 
     839             :   // This block does not need a context.
     840     8946210 :   num_heap_slots_ = 0;
     841             : 
     842             :   // Mark scope as removed by making it its own sibling.
     843     8946210 :   sibling_ = this;
     844             :   DCHECK(HasBeenRemoved());
     845             : 
     846     8946210 :   return nullptr;
     847             : }
     848             : 
     849           0 : void DeclarationScope::AddLocal(Variable* var) {
     850             :   DCHECK(!already_resolved_);
     851             :   // Temporaries are only placed in ClosureScopes.
     852             :   DCHECK_EQ(GetClosureScope(), this);
     853             :   locals_.Add(var);
     854           0 : }
     855             : 
     856    48966242 : Variable* Scope::Declare(Zone* zone, const AstRawString* name,
     857             :                          VariableMode mode, VariableKind kind,
     858             :                          InitializationFlag initialization_flag,
     859             :                          MaybeAssignedFlag maybe_assigned_flag) {
     860             :   bool added;
     861             :   Variable* var =
     862             :       variables_.Declare(zone, this, name, mode, kind, initialization_flag,
     863    48966242 :                          maybe_assigned_flag, &added);
     864    48966228 :   if (added) locals_.Add(var);
     865    48966228 :   return var;
     866             : }
     867             : 
     868      685823 : void Scope::Snapshot::Reparent(DeclarationScope* new_parent) const {
     869             :   DCHECK_EQ(new_parent, outer_scope_->inner_scope_);
     870             :   DCHECK_EQ(new_parent->outer_scope_, outer_scope_);
     871             :   DCHECK_EQ(new_parent, new_parent->GetClosureScope());
     872             :   DCHECK_NULL(new_parent->inner_scope_);
     873             :   DCHECK_NULL(new_parent->unresolved_);
     874             :   DCHECK(new_parent->locals_.is_empty());
     875      686235 :   Scope* inner_scope = new_parent->sibling_;
     876      685823 :   if (inner_scope != top_inner_scope_) {
     877        2983 :     for (; inner_scope->sibling() != top_inner_scope_;
     878             :          inner_scope = inner_scope->sibling()) {
     879         412 :       inner_scope->outer_scope_ = new_parent;
     880         412 :       if (inner_scope->inner_scope_calls_eval_) {
     881           0 :         new_parent->inner_scope_calls_eval_ = true;
     882             :       }
     883             :       DCHECK_NE(inner_scope, new_parent);
     884             :     }
     885        2571 :     inner_scope->outer_scope_ = new_parent;
     886        2571 :     if (inner_scope->inner_scope_calls_eval_) {
     887         162 :       new_parent->inner_scope_calls_eval_ = true;
     888             :     }
     889        2571 :     new_parent->inner_scope_ = new_parent->sibling_;
     890        2571 :     inner_scope->sibling_ = nullptr;
     891             :     // Reset the sibling rather than the inner_scope_ since we
     892             :     // want to keep new_parent there.
     893        2571 :     new_parent->sibling_ = top_inner_scope_;
     894             :   }
     895             : 
     896      685823 :   if (outer_scope_->unresolved_ != top_unresolved_) {
     897      627851 :     VariableProxy* last = outer_scope_->unresolved_;
     898      627851 :     while (last->next_unresolved() != top_unresolved_) {
     899             :       last = last->next_unresolved();
     900             :     }
     901             :     last->set_next_unresolved(nullptr);
     902      283605 :     new_parent->unresolved_ = outer_scope_->unresolved_;
     903      283605 :     outer_scope_->unresolved_ = top_unresolved_;
     904             :   }
     905             : 
     906             :   // TODO(verwaest): This currently only moves do-expression declared variables
     907             :   // in default arguments that weren't already previously declared with the same
     908             :   // name in the closure-scope. See
     909             :   // test/mjsunit/harmony/default-parameter-do-expression.js.
     910      685823 :   DeclarationScope* outer_closure = outer_scope_->GetClosureScope();
     911             : 
     912             :   new_parent->locals_.MoveTail(outer_closure->locals(), top_local_);
     913     1374694 :   for (Variable* local : new_parent->locals_) {
     914             :     DCHECK(local->mode() == TEMPORARY || local->mode() == VAR);
     915             :     DCHECK_EQ(local->scope(), local->scope()->GetClosureScope());
     916             :     DCHECK_NE(local->scope(), new_parent);
     917             :     local->set_scope(new_parent);
     918        1524 :     if (local->mode() == VAR) {
     919             :       outer_closure->variables_.Remove(local);
     920          29 :       new_parent->variables_.Add(new_parent->zone(), local);
     921             :     }
     922             :   }
     923             :   outer_closure->locals_.Rewind(top_local_);
     924             :   outer_closure->decls_.Rewind(top_decl_);
     925             : 
     926             :   // Move eval calls since Snapshot's creation into new_parent.
     927      685823 :   if (outer_scope_->scope_calls_eval_) {
     928         512 :     new_parent->scope_calls_eval_ = true;
     929         512 :     new_parent->inner_scope_calls_eval_ = true;
     930             :   }
     931             :   // Reset the outer_scope's eval state. It will be restored to its
     932             :   // original value as necessary in the destructor of this class.
     933      685823 :   outer_scope_->scope_calls_eval_ = false;
     934      685823 : }
     935             : 
     936     1541479 : void Scope::ReplaceOuterScope(Scope* outer) {
     937             :   DCHECK_NOT_NULL(outer);
     938             :   DCHECK_NOT_NULL(outer_scope_);
     939             :   DCHECK(!already_resolved_);
     940     1541479 :   outer_scope_->RemoveInnerScope(this);
     941             :   outer->AddInnerScope(this);
     942             :   outer_scope_ = outer;
     943     1541479 : }
     944             : 
     945     5043164 : Variable* Scope::LookupInScopeInfo(const AstRawString* name) {
     946             :   Handle<String> name_handle = name->string();
     947             :   // The Scope is backed up by ScopeInfo. This means it cannot operate in a
     948             :   // heap-independent mode, and all strings must be internalized immediately. So
     949             :   // it's ok to get the Handle<String> here.
     950             :   // If we have a serialized scope info, we might find the variable there.
     951             :   // There should be no local slot with the given name.
     952             :   DCHECK_LT(scope_info_->StackSlotIndex(*name_handle), 0);
     953             : 
     954             :   bool found = false;
     955             : 
     956             :   VariableLocation location;
     957             :   int index;
     958             :   VariableMode mode;
     959             :   InitializationFlag init_flag;
     960             :   MaybeAssignedFlag maybe_assigned_flag;
     961             : 
     962             :   {
     963             :     location = VariableLocation::CONTEXT;
     964             :     index = ScopeInfo::ContextSlotIndex(scope_info_, name_handle, &mode,
     965     2521334 :                                         &init_flag, &maybe_assigned_flag);
     966     2521334 :     found = index >= 0;
     967             :   }
     968             : 
     969     3736474 :   if (!found && scope_type() == MODULE_SCOPE) {
     970             :     location = VariableLocation::MODULE;
     971             :     index = scope_info_->ModuleIndex(name_handle, &mode, &init_flag,
     972        5331 :                                      &maybe_assigned_flag);
     973        5331 :     found = index != 0;
     974             :   }
     975             : 
     976     2521334 :   if (!found) {
     977     1214644 :     index = scope_info_->FunctionContextSlotIndex(*name_handle);
     978     1214644 :     if (index < 0) return nullptr;  // Nowhere found.
     979        1425 :     Variable* var = AsDeclarationScope()->DeclareFunctionVar(name);
     980             :     DCHECK_EQ(CONST, var->mode());
     981             :     var->AllocateTo(VariableLocation::CONTEXT, index);
     982        1425 :     return variables_.Lookup(name);
     983             :   }
     984             : 
     985             :   VariableKind kind = NORMAL_VARIABLE;
     986     2612884 :   if (location == VariableLocation::CONTEXT &&
     987     1306194 :       index == scope_info_->ReceiverContextSlotIndex()) {
     988             :     kind = THIS_VARIABLE;
     989             :   }
     990             :   // TODO(marja, rossberg): Correctly declare FUNCTION, CLASS, NEW_TARGET, and
     991             :   // ARGUMENTS bindings as their corresponding VariableKind.
     992             : 
     993             :   Variable* var = variables_.Declare(zone(), this, name, mode, kind, init_flag,
     994     2613380 :                                      maybe_assigned_flag);
     995             :   var->AllocateTo(location, index);
     996     1306690 :   return var;
     997             : }
     998             : 
     999       32216 : Variable* Scope::Lookup(const AstRawString* name) {
    1000       33742 :   for (Scope* scope = this;
    1001             :        scope != NULL;
    1002             :        scope = scope->outer_scope()) {
    1003       33742 :     Variable* var = scope->LookupLocal(name);
    1004       33742 :     if (var != NULL) return var;
    1005             :   }
    1006             :   return NULL;
    1007             : }
    1008             : 
    1009     9006180 : Variable* DeclarationScope::DeclareParameter(
    1010             :     const AstRawString* name, VariableMode mode, bool is_optional, bool is_rest,
    1011     9006181 :     bool* is_duplicate, AstValueFactory* ast_value_factory, int position) {
    1012             :   DCHECK(!already_resolved_);
    1013             :   DCHECK(is_function_scope() || is_module_scope());
    1014             :   DCHECK(!has_rest_);
    1015             :   DCHECK(!is_optional || !is_rest);
    1016             :   DCHECK(!is_being_lazily_parsed_);
    1017             :   DCHECK(!was_lazily_parsed_);
    1018             :   Variable* var;
    1019     9006180 :   if (mode == TEMPORARY) {
    1020    18012361 :     var = NewTemporary(name);
    1021             :   } else {
    1022             :     DCHECK_EQ(mode, VAR);
    1023    17767584 :     var = Declare(zone(), name, mode);
    1024             :     // TODO(wingo): Avoid O(n^2) check.
    1025     8883793 :     *is_duplicate = IsDeclaredParameter(name);
    1026             :   }
    1027     9006181 :   has_rest_ = is_rest;
    1028             :   var->set_initializer_position(position);
    1029             :   params_.Add(var, zone());
    1030     9006181 :   if (name == ast_value_factory->arguments_string()) {
    1031        1253 :     has_arguments_parameter_ = true;
    1032             :   }
    1033     9006181 :   return var;
    1034             : }
    1035             : 
    1036      651128 : Variable* DeclarationScope::DeclareParameterName(
    1037             :     const AstRawString* name, bool is_rest,
    1038      651128 :     AstValueFactory* ast_value_factory) {
    1039             :   DCHECK(!already_resolved_);
    1040             :   DCHECK(is_function_scope() || is_module_scope());
    1041             :   DCHECK(!has_rest_ || is_rest);
    1042             :   DCHECK(is_being_lazily_parsed_);
    1043      651128 :   has_rest_ = is_rest;
    1044      651128 :   if (name == ast_value_factory->arguments_string()) {
    1045           7 :     has_arguments_parameter_ = true;
    1046             :   }
    1047      651128 :   if (FLAG_experimental_preparser_scope_analysis) {
    1048        4978 :     Variable* var = Declare(zone(), name, VAR);
    1049             :     params_.Add(var, zone());
    1050             :     return var;
    1051             :   }
    1052      646150 :   DeclareVariableName(name, VAR);
    1053      646150 :   return nullptr;
    1054             : }
    1055             : 
    1056      750946 : Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode,
    1057             :                               InitializationFlag init_flag, VariableKind kind,
    1058    16373841 :                               MaybeAssignedFlag maybe_assigned_flag) {
    1059             :   DCHECK(!already_resolved_);
    1060             :   // This function handles VAR, LET, and CONST modes.  DYNAMIC variables are
    1061             :   // introduced during variable allocation, and TEMPORARY variables are
    1062             :   // allocated via NewTemporary().
    1063             :   DCHECK(IsDeclaredVariableMode(mode));
    1064             :   DCHECK_IMPLIES(GetDeclarationScope()->is_being_lazily_parsed(),
    1065             :                  mode == VAR || mode == LET || mode == CONST);
    1066             :   DCHECK(!GetDeclarationScope()->was_lazily_parsed());
    1067    32747682 :   return Declare(zone(), name, mode, kind, init_flag, maybe_assigned_flag);
    1068             : }
    1069             : 
    1070    18418634 : Variable* Scope::DeclareVariable(
    1071    16427514 :     Declaration* declaration, VariableMode mode, InitializationFlag init,
    1072             :     bool allow_harmony_restrictive_generators,
    1073    16756424 :     bool* sloppy_mode_block_scope_function_redefinition, bool* ok) {
    1074             :   DCHECK(IsDeclaredVariableMode(mode));
    1075             :   DCHECK(!already_resolved_);
    1076             :   DCHECK(!GetDeclarationScope()->is_being_lazily_parsed());
    1077             :   DCHECK(!GetDeclarationScope()->was_lazily_parsed());
    1078             : 
    1079    35014538 :   if (mode == VAR && !is_declaration_scope()) {
    1080             :     return GetDeclarationScope()->DeclareVariable(
    1081             :         declaration, mode, init, allow_harmony_restrictive_generators,
    1082     3982240 :         sloppy_mode_block_scope_function_redefinition, ok);
    1083             :   }
    1084             :   DCHECK(!is_catch_scope());
    1085             :   DCHECK(!is_with_scope());
    1086             :   DCHECK(is_declaration_scope() ||
    1087             :          (IsLexicalVariableMode(mode) && is_block_scope()));
    1088             : 
    1089             :   VariableProxy* proxy = declaration->proxy();
    1090             :   DCHECK(proxy->raw_name() != NULL);
    1091         478 :   const AstRawString* name = proxy->raw_name();
    1092             :   bool is_function_declaration = declaration->IsFunctionDeclaration();
    1093             : 
    1094             :   // Pessimistically assume that top-level variables will be assigned.
    1095             :   //
    1096             :   // Top-level variables in a script can be accessed by other scripts or even
    1097             :   // become global properties. While this does not apply to top-level variables
    1098             :   // in a module (assuming they are not exported), we must still mark these as
    1099             :   // assigned because they might be accessed by a lazily parsed top-level
    1100             :   // function, which, for efficiency, we preparse without variable tracking.
    1101    16427514 :   if (is_script_scope() || is_module_scope()) {
    1102     2427299 :     if (mode != CONST) proxy->set_is_assigned();
    1103             :   }
    1104             : 
    1105      436349 :   Variable* var = nullptr;
    1106    17566000 :   if (is_eval_scope() && is_sloppy(language_mode()) && mode == VAR) {
    1107             :     // In a var binding in a sloppy direct eval, pollute the enclosing scope
    1108             :     // with this new binding by doing the following:
    1109             :     // The proxy is bound to a lookup variable to force a dynamic declaration
    1110             :     // using the DeclareEvalVar or DeclareEvalFunction runtime functions.
    1111             :     var = new (zone())
    1112      328910 :         Variable(this, name, mode, NORMAL_VARIABLE, init, kMaybeAssigned);
    1113             :     var->AllocateTo(VariableLocation::LOOKUP, -1);
    1114             :   } else {
    1115             :     // Declare the variable in the declaration scope.
    1116    16098604 :     var = LookupLocal(name);
    1117    16098605 :     if (var == NULL) {
    1118             :       // Declare the name.
    1119             :       VariableKind kind = NORMAL_VARIABLE;
    1120    15594997 :       if (is_function_declaration) {
    1121             :         kind = FUNCTION_VARIABLE;
    1122             :       }
    1123             :       var = DeclareLocal(name, mode, init, kind, kNotAssigned);
    1124      939957 :     } else if (IsLexicalVariableMode(mode) ||
    1125             :                IsLexicalVariableMode(var->mode())) {
    1126             :       // Allow duplicate function decls for web compat, see bug 4693.
    1127             :       bool duplicate_allowed = false;
    1128       81612 :       if (is_sloppy(language_mode()) && is_function_declaration &&
    1129             :           var->is_function()) {
    1130             :         DCHECK(IsLexicalVariableMode(mode) &&
    1131             :                IsLexicalVariableMode(var->mode()));
    1132             :         // If the duplication is allowed, then the var will show up
    1133             :         // in the SloppyBlockFunctionMap and the new FunctionKind
    1134             :         // will be a permitted duplicate.
    1135             :         FunctionKind function_kind =
    1136        1436 :             declaration->AsFunctionDeclaration()->fun()->kind();
    1137             :         SloppyBlockFunctionMap* map =
    1138         718 :             GetDeclarationScope()->sloppy_block_function_map();
    1139         478 :         duplicate_allowed = map != nullptr &&
    1140             :                             map->Lookup(const_cast<AstRawString*>(name),
    1141        2152 :                                         name->hash()) != nullptr &&
    1142        1004 :                             !IsAsyncFunction(function_kind) &&
    1143             :                             !(allow_harmony_restrictive_generators &&
    1144         240 :                               IsGeneratorFunction(function_kind));
    1145             :       }
    1146       80515 :       if (duplicate_allowed) {
    1147         238 :         *sloppy_mode_block_scope_function_redefinition = true;
    1148             :       } else {
    1149             :         // The name was declared in this scope before; check for conflicting
    1150             :         // re-declarations. We have a conflict if either of the declarations
    1151             :         // is not a var (in script scope, we also have to ignore legacy const
    1152             :         // for compatibility). There is similar code in runtime.cc in the
    1153             :         // Declare functions. The function CheckConflictingVarDeclarations
    1154             :         // checks for var and let bindings from different scopes whereas this
    1155             :         // is a check for conflicting declarations within the same scope. This
    1156             :         // check also covers the special case
    1157             :         //
    1158             :         // function () { let x; { var x; } }
    1159             :         //
    1160             :         // because the var declaration is hoisted to the function scope where
    1161             :         // 'x' is already bound.
    1162             :         DCHECK(IsDeclaredVariableMode(var->mode()));
    1163             :         // In harmony we treat re-declarations as early errors. See
    1164             :         // ES5 16 for a definition of early errors.
    1165       80277 :         *ok = false;
    1166       80277 :         return nullptr;
    1167             :       }
    1168      423093 :     } else if (mode == VAR) {
    1169             :       var->set_maybe_assigned();
    1170             :     }
    1171             :   }
    1172             :   DCHECK_NOT_NULL(var);
    1173             : 
    1174             :   // We add a declaration node for every declaration. The compiler
    1175             :   // will only generate code if necessary. In particular, declarations
    1176             :   // for inner local variables that do not represent functions won't
    1177             :   // result in any generated code.
    1178             :   //
    1179             :   // This will lead to multiple declaration nodes for the
    1180             :   // same variable if it is declared several times. This is not a
    1181             :   // semantic issue, but it may be a performance issue since it may
    1182             :   // lead to repeated DeclareEvalVar or DeclareEvalFunction calls.
    1183             :   decls_.Add(declaration);
    1184    16347236 :   proxy->BindTo(var);
    1185    16347237 :   return var;
    1186             : }
    1187             : 
    1188     1836741 : Variable* Scope::DeclareVariableName(const AstRawString* name,
    1189     1409420 :                                      VariableMode mode) {
    1190             :   DCHECK(IsDeclaredVariableMode(mode));
    1191             :   DCHECK(!already_resolved_);
    1192             :   DCHECK(GetDeclarationScope()->is_being_lazily_parsed());
    1193             : 
    1194     3612353 :   if (mode == VAR && !is_declaration_scope()) {
    1195      796282 :     return GetDeclarationScope()->DeclareVariableName(name, mode);
    1196             :   }
    1197             :   DCHECK(!is_with_scope());
    1198             :   DCHECK(!is_eval_scope());
    1199             :   // Unlike DeclareVariable, DeclareVariableName allows declaring variables in
    1200             :   // catch scopes: Parser::RewriteCatchPattern bypasses DeclareVariable by
    1201             :   // calling DeclareLocal directly, and it doesn't make sense to add a similar
    1202             :   // bypass mechanism for PreParser.
    1203             :   DCHECK(is_declaration_scope() || (IsLexicalVariableMode(mode) &&
    1204             :                                     (is_block_scope() || is_catch_scope())));
    1205             :   DCHECK(scope_info_.is_null());
    1206             : 
    1207             :   // Declare the variable in the declaration scope.
    1208     1438600 :   if (FLAG_experimental_preparser_scope_analysis) {
    1209       29180 :     Variable* var = LookupLocal(name);
    1210             :     DCHECK_NE(var, kDummyPreParserLexicalVariable);
    1211             :     DCHECK_NE(var, kDummyPreParserVariable);
    1212       29180 :     if (var == nullptr) {
    1213             :       var = DeclareLocal(name, mode);
    1214        1282 :     } else if (mode == VAR) {
    1215             :       DCHECK_EQ(var->mode(), VAR);
    1216             :       var->set_maybe_assigned();
    1217             :     }
    1218             :     var->set_is_used();
    1219       29180 :     return var;
    1220             :   } else {
    1221     2818840 :     return variables_.DeclareName(zone(), name, mode);
    1222             :   }
    1223             : }
    1224             : 
    1225   106191558 : VariableProxy* Scope::NewUnresolved(AstNodeFactory* factory,
    1226             :                                     const AstRawString* name,
    1227             :                                     int start_position, VariableKind kind) {
    1228             :   // Note that we must not share the unresolved variables with
    1229             :   // the same name because they may be removed selectively via
    1230             :   // RemoveUnresolved().
    1231             :   DCHECK(!already_resolved_);
    1232             :   DCHECK_EQ(factory->zone(), zone());
    1233             :   VariableProxy* proxy = factory->NewVariableProxy(name, kind, start_position);
    1234   106191517 :   proxy->set_next_unresolved(unresolved_);
    1235   106191517 :   unresolved_ = proxy;
    1236   106191517 :   return proxy;
    1237             : }
    1238             : 
    1239        1457 : void Scope::AddUnresolved(VariableProxy* proxy) {
    1240             :   DCHECK(!already_resolved_);
    1241             :   DCHECK(!proxy->is_resolved());
    1242        1457 :   proxy->set_next_unresolved(unresolved_);
    1243        1457 :   unresolved_ = proxy;
    1244        1457 : }
    1245             : 
    1246     8101489 : Variable* DeclarationScope::DeclareDynamicGlobal(const AstRawString* name,
    1247             :                                                  VariableKind kind) {
    1248             :   DCHECK(is_script_scope());
    1249     8101489 :   return variables_.Declare(zone(), this, name, DYNAMIC_GLOBAL, kind);
    1250             :   // TODO(neis): Mark variable as maybe-assigned?
    1251             : }
    1252             : 
    1253             : 
    1254    25961694 : bool Scope::RemoveUnresolved(VariableProxy* var) {
    1255    15175552 :   if (unresolved_ == var) {
    1256    10786142 :     unresolved_ = var->next_unresolved();
    1257             :     var->set_next_unresolved(nullptr);
    1258    10786142 :     return true;
    1259             :   }
    1260     8120917 :   VariableProxy* current = unresolved_;
    1261     8122402 :   while (current != nullptr) {
    1262     4387925 :     VariableProxy* next = current->next_unresolved();
    1263     8120917 :     if (var == next) {
    1264             :       current->set_next_unresolved(next->next_unresolved());
    1265             :       var->set_next_unresolved(nullptr);
    1266     4387925 :       return true;
    1267             :     }
    1268             :     current = next;
    1269             :   }
    1270             :   return false;
    1271             : }
    1272             : 
    1273     3725422 : Variable* Scope::NewTemporary(const AstRawString* name) {
    1274     3891540 :   return NewTemporary(name, kMaybeAssigned);
    1275             : }
    1276             : 
    1277     4002381 : Variable* Scope::NewTemporary(const AstRawString* name,
    1278     4002381 :                               MaybeAssignedFlag maybe_assigned) {
    1279             :   DeclarationScope* scope = GetClosureScope();
    1280             :   Variable* var = new (zone())
    1281     4002387 :       Variable(scope, name, TEMPORARY, NORMAL_VARIABLE, kCreatedInitialized);
    1282             :   scope->AddLocal(var);
    1283     4002388 :   if (maybe_assigned == kMaybeAssigned) var->set_maybe_assigned();
    1284     4002388 :   return var;
    1285             : }
    1286             : 
    1287    11036823 : Declaration* Scope::CheckConflictingVarDeclarations() {
    1288    65547649 :   for (Declaration* decl : decls_) {
    1289    15541858 :     VariableMode mode = decl->proxy()->var()->mode();
    1290    16591480 :     if (IsLexicalVariableMode(mode) && !is_block_scope()) continue;
    1291             : 
    1292             :     // Iterate through all scopes until and including the declaration scope.
    1293             :     Scope* previous = NULL;
    1294             :     Scope* current = decl->scope();
    1295             :     // Lexical vs lexical conflicts within the same scope have already been
    1296             :     // captured in Parser::Declare. The only conflicts we still need to check
    1297             :     // are lexical vs VAR, or any declarations within a declaration block scope
    1298             :     // vs lexical declarations in its surrounding (function) scope.
    1299    14527527 :     if (IsLexicalVariableMode(mode)) current = current->outer_scope_;
    1300    18128658 :     do {
    1301             :       // There is a conflict if there exists a non-VAR binding.
    1302    14192219 :       Variable* other_var =
    1303    18166654 :           current->variables_.Lookup(decl->proxy()->raw_name());
    1304    32358873 :       if (other_var != NULL && IsLexicalVariableMode(other_var->mode())) {
    1305             :         return decl;
    1306             :       }
    1307             :       previous = current;
    1308    18128658 :       current = current->outer_scope_;
    1309             :     } while (!previous->is_declaration_scope());
    1310             :   }
    1311             :   return NULL;
    1312             : }
    1313             : 
    1314        1619 : Declaration* Scope::CheckLexDeclarationsConflictingWith(
    1315             :     const ZoneList<const AstRawString*>& names) {
    1316             :   DCHECK(is_block_scope());
    1317        5412 :   for (int i = 0; i < names.length(); ++i) {
    1318        4325 :     Variable* var = LookupLocal(names.at(i));
    1319        1619 :     if (var != nullptr) {
    1320             :       // Conflict; find and return its declaration.
    1321             :       DCHECK(IsLexicalVariableMode(var->mode()));
    1322         532 :       const AstRawString* name = names.at(i);
    1323        2156 :       for (Declaration* decl : decls_) {
    1324         812 :         if (decl->proxy()->raw_name() == name) return decl;
    1325             :       }
    1326             :       DCHECK(false);
    1327             :     }
    1328             :   }
    1329             :   return nullptr;
    1330             : }
    1331             : 
    1332     2876570 : void DeclarationScope::AllocateVariables(ParseInfo* info, Isolate* isolate,
    1333             :                                          AnalyzeMode mode) {
    1334             :   // Module variables must be allocated before variable resolution
    1335             :   // to ensure that AccessNeedsHoleCheck() can detect import variables.
    1336     4336389 :   if (is_module_scope()) AsModuleScope()->AllocateModuleVariables();
    1337             : 
    1338     2876570 :   ResolveVariablesRecursively(info);
    1339     2876580 :   AllocateVariablesRecursively();
    1340             : 
    1341             :   MaybeHandle<ScopeInfo> outer_scope;
    1342     2876581 :   if (outer_scope_ != nullptr) outer_scope = outer_scope_->scope_info_;
    1343             : 
    1344     2876581 :   AllocateScopeInfosRecursively(isolate, outer_scope);
    1345     2876581 :   if (mode == AnalyzeMode::kDebugger) {
    1346      194942 :     AllocateDebuggerScopeInfos(isolate, outer_scope);
    1347             :   }
    1348             :   // The debugger expects all shared function infos to contain a scope info.
    1349             :   // Since the top-most scope will end up in a shared function info, make sure
    1350             :   // it has one, even if it doesn't need a scope info.
    1351             :   // TODO(jochen|yangguo): Remove this requirement.
    1352     2876581 :   if (scope_info_.is_null()) {
    1353     2919638 :     scope_info_ = ScopeInfo::Create(isolate, zone(), this, outer_scope);
    1354             :   }
    1355     2876582 : }
    1356             : 
    1357     8492807 : bool Scope::AllowsLazyParsingWithoutUnresolvedVariables(
    1358             :     const Scope* outer) const {
    1359             :   // If none of the outer scopes need to decide whether to context allocate
    1360             :   // specific variables, we can preparse inner functions without unresolved
    1361             :   // variables. Otherwise we need to find unresolved variables to force context
    1362             :   // allocation of the matching declarations. We can stop at the outer scope for
    1363             :   // the parse, since context allocation of those variables is already
    1364             :   // guaranteed to be correct.
    1365     8545520 :   for (const Scope* s = this; s != outer; s = s->outer_scope_) {
    1366             :     // Eval forces context allocation on all outer scopes, so we don't need to
    1367             :     // look at those scopes. Sloppy eval makes top-level non-lexical variables
    1368             :     // dynamic, whereas strict-mode requires context allocation.
    1369     6738932 :     if (s->is_eval_scope()) return is_sloppy(s->language_mode());
    1370             :     // Catch scopes force context allocation of all variables.
    1371     5212132 :     if (s->is_catch_scope()) continue;
    1372             :     // With scopes do not introduce variables that need allocation.
    1373     5211626 :     if (s->is_with_scope()) continue;
    1374             :     // If everything is guaranteed to be context allocated we can ignore the
    1375             :     // scope.
    1376     5211170 :     if (s->has_forced_context_allocation()) continue;
    1377             :     // Only block scopes and function scopes should disallow preparsing.
    1378             :     DCHECK(s->is_block_scope() || s->is_function_scope());
    1379             :     return false;
    1380             :   }
    1381             :   return true;
    1382             : }
    1383             : 
    1384     7235378 : bool DeclarationScope::AllowsLazyCompilation() const {
    1385     7235378 :   return !force_eager_compilation_;
    1386             : }
    1387             : 
    1388     6901825 : int Scope::ContextChainLength(Scope* scope) const {
    1389             :   int n = 0;
    1390     9064220 :   for (const Scope* s = this; s != scope; s = s->outer_scope_) {
    1391             :     DCHECK(s != NULL);  // scope must be in the scope chain
    1392     2162395 :     if (s->NeedsContext()) n++;
    1393             :   }
    1394     6901825 :   return n;
    1395             : }
    1396             : 
    1397      463047 : int Scope::ContextChainLengthUntilOutermostSloppyEval() const {
    1398             :   int result = 0;
    1399             :   int length = 0;
    1400             : 
    1401     1909897 :   for (const Scope* s = this; s != nullptr; s = s->outer_scope()) {
    1402     1446850 :     if (!s->NeedsContext()) continue;
    1403     1046258 :     length++;
    1404     1046258 :     if (s->calls_sloppy_eval()) result = length;
    1405             :   }
    1406             : 
    1407      463047 :   return result;
    1408             : }
    1409             : 
    1410     2424070 : int Scope::MaxNestedContextChainLength() {
    1411     2424070 :   int max_context_chain_length = 0;
    1412     6360240 :   for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
    1413     3936170 :     if (scope->is_function_scope()) continue;
    1414      346610 :     max_context_chain_length = std::max(scope->MaxNestedContextChainLength(),
    1415      693220 :                                         max_context_chain_length);
    1416             :   }
    1417     2424070 :   if (NeedsContext()) {
    1418      379809 :     max_context_chain_length += 1;
    1419             :   }
    1420     2424070 :   return max_context_chain_length;
    1421             : }
    1422             : 
    1423    20942412 : DeclarationScope* Scope::GetDeclarationScope() {
    1424    14016479 :   Scope* scope = this;
    1425    62457070 :   while (!scope->is_declaration_scope()) {
    1426             :     scope = scope->outer_scope();
    1427             :   }
    1428    20942412 :   return scope->AsDeclarationScope();
    1429             : }
    1430             : 
    1431           0 : const DeclarationScope* Scope::GetClosureScope() const {
    1432           0 :   const Scope* scope = this;
    1433           0 :   while (!scope->is_declaration_scope() || scope->is_block_scope()) {
    1434             :     scope = scope->outer_scope();
    1435             :   }
    1436           0 :   return scope->AsDeclarationScope();
    1437             : }
    1438             : 
    1439     1315214 : DeclarationScope* Scope::GetClosureScope() {
    1440   436714521 :   Scope* scope = this;
    1441   720982429 :   while (!scope->is_declaration_scope() || scope->is_block_scope()) {
    1442             :     scope = scope->outer_scope();
    1443             :   }
    1444     1315214 :   return scope->AsDeclarationScope();
    1445             : }
    1446             : 
    1447     4267312 : bool Scope::NeedsScopeInfo() const {
    1448             :   DCHECK(!already_resolved_);
    1449             :   DCHECK(GetClosureScope()->ShouldEagerCompile());
    1450             :   // The debugger expects all functions to have scope infos.
    1451             :   // TODO(jochen|yangguo): Remove this requirement.
    1452     4267312 :   if (is_function_scope()) return true;
    1453           0 :   return NeedsContext();
    1454             : }
    1455             : 
    1456           0 : ModuleScope* Scope::GetModuleScope() {
    1457           0 :   Scope* scope = this;
    1458             :   DCHECK(!scope->is_script_scope());
    1459           0 :   while (!scope->is_module_scope()) {
    1460             :     scope = scope->outer_scope();
    1461             :     DCHECK_NOT_NULL(scope);
    1462             :   }
    1463           0 :   return scope->AsModuleScope();
    1464             : }
    1465             : 
    1466       60795 : DeclarationScope* Scope::GetReceiverScope() {
    1467       18231 :   Scope* scope = this;
    1468      218847 :   while (!scope->is_script_scope() &&
    1469       57047 :          (!scope->is_function_scope() ||
    1470             :           scope->AsDeclarationScope()->is_arrow_scope())) {
    1471             :     scope = scope->outer_scope();
    1472             :   }
    1473       60795 :   return scope->AsDeclarationScope();
    1474             : }
    1475             : 
    1476     7826979 : Scope* Scope::GetOuterScopeWithContext() {
    1477    10002742 :   Scope* scope = outer_scope_;
    1478    27085543 :   while (scope && !scope->NeedsContext()) {
    1479             :     scope = scope->outer_scope();
    1480             :   }
    1481     7826979 :   return scope;
    1482             : }
    1483             : 
    1484      195620 : Handle<StringSet> DeclarationScope::CollectNonLocals(
    1485             :     ParseInfo* info, Handle<StringSet> non_locals) {
    1486      195620 :   VariableProxy* free_variables = FetchFreeVariables(this, info);
    1487     2812582 :   for (VariableProxy* proxy = free_variables; proxy != nullptr;
    1488             :        proxy = proxy->next_unresolved()) {
    1489     2616962 :     non_locals = StringSet::Add(non_locals, proxy->name());
    1490             :   }
    1491      195620 :   return non_locals;
    1492             : }
    1493             : 
    1494     1384502 : void DeclarationScope::ResetAfterPreparsing(AstValueFactory* ast_value_factory,
    1495             :                                             bool aborted) {
    1496             :   DCHECK(is_function_scope());
    1497             : 
    1498             :   // Reset all non-trivial members.
    1499     1384502 :   if (!aborted || !IsArrowFunction(function_kind_)) {
    1500             :     // Do not remove parameters when lazy parsing an Arrow Function has failed,
    1501             :     // as the formal parameters are not re-parsed.
    1502             :     params_.Clear();
    1503             :   }
    1504             :   decls_.Clear();
    1505             :   locals_.Clear();
    1506     1384450 :   inner_scope_ = nullptr;
    1507     1384450 :   unresolved_ = nullptr;
    1508     1384450 :   sloppy_block_function_map_ = nullptr;
    1509             : 
    1510     1384450 :   if (aborted) {
    1511             :     // Prepare scope for use in the outer zone.
    1512          52 :     zone_ = ast_value_factory->zone();
    1513          52 :     variables_.Reset(ZoneAllocationPolicy(zone_));
    1514         104 :     if (!IsArrowFunction(function_kind_)) {
    1515          44 :       DeclareDefaultFunctionVariables(ast_value_factory);
    1516             :     }
    1517             :   } else {
    1518             :     // Make sure this scope isn't used for allocation anymore.
    1519     1384398 :     zone_ = nullptr;
    1520             :     variables_.Invalidate();
    1521             :   }
    1522             : 
    1523             : #ifdef DEBUG
    1524             :   needs_migration_ = false;
    1525             :   is_being_lazily_parsed_ = false;
    1526             : #endif
    1527             : 
    1528     1384450 :   was_lazily_parsed_ = !aborted;
    1529     1384450 : }
    1530             : 
    1531     1355757 : void DeclarationScope::AnalyzePartially(
    1532     3890462 :     AstNodeFactory* ast_node_factory,
    1533       14815 :     PreParsedScopeData* preparsed_scope_data) {
    1534             :   DCHECK(!force_eager_compilation_);
    1535             :   VariableProxy* unresolved = nullptr;
    1536             : 
    1537     1355757 :   if (!outer_scope_->is_script_scope()) {
    1538             :     // Try to resolve unresolved variables for this Scope and migrate those
    1539             :     // which cannot be resolved inside. It doesn't make sense to try to resolve
    1540             :     // them in the outer Scopes here, because they are incomplete.
    1541     3134965 :     for (VariableProxy* proxy = FetchFreeVariables(this); proxy != nullptr;
    1542             :          proxy = proxy->next_unresolved()) {
    1543             :       DCHECK(!proxy->is_resolved());
    1544             :       VariableProxy* copy = ast_node_factory->CopyVariableProxy(proxy);
    1545             :       copy->set_next_unresolved(unresolved);
    1546             :       unresolved = copy;
    1547             :     }
    1548             : 
    1549             :     // Clear arguments_ if unused. This is used as a signal for optimization.
    1550     1730330 :     if (arguments_ != nullptr &&
    1551      541421 :         !(MustAllocate(arguments_) && !has_arguments_parameter_)) {
    1552      518206 :       arguments_ = nullptr;
    1553             :     }
    1554             : 
    1555      615075 :     if (FLAG_experimental_preparser_scope_analysis &&
    1556             :         preparsed_scope_data->Producing()) {
    1557             :       // Store the information needed for allocating the locals of this scope
    1558             :       // and its inner scopes.
    1559       14801 :       preparsed_scope_data->SaveData(this);
    1560             :     }
    1561             :   }
    1562             : #ifdef DEBUG
    1563             :   if (FLAG_print_scopes) {
    1564             :     PrintF("Inner function scope:\n");
    1565             :     Print();
    1566             :   }
    1567             : #endif
    1568             : 
    1569     1355757 :   ResetAfterPreparsing(ast_node_factory->ast_value_factory(), false);
    1570             : 
    1571     1355757 :   unresolved_ = unresolved;
    1572     1355757 : }
    1573             : 
    1574             : #ifdef DEBUG
    1575             : namespace {
    1576             : 
    1577             : const char* Header(ScopeType scope_type, FunctionKind function_kind,
    1578             :                    bool is_declaration_scope) {
    1579             :   switch (scope_type) {
    1580             :     case EVAL_SCOPE: return "eval";
    1581             :     // TODO(adamk): Should we print concise method scopes specially?
    1582             :     case FUNCTION_SCOPE:
    1583             :       if (IsGeneratorFunction(function_kind)) return "function*";
    1584             :       if (IsAsyncFunction(function_kind)) return "async function";
    1585             :       if (IsArrowFunction(function_kind)) return "arrow";
    1586             :       return "function";
    1587             :     case MODULE_SCOPE: return "module";
    1588             :     case SCRIPT_SCOPE: return "global";
    1589             :     case CATCH_SCOPE: return "catch";
    1590             :     case BLOCK_SCOPE: return is_declaration_scope ? "varblock" : "block";
    1591             :     case WITH_SCOPE: return "with";
    1592             :   }
    1593             :   UNREACHABLE();
    1594             :   return NULL;
    1595             : }
    1596             : 
    1597             : void Indent(int n, const char* str) { PrintF("%*s%s", n, "", str); }
    1598             : 
    1599             : void PrintName(const AstRawString* name) {
    1600             :   PrintF("%.*s", name->length(), name->raw_data());
    1601             : }
    1602             : 
    1603             : void PrintLocation(Variable* var) {
    1604             :   switch (var->location()) {
    1605             :     case VariableLocation::UNALLOCATED:
    1606             :       break;
    1607             :     case VariableLocation::PARAMETER:
    1608             :       PrintF("parameter[%d]", var->index());
    1609             :       break;
    1610             :     case VariableLocation::LOCAL:
    1611             :       PrintF("local[%d]", var->index());
    1612             :       break;
    1613             :     case VariableLocation::CONTEXT:
    1614             :       PrintF("context[%d]", var->index());
    1615             :       break;
    1616             :     case VariableLocation::LOOKUP:
    1617             :       PrintF("lookup");
    1618             :       break;
    1619             :     case VariableLocation::MODULE:
    1620             :       PrintF("module");
    1621             :       break;
    1622             :   }
    1623             : }
    1624             : 
    1625             : void PrintVar(int indent, Variable* var) {
    1626             :   Indent(indent, VariableMode2String(var->mode()));
    1627             :   PrintF(" ");
    1628             :   if (var->raw_name()->IsEmpty())
    1629             :     PrintF(".%p", reinterpret_cast<void*>(var));
    1630             :   else
    1631             :     PrintName(var->raw_name());
    1632             :   PrintF(";  // (%p) ", reinterpret_cast<void*>(var));
    1633             :   PrintLocation(var);
    1634             :   bool comma = !var->IsUnallocated();
    1635             :   if (var->has_forced_context_allocation()) {
    1636             :     if (comma) PrintF(", ");
    1637             :     PrintF("forced context allocation");
    1638             :     comma = true;
    1639             :   }
    1640             :   if (var->maybe_assigned() == kNotAssigned) {
    1641             :     if (comma) PrintF(", ");
    1642             :     PrintF("never assigned");
    1643             :   }
    1644             :   PrintF("\n");
    1645             : }
    1646             : 
    1647             : void PrintMap(int indent, const char* label, VariableMap* map, bool locals,
    1648             :               Variable* function_var) {
    1649             :   bool printed_label = false;
    1650             :   for (VariableMap::Entry* p = map->Start(); p != nullptr; p = map->Next(p)) {
    1651             :     Variable* var = reinterpret_cast<Variable*>(p->value);
    1652             :     if (var == function_var) continue;
    1653             :     if (var == kDummyPreParserVariable ||
    1654             :         var == kDummyPreParserLexicalVariable) {
    1655             :       continue;
    1656             :     }
    1657             :     bool local = !IsDynamicVariableMode(var->mode());
    1658             :     if ((locals ? local : !local) &&
    1659             :         (var->is_used() || !var->IsUnallocated())) {
    1660             :       if (!printed_label) {
    1661             :         Indent(indent, label);
    1662             :         printed_label = true;
    1663             :       }
    1664             :       PrintVar(indent, var);
    1665             :     }
    1666             :   }
    1667             : }
    1668             : 
    1669             : }  // anonymous namespace
    1670             : 
    1671             : void DeclarationScope::PrintParameters() {
    1672             :   PrintF(" (");
    1673             :   for (int i = 0; i < params_.length(); i++) {
    1674             :     if (i > 0) PrintF(", ");
    1675             :     const AstRawString* name = params_[i]->raw_name();
    1676             :     if (name->IsEmpty())
    1677             :       PrintF(".%p", reinterpret_cast<void*>(params_[i]));
    1678             :     else
    1679             :       PrintName(name);
    1680             :   }
    1681             :   PrintF(")");
    1682             : }
    1683             : 
    1684             : void Scope::Print(int n) {
    1685             :   int n0 = (n > 0 ? n : 0);
    1686             :   int n1 = n0 + 2;  // indentation
    1687             : 
    1688             :   // Print header.
    1689             :   FunctionKind function_kind = is_function_scope()
    1690             :                                    ? AsDeclarationScope()->function_kind()
    1691             :                                    : kNormalFunction;
    1692             :   Indent(n0, Header(scope_type_, function_kind, is_declaration_scope()));
    1693             :   if (scope_name_ != nullptr && !scope_name_->IsEmpty()) {
    1694             :     PrintF(" ");
    1695             :     PrintName(scope_name_);
    1696             :   }
    1697             : 
    1698             :   // Print parameters, if any.
    1699             :   Variable* function = nullptr;
    1700             :   if (is_function_scope()) {
    1701             :     AsDeclarationScope()->PrintParameters();
    1702             :     function = AsDeclarationScope()->function_var();
    1703             :   }
    1704             : 
    1705             :   PrintF(" { // (%p) (%d, %d)\n", reinterpret_cast<void*>(this),
    1706             :          start_position(), end_position());
    1707             :   if (is_hidden()) {
    1708             :     Indent(n1, "// is hidden\n");
    1709             :   }
    1710             : 
    1711             :   // Function name, if any (named function literals, only).
    1712             :   if (function != nullptr) {
    1713             :     Indent(n1, "// (local) function name: ");
    1714             :     PrintName(function->raw_name());
    1715             :     PrintF("\n");
    1716             :   }
    1717             : 
    1718             :   // Scope info.
    1719             :   if (is_strict(language_mode())) {
    1720             :     Indent(n1, "// strict mode scope\n");
    1721             :   }
    1722             :   if (IsAsmModule()) Indent(n1, "// scope is an asm module\n");
    1723             :   if (IsAsmFunction()) Indent(n1, "// scope is an asm function\n");
    1724             :   if (scope_calls_eval_) Indent(n1, "// scope calls 'eval'\n");
    1725             :   if (is_declaration_scope() && AsDeclarationScope()->uses_super_property()) {
    1726             :     Indent(n1, "// scope uses 'super' property\n");
    1727             :   }
    1728             :   if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n");
    1729             :   if (is_declaration_scope()) {
    1730             :     DeclarationScope* scope = AsDeclarationScope();
    1731             :     if (scope->was_lazily_parsed()) Indent(n1, "// lazily parsed\n");
    1732             :     if (scope->ShouldEagerCompile()) Indent(n1, "// will be compiled\n");
    1733             :   }
    1734             :   if (has_forced_context_allocation()) {
    1735             :     Indent(n1, "// forces context allocation\n");
    1736             :   }
    1737             :   if (num_stack_slots_ > 0) {
    1738             :     Indent(n1, "// ");
    1739             :     PrintF("%d stack slots\n", num_stack_slots_);
    1740             :   }
    1741             :   if (num_heap_slots_ > 0) {
    1742             :     Indent(n1, "// ");
    1743             :     PrintF("%d heap slots\n", num_heap_slots_);
    1744             :   }
    1745             : 
    1746             :   // Print locals.
    1747             :   if (function != nullptr) {
    1748             :     Indent(n1, "// function var:\n");
    1749             :     PrintVar(n1, function);
    1750             :   }
    1751             : 
    1752             :   // Print temporaries.
    1753             :   {
    1754             :     bool printed_header = false;
    1755             :     for (Variable* local : locals_) {
    1756             :       if (local->mode() != TEMPORARY) continue;
    1757             :       if (!printed_header) {
    1758             :         printed_header = true;
    1759             :         Indent(n1, "// temporary vars:\n");
    1760             :       }
    1761             :       PrintVar(n1, local);
    1762             :     }
    1763             :   }
    1764             : 
    1765             :   if (variables_.occupancy() > 0) {
    1766             :     PrintMap(n1, "// local vars:\n", &variables_, true, function);
    1767             :     PrintMap(n1, "// dynamic vars:\n", &variables_, false, function);
    1768             :   }
    1769             : 
    1770             :   // Print inner scopes (disable by providing negative n).
    1771             :   if (n >= 0) {
    1772             :     for (Scope* scope = inner_scope_; scope != nullptr;
    1773             :          scope = scope->sibling_) {
    1774             :       PrintF("\n");
    1775             :       scope->Print(n1);
    1776             :     }
    1777             :   }
    1778             : 
    1779             :   Indent(n0, "}\n");
    1780             : }
    1781             : 
    1782             : void Scope::CheckScopePositions() {
    1783             :   // Visible leaf scopes must have real positions.
    1784             :   if (!is_hidden() && inner_scope_ == nullptr) {
    1785             :     CHECK_NE(kNoSourcePosition, start_position());
    1786             :     CHECK_NE(kNoSourcePosition, end_position());
    1787             :   }
    1788             :   for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
    1789             :     scope->CheckScopePositions();
    1790             :   }
    1791             : }
    1792             : 
    1793             : void Scope::CheckZones() {
    1794             :   DCHECK(!needs_migration_);
    1795             :   for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
    1796             :     if (scope->is_declaration_scope() &&
    1797             :         scope->AsDeclarationScope()->was_lazily_parsed()) {
    1798             :       DCHECK_NULL(scope->zone());
    1799             :       DCHECK_NULL(scope->inner_scope_);
    1800             :       continue;
    1801             :     }
    1802             :     CHECK_EQ(scope->zone(), zone());
    1803             :     scope->CheckZones();
    1804             :   }
    1805             : }
    1806             : #endif  // DEBUG
    1807             : 
    1808     1796790 : Variable* Scope::NonLocal(const AstRawString* name, VariableMode mode) {
    1809             :   // Declare a new non-local.
    1810             :   DCHECK(IsDynamicVariableMode(mode));
    1811     1796790 :   Variable* var = variables_.Declare(zone(), nullptr, name, mode);
    1812             :   // Allocate it by giving it a dynamic lookup.
    1813             :   var->AllocateTo(VariableLocation::LOOKUP, -1);
    1814      898395 :   return var;
    1815             : }
    1816             : 
    1817   138662785 : Variable* Scope::LookupRecursive(VariableProxy* proxy, Scope* outer_scope_end) {
    1818             :   DCHECK_NE(outer_scope_end, this);
    1819             :   // Short-cut: whenever we find a debug-evaluate scope, just look everything up
    1820             :   // dynamically. Debug-evaluate doesn't properly create scope info for the
    1821             :   // lookups it does. It may not have a valid 'this' declaration, and anything
    1822             :   // accessed through debug-evaluate might invalidly resolve to stack-allocated
    1823             :   // variables.
    1824             :   // TODO(yangguo): Remove once debug-evaluate creates proper ScopeInfo for the
    1825             :   // scopes in which it's evaluating.
    1826   110844551 :   if (is_debug_evaluate_scope_) return NonLocal(proxy->raw_name(), DYNAMIC);
    1827             : 
    1828             :   // Try to find the variable in this scope.
    1829   110815633 :   Variable* var = LookupLocal(proxy->raw_name());
    1830             : 
    1831             :   // We found a variable and we are done. (Even if there is an 'eval' in this
    1832             :   // scope which introduces the same variable again, the resulting variable
    1833             :   // remains the same.)
    1834   110815655 :   if (var != nullptr) return var;
    1835             : 
    1836    28041063 :   if (outer_scope_ == outer_scope_end) {
    1837             :     // We may just be trying to find all free variables. In that case, don't
    1838             :     // declare them in the outer scope.
    1839     7622904 :     if (!is_script_scope()) return nullptr;
    1840             :     // No binding has been found. Declare a variable on the global object.
    1841             :     return AsDeclarationScope()->DeclareDynamicGlobal(proxy->raw_name(),
    1842     2471237 :                                                       NORMAL_VARIABLE);
    1843             :   }
    1844             : 
    1845             :   DCHECK(!is_script_scope());
    1846             : 
    1847    20418159 :   var = outer_scope_->LookupRecursive(proxy, outer_scope_end);
    1848             : 
    1849             :   // The variable could not be resolved statically.
    1850    20418163 :   if (var == nullptr) return var;
    1851             : 
    1852             :   // TODO(marja): Separate LookupRecursive for preparsed scopes better.
    1853    20274522 :   if (var == kDummyPreParserVariable || var == kDummyPreParserLexicalVariable) {
    1854             :     DCHECK(GetDeclarationScope()->is_being_lazily_parsed());
    1855             :     DCHECK(FLAG_lazy_inner_functions);
    1856             :     return var;
    1857             :   }
    1858             : 
    1859    37151566 :   if (is_function_scope() && !var->is_dynamic()) {
    1860             :     var->ForceContextAllocation();
    1861             :   }
    1862             :   // "this" can't be shadowed by "eval"-introduced bindings or by "with"
    1863             :   // scopes.
    1864             :   // TODO(wingo): There are other variables in this category; add them.
    1865    20202462 :   if (var->is_this()) return var;
    1866             : 
    1867    19929814 :   if (is_with_scope()) {
    1868             :     // The current scope is a with scope, so the variable binding can not be
    1869             :     // statically resolved. However, note that it was necessary to do a lookup
    1870             :     // in the outer scope anyway, because if a binding exists in an outer
    1871             :     // scope, the associated variable has to be marked as potentially being
    1872             :     // accessed from inside of an inner with scope (the property may not be in
    1873             :     // the 'with' object).
    1874       24434 :     if (!var->is_dynamic() && var->IsUnallocated()) {
    1875             :       DCHECK(!already_resolved_);
    1876             :       var->set_is_used();
    1877             :       var->ForceContextAllocation();
    1878        7327 :       if (proxy->is_assigned()) var->set_maybe_assigned();
    1879             :     }
    1880       16833 :     return NonLocal(proxy->raw_name(), DYNAMIC);
    1881             :   }
    1882             : 
    1883    20856833 :   if (calls_sloppy_eval() && is_declaration_scope()) {
    1884             :     // A variable binding may have been found in an outer scope, but the current
    1885             :     // scope makes a sloppy 'eval' call, so the found variable may not be the
    1886             :     // correct one (the 'eval' may introduce a binding with the same name). In
    1887             :     // that case, change the lookup result to reflect this situation. Only
    1888             :     // scopes that can host var bindings (declaration scopes) need be considered
    1889             :     // here (this excludes block and catch scopes), and variable lookups at
    1890             :     // script scope are always dynamic.
    1891      939790 :     if (var->IsGlobalObjectProperty()) {
    1892      735941 :       return NonLocal(proxy->raw_name(), DYNAMIC_GLOBAL);
    1893             :     }
    1894             : 
    1895      203849 :     if (var->is_dynamic()) return var;
    1896             : 
    1897             :     Variable* invalidated = var;
    1898       64846 :     var = NonLocal(proxy->raw_name(), DYNAMIC_LOCAL);
    1899             :     var->set_local_if_not_shadowed(invalidated);
    1900             :   }
    1901             : 
    1902    19038037 :   return var;
    1903             : }
    1904             : 
    1905    65603090 : void Scope::ResolveVariable(ParseInfo* info, VariableProxy* proxy) {
    1906             :   DCHECK(info->script_scope()->is_script_scope());
    1907             :   DCHECK(!proxy->is_resolved());
    1908    65603090 :   Variable* var = LookupRecursive(proxy, nullptr);
    1909    65603104 :   ResolveTo(info, proxy, var);
    1910    65603094 : }
    1911             : 
    1912             : namespace {
    1913             : 
    1914    80177453 : bool AccessNeedsHoleCheck(Variable* var, VariableProxy* proxy, Scope* scope) {
    1915    76972928 :   if (var->mode() == DYNAMIC_LOCAL) {
    1916             :     // Dynamically introduced variables never need a hole check (since they're
    1917             :     // VAR bindings, either from var or function declarations), but the variable
    1918             :     // they shadow might need a hole check, which we want to do if we decide
    1919             :     // that no shadowing variable was dynamically introoduced.
    1920             :     DCHECK(!var->binding_needs_init());
    1921       65435 :     return AccessNeedsHoleCheck(var->local_if_not_shadowed(), proxy, scope);
    1922             :   }
    1923             : 
    1924    76907493 :   if (!var->binding_needs_init()) {
    1925             :     return false;
    1926             :   }
    1927             : 
    1928             :   // It's impossible to eliminate module import hole checks here, because it's
    1929             :   // unknown at compilation time whether the binding referred to in the
    1930             :   // exporting module itself requires hole checks.
    1931     1861078 :   if (var->location() == VariableLocation::MODULE && !var->IsExport()) {
    1932             :     return true;
    1933             :   }
    1934             : 
    1935             :   // Check if the binding really needs an initialization check. The check
    1936             :   // can be skipped in the following situation: we have a LET or CONST
    1937             :   // binding, both the Variable and the VariableProxy have the same
    1938             :   // declaration scope (i.e. they are both in global code, in the
    1939             :   // same function or in the same eval code), the VariableProxy is in
    1940             :   // the source physically located after the initializer of the variable,
    1941             :   // and that the initializer cannot be skipped due to a nonlinear scope.
    1942             :   //
    1943             :   // The condition on the declaration scopes is a conservative check for
    1944             :   // nested functions that access a binding and are called before the
    1945             :   // binding is initialized:
    1946             :   //   function() { f(); let x = 1; function f() { x = 2; } }
    1947             :   //
    1948             :   // The check cannot be skipped on non-linear scopes, namely switch
    1949             :   // scopes, to ensure tests are done in cases like the following:
    1950             :   //   switch (1) { case 0: let x = 2; case 1: f(x); }
    1951             :   // The scope of the variable needs to be checked, in case the use is
    1952             :   // in a sub-block which may be linear.
    1953     1858419 :   if (var->scope()->GetDeclarationScope() != scope->GetDeclarationScope()) {
    1954             :     return true;
    1955             :   }
    1956             : 
    1957     1405412 :   if (var->is_this()) {
    1958             :     DCHECK(IsDerivedConstructor(scope->GetDeclarationScope()->function_kind()));
    1959             :     // TODO(littledan): implement 'this' hole check elimination.
    1960             :     return true;
    1961             :   }
    1962             : 
    1963             :   // We should always have valid source positions.
    1964             :   DCHECK(var->initializer_position() != kNoSourcePosition);
    1965             :   DCHECK(proxy->position() != kNoSourcePosition);
    1966             : 
    1967     2692333 :   return var->scope()->is_nonlinear() ||
    1968     2692333 :          var->initializer_position() >= proxy->position();
    1969             : }
    1970             : 
    1971             : }  // anonymous namespace
    1972             : 
    1973    76907493 : void Scope::ResolveTo(ParseInfo* info, VariableProxy* proxy, Variable* var) {
    1974             : #ifdef DEBUG
    1975             :   if (info->script_is_native()) {
    1976             :     // To avoid polluting the global object in native scripts
    1977             :     //  - Variables must not be allocated to the global scope.
    1978             :     CHECK_NOT_NULL(outer_scope());
    1979             :     //  - Variables must be bound locally or unallocated.
    1980             :     if (var->IsGlobalObjectProperty()) {
    1981             :       // The following variable name may be minified. If so, disable
    1982             :       // minification in js2c.py for better output.
    1983             :       Handle<String> name = proxy->raw_name()->string();
    1984             :       V8_Fatal(__FILE__, __LINE__, "Unbound variable: '%s' in native script.",
    1985             :                name->ToCString().get());
    1986             :     }
    1987             :     VariableLocation location = var->location();
    1988             :     CHECK(location == VariableLocation::LOCAL ||
    1989             :           location == VariableLocation::CONTEXT ||
    1990             :           location == VariableLocation::PARAMETER ||
    1991             :           location == VariableLocation::UNALLOCATED);
    1992             :   }
    1993             : #endif
    1994             : 
    1995             :   DCHECK_NOT_NULL(var);
    1996    76907493 :   if (AccessNeedsHoleCheck(var, proxy, this)) proxy->set_needs_hole_check();
    1997    76907492 :   proxy->BindTo(var);
    1998    76907490 : }
    1999             : 
    2000    12842037 : void Scope::ResolveVariablesRecursively(ParseInfo* info) {
    2001             :   DCHECK(info->script_scope()->is_script_scope());
    2002             :   // Lazy parsed declaration scopes are already partially analyzed. If there are
    2003             :   // unresolved references remaining, they just need to be resolved in outer
    2004             :   // scopes.
    2005    19741802 :   if (is_declaration_scope() && AsDeclarationScope()->was_lazily_parsed()) {
    2006             :     DCHECK(variables_.occupancy() == 0);
    2007     5919528 :     for (VariableProxy* proxy = unresolved_; proxy != nullptr;
    2008             :          proxy = proxy->next_unresolved()) {
    2009     2491455 :       Variable* var = outer_scope()->LookupRecursive(proxy, nullptr);
    2010     2491455 :       if (!var->is_dynamic()) {
    2011             :         var->set_is_used();
    2012             :         var->ForceContextAllocation();
    2013     2136980 :         if (proxy->is_assigned()) var->set_maybe_assigned();
    2014             :       }
    2015             :     }
    2016             :   } else {
    2017             :     // Resolve unresolved variables for this scope.
    2018    74662583 :     for (VariableProxy* proxy = unresolved_; proxy != nullptr;
    2019             :          proxy = proxy->next_unresolved()) {
    2020    65603091 :       ResolveVariable(info, proxy);
    2021             :     }
    2022             : 
    2023             :     // Resolve unresolved variables for inner scopes.
    2024    16533507 :     for (Scope* scope = inner_scope_; scope != nullptr;
    2025             :          scope = scope->sibling_) {
    2026     7474009 :       scope->ResolveVariablesRecursively(info);
    2027             :     }
    2028             :   }
    2029    10350591 : }
    2030             : 
    2031     1411012 : VariableProxy* Scope::FetchFreeVariables(DeclarationScope* max_outer_scope,
    2032             :                                          ParseInfo* info,
    2033     1060025 :                                          VariableProxy* stack) {
    2034             :   // Module variables must be allocated before variable resolution
    2035             :   // to ensure that AccessNeedsHoleCheck() can detect import variables.
    2036     2114901 :   if (info != nullptr && is_module_scope()) {
    2037         468 :     AsModuleScope()->AllocateModuleVariables();
    2038             :   }
    2039             :   // Lazy parsed declaration scopes are already partially analyzed. If there are
    2040             :   // unresolved references remaining, they just need to be resolved in outer
    2041             :   // scopes.
    2042             :   Scope* lookup =
    2043     1229511 :       is_declaration_scope() && AsDeclarationScope()->was_lazily_parsed()
    2044             :           ? outer_scope()
    2045     1767148 :           : this;
    2046    25184837 :   for (VariableProxy *proxy = unresolved_, *next = nullptr; proxy != nullptr;
    2047             :        proxy = next) {
    2048             :     next = proxy->next_unresolved();
    2049             :     DCHECK(!proxy->is_resolved());
    2050             :     Variable* var =
    2051    22317517 :         lookup->LookupRecursive(proxy, max_outer_scope->outer_scope());
    2052    22317517 :     if (var == nullptr) {
    2053             :       proxy->set_next_unresolved(stack);
    2054             :       stack = proxy;
    2055    28573773 :     } else if (var != kDummyPreParserVariable &&
    2056    11407923 :                var != kDummyPreParserLexicalVariable) {
    2057    11349687 :       if (info != nullptr) {
    2058             :         // In this case we need to leave scopes in a way that they can be
    2059             :         // allocated. If we resolved variables from lazy parsed scopes, we need
    2060             :         // to context allocate the var.
    2061    11304391 :         ResolveTo(info, proxy, var);
    2062    11304391 :         if (!var->is_dynamic() && lookup != this) var->ForceContextAllocation();
    2063             :       } else {
    2064             :         var->set_is_used();
    2065       45296 :         if (proxy->is_assigned()) {
    2066             :           var->set_maybe_assigned();
    2067             :         }
    2068             :       }
    2069             :     }
    2070             :   }
    2071             : 
    2072             :   // Clear unresolved_ as it's in an inconsistent state.
    2073     1411012 :   unresolved_ = nullptr;
    2074             : 
    2075     2026144 :   for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
    2076      615132 :     stack = scope->FetchFreeVariables(max_outer_scope, info, stack);
    2077             :   }
    2078             : 
    2079     1411012 :   return stack;
    2080             : }
    2081             : 
    2082   230474141 : bool Scope::MustAllocate(Variable* var) {
    2083    61500814 :   if (var == kDummyPreParserLexicalVariable || var == kDummyPreParserVariable) {
    2084             :     return true;
    2085             :   }
    2086             :   DCHECK(var->location() != VariableLocation::MODULE);
    2087             :   // Give var a read/write use if there is a chance it might be accessed
    2088             :   // via an eval() call.  This is only possible if the variable has a
    2089             :   // visible name.
    2090   175414708 :   if ((var->is_this() || !var->raw_name()->IsEmpty()) &&
    2091    56823447 :       (inner_scope_calls_eval_ || is_catch_scope() || is_script_scope())) {
    2092             :     var->set_is_used();
    2093     5326493 :     if (inner_scope_calls_eval_) var->set_maybe_assigned();
    2094             :   }
    2095             :   DCHECK(!var->has_forced_context_allocation() || var->is_used());
    2096             :   // Global variables do not need to be allocated.
    2097   121237572 :   return !var->IsGlobalObjectProperty() && var->is_used();
    2098             : }
    2099             : 
    2100             : 
    2101    83505067 : bool Scope::MustAllocateInContext(Variable* var) {
    2102             :   // If var is accessed from an inner scope, or if there is a possibility
    2103             :   // that it might be accessed from the current or an inner scope (through
    2104             :   // an eval() call or a runtime with lookup), it must be allocated in the
    2105             :   // context.
    2106             :   //
    2107             :   // Exceptions: If the scope as a whole has forced context allocation, all
    2108             :   // variables will have context allocation, even temporaries.  Otherwise
    2109             :   // temporary variables are always stack-allocated.  Catch-bound variables are
    2110             :   // always context-allocated.
    2111    28824445 :   if (has_forced_context_allocation()) return true;
    2112    28629805 :   if (var->mode() == TEMPORARY) return false;
    2113    26050817 :   if (is_catch_scope()) return true;
    2114    26457910 :   if ((is_script_scope() || is_eval_scope()) &&
    2115             :       IsLexicalVariableMode(var->mode())) {
    2116             :     return true;
    2117             :   }
    2118    25339197 :   return var->has_forced_context_allocation() || inner_scope_calls_eval_;
    2119             : }
    2120             : 
    2121             : 
    2122    13874770 : void Scope::AllocateStackSlot(Variable* var) {
    2123    13874770 :   if (is_block_scope()) {
    2124      447039 :     outer_scope()->GetDeclarationScope()->AllocateStackSlot(var);
    2125             :   } else {
    2126    13427731 :     var->AllocateTo(VariableLocation::LOCAL, num_stack_slots_++);
    2127             :   }
    2128    13427731 : }
    2129             : 
    2130             : 
    2131           0 : void Scope::AllocateHeapSlot(Variable* var) {
    2132     5022232 :   var->AllocateTo(VariableLocation::CONTEXT, num_heap_slots_++);
    2133           0 : }
    2134             : 
    2135     6529626 : void DeclarationScope::AllocateParameterLocals() {
    2136             :   DCHECK(is_function_scope());
    2137             : 
    2138             :   bool uses_sloppy_arguments = false;
    2139             : 
    2140     6529626 :   if (arguments_ != nullptr) {
    2141             :     DCHECK(!is_arrow_scope());
    2142             :     // 'arguments' is used. Unless there is also a parameter called
    2143             :     // 'arguments', we must be conservative and allocate all parameters to
    2144             :     // the context assuming they will be captured by the arguments object.
    2145             :     // If we have a parameter named 'arguments', a (new) value is always
    2146             :     // assigned to it via the function invocation. Then 'arguments' denotes
    2147             :     // that specific parameter value and cannot be used to access the
    2148             :     // parameters, which is why we don't need to allocate an arguments
    2149             :     // object in that case.
    2150     5892758 :     if (MustAllocate(arguments_) && !has_arguments_parameter_) {
    2151             :       // In strict mode 'arguments' does not alias formal parameters.
    2152             :       // Therefore in strict mode we allocate parameters as if 'arguments'
    2153             :       // were not used.
    2154             :       // If the parameter list is not simple, arguments isn't sloppy either.
    2155             :       uses_sloppy_arguments =
    2156      452289 :           is_sloppy(language_mode()) && has_simple_parameters();
    2157             :     } else {
    2158             :       // 'arguments' is unused. Tell the code generator that it does not need to
    2159             :       // allocate the arguments object by nulling out arguments_.
    2160     5631012 :       arguments_ = nullptr;
    2161             :     }
    2162             :   }
    2163             : 
    2164             :   // The same parameter may occur multiple times in the parameters_ list.
    2165             :   // If it does, and if it is not copied into the context object, it must
    2166             :   // receive the highest parameter index for that parameter; thus iteration
    2167             :   // order is relevant!
    2168    14956609 :   for (int i = num_parameters() - 1; i >= 0; --i) {
    2169    16853950 :     Variable* var = params_[i];
    2170             :     DCHECK(!has_rest_ || var != rest_parameter());
    2171             :     DCHECK_EQ(this, var->scope());
    2172     8426975 :     if (uses_sloppy_arguments) {
    2173             :       var->set_is_used();
    2174             :       var->set_maybe_assigned();
    2175             :       var->ForceContextAllocation();
    2176             :     }
    2177     8426975 :     AllocateParameter(var, i);
    2178             :   }
    2179     6529634 : }
    2180             : 
    2181    14367995 : void DeclarationScope::AllocateParameter(Variable* var, int index) {
    2182    14367995 :   if (MustAllocate(var)) {
    2183    11221314 :     if (MustAllocateInContext(var)) {
    2184             :       DCHECK(var->IsUnallocated() || var->IsContextSlot());
    2185      844695 :       if (var->IsUnallocated()) {
    2186             :         AllocateHeapSlot(var);
    2187             :       }
    2188             :     } else {
    2189             :       DCHECK(var->IsUnallocated() || var->IsParameter());
    2190    10376619 :       if (var->IsUnallocated()) {
    2191             :         var->AllocateTo(VariableLocation::PARAMETER, index);
    2192             :       }
    2193             :     }
    2194             :   }
    2195    14367996 : }
    2196             : 
    2197    14073158 : void DeclarationScope::AllocateReceiver() {
    2198    16264272 :   if (!has_this_declaration()) return;
    2199             :   DCHECK_NOT_NULL(receiver());
    2200             :   DCHECK_EQ(receiver()->scope(), this);
    2201     5941022 :   AllocateParameter(receiver(), -1);
    2202             : }
    2203             : 
    2204    45517160 : void Scope::AllocateNonParameterLocal(Variable* var) {
    2205             :   DCHECK(var->scope() == this);
    2206    45517160 :   if (var->IsUnallocated() && MustAllocate(var)) {
    2207    17600683 :     if (MustAllocateInContext(var)) {
    2208             :       AllocateHeapSlot(var);
    2209             :     } else {
    2210    13427733 :       AllocateStackSlot(var);
    2211             :     }
    2212             :   }
    2213    45517163 : }
    2214             : 
    2215     9108971 : void Scope::AllocateNonParameterLocalsAndDeclaredGlobals() {
    2216    62833625 :   for (Variable* local : locals_) {
    2217    44615682 :     AllocateNonParameterLocal(local);
    2218             :   }
    2219             : 
    2220     9108972 :   if (is_declaration_scope()) {
    2221     8132147 :     AsDeclarationScope()->AllocateLocals();
    2222             :   }
    2223     9108974 : }
    2224             : 
    2225    16264293 : void DeclarationScope::AllocateLocals() {
    2226             :   // For now, function_ must be allocated at the very end.  If it gets
    2227             :   // allocated in the context, it must be the last slot in the context,
    2228             :   // because of the current ScopeInfo implementation (see
    2229             :   // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor).
    2230     8132146 :   if (function_ != nullptr) {
    2231      901483 :     AllocateNonParameterLocal(function_);
    2232             :   }
    2233             : 
    2234             :   DCHECK(!has_rest_ || !MustAllocate(rest_parameter()) ||
    2235             :          !rest_parameter()->IsUnallocated());
    2236             : 
    2237     8132147 :   if (new_target_ != nullptr && !MustAllocate(new_target_)) {
    2238     5654645 :     new_target_ = nullptr;
    2239             :   }
    2240             : 
    2241             :   NullifyRareVariableIf(RareVariable::kThisFunction,
    2242      480000 :                         [=](Variable* var) { return !MustAllocate(var); });
    2243     8132147 : }
    2244             : 
    2245       13848 : void ModuleScope::AllocateModuleVariables() {
    2246       14551 :   for (const auto& it : module()->regular_imports()) {
    2247         703 :     Variable* var = LookupLocal(it.first);
    2248         703 :     var->AllocateTo(VariableLocation::MODULE, it.second->cell_index);
    2249             :     DCHECK(!var->IsExport());
    2250             :   }
    2251             : 
    2252       15214 :   for (const auto& it : module()->regular_exports()) {
    2253        1366 :     Variable* var = LookupLocal(it.first);
    2254        1366 :     var->AllocateTo(VariableLocation::MODULE, it.second->cell_index);
    2255             :     DCHECK(var->IsExport());
    2256             :   }
    2257        6924 : }
    2258             : 
    2259    27641158 : void Scope::AllocateVariablesRecursively() {
    2260             :   DCHECK(!already_resolved_);
    2261             :   DCHECK_IMPLIES(!FLAG_experimental_preparser_scope_analysis,
    2262             :                  num_stack_slots_ == 0);
    2263             : 
    2264             :   // Don't allocate variables of preparsed scopes.
    2265    19823264 :   if (is_declaration_scope() && AsDeclarationScope()->was_lazily_parsed()) {
    2266    10400049 :     return;
    2267             :   }
    2268             : 
    2269             :   // Allocate variables for inner scopes.
    2270    16617716 :   for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
    2271     7508750 :     scope->AllocateVariablesRecursively();
    2272             :   }
    2273             : 
    2274             :   DCHECK(!already_resolved_);
    2275             :   DCHECK_EQ(Context::MIN_CONTEXT_SLOTS, num_heap_slots_);
    2276             : 
    2277             :   // Allocate variables for this scope.
    2278             :   // Parameters must be allocated first, if any.
    2279     9108966 :   if (is_declaration_scope()) {
    2280     8132142 :     if (is_function_scope()) {
    2281     6529629 :       AsDeclarationScope()->AllocateParameterLocals();
    2282             :     }
    2283     8132147 :     AsDeclarationScope()->AllocateReceiver();
    2284             :   }
    2285     9108969 :   AllocateNonParameterLocalsAndDeclaredGlobals();
    2286             : 
    2287             :   // Force allocation of a context for this scope if necessary. For a 'with'
    2288             :   // scope and for a function scope that makes an 'eval' call we need a context,
    2289             :   // even if no local variables were statically allocated in the scope.
    2290             :   // Likewise for modules and function scopes representing asm.js modules.
    2291             :   bool must_have_context =
    2292    18101036 :       is_with_scope() || is_module_scope() || IsAsmModule() ||
    2293    15627542 :       (is_function_scope() && calls_sloppy_eval()) ||
    2294      470574 :       (is_block_scope() && is_declaration_scope() && calls_sloppy_eval());
    2295             : 
    2296             :   // If we didn't allocate any locals in the local context, then we only
    2297             :   // need the minimal number of slots if we must have a context.
    2298     9108975 :   if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && !must_have_context) {
    2299     7837590 :     num_heap_slots_ = 0;
    2300             :   }
    2301             : 
    2302             :   // Allocation done.
    2303             :   DCHECK(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS);
    2304             : }
    2305             : 
    2306     4267312 : void Scope::AllocateScopeInfosRecursively(Isolate* isolate,
    2307     2477468 :                                           MaybeHandle<ScopeInfo> outer_scope) {
    2308             :   DCHECK(scope_info_.is_null());
    2309     4267312 :   MaybeHandle<ScopeInfo> next_outer_scope = outer_scope;
    2310             : 
    2311     4267312 :   if (NeedsScopeInfo()) {
    2312     4954936 :     scope_info_ = ScopeInfo::Create(isolate, zone(), this, outer_scope);
    2313             :     // The ScopeInfo chain should mirror the context chain, so we only link to
    2314             :     // the next outer scope that needs a context.
    2315     2477461 :     if (NeedsContext()) next_outer_scope = scope_info_;
    2316             :   }
    2317             : 
    2318             :   // Allocate ScopeInfos for inner scopes.
    2319    10679272 :   for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
    2320    12256626 :     if (!scope->is_function_scope() ||
    2321             :         scope->AsDeclarationScope()->ShouldEagerCompile()) {
    2322     1390728 :       scope->AllocateScopeInfosRecursively(isolate, next_outer_scope);
    2323             :     }
    2324             :   }
    2325     4267313 : }
    2326             : 
    2327      309972 : void Scope::AllocateDebuggerScopeInfos(Isolate* isolate,
    2328       95504 :                                        MaybeHandle<ScopeInfo> outer_scope) {
    2329      309972 :   if (scope_info_.is_null()) {
    2330      191008 :     scope_info_ = ScopeInfo::Create(isolate, zone(), this, outer_scope);
    2331             :   }
    2332      309972 :   MaybeHandle<ScopeInfo> outer = NeedsContext() ? scope_info_ : outer_scope;
    2333      801377 :   for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
    2334      491405 :     if (scope->is_function_scope()) continue;
    2335      115030 :     scope->AllocateDebuggerScopeInfos(isolate, outer);
    2336             :   }
    2337      309972 : }
    2338             : 
    2339        4878 : int Scope::StackLocalCount() const {
    2340             :   Variable* function =
    2341        2439 :       is_function_scope() ? AsDeclarationScope()->function_var() : nullptr;
    2342        2439 :   return num_stack_slots() -
    2343         740 :          (function != nullptr && function->IsStackLocal() ? 1 : 0);
    2344             : }
    2345             : 
    2346             : 
    2347       39772 : int Scope::ContextLocalCount() const {
    2348       31013 :   if (num_heap_slots() == 0) return 0;
    2349             :   Variable* function =
    2350        8759 :       is_function_scope() ? AsDeclarationScope()->function_var() : nullptr;
    2351             :   bool is_function_var_in_context =
    2352        8759 :       function != nullptr && function->IsContextSlot();
    2353        8759 :   return num_heap_slots() - Context::MIN_CONTEXT_SLOTS -
    2354        8759 :          (is_function_var_in_context ? 1 : 0);
    2355             : }
    2356             : 
    2357             : }  // namespace internal
    2358             : }  // namespace v8

Generated by: LCOV version 1.10