xref: /third_party/node/deps/v8/src/ast/scopes.cc (revision 1cb0ef41)
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/ast/ast.h"
10#include "src/base/logging.h"
11#include "src/base/optional.h"
12#include "src/builtins/accessors.h"
13#include "src/common/message-template.h"
14#include "src/heap/local-factory-inl.h"
15#include "src/init/bootstrapper.h"
16#include "src/logging/runtime-call-stats-scope.h"
17#include "src/objects/module-inl.h"
18#include "src/objects/objects-inl.h"
19#include "src/objects/scope-info.h"
20#include "src/objects/string-set-inl.h"
21#include "src/parsing/parse-info.h"
22#include "src/parsing/parser.h"
23#include "src/parsing/preparse-data.h"
24#include "src/zone/zone-list-inl.h"
25#include "src/zone/zone.h"
26
27namespace v8 {
28namespace internal {
29
30// ----------------------------------------------------------------------------
31// Implementation of LocalsMap
32//
33// Note: We are storing the handle locations as key values in the hash map.
34//       When inserting a new variable via Declare(), we rely on the fact that
35//       the handle location remains alive for the duration of that variable
36//       use. Because a Variable holding a handle with the same location exists
37//       this is ensured.
38
39static_assert(sizeof(VariableMap) == (sizeof(void*) + 2 * sizeof(uint32_t) +
40                                      sizeof(ZoneAllocationPolicy)),
41              "Empty base optimization didn't kick in for VariableMap");
42
43VariableMap::VariableMap(Zone* zone)
44    : ZoneHashMap(8, ZoneAllocationPolicy(zone)) {}
45
46VariableMap::VariableMap(const VariableMap& other, Zone* zone)
47    : ZoneHashMap(other, ZoneAllocationPolicy(zone)) {}
48
49Variable* VariableMap::Declare(Zone* zone, Scope* scope,
50                               const AstRawString* name, VariableMode mode,
51                               VariableKind kind,
52                               InitializationFlag initialization_flag,
53                               MaybeAssignedFlag maybe_assigned_flag,
54                               IsStaticFlag is_static_flag, bool* was_added) {
55  DCHECK_EQ(zone, allocator().zone());
56  // AstRawStrings are unambiguous, i.e., the same string is always represented
57  // by the same AstRawString*.
58  // FIXME(marja): fix the type of Lookup.
59  Entry* p = ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name),
60                                         name->Hash());
61  *was_added = p->value == nullptr;
62  if (*was_added) {
63    // The variable has not been declared yet -> insert it.
64    DCHECK_EQ(name, p->key);
65    Variable* variable =
66        zone->New<Variable>(scope, name, mode, kind, initialization_flag,
67                            maybe_assigned_flag, is_static_flag);
68    p->value = variable;
69  }
70  return reinterpret_cast<Variable*>(p->value);
71}
72
73void VariableMap::Remove(Variable* var) {
74  const AstRawString* name = var->raw_name();
75  ZoneHashMap::Remove(const_cast<AstRawString*>(name), name->Hash());
76}
77
78void VariableMap::Add(Variable* var) {
79  const AstRawString* name = var->raw_name();
80  Entry* p = ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name),
81                                         name->Hash());
82  DCHECK_NULL(p->value);
83  DCHECK_EQ(name, p->key);
84  p->value = var;
85}
86
87Variable* VariableMap::Lookup(const AstRawString* name) {
88  Entry* p = ZoneHashMap::Lookup(const_cast<AstRawString*>(name), name->Hash());
89  if (p != nullptr) {
90    DCHECK(reinterpret_cast<const AstRawString*>(p->key) == name);
91    DCHECK_NOT_NULL(p->value);
92    return reinterpret_cast<Variable*>(p->value);
93  }
94  return nullptr;
95}
96
97// ----------------------------------------------------------------------------
98// Implementation of Scope
99
100Scope::Scope(Zone* zone)
101    : outer_scope_(nullptr), variables_(zone), scope_type_(SCRIPT_SCOPE) {
102  SetDefaults();
103}
104
105Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type)
106    : outer_scope_(outer_scope), variables_(zone), scope_type_(scope_type) {
107  DCHECK_NE(SCRIPT_SCOPE, scope_type);
108  SetDefaults();
109  set_language_mode(outer_scope->language_mode());
110  private_name_lookup_skips_outer_class_ =
111      outer_scope->is_class_scope() &&
112      outer_scope->AsClassScope()->IsParsingHeritage();
113  outer_scope_->AddInnerScope(this);
114}
115
116Variable* Scope::DeclareHomeObjectVariable(AstValueFactory* ast_value_factory) {
117  bool was_added;
118  Variable* home_object_variable = Declare(
119      zone(), ast_value_factory->dot_home_object_string(), VariableMode::kConst,
120      NORMAL_VARIABLE, InitializationFlag::kCreatedInitialized,
121      MaybeAssignedFlag::kNotAssigned, &was_added);
122  DCHECK(was_added);
123  home_object_variable->set_is_used();
124  home_object_variable->ForceContextAllocation();
125  return home_object_variable;
126}
127
128Variable* Scope::DeclareStaticHomeObjectVariable(
129    AstValueFactory* ast_value_factory) {
130  bool was_added;
131  Variable* static_home_object_variable =
132      Declare(zone(), ast_value_factory->dot_static_home_object_string(),
133              VariableMode::kConst, NORMAL_VARIABLE,
134              InitializationFlag::kCreatedInitialized,
135              MaybeAssignedFlag::kNotAssigned, &was_added);
136  DCHECK(was_added);
137  static_home_object_variable->set_is_used();
138  static_home_object_variable->ForceContextAllocation();
139  return static_home_object_variable;
140}
141
142DeclarationScope::DeclarationScope(Zone* zone,
143                                   AstValueFactory* ast_value_factory,
144                                   REPLMode repl_mode)
145    : Scope(zone),
146      function_kind_(repl_mode == REPLMode::kYes
147                         ? FunctionKind::kAsyncFunction
148                         : FunctionKind::kNormalFunction),
149      params_(4, zone) {
150  DCHECK_EQ(scope_type_, SCRIPT_SCOPE);
151  SetDefaults();
152  is_repl_mode_scope_ = repl_mode == REPLMode::kYes;
153  receiver_ = DeclareDynamicGlobal(ast_value_factory->this_string(),
154                                   THIS_VARIABLE, this);
155}
156
157DeclarationScope::DeclarationScope(Zone* zone, Scope* outer_scope,
158                                   ScopeType scope_type,
159                                   FunctionKind function_kind)
160    : Scope(zone, outer_scope, scope_type),
161      function_kind_(function_kind),
162      params_(4, zone) {
163  DCHECK_NE(scope_type, SCRIPT_SCOPE);
164  SetDefaults();
165}
166
167ModuleScope::ModuleScope(DeclarationScope* script_scope,
168                         AstValueFactory* avfactory)
169    : DeclarationScope(avfactory->single_parse_zone(), script_scope,
170                       MODULE_SCOPE, FunctionKind::kModule),
171      module_descriptor_(
172          avfactory->single_parse_zone()->New<SourceTextModuleDescriptor>(
173              avfactory->single_parse_zone())) {
174  set_language_mode(LanguageMode::kStrict);
175  DeclareThis(avfactory);
176}
177
178ModuleScope::ModuleScope(Handle<ScopeInfo> scope_info,
179                         AstValueFactory* avfactory)
180    : DeclarationScope(avfactory->single_parse_zone(), MODULE_SCOPE, avfactory,
181                       scope_info),
182      module_descriptor_(nullptr) {
183  set_language_mode(LanguageMode::kStrict);
184}
185
186ClassScope::ClassScope(Zone* zone, Scope* outer_scope, bool is_anonymous)
187    : Scope(zone, outer_scope, CLASS_SCOPE),
188      rare_data_and_is_parsing_heritage_(nullptr),
189      is_anonymous_class_(is_anonymous) {
190  set_language_mode(LanguageMode::kStrict);
191}
192
193template <typename IsolateT>
194ClassScope::ClassScope(IsolateT* isolate, Zone* zone,
195                       AstValueFactory* ast_value_factory,
196                       Handle<ScopeInfo> scope_info)
197    : Scope(zone, CLASS_SCOPE, ast_value_factory, scope_info),
198      rare_data_and_is_parsing_heritage_(nullptr) {
199  set_language_mode(LanguageMode::kStrict);
200  if (scope_info->ClassScopeHasPrivateBrand()) {
201    Variable* brand =
202        LookupInScopeInfo(ast_value_factory->dot_brand_string(), this);
203    DCHECK_NOT_NULL(brand);
204    EnsureRareData()->brand = brand;
205  }
206
207  // If the class variable is context-allocated and its index is
208  // saved for deserialization, deserialize it.
209  if (scope_info->HasSavedClassVariable()) {
210    String name;
211    int index;
212    std::tie(name, index) = scope_info->SavedClassVariable();
213    DCHECK_EQ(scope_info->ContextLocalMode(index), VariableMode::kConst);
214    DCHECK_EQ(scope_info->ContextLocalInitFlag(index),
215              InitializationFlag::kNeedsInitialization);
216    DCHECK_EQ(scope_info->ContextLocalMaybeAssignedFlag(index),
217              MaybeAssignedFlag::kMaybeAssigned);
218    Variable* var = DeclareClassVariable(
219        ast_value_factory,
220        ast_value_factory->GetString(name,
221                                     SharedStringAccessGuardIfNeeded(isolate)),
222        kNoSourcePosition);
223    var->AllocateTo(VariableLocation::CONTEXT,
224                    Context::MIN_CONTEXT_SLOTS + index);
225  }
226
227  DCHECK(scope_info->HasPositionInfo());
228  set_start_position(scope_info->StartPosition());
229  set_end_position(scope_info->EndPosition());
230}
231template ClassScope::ClassScope(Isolate* isolate, Zone* zone,
232                                AstValueFactory* ast_value_factory,
233                                Handle<ScopeInfo> scope_info);
234template ClassScope::ClassScope(LocalIsolate* isolate, Zone* zone,
235                                AstValueFactory* ast_value_factory,
236                                Handle<ScopeInfo> scope_info);
237
238Scope::Scope(Zone* zone, ScopeType scope_type,
239             AstValueFactory* ast_value_factory, Handle<ScopeInfo> scope_info)
240    : outer_scope_(nullptr),
241      variables_(zone),
242      scope_info_(scope_info),
243      scope_type_(scope_type) {
244  DCHECK(!scope_info.is_null());
245  SetDefaults();
246#ifdef DEBUG
247  already_resolved_ = true;
248#endif
249  set_language_mode(scope_info->language_mode());
250  DCHECK_EQ(ContextHeaderLength(), num_heap_slots_);
251  private_name_lookup_skips_outer_class_ =
252      scope_info->PrivateNameLookupSkipsOuterClass();
253  // We don't really need to use the preparsed scope data; this is just to
254  // shorten the recursion in SetMustUsePreparseData.
255  must_use_preparsed_scope_data_ = true;
256
257  if (scope_type == BLOCK_SCOPE) {
258    // Set is_block_scope_for_object_literal_ based on the existince of the home
259    // object variable (we don't store it explicitly).
260    DCHECK_NOT_NULL(ast_value_factory);
261    int home_object_index = scope_info->ContextSlotIndex(
262        ast_value_factory->dot_home_object_string()->string());
263    DCHECK_IMPLIES(home_object_index >= 0,
264                   scope_type == CLASS_SCOPE || scope_type == BLOCK_SCOPE);
265    if (home_object_index >= 0) {
266      is_block_scope_for_object_literal_ = true;
267    }
268  }
269}
270
271DeclarationScope::DeclarationScope(Zone* zone, ScopeType scope_type,
272                                   AstValueFactory* ast_value_factory,
273                                   Handle<ScopeInfo> scope_info)
274    : Scope(zone, scope_type, ast_value_factory, scope_info),
275      function_kind_(scope_info->function_kind()),
276      params_(0, zone) {
277  DCHECK_NE(scope_type, SCRIPT_SCOPE);
278  SetDefaults();
279  if (scope_info->SloppyEvalCanExtendVars()) {
280    DCHECK(!is_eval_scope());
281    sloppy_eval_can_extend_vars_ = true;
282  }
283  if (scope_info->ClassScopeHasPrivateBrand()) {
284    DCHECK(IsClassConstructor(function_kind()));
285    class_scope_has_private_brand_ = true;
286  }
287}
288
289Scope::Scope(Zone* zone, const AstRawString* catch_variable_name,
290             MaybeAssignedFlag maybe_assigned, Handle<ScopeInfo> scope_info)
291    : outer_scope_(nullptr),
292      variables_(zone),
293      scope_info_(scope_info),
294      scope_type_(CATCH_SCOPE) {
295  SetDefaults();
296#ifdef DEBUG
297  already_resolved_ = true;
298#endif
299  // Cache the catch variable, even though it's also available via the
300  // scope_info, as the parser expects that a catch scope always has the catch
301  // variable as first and only variable.
302  bool was_added;
303  Variable* variable =
304      Declare(zone, catch_variable_name, VariableMode::kVar, NORMAL_VARIABLE,
305              kCreatedInitialized, maybe_assigned, &was_added);
306  DCHECK(was_added);
307  AllocateHeapSlot(variable);
308}
309
310void DeclarationScope::SetDefaults() {
311  is_declaration_scope_ = true;
312  has_simple_parameters_ = true;
313#if V8_ENABLE_WEBASSEMBLY
314  is_asm_module_ = false;
315#endif  // V8_ENABLE_WEBASSEMBLY
316  force_eager_compilation_ = false;
317  has_arguments_parameter_ = false;
318  uses_super_property_ = false;
319  has_checked_syntax_ = false;
320  has_this_reference_ = false;
321  has_this_declaration_ =
322      (is_function_scope() && !is_arrow_scope()) || is_module_scope();
323  needs_private_name_context_chain_recalc_ = false;
324  has_rest_ = false;
325  receiver_ = nullptr;
326  new_target_ = nullptr;
327  function_ = nullptr;
328  arguments_ = nullptr;
329  rare_data_ = nullptr;
330  should_eager_compile_ = false;
331  was_lazily_parsed_ = false;
332  is_skipped_function_ = false;
333  preparse_data_builder_ = nullptr;
334  class_scope_has_private_brand_ = false;
335#ifdef DEBUG
336  DeclarationScope* outer_declaration_scope =
337      outer_scope_ ? outer_scope_->GetDeclarationScope() : nullptr;
338  is_being_lazily_parsed_ =
339      outer_declaration_scope ? outer_declaration_scope->is_being_lazily_parsed_
340                              : false;
341#endif
342}
343
344void Scope::SetDefaults() {
345#ifdef DEBUG
346  scope_name_ = nullptr;
347  already_resolved_ = false;
348  needs_migration_ = false;
349#endif
350  inner_scope_ = nullptr;
351  sibling_ = nullptr;
352  unresolved_list_.Clear();
353
354  start_position_ = kNoSourcePosition;
355  end_position_ = kNoSourcePosition;
356
357  calls_eval_ = false;
358  sloppy_eval_can_extend_vars_ = false;
359  scope_nonlinear_ = false;
360  is_hidden_ = false;
361  is_debug_evaluate_scope_ = false;
362
363  inner_scope_calls_eval_ = false;
364  force_context_allocation_for_parameters_ = false;
365
366  is_declaration_scope_ = false;
367
368  private_name_lookup_skips_outer_class_ = false;
369
370  must_use_preparsed_scope_data_ = false;
371  is_repl_mode_scope_ = false;
372
373  deserialized_scope_uses_external_cache_ = false;
374
375  needs_home_object_ = false;
376  is_block_scope_for_object_literal_ = false;
377
378  num_stack_slots_ = 0;
379  num_heap_slots_ = ContextHeaderLength();
380
381  set_language_mode(LanguageMode::kSloppy);
382}
383
384bool Scope::HasSimpleParameters() {
385  DeclarationScope* scope = GetClosureScope();
386  return !scope->is_function_scope() || scope->has_simple_parameters();
387}
388
389void DeclarationScope::set_should_eager_compile() {
390  should_eager_compile_ = !was_lazily_parsed_;
391}
392
393#if V8_ENABLE_WEBASSEMBLY
394void DeclarationScope::set_is_asm_module() { is_asm_module_ = true; }
395
396bool Scope::IsAsmModule() const {
397  return is_function_scope() && AsDeclarationScope()->is_asm_module();
398}
399
400bool Scope::ContainsAsmModule() const {
401  if (IsAsmModule()) return true;
402
403  // Check inner scopes recursively
404  for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
405    // Don't check inner functions which won't be eagerly compiled.
406    if (!scope->is_function_scope() ||
407        scope->AsDeclarationScope()->ShouldEagerCompile()) {
408      if (scope->ContainsAsmModule()) return true;
409    }
410  }
411
412  return false;
413}
414#endif  // V8_ENABLE_WEBASSEMBLY
415
416template <typename IsolateT>
417Scope* Scope::DeserializeScopeChain(IsolateT* isolate, Zone* zone,
418                                    ScopeInfo scope_info,
419                                    DeclarationScope* script_scope,
420                                    AstValueFactory* ast_value_factory,
421                                    DeserializationMode deserialization_mode) {
422  // Reconstruct the outer scope chain from a closure's context chain.
423  Scope* current_scope = nullptr;
424  Scope* innermost_scope = nullptr;
425  Scope* outer_scope = nullptr;
426  bool cache_scope_found = false;
427  while (!scope_info.is_null()) {
428    if (scope_info.scope_type() == WITH_SCOPE) {
429      if (scope_info.IsDebugEvaluateScope()) {
430        outer_scope =
431            zone->New<DeclarationScope>(zone, FUNCTION_SCOPE, ast_value_factory,
432                                        handle(scope_info, isolate));
433        outer_scope->set_is_debug_evaluate_scope();
434      } else {
435        // For scope analysis, debug-evaluate is equivalent to a with scope.
436        outer_scope = zone->New<Scope>(zone, WITH_SCOPE, ast_value_factory,
437                                       handle(scope_info, isolate));
438      }
439
440    } else if (scope_info.scope_type() == SCRIPT_SCOPE) {
441      // If we reach a script scope, it's the outermost scope. Install the
442      // scope info of this script context onto the existing script scope to
443      // avoid nesting script scopes.
444      if (deserialization_mode == DeserializationMode::kIncludingVariables) {
445        script_scope->SetScriptScopeInfo(handle(scope_info, isolate));
446      }
447      if (scope_info.IsReplModeScope()) script_scope->set_is_repl_mode_scope();
448      DCHECK(!scope_info.HasOuterScopeInfo());
449      break;
450    } else if (scope_info.scope_type() == FUNCTION_SCOPE) {
451      outer_scope = zone->New<DeclarationScope>(
452          zone, FUNCTION_SCOPE, ast_value_factory, handle(scope_info, isolate));
453#if V8_ENABLE_WEBASSEMBLY
454      if (scope_info.IsAsmModule()) {
455        outer_scope->AsDeclarationScope()->set_is_asm_module();
456      }
457#endif  // V8_ENABLE_WEBASSEMBLY
458    } else if (scope_info.scope_type() == EVAL_SCOPE) {
459      outer_scope = zone->New<DeclarationScope>(
460          zone, EVAL_SCOPE, ast_value_factory, handle(scope_info, isolate));
461    } else if (scope_info.scope_type() == CLASS_SCOPE) {
462      outer_scope = zone->New<ClassScope>(isolate, zone, ast_value_factory,
463                                          handle(scope_info, isolate));
464    } else if (scope_info.scope_type() == BLOCK_SCOPE) {
465      if (scope_info.is_declaration_scope()) {
466        outer_scope = zone->New<DeclarationScope>(
467            zone, BLOCK_SCOPE, ast_value_factory, handle(scope_info, isolate));
468      } else {
469        outer_scope = zone->New<Scope>(zone, BLOCK_SCOPE, ast_value_factory,
470                                       handle(scope_info, isolate));
471      }
472    } else if (scope_info.scope_type() == MODULE_SCOPE) {
473      outer_scope = zone->New<ModuleScope>(handle(scope_info, isolate),
474                                           ast_value_factory);
475    } else {
476      DCHECK_EQ(scope_info.scope_type(), CATCH_SCOPE);
477      DCHECK_EQ(scope_info.ContextLocalCount(), 1);
478      DCHECK_EQ(scope_info.ContextLocalMode(0), VariableMode::kVar);
479      DCHECK_EQ(scope_info.ContextLocalInitFlag(0), kCreatedInitialized);
480      DCHECK(scope_info.HasInlinedLocalNames());
481      String name = scope_info.ContextInlinedLocalName(0);
482      MaybeAssignedFlag maybe_assigned =
483          scope_info.ContextLocalMaybeAssignedFlag(0);
484      outer_scope =
485          zone->New<Scope>(zone,
486                           ast_value_factory->GetString(
487                               name, SharedStringAccessGuardIfNeeded(isolate)),
488                           maybe_assigned, handle(scope_info, isolate));
489    }
490    if (deserialization_mode == DeserializationMode::kScopesOnly) {
491      outer_scope->scope_info_ = Handle<ScopeInfo>::null();
492    }
493
494    if (cache_scope_found) {
495      outer_scope->set_deserialized_scope_uses_external_cache();
496    } else {
497      DCHECK(!cache_scope_found);
498      cache_scope_found =
499          outer_scope->is_declaration_scope() && !outer_scope->is_eval_scope();
500    }
501
502    if (current_scope != nullptr) {
503      outer_scope->AddInnerScope(current_scope);
504    }
505    current_scope = outer_scope;
506    if (innermost_scope == nullptr) innermost_scope = current_scope;
507    scope_info = scope_info.HasOuterScopeInfo() ? scope_info.OuterScopeInfo()
508                                                : ScopeInfo();
509  }
510
511  if (deserialization_mode == DeserializationMode::kIncludingVariables) {
512    SetScriptScopeInfo(isolate, script_scope);
513  }
514
515  if (innermost_scope == nullptr) return script_scope;
516  script_scope->AddInnerScope(current_scope);
517  return innermost_scope;
518}
519
520template <typename IsolateT>
521void Scope::SetScriptScopeInfo(IsolateT* isolate,
522                               DeclarationScope* script_scope) {
523  if (script_scope->scope_info_.is_null()) {
524    script_scope->SetScriptScopeInfo(
525        ReadOnlyRoots(isolate).global_this_binding_scope_info_handle());
526  }
527}
528
529template EXPORT_TEMPLATE_DEFINE(
530    V8_EXPORT_PRIVATE) void Scope::SetScriptScopeInfo(Isolate* isolate,
531                                                      DeclarationScope*
532                                                          script_scope);
533template EXPORT_TEMPLATE_DEFINE(
534    V8_EXPORT_PRIVATE) void Scope::SetScriptScopeInfo(LocalIsolate* isolate,
535                                                      DeclarationScope*
536                                                          script_scope);
537
538template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
539    Scope* Scope::DeserializeScopeChain(
540        Isolate* isolate, Zone* zone, ScopeInfo scope_info,
541        DeclarationScope* script_scope, AstValueFactory* ast_value_factory,
542        DeserializationMode deserialization_mode);
543template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
544    Scope* Scope::DeserializeScopeChain(
545        LocalIsolate* isolate, Zone* zone, ScopeInfo scope_info,
546        DeclarationScope* script_scope, AstValueFactory* ast_value_factory,
547        DeserializationMode deserialization_mode);
548
549#ifdef DEBUG
550bool Scope::IsReparsedMemberInitializerScope() const {
551  return is_declaration_scope() &&
552         IsClassMembersInitializerFunction(
553             AsDeclarationScope()->function_kind()) &&
554         outer_scope()->AsClassScope()->is_reparsed_class_scope();
555}
556#endif
557
558DeclarationScope* Scope::AsDeclarationScope() {
559  DCHECK(is_declaration_scope());
560  return static_cast<DeclarationScope*>(this);
561}
562
563const DeclarationScope* Scope::AsDeclarationScope() const {
564  DCHECK(is_declaration_scope());
565  return static_cast<const DeclarationScope*>(this);
566}
567
568ModuleScope* Scope::AsModuleScope() {
569  DCHECK(is_module_scope());
570  return static_cast<ModuleScope*>(this);
571}
572
573const ModuleScope* Scope::AsModuleScope() const {
574  DCHECK(is_module_scope());
575  return static_cast<const ModuleScope*>(this);
576}
577
578ClassScope* Scope::AsClassScope() {
579  DCHECK(is_class_scope());
580  return static_cast<ClassScope*>(this);
581}
582
583const ClassScope* Scope::AsClassScope() const {
584  DCHECK(is_class_scope());
585  return static_cast<const ClassScope*>(this);
586}
587
588void DeclarationScope::DeclareSloppyBlockFunction(
589    SloppyBlockFunctionStatement* sloppy_block_function) {
590  sloppy_block_functions_.Add(sloppy_block_function);
591}
592
593void DeclarationScope::HoistSloppyBlockFunctions(AstNodeFactory* factory) {
594  DCHECK(is_sloppy(language_mode()));
595  DCHECK(is_function_scope() || is_eval_scope() || is_script_scope() ||
596         (is_block_scope() && outer_scope()->is_function_scope()));
597  DCHECK(HasSimpleParameters() || is_block_scope() || is_being_lazily_parsed_);
598  DCHECK_EQ(factory == nullptr, is_being_lazily_parsed_);
599
600  if (sloppy_block_functions_.is_empty()) return;
601
602  // In case of complex parameters the current scope is the body scope and the
603  // parameters are stored in the outer scope.
604  Scope* parameter_scope = HasSimpleParameters() ? this : outer_scope_;
605  DCHECK(parameter_scope->is_function_scope() || is_eval_scope() ||
606         is_script_scope());
607
608  DeclarationScope* decl_scope = GetNonEvalDeclarationScope();
609  Scope* outer_scope = decl_scope->outer_scope();
610
611  // For each variable which is used as a function declaration in a sloppy
612  // block,
613  for (SloppyBlockFunctionStatement* sloppy_block_function :
614       sloppy_block_functions_) {
615    const AstRawString* name = sloppy_block_function->name();
616
617    // If the variable wouldn't conflict with a lexical declaration
618    // or parameter,
619
620    // Check if there's a conflict with a parameter.
621    Variable* maybe_parameter = parameter_scope->LookupLocal(name);
622    if (maybe_parameter != nullptr && maybe_parameter->is_parameter()) {
623      continue;
624    }
625
626    // Check if there's a conflict with a lexical declaration
627    Scope* query_scope = sloppy_block_function->scope()->outer_scope();
628    bool should_hoist = true;
629
630    // It is not sufficient to just do a Lookup on query_scope: for
631    // example, that does not prevent hoisting of the function in
632    // `{ let e; try {} catch (e) { function e(){} } }`
633    //
634    // Don't use a generic cache scope, as the cache scope would be the outer
635    // scope and we terminate the iteration there anyway.
636    do {
637      Variable* var = query_scope->LookupInScopeOrScopeInfo(name, query_scope);
638      if (var != nullptr && IsLexicalVariableMode(var->mode())) {
639        should_hoist = false;
640        break;
641      }
642      query_scope = query_scope->outer_scope();
643    } while (query_scope != outer_scope);
644
645    if (!should_hoist) continue;
646
647    if (factory) {
648      DCHECK(!is_being_lazily_parsed_);
649      int pos = sloppy_block_function->position();
650      bool ok = true;
651      bool was_added;
652      auto declaration = factory->NewVariableDeclaration(pos);
653      // Based on the preceding checks, it doesn't matter what we pass as
654      // sloppy_mode_block_scope_function_redefinition.
655      Variable* var = DeclareVariable(
656          declaration, name, pos, VariableMode::kVar, NORMAL_VARIABLE,
657          Variable::DefaultInitializationFlag(VariableMode::kVar), &was_added,
658          nullptr, &ok);
659      DCHECK(ok);
660      VariableProxy* source =
661          factory->NewVariableProxy(sloppy_block_function->var());
662      VariableProxy* target = factory->NewVariableProxy(var);
663      Assignment* assignment = factory->NewAssignment(
664          sloppy_block_function->init(), target, source, pos);
665      assignment->set_lookup_hoisting_mode(LookupHoistingMode::kLegacySloppy);
666      Statement* statement = factory->NewExpressionStatement(assignment, pos);
667      sloppy_block_function->set_statement(statement);
668    } else {
669      DCHECK(is_being_lazily_parsed_);
670      bool was_added;
671      Variable* var = DeclareVariableName(name, VariableMode::kVar, &was_added);
672      if (sloppy_block_function->init() == Token::ASSIGN) {
673        var->SetMaybeAssigned();
674      }
675    }
676  }
677}
678
679bool DeclarationScope::Analyze(ParseInfo* info) {
680  RCS_SCOPE(info->runtime_call_stats(),
681            RuntimeCallCounterId::kCompileScopeAnalysis,
682            RuntimeCallStats::kThreadSpecific);
683  DCHECK_NOT_NULL(info->literal());
684  DeclarationScope* scope = info->literal()->scope();
685
686  base::Optional<AllowHandleDereference> allow_deref;
687#ifdef DEBUG
688  if (scope->outer_scope() && !scope->outer_scope()->scope_info_.is_null()) {
689    allow_deref.emplace();
690  }
691#endif
692
693  if (scope->is_eval_scope() && is_sloppy(scope->language_mode())) {
694    AstNodeFactory factory(info->ast_value_factory(), info->zone());
695    scope->HoistSloppyBlockFunctions(&factory);
696  }
697
698  // We are compiling one of four cases:
699  // 1) top-level code,
700  // 2) a function/eval/module on the top-level
701  // 4) a class member initializer function scope
702  // 3) 4 function/eval in a scope that was already resolved.
703  DCHECK(scope->is_script_scope() || scope->outer_scope()->is_script_scope() ||
704         scope->IsReparsedMemberInitializerScope() ||
705         scope->outer_scope()->already_resolved_);
706
707  // The outer scope is never lazy.
708  scope->set_should_eager_compile();
709
710  if (scope->must_use_preparsed_scope_data_) {
711    DCHECK_EQ(scope->scope_type_, ScopeType::FUNCTION_SCOPE);
712    allow_deref.emplace();
713    info->consumed_preparse_data()->RestoreScopeAllocationData(
714        scope, info->ast_value_factory(), info->zone());
715  }
716
717  if (!scope->AllocateVariables(info)) return false;
718  scope->GetScriptScope()->RewriteReplGlobalVariables();
719
720#ifdef DEBUG
721  if (FLAG_print_scopes) {
722    PrintF("Global scope:\n");
723    scope->Print();
724  }
725  scope->CheckScopePositions();
726  scope->CheckZones();
727#endif
728
729  return true;
730}
731
732void DeclarationScope::DeclareThis(AstValueFactory* ast_value_factory) {
733  DCHECK(has_this_declaration());
734
735  bool derived_constructor = IsDerivedConstructor(function_kind_);
736
737  receiver_ = zone()->New<Variable>(
738      this, ast_value_factory->this_string(),
739      derived_constructor ? VariableMode::kConst : VariableMode::kVar,
740      THIS_VARIABLE,
741      derived_constructor ? kNeedsInitialization : kCreatedInitialized,
742      kNotAssigned);
743  locals_.Add(receiver_);
744}
745
746void DeclarationScope::DeclareArguments(AstValueFactory* ast_value_factory) {
747  DCHECK(is_function_scope());
748  DCHECK(!is_arrow_scope());
749
750  // Because when arguments_ is not nullptr, we already declared
751  // "arguments exotic object" to add it into parameters before
752  // impl()->InsertShadowingVarBindingInitializers, so here
753  // only declare "arguments exotic object" when arguments_
754  // is nullptr
755  if (arguments_ != nullptr) {
756    return;
757  }
758
759  // Declare 'arguments' variable which exists in all non arrow functions.  Note
760  // that it might never be accessed, in which case it won't be allocated during
761  // variable allocation.
762  bool was_added = false;
763
764  arguments_ =
765      Declare(zone(), ast_value_factory->arguments_string(), VariableMode::kVar,
766              NORMAL_VARIABLE, kCreatedInitialized, kNotAssigned, &was_added);
767  // According to ES#sec-functiondeclarationinstantiation step 18
768  // we should set argumentsObjectNeeded to false if has lexical
769  // declared arguments only when hasParameterExpressions is false
770  if (!was_added && IsLexicalVariableMode(arguments_->mode()) &&
771      has_simple_parameters_) {
772    // Check if there's lexically declared variable named arguments to avoid
773    // redeclaration. See ES#sec-functiondeclarationinstantiation, step 20.
774    arguments_ = nullptr;
775  }
776}
777
778void DeclarationScope::DeclareDefaultFunctionVariables(
779    AstValueFactory* ast_value_factory) {
780  DCHECK(is_function_scope());
781  DCHECK(!is_arrow_scope());
782
783  DeclareThis(ast_value_factory);
784  bool was_added;
785  new_target_ = Declare(zone(), ast_value_factory->new_target_string(),
786                        VariableMode::kConst, NORMAL_VARIABLE,
787                        kCreatedInitialized, kNotAssigned, &was_added);
788  DCHECK(was_added);
789
790  if (IsConciseMethod(function_kind_) || IsClassConstructor(function_kind_) ||
791      IsAccessorFunction(function_kind_)) {
792    EnsureRareData()->this_function = Declare(
793        zone(), ast_value_factory->this_function_string(), VariableMode::kConst,
794        NORMAL_VARIABLE, kCreatedInitialized, kNotAssigned, &was_added);
795    DCHECK(was_added);
796  }
797}
798
799Variable* DeclarationScope::DeclareFunctionVar(const AstRawString* name,
800                                               Scope* cache) {
801  DCHECK(is_function_scope());
802  DCHECK_NULL(function_);
803  if (cache == nullptr) cache = this;
804  DCHECK(this->IsOuterScopeOf(cache));
805  DCHECK_NULL(cache->variables_.Lookup(name));
806  VariableKind kind = is_sloppy(language_mode()) ? SLOPPY_FUNCTION_NAME_VARIABLE
807                                                 : NORMAL_VARIABLE;
808  function_ = zone()->New<Variable>(this, name, VariableMode::kConst, kind,
809                                    kCreatedInitialized);
810  if (sloppy_eval_can_extend_vars()) {
811    cache->NonLocal(name, VariableMode::kDynamic);
812  } else {
813    cache->variables_.Add(function_);
814  }
815  return function_;
816}
817
818Variable* DeclarationScope::DeclareGeneratorObjectVar(
819    const AstRawString* name) {
820  DCHECK(is_function_scope() || is_module_scope() || is_repl_mode_scope());
821  DCHECK_NULL(generator_object_var());
822
823  Variable* result = EnsureRareData()->generator_object =
824      NewTemporary(name, kNotAssigned);
825  result->set_is_used();
826  return result;
827}
828
829Scope* Scope::FinalizeBlockScope() {
830  DCHECK(is_block_scope());
831#ifdef DEBUG
832  DCHECK_NE(sibling_, this);
833#endif
834
835  if (variables_.occupancy() > 0 ||
836      (is_declaration_scope() &&
837       AsDeclarationScope()->sloppy_eval_can_extend_vars())) {
838    return this;
839  }
840
841  DCHECK(!is_class_scope());
842
843  // Remove this scope from outer scope.
844  outer_scope()->RemoveInnerScope(this);
845
846  // Reparent inner scopes.
847  if (inner_scope_ != nullptr) {
848    Scope* scope = inner_scope_;
849    scope->outer_scope_ = outer_scope();
850    while (scope->sibling_ != nullptr) {
851      scope = scope->sibling_;
852      scope->outer_scope_ = outer_scope();
853    }
854    scope->sibling_ = outer_scope()->inner_scope_;
855    outer_scope()->inner_scope_ = inner_scope_;
856    inner_scope_ = nullptr;
857  }
858
859  // Move unresolved variables
860  if (!unresolved_list_.is_empty()) {
861    outer_scope()->unresolved_list_.Prepend(std::move(unresolved_list_));
862    unresolved_list_.Clear();
863  }
864
865  if (inner_scope_calls_eval_) outer_scope()->inner_scope_calls_eval_ = true;
866
867  // No need to propagate sloppy_eval_can_extend_vars_, since if it was relevant
868  // to this scope we would have had to bail out at the top.
869  DCHECK(!is_declaration_scope() ||
870         !AsDeclarationScope()->sloppy_eval_can_extend_vars());
871
872  // This block does not need a context.
873  num_heap_slots_ = 0;
874
875  // Mark scope as removed by making it its own sibling.
876#ifdef DEBUG
877  sibling_ = this;
878#endif
879
880  return nullptr;
881}
882
883void DeclarationScope::AddLocal(Variable* var) {
884  DCHECK(!already_resolved_);
885  // Temporaries are only placed in ClosureScopes.
886  DCHECK_EQ(GetClosureScope(), this);
887  locals_.Add(var);
888}
889
890void Scope::Snapshot::Reparent(DeclarationScope* new_parent) {
891  DCHECK_EQ(new_parent, outer_scope_->inner_scope_);
892  DCHECK_EQ(new_parent->outer_scope_, outer_scope_);
893  DCHECK_EQ(new_parent, new_parent->GetClosureScope());
894  DCHECK_NULL(new_parent->inner_scope_);
895  DCHECK(new_parent->unresolved_list_.is_empty());
896  Scope* inner_scope = new_parent->sibling_;
897  if (inner_scope != top_inner_scope_) {
898    for (; inner_scope->sibling() != top_inner_scope_;
899         inner_scope = inner_scope->sibling()) {
900      inner_scope->outer_scope_ = new_parent;
901      if (inner_scope->inner_scope_calls_eval_) {
902        new_parent->inner_scope_calls_eval_ = true;
903      }
904      DCHECK_NE(inner_scope, new_parent);
905    }
906    inner_scope->outer_scope_ = new_parent;
907    if (inner_scope->inner_scope_calls_eval_) {
908      new_parent->inner_scope_calls_eval_ = true;
909    }
910    new_parent->inner_scope_ = new_parent->sibling_;
911    inner_scope->sibling_ = nullptr;
912    // Reset the sibling rather than the inner_scope_ since we
913    // want to keep new_parent there.
914    new_parent->sibling_ = top_inner_scope_;
915  }
916
917  new_parent->unresolved_list_.MoveTail(&outer_scope_->unresolved_list_,
918                                        top_unresolved_);
919
920  // Move temporaries allocated for complex parameter initializers.
921  DeclarationScope* outer_closure = outer_scope_->GetClosureScope();
922  for (auto it = top_local_; it != outer_closure->locals()->end(); ++it) {
923    Variable* local = *it;
924    DCHECK_EQ(VariableMode::kTemporary, local->mode());
925    DCHECK_EQ(local->scope(), local->scope()->GetClosureScope());
926    DCHECK_NE(local->scope(), new_parent);
927    local->set_scope(new_parent);
928  }
929  new_parent->locals_.MoveTail(outer_closure->locals(), top_local_);
930  outer_closure->locals_.Rewind(top_local_);
931
932  // Move eval calls since Snapshot's creation into new_parent.
933  if (outer_scope_->calls_eval_) {
934    new_parent->RecordEvalCall();
935    outer_scope_->calls_eval_ = false;
936    declaration_scope_->sloppy_eval_can_extend_vars_ = false;
937  }
938}
939
940void Scope::ReplaceOuterScope(Scope* outer) {
941  DCHECK_NOT_NULL(outer);
942  DCHECK_NOT_NULL(outer_scope_);
943  DCHECK(!already_resolved_);
944  outer_scope_->RemoveInnerScope(this);
945  outer->AddInnerScope(this);
946  outer_scope_ = outer;
947}
948
949Variable* Scope::LookupInScopeInfo(const AstRawString* name, Scope* cache) {
950  DCHECK(!scope_info_.is_null());
951  DCHECK(this->IsOuterScopeOf(cache));
952  DCHECK(!cache->deserialized_scope_uses_external_cache());
953  // The case where where the cache can be another scope is when the cache scope
954  // is the last scope that doesn't use an external cache.
955  DCHECK_IMPLIES(
956      cache != this,
957      cache->outer_scope()->deserialized_scope_uses_external_cache());
958  DCHECK_NULL(cache->variables_.Lookup(name));
959  DisallowGarbageCollection no_gc;
960
961  String name_handle = *name->string();
962  ScopeInfo scope_info = *scope_info_;
963  // The Scope is backed up by ScopeInfo. This means it cannot operate in a
964  // heap-independent mode, and all strings must be internalized immediately. So
965  // it's ok to get the Handle<String> here.
966  bool found = false;
967
968  VariableLocation location;
969  int index;
970  VariableLookupResult lookup_result;
971
972  {
973    location = VariableLocation::CONTEXT;
974    index = scope_info.ContextSlotIndex(name->string(), &lookup_result);
975    found = index >= 0;
976  }
977
978  if (!found && is_module_scope()) {
979    location = VariableLocation::MODULE;
980    index = scope_info.ModuleIndex(name_handle, &lookup_result.mode,
981                                   &lookup_result.init_flag,
982                                   &lookup_result.maybe_assigned_flag);
983    found = index != 0;
984  }
985
986  if (!found) {
987    index = scope_info.FunctionContextSlotIndex(name_handle);
988    if (index < 0) return nullptr;  // Nowhere found.
989    Variable* var = AsDeclarationScope()->DeclareFunctionVar(name, cache);
990    DCHECK_EQ(VariableMode::kConst, var->mode());
991    var->AllocateTo(VariableLocation::CONTEXT, index);
992    return cache->variables_.Lookup(name);
993  }
994
995  if (!is_module_scope()) {
996    DCHECK_NE(index, scope_info.ReceiverContextSlotIndex());
997  }
998
999  bool was_added;
1000  Variable* var = cache->variables_.Declare(
1001      zone(), this, name, lookup_result.mode, NORMAL_VARIABLE,
1002      lookup_result.init_flag, lookup_result.maybe_assigned_flag,
1003      IsStaticFlag::kNotStatic, &was_added);
1004  DCHECK(was_added);
1005  var->AllocateTo(location, index);
1006  return var;
1007}
1008
1009Variable* DeclarationScope::DeclareParameter(const AstRawString* name,
1010                                             VariableMode mode,
1011                                             bool is_optional, bool is_rest,
1012                                             AstValueFactory* ast_value_factory,
1013                                             int position) {
1014  DCHECK(!already_resolved_);
1015  DCHECK(is_function_scope() || is_module_scope());
1016  DCHECK(!has_rest_);
1017  DCHECK(!is_optional || !is_rest);
1018  DCHECK(!is_being_lazily_parsed_);
1019  DCHECK(!was_lazily_parsed_);
1020  Variable* var;
1021  if (mode == VariableMode::kTemporary) {
1022    var = NewTemporary(name);
1023  } else {
1024    var = LookupLocal(name);
1025    DCHECK_EQ(mode, VariableMode::kVar);
1026    DCHECK(var->is_parameter());
1027  }
1028  has_rest_ = is_rest;
1029  var->set_initializer_position(position);
1030  params_.Add(var, zone());
1031  if (!is_rest) ++num_parameters_;
1032  if (name == ast_value_factory->arguments_string()) {
1033    has_arguments_parameter_ = true;
1034  }
1035  // Params are automatically marked as used to make sure that the debugger and
1036  // function.arguments sees them.
1037  // TODO(verwaest): Reevaluate whether we always need to do this, since
1038  // strict-mode function.arguments does not make the arguments available.
1039  var->set_is_used();
1040  return var;
1041}
1042
1043void DeclarationScope::RecordParameter(bool is_rest) {
1044  DCHECK(!already_resolved_);
1045  DCHECK(is_function_scope() || is_module_scope());
1046  DCHECK(is_being_lazily_parsed_);
1047  DCHECK(!has_rest_);
1048  has_rest_ = is_rest;
1049  if (!is_rest) ++num_parameters_;
1050}
1051
1052Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode,
1053                              VariableKind kind, bool* was_added,
1054                              InitializationFlag init_flag) {
1055  DCHECK(!already_resolved_);
1056  // Private methods should be declared with ClassScope::DeclarePrivateName()
1057  DCHECK(!IsPrivateMethodOrAccessorVariableMode(mode));
1058  // This function handles VariableMode::kVar, VariableMode::kLet, and
1059  // VariableMode::kConst modes.  VariableMode::kDynamic variables are
1060  // introduced during variable allocation, and VariableMode::kTemporary
1061  // variables are allocated via NewTemporary().
1062  DCHECK(IsDeclaredVariableMode(mode));
1063  DCHECK_IMPLIES(GetDeclarationScope()->is_being_lazily_parsed(),
1064                 mode == VariableMode::kVar || mode == VariableMode::kLet ||
1065                     mode == VariableMode::kConst);
1066  DCHECK(!GetDeclarationScope()->was_lazily_parsed());
1067  Variable* var =
1068      Declare(zone(), name, mode, kind, init_flag, kNotAssigned, was_added);
1069
1070  // Pessimistically assume that top-level variables will be assigned and used.
1071  //
1072  // Top-level variables in a script can be accessed by other scripts or even
1073  // become global properties. While this does not apply to top-level variables
1074  // in a module (assuming they are not exported), we must still mark these as
1075  // assigned because they might be accessed by a lazily parsed top-level
1076  // function, which, for efficiency, we preparse without variable tracking.
1077  if (is_script_scope() || is_module_scope()) {
1078    if (mode != VariableMode::kConst) var->SetMaybeAssigned();
1079    var->set_is_used();
1080  }
1081
1082  return var;
1083}
1084
1085Variable* Scope::DeclareVariable(
1086    Declaration* declaration, const AstRawString* name, int pos,
1087    VariableMode mode, VariableKind kind, InitializationFlag init,
1088    bool* was_added, bool* sloppy_mode_block_scope_function_redefinition,
1089    bool* ok) {
1090  // Private methods should be declared with ClassScope::DeclarePrivateName()
1091  DCHECK(!IsPrivateMethodOrAccessorVariableMode(mode));
1092  DCHECK(IsDeclaredVariableMode(mode));
1093  DCHECK(!already_resolved_);
1094  DCHECK(!GetDeclarationScope()->is_being_lazily_parsed());
1095  DCHECK(!GetDeclarationScope()->was_lazily_parsed());
1096
1097  if (mode == VariableMode::kVar && !is_declaration_scope()) {
1098    return GetDeclarationScope()->DeclareVariable(
1099        declaration, name, pos, mode, kind, init, was_added,
1100        sloppy_mode_block_scope_function_redefinition, ok);
1101  }
1102  DCHECK(!is_catch_scope());
1103  DCHECK(!is_with_scope());
1104  DCHECK(is_declaration_scope() ||
1105         (IsLexicalVariableMode(mode) && is_block_scope()));
1106
1107  DCHECK_NOT_NULL(name);
1108
1109  Variable* var = LookupLocal(name);
1110  // Declare the variable in the declaration scope.
1111  *was_added = var == nullptr;
1112  if (V8_LIKELY(*was_added)) {
1113    if (V8_UNLIKELY(is_eval_scope() && is_sloppy(language_mode()) &&
1114                    mode == VariableMode::kVar)) {
1115      // In a var binding in a sloppy direct eval, pollute the enclosing scope
1116      // with this new binding by doing the following:
1117      // The proxy is bound to a lookup variable to force a dynamic declaration
1118      // using the DeclareEvalVar or DeclareEvalFunction runtime functions.
1119      DCHECK_EQ(NORMAL_VARIABLE, kind);
1120      var = NonLocal(name, VariableMode::kDynamic);
1121      // Mark the var as used in case anyone outside the eval wants to use it.
1122      var->set_is_used();
1123    } else {
1124      // Declare the name.
1125      var = DeclareLocal(name, mode, kind, was_added, init);
1126      DCHECK(*was_added);
1127    }
1128  } else {
1129    var->SetMaybeAssigned();
1130    if (V8_UNLIKELY(IsLexicalVariableMode(mode) ||
1131                    IsLexicalVariableMode(var->mode()))) {
1132      // The name was declared in this scope before; check for conflicting
1133      // re-declarations. We have a conflict if either of the declarations is
1134      // not a var (in script scope, we also have to ignore legacy const for
1135      // compatibility). There is similar code in runtime.cc in the Declare
1136      // functions. The function CheckConflictingVarDeclarations checks for
1137      // var and let bindings from different scopes whereas this is a check
1138      // for conflicting declarations within the same scope. This check also
1139      // covers the special case
1140      //
1141      // function () { let x; { var x; } }
1142      //
1143      // because the var declaration is hoisted to the function scope where
1144      // 'x' is already bound.
1145      //
1146      // In harmony we treat re-declarations as early errors. See ES5 16 for a
1147      // definition of early errors.
1148      //
1149      // Allow duplicate function decls for web compat, see bug 4693.
1150      *ok = var->is_sloppy_block_function() &&
1151            kind == SLOPPY_BLOCK_FUNCTION_VARIABLE;
1152      *sloppy_mode_block_scope_function_redefinition = *ok;
1153    }
1154  }
1155  DCHECK_NOT_NULL(var);
1156
1157  // We add a declaration node for every declaration. The compiler
1158  // will only generate code if necessary. In particular, declarations
1159  // for inner local variables that do not represent functions won't
1160  // result in any generated code.
1161  //
1162  // This will lead to multiple declaration nodes for the
1163  // same variable if it is declared several times. This is not a
1164  // semantic issue, but it may be a performance issue since it may
1165  // lead to repeated DeclareEvalVar or DeclareEvalFunction calls.
1166  decls_.Add(declaration);
1167  declaration->set_var(var);
1168  return var;
1169}
1170
1171Variable* Scope::DeclareVariableName(const AstRawString* name,
1172                                     VariableMode mode, bool* was_added,
1173                                     VariableKind kind) {
1174  DCHECK(IsDeclaredVariableMode(mode));
1175  DCHECK(!already_resolved_);
1176  DCHECK(GetDeclarationScope()->is_being_lazily_parsed());
1177  // Private methods should be declared with ClassScope::DeclarePrivateName()
1178  DCHECK(!IsPrivateMethodOrAccessorVariableMode(mode));
1179  if (mode == VariableMode::kVar && !is_declaration_scope()) {
1180    return GetDeclarationScope()->DeclareVariableName(name, mode, was_added,
1181                                                      kind);
1182  }
1183  DCHECK(!is_with_scope());
1184  DCHECK(!is_eval_scope());
1185  DCHECK(is_declaration_scope() || IsLexicalVariableMode(mode));
1186  DCHECK(scope_info_.is_null());
1187
1188  // Declare the variable in the declaration scope.
1189  Variable* var = DeclareLocal(name, mode, kind, was_added);
1190  if (!*was_added) {
1191    if (IsLexicalVariableMode(mode) || IsLexicalVariableMode(var->mode())) {
1192      if (!var->is_sloppy_block_function() ||
1193          kind != SLOPPY_BLOCK_FUNCTION_VARIABLE) {
1194        // Duplicate functions are allowed in the sloppy mode, but if this is
1195        // not a function declaration, it's an error. This is an error PreParser
1196        // hasn't previously detected.
1197        return nullptr;
1198      }
1199      // Sloppy block function redefinition.
1200    }
1201    var->SetMaybeAssigned();
1202  }
1203  var->set_is_used();
1204  return var;
1205}
1206
1207Variable* Scope::DeclareCatchVariableName(const AstRawString* name) {
1208  DCHECK(!already_resolved_);
1209  DCHECK(is_catch_scope());
1210  DCHECK(scope_info_.is_null());
1211
1212  bool was_added;
1213  Variable* result = Declare(zone(), name, VariableMode::kVar, NORMAL_VARIABLE,
1214                             kCreatedInitialized, kNotAssigned, &was_added);
1215  DCHECK(was_added);
1216  return result;
1217}
1218
1219void Scope::AddUnresolved(VariableProxy* proxy) {
1220  DCHECK(!already_resolved_);
1221  DCHECK(!proxy->is_resolved());
1222  unresolved_list_.Add(proxy);
1223}
1224
1225Variable* DeclarationScope::DeclareDynamicGlobal(const AstRawString* name,
1226                                                 VariableKind kind,
1227                                                 Scope* cache) {
1228  DCHECK(is_script_scope());
1229  bool was_added;
1230  return cache->variables_.Declare(
1231      zone(), this, name, VariableMode::kDynamicGlobal, kind,
1232      kCreatedInitialized, kNotAssigned, IsStaticFlag::kNotStatic, &was_added);
1233  // TODO(neis): Mark variable as maybe-assigned?
1234}
1235
1236bool Scope::RemoveUnresolved(VariableProxy* var) {
1237  return unresolved_list_.Remove(var);
1238}
1239
1240void Scope::DeleteUnresolved(VariableProxy* var) {
1241  DCHECK(unresolved_list_.Contains(var));
1242  var->mark_removed_from_unresolved();
1243}
1244
1245Variable* Scope::NewTemporary(const AstRawString* name) {
1246  return NewTemporary(name, kMaybeAssigned);
1247}
1248
1249Variable* Scope::NewTemporary(const AstRawString* name,
1250                              MaybeAssignedFlag maybe_assigned) {
1251  DeclarationScope* scope = GetClosureScope();
1252  Variable* var = zone()->New<Variable>(scope, name, VariableMode::kTemporary,
1253                                        NORMAL_VARIABLE, kCreatedInitialized);
1254  scope->AddLocal(var);
1255  if (maybe_assigned == kMaybeAssigned) var->SetMaybeAssigned();
1256  return var;
1257}
1258
1259Declaration* DeclarationScope::CheckConflictingVarDeclarations(
1260    bool* allowed_catch_binding_var_redeclaration) {
1261  if (has_checked_syntax_) return nullptr;
1262  for (Declaration* decl : decls_) {
1263    // Lexical vs lexical conflicts within the same scope have already been
1264    // captured in Parser::Declare. The only conflicts we still need to check
1265    // are lexical vs nested var.
1266    if (decl->IsVariableDeclaration() &&
1267        decl->AsVariableDeclaration()->AsNested() != nullptr) {
1268      Scope* current = decl->AsVariableDeclaration()->AsNested()->scope();
1269      DCHECK(decl->var()->mode() == VariableMode::kVar ||
1270             decl->var()->mode() == VariableMode::kDynamic);
1271      // Iterate through all scopes until the declaration scope.
1272      do {
1273        // There is a conflict if there exists a non-VAR binding.
1274        Variable* other_var = current->LookupLocal(decl->var()->raw_name());
1275        if (current->is_catch_scope()) {
1276          *allowed_catch_binding_var_redeclaration |= other_var != nullptr;
1277          current = current->outer_scope();
1278          continue;
1279        }
1280        if (other_var != nullptr) {
1281          DCHECK(IsLexicalVariableMode(other_var->mode()));
1282          return decl;
1283        }
1284        current = current->outer_scope();
1285      } while (current != this);
1286    }
1287  }
1288
1289  if (V8_LIKELY(!is_eval_scope())) return nullptr;
1290  if (!is_sloppy(language_mode())) return nullptr;
1291
1292  // Var declarations in sloppy eval are hoisted to the first non-eval
1293  // declaration scope. Check for conflicts between the eval scope that
1294  // declaration scope.
1295  Scope* end = outer_scope()->GetNonEvalDeclarationScope()->outer_scope();
1296
1297  for (Declaration* decl : decls_) {
1298    if (IsLexicalVariableMode(decl->var()->mode())) continue;
1299    Scope* current = outer_scope_;
1300    // Iterate through all scopes until and including the declaration scope.
1301    do {
1302      // There is a conflict if there exists a non-VAR binding up to the
1303      // declaration scope in which this sloppy-eval runs.
1304      //
1305      // Use the current scope as the cache, since the general cache would be
1306      // the end scope.
1307      Variable* other_var =
1308          current->LookupInScopeOrScopeInfo(decl->var()->raw_name(), current);
1309      if (other_var != nullptr && !current->is_catch_scope()) {
1310        // If this is a VAR, then we know that it doesn't conflict with
1311        // anything, so we can't conflict with anything either. The one
1312        // exception is the binding variable in catch scopes, which is handled
1313        // by the if above.
1314        if (!IsLexicalVariableMode(other_var->mode())) break;
1315        return decl;
1316      }
1317      current = current->outer_scope();
1318    } while (current != end);
1319  }
1320  return nullptr;
1321}
1322
1323const AstRawString* Scope::FindVariableDeclaredIn(Scope* scope,
1324                                                  VariableMode mode_limit) {
1325  const VariableMap& variables = scope->variables_;
1326  for (ZoneHashMap::Entry* p = variables.Start(); p != nullptr;
1327       p = variables.Next(p)) {
1328    const AstRawString* name = static_cast<const AstRawString*>(p->key);
1329    Variable* var = LookupLocal(name);
1330    if (var != nullptr && var->mode() <= mode_limit) return name;
1331  }
1332  return nullptr;
1333}
1334
1335void DeclarationScope::DeserializeReceiver(AstValueFactory* ast_value_factory) {
1336  if (is_script_scope()) {
1337    DCHECK_NOT_NULL(receiver_);
1338    return;
1339  }
1340  DCHECK(has_this_declaration());
1341  DeclareThis(ast_value_factory);
1342  if (is_debug_evaluate_scope()) {
1343    receiver_->AllocateTo(VariableLocation::LOOKUP, -1);
1344  } else {
1345    receiver_->AllocateTo(VariableLocation::CONTEXT,
1346                          scope_info_->ReceiverContextSlotIndex());
1347  }
1348}
1349
1350bool DeclarationScope::AllocateVariables(ParseInfo* info) {
1351  // Module variables must be allocated before variable resolution
1352  // to ensure that UpdateNeedsHoleCheck() can detect import variables.
1353  if (is_module_scope()) AsModuleScope()->AllocateModuleVariables();
1354
1355  PrivateNameScopeIterator private_name_scope_iter(this);
1356  if (!private_name_scope_iter.Done() &&
1357      !private_name_scope_iter.GetScope()->ResolvePrivateNames(info)) {
1358    DCHECK(info->pending_error_handler()->has_pending_error());
1359    return false;
1360  }
1361
1362  if (!ResolveVariablesRecursively(info->scope())) {
1363    DCHECK(info->pending_error_handler()->has_pending_error());
1364    return false;
1365  }
1366
1367  // Don't allocate variables of preparsed scopes.
1368  if (!was_lazily_parsed()) AllocateVariablesRecursively();
1369
1370  return true;
1371}
1372
1373bool Scope::HasThisReference() const {
1374  if (is_declaration_scope() && AsDeclarationScope()->has_this_reference()) {
1375    return true;
1376  }
1377
1378  for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
1379    if (!scope->is_declaration_scope() ||
1380        !scope->AsDeclarationScope()->has_this_declaration()) {
1381      if (scope->HasThisReference()) return true;
1382    }
1383  }
1384
1385  return false;
1386}
1387
1388bool Scope::AllowsLazyParsingWithoutUnresolvedVariables(
1389    const Scope* outer) const {
1390  // If none of the outer scopes need to decide whether to context allocate
1391  // specific variables, we can preparse inner functions without unresolved
1392  // variables. Otherwise we need to find unresolved variables to force context
1393  // allocation of the matching declarations. We can stop at the outer scope for
1394  // the parse, since context allocation of those variables is already
1395  // guaranteed to be correct.
1396  for (const Scope* s = this; s != outer; s = s->outer_scope_) {
1397    // Eval forces context allocation on all outer scopes, so we don't need to
1398    // look at those scopes. Sloppy eval makes top-level non-lexical variables
1399    // dynamic, whereas strict-mode requires context allocation.
1400    if (s->is_eval_scope()) return is_sloppy(s->language_mode());
1401    // Catch scopes force context allocation of all variables.
1402    if (s->is_catch_scope()) continue;
1403    // With scopes do not introduce variables that need allocation.
1404    if (s->is_with_scope()) continue;
1405    DCHECK(s->is_module_scope() || s->is_block_scope() ||
1406           s->is_function_scope());
1407    return false;
1408  }
1409  return true;
1410}
1411
1412bool DeclarationScope::AllowsLazyCompilation() const {
1413  // Functions which force eager compilation and class member initializer
1414  // functions are not lazily compilable.
1415  return !force_eager_compilation_ &&
1416         !IsClassMembersInitializerFunction(function_kind());
1417}
1418
1419int Scope::ContextChainLength(Scope* scope) const {
1420  int n = 0;
1421  for (const Scope* s = this; s != scope; s = s->outer_scope_) {
1422    DCHECK_NOT_NULL(s);  // scope must be in the scope chain
1423    if (s->NeedsContext()) n++;
1424  }
1425  return n;
1426}
1427
1428int Scope::ContextChainLengthUntilOutermostSloppyEval() const {
1429  int result = 0;
1430  int length = 0;
1431
1432  for (const Scope* s = this; s != nullptr; s = s->outer_scope()) {
1433    if (!s->NeedsContext()) continue;
1434    length++;
1435    if (s->is_declaration_scope() &&
1436        s->AsDeclarationScope()->sloppy_eval_can_extend_vars()) {
1437      result = length;
1438    }
1439  }
1440
1441  return result;
1442}
1443
1444DeclarationScope* Scope::GetDeclarationScope() {
1445  Scope* scope = this;
1446  while (!scope->is_declaration_scope()) {
1447    scope = scope->outer_scope();
1448  }
1449  return scope->AsDeclarationScope();
1450}
1451
1452DeclarationScope* Scope::GetNonEvalDeclarationScope() {
1453  Scope* scope = this;
1454  while (!scope->is_declaration_scope() || scope->is_eval_scope()) {
1455    scope = scope->outer_scope();
1456  }
1457  return scope->AsDeclarationScope();
1458}
1459
1460const DeclarationScope* Scope::GetClosureScope() const {
1461  const Scope* scope = this;
1462  while (!scope->is_declaration_scope() || scope->is_block_scope()) {
1463    scope = scope->outer_scope();
1464  }
1465  return scope->AsDeclarationScope();
1466}
1467
1468DeclarationScope* Scope::GetClosureScope() {
1469  Scope* scope = this;
1470  while (!scope->is_declaration_scope() || scope->is_block_scope()) {
1471    scope = scope->outer_scope();
1472  }
1473  return scope->AsDeclarationScope();
1474}
1475
1476bool Scope::NeedsScopeInfo() const {
1477  DCHECK(!already_resolved_);
1478  DCHECK(GetClosureScope()->ShouldEagerCompile());
1479  // The debugger expects all functions to have scope infos.
1480  // TODO(yangguo): Remove this requirement.
1481  if (is_function_scope()) return true;
1482  return NeedsContext();
1483}
1484
1485bool Scope::ShouldBanArguments() {
1486  return GetReceiverScope()->should_ban_arguments();
1487}
1488
1489DeclarationScope* Scope::GetReceiverScope() {
1490  Scope* scope = this;
1491  while (!scope->is_declaration_scope() ||
1492         (!scope->is_script_scope() &&
1493          !scope->AsDeclarationScope()->has_this_declaration())) {
1494    scope = scope->outer_scope();
1495  }
1496  return scope->AsDeclarationScope();
1497}
1498
1499DeclarationScope* Scope::GetConstructorScope() {
1500  Scope* scope = this;
1501  while (scope != nullptr && !scope->IsConstructorScope()) {
1502    scope = scope->outer_scope();
1503  }
1504  if (scope == nullptr) {
1505    return nullptr;
1506  }
1507  DCHECK(scope->IsConstructorScope());
1508  return scope->AsDeclarationScope();
1509}
1510
1511Scope* Scope::GetHomeObjectScope() {
1512  Scope* scope = this;
1513  while (scope != nullptr && !scope->is_home_object_scope()) {
1514    if (scope->is_function_scope()) {
1515      FunctionKind function_kind = scope->AsDeclarationScope()->function_kind();
1516      // "super" in arrow functions binds outside the arrow function. But if we
1517      // find a function which doesn't bind "super" (is not a method etc.) and
1518      // not an arrow function, we know "super" here doesn't bind anywhere and
1519      // we can return nullptr.
1520      if (!IsArrowFunction(function_kind) && !BindsSuper(function_kind)) {
1521        return nullptr;
1522      }
1523    }
1524    if (scope->private_name_lookup_skips_outer_class()) {
1525      DCHECK(scope->outer_scope()->is_class_scope());
1526      scope = scope->outer_scope()->outer_scope();
1527    } else {
1528      scope = scope->outer_scope();
1529    }
1530  }
1531  return scope;
1532}
1533
1534DeclarationScope* Scope::GetScriptScope() {
1535  Scope* scope = this;
1536  while (!scope->is_script_scope()) {
1537    scope = scope->outer_scope();
1538  }
1539  return scope->AsDeclarationScope();
1540}
1541
1542Scope* Scope::GetOuterScopeWithContext() {
1543  Scope* scope = outer_scope_;
1544  while (scope && !scope->NeedsContext()) {
1545    scope = scope->outer_scope();
1546  }
1547  return scope;
1548}
1549
1550namespace {
1551bool WasLazilyParsed(Scope* scope) {
1552  return scope->is_declaration_scope() &&
1553         scope->AsDeclarationScope()->was_lazily_parsed();
1554}
1555
1556}  // namespace
1557
1558template <typename FunctionType>
1559void Scope::ForEach(FunctionType callback) {
1560  Scope* scope = this;
1561  while (true) {
1562    Iteration iteration = callback(scope);
1563    // Try to descend into inner scopes first.
1564    if ((iteration == Iteration::kDescend) && scope->inner_scope_ != nullptr) {
1565      scope = scope->inner_scope_;
1566    } else {
1567      // Find the next outer scope with a sibling.
1568      while (scope->sibling_ == nullptr) {
1569        if (scope == this) return;
1570        scope = scope->outer_scope_;
1571      }
1572      if (scope == this) return;
1573      scope = scope->sibling_;
1574    }
1575  }
1576}
1577
1578bool Scope::IsConstructorScope() const {
1579  return is_declaration_scope() &&
1580         IsClassConstructor(AsDeclarationScope()->function_kind());
1581}
1582
1583bool Scope::IsOuterScopeOf(Scope* other) const {
1584  Scope* scope = other;
1585  while (scope) {
1586    if (scope == this) return true;
1587    scope = scope->outer_scope();
1588  }
1589  return false;
1590}
1591
1592void Scope::CollectNonLocals(DeclarationScope* max_outer_scope,
1593                             Isolate* isolate, Handle<StringSet>* non_locals) {
1594  this->ForEach([max_outer_scope, isolate, non_locals](Scope* scope) {
1595    // Module variables must be allocated before variable resolution
1596    // to ensure that UpdateNeedsHoleCheck() can detect import variables.
1597    if (scope->is_module_scope()) {
1598      scope->AsModuleScope()->AllocateModuleVariables();
1599    }
1600
1601    // Lazy parsed declaration scopes are already partially analyzed. If there
1602    // are unresolved references remaining, they just need to be resolved in
1603    // outer scopes.
1604    Scope* lookup = WasLazilyParsed(scope) ? scope->outer_scope() : scope;
1605
1606    for (VariableProxy* proxy : scope->unresolved_list_) {
1607      DCHECK(!proxy->is_resolved());
1608      Variable* var =
1609          Lookup<kParsedScope>(proxy, lookup, max_outer_scope->outer_scope());
1610      if (var == nullptr) {
1611        *non_locals = StringSet::Add(isolate, *non_locals, proxy->name());
1612      } else {
1613        // In this case we need to leave scopes in a way that they can be
1614        // allocated. If we resolved variables from lazy parsed scopes, we need
1615        // to context allocate the var.
1616        scope->ResolveTo(proxy, var);
1617        if (!var->is_dynamic() && lookup != scope)
1618          var->ForceContextAllocation();
1619      }
1620    }
1621
1622    // Clear unresolved_list_ as it's in an inconsistent state.
1623    scope->unresolved_list_.Clear();
1624    return Iteration::kDescend;
1625  });
1626}
1627
1628void Scope::AnalyzePartially(DeclarationScope* max_outer_scope,
1629                             AstNodeFactory* ast_node_factory,
1630                             UnresolvedList* new_unresolved_list,
1631                             bool maybe_in_arrowhead) {
1632  this->ForEach([max_outer_scope, ast_node_factory, new_unresolved_list,
1633                 maybe_in_arrowhead](Scope* scope) {
1634    DCHECK_IMPLIES(scope->is_declaration_scope(),
1635                   !scope->AsDeclarationScope()->was_lazily_parsed());
1636
1637    for (VariableProxy* proxy = scope->unresolved_list_.first();
1638         proxy != nullptr; proxy = proxy->next_unresolved()) {
1639      if (proxy->is_removed_from_unresolved()) continue;
1640      DCHECK(!proxy->is_resolved());
1641      Variable* var =
1642          Lookup<kParsedScope>(proxy, scope, max_outer_scope->outer_scope());
1643      if (var == nullptr) {
1644        // Don't copy unresolved references to the script scope, unless it's a
1645        // reference to a private name or method. In that case keep it so we
1646        // can fail later.
1647        if (!max_outer_scope->outer_scope()->is_script_scope() ||
1648            maybe_in_arrowhead) {
1649          VariableProxy* copy = ast_node_factory->CopyVariableProxy(proxy);
1650          new_unresolved_list->Add(copy);
1651        }
1652      } else {
1653        var->set_is_used();
1654        if (proxy->is_assigned()) var->SetMaybeAssigned();
1655      }
1656    }
1657
1658    // Clear unresolved_list_ as it's in an inconsistent state.
1659    scope->unresolved_list_.Clear();
1660    return Iteration::kDescend;
1661  });
1662}
1663
1664Handle<StringSet> DeclarationScope::CollectNonLocals(
1665    Isolate* isolate, Handle<StringSet> non_locals) {
1666  Scope::CollectNonLocals(this, isolate, &non_locals);
1667  return non_locals;
1668}
1669
1670void DeclarationScope::ResetAfterPreparsing(AstValueFactory* ast_value_factory,
1671                                            bool aborted) {
1672  DCHECK(is_function_scope());
1673
1674  // Reset all non-trivial members.
1675  params_.DropAndClear();
1676  decls_.Clear();
1677  locals_.Clear();
1678  inner_scope_ = nullptr;
1679  unresolved_list_.Clear();
1680  sloppy_block_functions_.Clear();
1681  rare_data_ = nullptr;
1682  has_rest_ = false;
1683  function_ = nullptr;
1684
1685  DCHECK_NE(zone(), ast_value_factory->single_parse_zone());
1686  // Make sure this scope and zone aren't used for allocation anymore.
1687  {
1688    // Get the zone, while variables_ is still valid
1689    Zone* zone = this->zone();
1690    variables_.Invalidate();
1691    zone->Reset();
1692  }
1693
1694  if (aborted) {
1695    // Prepare scope for use in the outer zone.
1696    variables_ = VariableMap(ast_value_factory->single_parse_zone());
1697    if (!IsArrowFunction(function_kind_)) {
1698      has_simple_parameters_ = true;
1699      DeclareDefaultFunctionVariables(ast_value_factory);
1700    }
1701  }
1702
1703#ifdef DEBUG
1704  needs_migration_ = false;
1705  is_being_lazily_parsed_ = false;
1706#endif
1707
1708  was_lazily_parsed_ = !aborted;
1709}
1710
1711bool Scope::IsSkippableFunctionScope() {
1712  // Lazy non-arrow function scopes are skippable. Lazy functions are exactly
1713  // those Scopes which have their own PreparseDataBuilder object. This
1714  // logic ensures that the scope allocation data is consistent with the
1715  // skippable function data (both agree on where the lazy function boundaries
1716  // are).
1717  if (!is_function_scope()) return false;
1718  DeclarationScope* declaration_scope = AsDeclarationScope();
1719  return !declaration_scope->is_arrow_scope() &&
1720         declaration_scope->preparse_data_builder() != nullptr;
1721}
1722
1723void Scope::SavePreparseData(Parser* parser) {
1724  this->ForEach([parser](Scope* scope) {
1725    if (scope->IsSkippableFunctionScope()) {
1726      scope->AsDeclarationScope()->SavePreparseDataForDeclarationScope(parser);
1727    }
1728    return Iteration::kDescend;
1729  });
1730}
1731
1732void DeclarationScope::SavePreparseDataForDeclarationScope(Parser* parser) {
1733  if (preparse_data_builder_ == nullptr) return;
1734  preparse_data_builder_->SaveScopeAllocationData(this, parser);
1735}
1736
1737void DeclarationScope::AnalyzePartially(Parser* parser,
1738                                        AstNodeFactory* ast_node_factory,
1739                                        bool maybe_in_arrowhead) {
1740  DCHECK(!force_eager_compilation_);
1741  UnresolvedList new_unresolved_list;
1742  if (!IsArrowFunction(function_kind_) &&
1743      (!outer_scope_->is_script_scope() || maybe_in_arrowhead ||
1744       (preparse_data_builder_ != nullptr &&
1745        preparse_data_builder_->HasInnerFunctions()))) {
1746    // Try to resolve unresolved variables for this Scope and migrate those
1747    // which cannot be resolved inside. It doesn't make sense to try to resolve
1748    // them in the outer Scopes here, because they are incomplete.
1749    Scope::AnalyzePartially(this, ast_node_factory, &new_unresolved_list,
1750                            maybe_in_arrowhead);
1751
1752    // Migrate function_ to the right Zone.
1753    if (function_ != nullptr) {
1754      function_ = ast_node_factory->CopyVariable(function_);
1755    }
1756
1757    SavePreparseData(parser);
1758  }
1759
1760#ifdef DEBUG
1761  if (FLAG_print_scopes) {
1762    PrintF("Inner function scope:\n");
1763    Print();
1764  }
1765#endif
1766
1767  ResetAfterPreparsing(ast_node_factory->ast_value_factory(), false);
1768
1769  unresolved_list_ = std::move(new_unresolved_list);
1770}
1771
1772void DeclarationScope::RewriteReplGlobalVariables() {
1773  DCHECK(is_script_scope());
1774  if (!is_repl_mode_scope()) return;
1775
1776  for (VariableMap::Entry* p = variables_.Start(); p != nullptr;
1777       p = variables_.Next(p)) {
1778    Variable* var = reinterpret_cast<Variable*>(p->value);
1779    var->RewriteLocationForRepl();
1780  }
1781}
1782
1783#ifdef DEBUG
1784namespace {
1785
1786const char* Header(ScopeType scope_type, FunctionKind function_kind,
1787                   bool is_declaration_scope) {
1788  switch (scope_type) {
1789    case EVAL_SCOPE: return "eval";
1790    case FUNCTION_SCOPE:
1791      if (IsGeneratorFunction(function_kind)) return "function*";
1792      if (IsAsyncFunction(function_kind)) return "async function";
1793      if (IsArrowFunction(function_kind)) return "arrow";
1794      return "function";
1795    case MODULE_SCOPE: return "module";
1796    case SCRIPT_SCOPE: return "global";
1797    case CATCH_SCOPE: return "catch";
1798    case BLOCK_SCOPE: return is_declaration_scope ? "varblock" : "block";
1799    case CLASS_SCOPE:
1800      return "class";
1801    case WITH_SCOPE: return "with";
1802  }
1803  UNREACHABLE();
1804}
1805
1806void Indent(int n, const char* str) { PrintF("%*s%s", n, "", str); }
1807
1808void PrintName(const AstRawString* name) {
1809  PrintF("%.*s", name->length(), name->raw_data());
1810}
1811
1812void PrintLocation(Variable* var) {
1813  switch (var->location()) {
1814    case VariableLocation::UNALLOCATED:
1815      break;
1816    case VariableLocation::PARAMETER:
1817      PrintF("parameter[%d]", var->index());
1818      break;
1819    case VariableLocation::LOCAL:
1820      PrintF("local[%d]", var->index());
1821      break;
1822    case VariableLocation::CONTEXT:
1823      PrintF("context[%d]", var->index());
1824      break;
1825    case VariableLocation::LOOKUP:
1826      PrintF("lookup");
1827      break;
1828    case VariableLocation::MODULE:
1829      PrintF("module");
1830      break;
1831    case VariableLocation::REPL_GLOBAL:
1832      PrintF("repl global[%d]", var->index());
1833      break;
1834  }
1835}
1836
1837void PrintVar(int indent, Variable* var) {
1838  Indent(indent, VariableMode2String(var->mode()));
1839  PrintF(" ");
1840  if (var->raw_name()->IsEmpty())
1841    PrintF(".%p", reinterpret_cast<void*>(var));
1842  else
1843    PrintName(var->raw_name());
1844  PrintF(";  // (%p) ", reinterpret_cast<void*>(var));
1845  PrintLocation(var);
1846  bool comma = !var->IsUnallocated();
1847  if (var->has_forced_context_allocation()) {
1848    if (comma) PrintF(", ");
1849    PrintF("forced context allocation");
1850    comma = true;
1851  }
1852  if (var->maybe_assigned() == kNotAssigned) {
1853    if (comma) PrintF(", ");
1854    PrintF("never assigned");
1855    comma = true;
1856  }
1857  if (var->initialization_flag() == kNeedsInitialization &&
1858      !var->binding_needs_init()) {
1859    if (comma) PrintF(", ");
1860    PrintF("hole initialization elided");
1861  }
1862  PrintF("\n");
1863}
1864
1865void PrintMap(int indent, const char* label, VariableMap* map, bool locals,
1866              Variable* function_var) {
1867  bool printed_label = false;
1868  for (VariableMap::Entry* p = map->Start(); p != nullptr; p = map->Next(p)) {
1869    Variable* var = reinterpret_cast<Variable*>(p->value);
1870    if (var == function_var) continue;
1871    bool local = !IsDynamicVariableMode(var->mode());
1872    if ((locals ? local : !local) &&
1873        (var->is_used() || !var->IsUnallocated())) {
1874      if (!printed_label) {
1875        Indent(indent, label);
1876        printed_label = true;
1877      }
1878      PrintVar(indent, var);
1879    }
1880  }
1881}
1882
1883}  // anonymous namespace
1884
1885void DeclarationScope::PrintParameters() {
1886  PrintF(" (");
1887  for (int i = 0; i < params_.length(); i++) {
1888    if (i > 0) PrintF(", ");
1889    const AstRawString* name = params_[i]->raw_name();
1890    if (name->IsEmpty()) {
1891      PrintF(".%p", reinterpret_cast<void*>(params_[i]));
1892    } else {
1893      PrintName(name);
1894    }
1895  }
1896  PrintF(")");
1897}
1898
1899void Scope::Print(int n) {
1900  int n0 = (n > 0 ? n : 0);
1901  int n1 = n0 + 2;  // indentation
1902
1903  // Print header.
1904  FunctionKind function_kind = is_function_scope()
1905                                   ? AsDeclarationScope()->function_kind()
1906                                   : FunctionKind::kNormalFunction;
1907  Indent(n0, Header(scope_type_, function_kind, is_declaration_scope()));
1908  if (scope_name_ != nullptr && !scope_name_->IsEmpty()) {
1909    PrintF(" ");
1910    PrintName(scope_name_);
1911  }
1912
1913  // Print parameters, if any.
1914  Variable* function = nullptr;
1915  if (is_function_scope()) {
1916    AsDeclarationScope()->PrintParameters();
1917    function = AsDeclarationScope()->function_var();
1918  }
1919
1920  PrintF(" { // (%p) (%d, %d)\n", reinterpret_cast<void*>(this),
1921         start_position(), end_position());
1922  if (is_hidden()) {
1923    Indent(n1, "// is hidden\n");
1924  }
1925
1926  // Function name, if any (named function literals, only).
1927  if (function != nullptr) {
1928    Indent(n1, "// (local) function name: ");
1929    PrintName(function->raw_name());
1930    PrintF("\n");
1931  }
1932
1933  // Scope info.
1934  if (is_strict(language_mode())) {
1935    Indent(n1, "// strict mode scope\n");
1936  }
1937#if V8_ENABLE_WEBASSEMBLY
1938  if (IsAsmModule()) Indent(n1, "// scope is an asm module\n");
1939#endif  // V8_ENABLE_WEBASSEMBLY
1940  if (is_declaration_scope() &&
1941      AsDeclarationScope()->sloppy_eval_can_extend_vars()) {
1942    Indent(n1, "// scope calls sloppy 'eval'\n");
1943  }
1944  if (private_name_lookup_skips_outer_class()) {
1945    Indent(n1, "// scope skips outer class for #-names\n");
1946  }
1947  if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n");
1948  if (is_declaration_scope()) {
1949    DeclarationScope* scope = AsDeclarationScope();
1950    if (scope->was_lazily_parsed()) Indent(n1, "// lazily parsed\n");
1951    if (scope->ShouldEagerCompile()) Indent(n1, "// will be compiled\n");
1952    if (scope->needs_private_name_context_chain_recalc()) {
1953      Indent(n1, "// needs #-name context chain recalc\n");
1954    }
1955    Indent(n1, "// ");
1956    PrintF("%s\n", FunctionKind2String(scope->function_kind()));
1957    if (scope->class_scope_has_private_brand()) {
1958      Indent(n1, "// class scope has private brand\n");
1959    }
1960  }
1961  if (num_stack_slots_ > 0) {
1962    Indent(n1, "// ");
1963    PrintF("%d stack slots\n", num_stack_slots_);
1964  }
1965  if (num_heap_slots_ > 0) {
1966    Indent(n1, "// ");
1967    PrintF("%d heap slots\n", num_heap_slots_);
1968  }
1969
1970  // Print locals.
1971  if (function != nullptr) {
1972    Indent(n1, "// function var:\n");
1973    PrintVar(n1, function);
1974  }
1975
1976  // Print temporaries.
1977  {
1978    bool printed_header = false;
1979    for (Variable* local : locals_) {
1980      if (local->mode() != VariableMode::kTemporary) continue;
1981      if (!printed_header) {
1982        printed_header = true;
1983        Indent(n1, "// temporary vars:\n");
1984      }
1985      PrintVar(n1, local);
1986    }
1987  }
1988
1989  if (variables_.occupancy() > 0) {
1990    PrintMap(n1, "// local vars:\n", &variables_, true, function);
1991    PrintMap(n1, "// dynamic vars:\n", &variables_, false, function);
1992  }
1993
1994  if (is_class_scope()) {
1995    ClassScope* class_scope = AsClassScope();
1996    if (class_scope->GetRareData() != nullptr) {
1997      PrintMap(n1, "// private name vars:\n",
1998               &(class_scope->GetRareData()->private_name_map), true, function);
1999      Variable* brand = class_scope->brand();
2000      if (brand != nullptr) {
2001        Indent(n1, "// brand var:\n");
2002        PrintVar(n1, brand);
2003      }
2004    }
2005    if (class_scope->class_variable() != nullptr) {
2006      Indent(n1, "// class var");
2007      PrintF("%s%s:\n",
2008             class_scope->class_variable()->is_used() ? ", used" : ", unused",
2009             class_scope->should_save_class_variable_index()
2010                 ? ", index saved"
2011                 : ", index not saved");
2012      PrintVar(n1, class_scope->class_variable());
2013    }
2014  }
2015
2016  // Print inner scopes (disable by providing negative n).
2017  if (n >= 0) {
2018    for (Scope* scope = inner_scope_; scope != nullptr;
2019         scope = scope->sibling_) {
2020      PrintF("\n");
2021      scope->Print(n1);
2022    }
2023  }
2024
2025  Indent(n0, "}\n");
2026}
2027
2028void Scope::CheckScopePositions() {
2029  this->ForEach([](Scope* scope) {
2030    // Visible leaf scopes must have real positions.
2031    if (!scope->is_hidden() && scope->inner_scope_ == nullptr) {
2032      DCHECK_NE(kNoSourcePosition, scope->start_position());
2033      DCHECK_NE(kNoSourcePosition, scope->end_position());
2034    }
2035    return Iteration::kDescend;
2036  });
2037}
2038
2039void Scope::CheckZones() {
2040  DCHECK(!needs_migration_);
2041  this->ForEach([](Scope* scope) {
2042    if (WasLazilyParsed(scope)) {
2043      DCHECK_NULL(scope->zone());
2044      DCHECK_NULL(scope->inner_scope_);
2045      return Iteration::kContinue;
2046    }
2047    return Iteration::kDescend;
2048  });
2049}
2050#endif  // DEBUG
2051
2052Variable* Scope::NonLocal(const AstRawString* name, VariableMode mode) {
2053  // Declare a new non-local.
2054  DCHECK(IsDynamicVariableMode(mode));
2055  bool was_added;
2056  Variable* var = variables_.Declare(zone(), this, name, mode, NORMAL_VARIABLE,
2057                                     kCreatedInitialized, kNotAssigned,
2058                                     IsStaticFlag::kNotStatic, &was_added);
2059  // Allocate it by giving it a dynamic lookup.
2060  var->AllocateTo(VariableLocation::LOOKUP, -1);
2061  return var;
2062}
2063
2064// static
2065template <Scope::ScopeLookupMode mode>
2066Variable* Scope::Lookup(VariableProxy* proxy, Scope* scope,
2067                        Scope* outer_scope_end, Scope* cache_scope,
2068                        bool force_context_allocation) {
2069  // If we have already passed the cache scope in earlier recursions, we should
2070  // first quickly check if the current scope uses the cache scope before
2071  // continuing.
2072  if (mode == kDeserializedScope &&
2073      scope->deserialized_scope_uses_external_cache()) {
2074    Variable* var = cache_scope->variables_.Lookup(proxy->raw_name());
2075    if (var != nullptr) return var;
2076  }
2077
2078  while (true) {
2079    DCHECK_IMPLIES(mode == kParsedScope, !scope->is_debug_evaluate_scope_);
2080    // Short-cut: whenever we find a debug-evaluate scope, just look everything
2081    // up dynamically. Debug-evaluate doesn't properly create scope info for the
2082    // lookups it does. It may not have a valid 'this' declaration, and anything
2083    // accessed through debug-evaluate might invalidly resolve to
2084    // stack-allocated variables.
2085    // TODO(yangguo): Remove once debug-evaluate creates proper ScopeInfo for
2086    // the scopes in which it's evaluating.
2087    if (mode == kDeserializedScope &&
2088        V8_UNLIKELY(scope->is_debug_evaluate_scope_)) {
2089      DCHECK(scope->deserialized_scope_uses_external_cache() ||
2090             scope == cache_scope);
2091      return cache_scope->NonLocal(proxy->raw_name(), VariableMode::kDynamic);
2092    }
2093
2094    // Try to find the variable in this scope.
2095    Variable* var;
2096    if (mode == kParsedScope) {
2097      var = scope->LookupLocal(proxy->raw_name());
2098    } else {
2099      DCHECK_EQ(mode, kDeserializedScope);
2100      bool external_cache = scope->deserialized_scope_uses_external_cache();
2101      if (!external_cache) {
2102        // Check the cache on each deserialized scope, up to the main cache
2103        // scope when we get to it (we may still have deserialized scopes
2104        // in-between the initial and cache scopes so we can't just check the
2105        // cache before the loop).
2106        var = scope->variables_.Lookup(proxy->raw_name());
2107        if (var != nullptr) return var;
2108      }
2109      var = scope->LookupInScopeInfo(proxy->raw_name(),
2110                                     external_cache ? cache_scope : scope);
2111    }
2112
2113    // We found a variable and we are done. (Even if there is an 'eval' in this
2114    // scope which introduces the same variable again, the resulting variable
2115    // remains the same.)
2116    //
2117    // For sloppy eval though, we skip dynamic variable to avoid resolving to a
2118    // variable when the variable and proxy are in the same eval execution. The
2119    // variable is not available on subsequent lazy executions of functions in
2120    // the eval, so this avoids inner functions from looking up different
2121    // variables during eager and lazy compilation.
2122    //
2123    // TODO(leszeks): Maybe we want to restrict this to e.g. lookups of a proxy
2124    // living in a different scope to the current one, or some other
2125    // optimisation.
2126    if (var != nullptr &&
2127        !(scope->is_eval_scope() && var->mode() == VariableMode::kDynamic)) {
2128      if (mode == kParsedScope && force_context_allocation &&
2129          !var->is_dynamic()) {
2130        var->ForceContextAllocation();
2131      }
2132      return var;
2133    }
2134
2135    if (scope->outer_scope_ == outer_scope_end) break;
2136
2137    DCHECK(!scope->is_script_scope());
2138    if (V8_UNLIKELY(scope->is_with_scope())) {
2139      return LookupWith(proxy, scope, outer_scope_end, cache_scope,
2140                        force_context_allocation);
2141    }
2142    if (V8_UNLIKELY(
2143            scope->is_declaration_scope() &&
2144            scope->AsDeclarationScope()->sloppy_eval_can_extend_vars())) {
2145      return LookupSloppyEval(proxy, scope, outer_scope_end, cache_scope,
2146                              force_context_allocation);
2147    }
2148
2149    force_context_allocation |= scope->is_function_scope();
2150    scope = scope->outer_scope_;
2151
2152    // TODO(verwaest): Separate through AnalyzePartially.
2153    if (mode == kParsedScope && !scope->scope_info_.is_null()) {
2154      DCHECK_NULL(cache_scope);
2155      cache_scope = scope->GetNonEvalDeclarationScope();
2156      return Lookup<kDeserializedScope>(proxy, scope, outer_scope_end,
2157                                        cache_scope);
2158    }
2159  }
2160
2161  // We may just be trying to find all free variables. In that case, don't
2162  // declare them in the outer scope.
2163  // TODO(marja): Separate Lookup for preparsed scopes better.
2164  if (mode == kParsedScope && !scope->is_script_scope()) {
2165    return nullptr;
2166  }
2167
2168  // No binding has been found. Declare a variable on the global object.
2169  return scope->AsDeclarationScope()->DeclareDynamicGlobal(
2170      proxy->raw_name(), NORMAL_VARIABLE,
2171      mode == kDeserializedScope ? cache_scope : scope);
2172}
2173
2174template Variable* Scope::Lookup<Scope::kParsedScope>(
2175    VariableProxy* proxy, Scope* scope, Scope* outer_scope_end,
2176    Scope* cache_scope, bool force_context_allocation);
2177template Variable* Scope::Lookup<Scope::kDeserializedScope>(
2178    VariableProxy* proxy, Scope* scope, Scope* outer_scope_end,
2179    Scope* cache_scope, bool force_context_allocation);
2180
2181Variable* Scope::LookupWith(VariableProxy* proxy, Scope* scope,
2182                            Scope* outer_scope_end, Scope* cache_scope,
2183                            bool force_context_allocation) {
2184  DCHECK(scope->is_with_scope());
2185
2186  Variable* var =
2187      scope->outer_scope_->scope_info_.is_null()
2188          ? Lookup<kParsedScope>(proxy, scope->outer_scope_, outer_scope_end,
2189                                 nullptr, force_context_allocation)
2190          : Lookup<kDeserializedScope>(proxy, scope->outer_scope_,
2191                                       outer_scope_end, cache_scope);
2192
2193  if (var == nullptr) return var;
2194
2195  // The current scope is a with scope, so the variable binding can not be
2196  // statically resolved. However, note that it was necessary to do a lookup
2197  // in the outer scope anyway, because if a binding exists in an outer
2198  // scope, the associated variable has to be marked as potentially being
2199  // accessed from inside of an inner with scope (the property may not be in
2200  // the 'with' object).
2201  if (!var->is_dynamic() && var->IsUnallocated()) {
2202    DCHECK(!scope->already_resolved_);
2203    var->set_is_used();
2204    var->ForceContextAllocation();
2205    if (proxy->is_assigned()) var->SetMaybeAssigned();
2206  }
2207  Scope* target_scope;
2208  if (scope->deserialized_scope_uses_external_cache()) {
2209    DCHECK_NOT_NULL(cache_scope);
2210    cache_scope->variables_.Remove(var);
2211    target_scope = cache_scope;
2212  } else {
2213    target_scope = scope;
2214  }
2215  Variable* dynamic =
2216      target_scope->NonLocal(proxy->raw_name(), VariableMode::kDynamic);
2217  dynamic->set_local_if_not_shadowed(var);
2218  return dynamic;
2219}
2220
2221Variable* Scope::LookupSloppyEval(VariableProxy* proxy, Scope* scope,
2222                                  Scope* outer_scope_end, Scope* cache_scope,
2223                                  bool force_context_allocation) {
2224  DCHECK(scope->is_declaration_scope() &&
2225         scope->AsDeclarationScope()->sloppy_eval_can_extend_vars());
2226
2227  // If we're compiling eval, it's possible that the outer scope is the first
2228  // ScopeInfo-backed scope. We use the next declaration scope as the cache for
2229  // this case, to avoid complexity around sloppy block function hoisting and
2230  // conflict detection through catch scopes in the eval.
2231  Scope* entry_cache = cache_scope == nullptr
2232                           ? scope->outer_scope()->GetNonEvalDeclarationScope()
2233                           : cache_scope;
2234  Variable* var =
2235      scope->outer_scope_->scope_info_.is_null()
2236          ? Lookup<kParsedScope>(proxy, scope->outer_scope_, outer_scope_end,
2237                                 nullptr, force_context_allocation)
2238          : Lookup<kDeserializedScope>(proxy, scope->outer_scope_,
2239                                       outer_scope_end, entry_cache);
2240  if (var == nullptr) return var;
2241
2242  // We may not want to use the cache scope, change it back to the given scope
2243  // if necessary.
2244  if (!scope->deserialized_scope_uses_external_cache()) {
2245    // For a deserialized scope, we'll be replacing the cache_scope.
2246    DCHECK_IMPLIES(!scope->scope_info_.is_null(), cache_scope != nullptr);
2247    cache_scope = scope;
2248  }
2249
2250  // A variable binding may have been found in an outer scope, but the current
2251  // scope makes a sloppy 'eval' call, so the found variable may not be the
2252  // correct one (the 'eval' may introduce a binding with the same name). In
2253  // that case, change the lookup result to reflect this situation. Only
2254  // scopes that can host var bindings (declaration scopes) need be considered
2255  // here (this excludes block and catch scopes), and variable lookups at
2256  // script scope are always dynamic.
2257  if (var->IsGlobalObjectProperty()) {
2258    Scope* target = cache_scope == nullptr ? scope : cache_scope;
2259    var = target->NonLocal(proxy->raw_name(), VariableMode::kDynamicGlobal);
2260  }
2261
2262  if (var->is_dynamic()) return var;
2263
2264  Variable* invalidated = var;
2265  if (cache_scope != nullptr) cache_scope->variables_.Remove(invalidated);
2266
2267  Scope* target = cache_scope == nullptr ? scope : cache_scope;
2268  var = target->NonLocal(proxy->raw_name(), VariableMode::kDynamicLocal);
2269  var->set_local_if_not_shadowed(invalidated);
2270
2271  return var;
2272}
2273
2274void Scope::ResolveVariable(VariableProxy* proxy) {
2275  DCHECK(!proxy->is_resolved());
2276  Variable* var = Lookup<kParsedScope>(proxy, this, nullptr);
2277  DCHECK_NOT_NULL(var);
2278  ResolveTo(proxy, var);
2279}
2280
2281namespace {
2282
2283void SetNeedsHoleCheck(Variable* var, VariableProxy* proxy) {
2284  proxy->set_needs_hole_check();
2285  var->ForceHoleInitialization();
2286}
2287
2288void UpdateNeedsHoleCheck(Variable* var, VariableProxy* proxy, Scope* scope) {
2289  if (var->mode() == VariableMode::kDynamicLocal) {
2290    // Dynamically introduced variables never need a hole check (since they're
2291    // VariableMode::kVar bindings, either from var or function declarations),
2292    // but the variable they shadow might need a hole check, which we want to do
2293    // if we decide that no shadowing variable was dynamically introoduced.
2294    DCHECK_EQ(kCreatedInitialized, var->initialization_flag());
2295    return UpdateNeedsHoleCheck(var->local_if_not_shadowed(), proxy, scope);
2296  }
2297
2298  if (var->initialization_flag() == kCreatedInitialized) return;
2299
2300  // It's impossible to eliminate module import hole checks here, because it's
2301  // unknown at compilation time whether the binding referred to in the
2302  // exporting module itself requires hole checks.
2303  if (var->location() == VariableLocation::MODULE && !var->IsExport()) {
2304    return SetNeedsHoleCheck(var, proxy);
2305  }
2306
2307  // Check if the binding really needs an initialization check. The check
2308  // can be skipped in the following situation: we have a VariableMode::kLet or
2309  // VariableMode::kConst binding, both the Variable and the VariableProxy have
2310  // the same declaration scope (i.e. they are both in global code, in the same
2311  // function or in the same eval code), the VariableProxy is in the source
2312  // physically located after the initializer of the variable, and that the
2313  // initializer cannot be skipped due to a nonlinear scope.
2314  //
2315  // The condition on the closure scopes is a conservative check for
2316  // nested functions that access a binding and are called before the
2317  // binding is initialized:
2318  //   function() { f(); let x = 1; function f() { x = 2; } }
2319  //
2320  // The check cannot be skipped on non-linear scopes, namely switch
2321  // scopes, to ensure tests are done in cases like the following:
2322  //   switch (1) { case 0: let x = 2; case 1: f(x); }
2323  // The scope of the variable needs to be checked, in case the use is
2324  // in a sub-block which may be linear.
2325  if (var->scope()->GetClosureScope() != scope->GetClosureScope()) {
2326    return SetNeedsHoleCheck(var, proxy);
2327  }
2328
2329  // We should always have valid source positions.
2330  DCHECK_NE(var->initializer_position(), kNoSourcePosition);
2331  DCHECK_NE(proxy->position(), kNoSourcePosition);
2332
2333  if (var->scope()->is_nonlinear() ||
2334      var->initializer_position() >= proxy->position()) {
2335    return SetNeedsHoleCheck(var, proxy);
2336  }
2337}
2338
2339}  // anonymous namespace
2340
2341void Scope::ResolveTo(VariableProxy* proxy, Variable* var) {
2342  DCHECK_NOT_NULL(var);
2343  UpdateNeedsHoleCheck(var, proxy, this);
2344  proxy->BindTo(var);
2345}
2346
2347void Scope::ResolvePreparsedVariable(VariableProxy* proxy, Scope* scope,
2348                                     Scope* end) {
2349  // Resolve the variable in all parsed scopes to force context allocation.
2350  for (; scope != end; scope = scope->outer_scope_) {
2351    Variable* var = scope->LookupLocal(proxy->raw_name());
2352    if (var != nullptr) {
2353      var->set_is_used();
2354      if (!var->is_dynamic()) {
2355        var->ForceContextAllocation();
2356        if (proxy->is_assigned()) var->SetMaybeAssigned();
2357        return;
2358      }
2359    }
2360  }
2361}
2362
2363bool Scope::ResolveVariablesRecursively(Scope* end) {
2364  // Lazy parsed declaration scopes are already partially analyzed. If there are
2365  // unresolved references remaining, they just need to be resolved in outer
2366  // scopes.
2367  if (WasLazilyParsed(this)) {
2368    DCHECK_EQ(variables_.occupancy(), 0);
2369    // Resolve in all parsed scopes except for the script scope.
2370    if (!end->is_script_scope()) end = end->outer_scope();
2371
2372    for (VariableProxy* proxy : unresolved_list_) {
2373      ResolvePreparsedVariable(proxy, outer_scope(), end);
2374    }
2375  } else {
2376    // Resolve unresolved variables for this scope.
2377    for (VariableProxy* proxy : unresolved_list_) {
2378      ResolveVariable(proxy);
2379    }
2380
2381    // Resolve unresolved variables for inner scopes.
2382    for (Scope* scope = inner_scope_; scope != nullptr;
2383         scope = scope->sibling_) {
2384      if (!scope->ResolveVariablesRecursively(end)) return false;
2385    }
2386  }
2387  return true;
2388}
2389
2390bool Scope::MustAllocate(Variable* var) {
2391  DCHECK(var->location() != VariableLocation::MODULE);
2392  // Give var a read/write use if there is a chance it might be accessed
2393  // via an eval() call.  This is only possible if the variable has a
2394  // visible name.
2395  if (!var->raw_name()->IsEmpty() &&
2396      (inner_scope_calls_eval_ || is_catch_scope() || is_script_scope())) {
2397    var->set_is_used();
2398    if (inner_scope_calls_eval_ && !var->is_this()) var->SetMaybeAssigned();
2399  }
2400  DCHECK(!var->has_forced_context_allocation() || var->is_used());
2401  // Global variables do not need to be allocated.
2402  return !var->IsGlobalObjectProperty() && var->is_used();
2403}
2404
2405
2406bool Scope::MustAllocateInContext(Variable* var) {
2407  // If var is accessed from an inner scope, or if there is a possibility
2408  // that it might be accessed from the current or an inner scope (through
2409  // an eval() call or a runtime with lookup), it must be allocated in the
2410  // context.
2411  //
2412  // Temporary variables are always stack-allocated.  Catch-bound variables are
2413  // always context-allocated.
2414  VariableMode mode = var->mode();
2415  if (mode == VariableMode::kTemporary) return false;
2416  if (is_catch_scope()) return true;
2417  if (is_script_scope() || is_eval_scope()) {
2418    if (IsLexicalVariableMode(mode)) {
2419      return true;
2420    }
2421  }
2422  return var->has_forced_context_allocation() || inner_scope_calls_eval_;
2423}
2424
2425void Scope::AllocateStackSlot(Variable* var) {
2426  if (is_block_scope()) {
2427    outer_scope()->GetDeclarationScope()->AllocateStackSlot(var);
2428  } else {
2429    var->AllocateTo(VariableLocation::LOCAL, num_stack_slots_++);
2430  }
2431}
2432
2433
2434void Scope::AllocateHeapSlot(Variable* var) {
2435  var->AllocateTo(VariableLocation::CONTEXT, num_heap_slots_++);
2436}
2437
2438void DeclarationScope::AllocateParameterLocals() {
2439  DCHECK(is_function_scope());
2440
2441  bool has_mapped_arguments = false;
2442  if (arguments_ != nullptr) {
2443    DCHECK(!is_arrow_scope());
2444    if (MustAllocate(arguments_) && !has_arguments_parameter_) {
2445      // 'arguments' is used and does not refer to a function
2446      // parameter of the same name. If the arguments object
2447      // aliases formal parameters, we conservatively allocate
2448      // them specially in the loop below.
2449      has_mapped_arguments =
2450          GetArgumentsType() == CreateArgumentsType::kMappedArguments;
2451    } else {
2452      // 'arguments' is unused. Tell the code generator that it does not need to
2453      // allocate the arguments object by nulling out arguments_.
2454      arguments_ = nullptr;
2455    }
2456  }
2457
2458  // The same parameter may occur multiple times in the parameters_ list.
2459  // If it does, and if it is not copied into the context object, it must
2460  // receive the highest parameter index for that parameter; thus iteration
2461  // order is relevant!
2462  for (int i = num_parameters() - 1; i >= 0; --i) {
2463    Variable* var = params_[i];
2464    DCHECK_NOT_NULL(var);
2465    DCHECK(!has_rest_ || var != rest_parameter());
2466    DCHECK_EQ(this, var->scope());
2467    if (has_mapped_arguments) {
2468      var->set_is_used();
2469      var->SetMaybeAssigned();
2470      var->ForceContextAllocation();
2471    }
2472    AllocateParameter(var, i);
2473  }
2474}
2475
2476void DeclarationScope::AllocateParameter(Variable* var, int index) {
2477  if (!MustAllocate(var)) return;
2478  if (has_forced_context_allocation_for_parameters() ||
2479      MustAllocateInContext(var)) {
2480    DCHECK(var->IsUnallocated() || var->IsContextSlot());
2481    if (var->IsUnallocated()) AllocateHeapSlot(var);
2482  } else {
2483    DCHECK(var->IsUnallocated() || var->IsParameter());
2484    if (var->IsUnallocated()) {
2485      var->AllocateTo(VariableLocation::PARAMETER, index);
2486    }
2487  }
2488}
2489
2490void DeclarationScope::AllocateReceiver() {
2491  if (!has_this_declaration()) return;
2492  DCHECK_NOT_NULL(receiver());
2493  DCHECK_EQ(receiver()->scope(), this);
2494  AllocateParameter(receiver(), -1);
2495}
2496
2497void Scope::AllocateNonParameterLocal(Variable* var) {
2498  DCHECK_EQ(var->scope(), this);
2499  if (var->IsUnallocated() && MustAllocate(var)) {
2500    if (MustAllocateInContext(var)) {
2501      AllocateHeapSlot(var);
2502      DCHECK_IMPLIES(is_catch_scope(),
2503                     var->index() == Context::THROWN_OBJECT_INDEX);
2504    } else {
2505      AllocateStackSlot(var);
2506    }
2507  }
2508}
2509
2510void Scope::AllocateNonParameterLocalsAndDeclaredGlobals() {
2511  if (is_declaration_scope() && AsDeclarationScope()->is_arrow_scope()) {
2512    // In arrow functions, allocate non-temporaries first and then all the
2513    // temporaries to make the local variable ordering stable when reparsing to
2514    // collect source positions.
2515    for (Variable* local : locals_) {
2516      if (local->mode() != VariableMode::kTemporary)
2517        AllocateNonParameterLocal(local);
2518    }
2519
2520    for (Variable* local : locals_) {
2521      if (local->mode() == VariableMode::kTemporary)
2522        AllocateNonParameterLocal(local);
2523    }
2524  } else {
2525    for (Variable* local : locals_) {
2526      AllocateNonParameterLocal(local);
2527    }
2528  }
2529
2530  if (is_declaration_scope()) {
2531    AsDeclarationScope()->AllocateLocals();
2532  }
2533}
2534
2535void DeclarationScope::AllocateLocals() {
2536  // For now, function_ must be allocated at the very end.  If it gets
2537  // allocated in the context, it must be the last slot in the context,
2538  // because of the current ScopeInfo implementation (see
2539  // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor).
2540  if (function_ != nullptr && MustAllocate(function_)) {
2541    AllocateNonParameterLocal(function_);
2542  } else {
2543    function_ = nullptr;
2544  }
2545
2546  DCHECK(!has_rest_ || !MustAllocate(rest_parameter()) ||
2547         !rest_parameter()->IsUnallocated());
2548
2549  if (new_target_ != nullptr && !MustAllocate(new_target_)) {
2550    new_target_ = nullptr;
2551  }
2552
2553  NullifyRareVariableIf(RareVariable::kThisFunction,
2554                        [=](Variable* var) { return !MustAllocate(var); });
2555}
2556
2557void ModuleScope::AllocateModuleVariables() {
2558  for (const auto& it : module()->regular_imports()) {
2559    Variable* var = LookupLocal(it.first);
2560    var->AllocateTo(VariableLocation::MODULE, it.second->cell_index);
2561    DCHECK(!var->IsExport());
2562  }
2563
2564  for (const auto& it : module()->regular_exports()) {
2565    Variable* var = LookupLocal(it.first);
2566    var->AllocateTo(VariableLocation::MODULE, it.second->cell_index);
2567    DCHECK(var->IsExport());
2568  }
2569}
2570
2571void Scope::AllocateVariablesRecursively() {
2572  this->ForEach([](Scope* scope) -> Iteration {
2573    DCHECK(!scope->already_resolved_);
2574    if (WasLazilyParsed(scope)) return Iteration::kContinue;
2575    if (scope->sloppy_eval_can_extend_vars_) {
2576      scope->num_heap_slots_ = Context::MIN_CONTEXT_EXTENDED_SLOTS;
2577    }
2578    DCHECK_EQ(scope->ContextHeaderLength(), scope->num_heap_slots_);
2579
2580    // Allocate variables for this scope.
2581    // Parameters must be allocated first, if any.
2582    if (scope->is_declaration_scope()) {
2583      scope->AsDeclarationScope()->AllocateReceiver();
2584      if (scope->is_function_scope()) {
2585        scope->AsDeclarationScope()->AllocateParameterLocals();
2586      }
2587    }
2588    scope->AllocateNonParameterLocalsAndDeclaredGlobals();
2589
2590    // Force allocation of a context for this scope if necessary. For a 'with'
2591    // scope and for a function scope that makes an 'eval' call we need a
2592    // context, even if no local variables were statically allocated in the
2593    // scope. Likewise for modules and function scopes representing asm.js
2594    // modules. Also force a context, if the scope is stricter than the outer
2595    // scope.
2596    bool must_have_context =
2597        scope->is_with_scope() || scope->is_module_scope() ||
2598#if V8_ENABLE_WEBASSEMBLY
2599        scope->IsAsmModule() ||
2600#endif  // V8_ENABLE_WEBASSEMBLY
2601        scope->ForceContextForLanguageMode() ||
2602        (scope->is_function_scope() &&
2603         scope->AsDeclarationScope()->sloppy_eval_can_extend_vars()) ||
2604        (scope->is_block_scope() && scope->is_declaration_scope() &&
2605         scope->AsDeclarationScope()->sloppy_eval_can_extend_vars());
2606
2607    // If we didn't allocate any locals in the local context, then we only
2608    // need the minimal number of slots if we must have a context.
2609    if (scope->num_heap_slots_ == scope->ContextHeaderLength() &&
2610        !must_have_context) {
2611      scope->num_heap_slots_ = 0;
2612    }
2613
2614    // Allocation done.
2615    DCHECK(scope->num_heap_slots_ == 0 ||
2616           scope->num_heap_slots_ >= scope->ContextHeaderLength());
2617    return Iteration::kDescend;
2618  });
2619}
2620
2621template <typename IsolateT>
2622void Scope::AllocateScopeInfosRecursively(IsolateT* isolate,
2623                                          MaybeHandle<ScopeInfo> outer_scope) {
2624  DCHECK(scope_info_.is_null());
2625  MaybeHandle<ScopeInfo> next_outer_scope = outer_scope;
2626
2627  if (NeedsScopeInfo()) {
2628    scope_info_ = ScopeInfo::Create(isolate, zone(), this, outer_scope);
2629    // The ScopeInfo chain should mirror the context chain, so we only link to
2630    // the next outer scope that needs a context.
2631    if (NeedsContext()) next_outer_scope = scope_info_;
2632  }
2633
2634  // Allocate ScopeInfos for inner scopes.
2635  for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
2636    if (!scope->is_function_scope() ||
2637        scope->AsDeclarationScope()->ShouldEagerCompile()) {
2638      scope->AllocateScopeInfosRecursively(isolate, next_outer_scope);
2639    }
2640  }
2641}
2642
2643template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE) void Scope::
2644    AllocateScopeInfosRecursively<Isolate>(Isolate* isolate,
2645                                           MaybeHandle<ScopeInfo> outer_scope);
2646template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE) void Scope::
2647    AllocateScopeInfosRecursively<LocalIsolate>(
2648        LocalIsolate* isolate, MaybeHandle<ScopeInfo> outer_scope);
2649
2650void DeclarationScope::RecalcPrivateNameContextChain() {
2651  // The outermost scope in a class heritage expression is marked to skip the
2652  // class scope during private name resolution. It is possible, however, that
2653  // either the class scope won't require a Context and ScopeInfo, or the
2654  // outermost scope in the heritage position won't. Simply copying the bit from
2655  // full parse into the ScopeInfo will break lazy compilation. In the former
2656  // case the scope that is marked to skip its outer scope will incorrectly skip
2657  // a different class scope than the one we intended to skip. In the latter
2658  // case variables resolved through an inner scope will incorrectly check the
2659  // class scope since we lost the skip bit from the outermost heritage scope.
2660  //
2661  // This method fixes both cases by, in outermost to innermost order, copying
2662  // the value of the skip bit from outer scopes that don't require a Context.
2663  DCHECK(needs_private_name_context_chain_recalc_);
2664  this->ForEach([](Scope* scope) {
2665    Scope* outer = scope->outer_scope();
2666    if (!outer) return Iteration::kDescend;
2667    if (!outer->NeedsContext()) {
2668      scope->private_name_lookup_skips_outer_class_ =
2669          outer->private_name_lookup_skips_outer_class();
2670    }
2671    if (!scope->is_function_scope() ||
2672        scope->AsDeclarationScope()->ShouldEagerCompile()) {
2673      return Iteration::kDescend;
2674    }
2675    return Iteration::kContinue;
2676  });
2677}
2678
2679void DeclarationScope::RecordNeedsPrivateNameContextChainRecalc() {
2680  DCHECK_EQ(GetClosureScope(), this);
2681  DeclarationScope* scope;
2682  for (scope = this; scope != nullptr;
2683       scope = scope->outer_scope() != nullptr
2684                   ? scope->outer_scope()->GetClosureScope()
2685                   : nullptr) {
2686    if (scope->needs_private_name_context_chain_recalc_) return;
2687    scope->needs_private_name_context_chain_recalc_ = true;
2688  }
2689}
2690
2691// static
2692template <typename IsolateT>
2693void DeclarationScope::AllocateScopeInfos(ParseInfo* info, IsolateT* isolate) {
2694  DeclarationScope* scope = info->literal()->scope();
2695
2696  // No one else should have allocated a scope info for this scope yet.
2697  DCHECK(scope->scope_info_.is_null());
2698
2699  MaybeHandle<ScopeInfo> outer_scope;
2700  if (scope->outer_scope_ != nullptr) {
2701    DCHECK((std::is_same<Isolate, v8::internal::Isolate>::value));
2702    outer_scope = scope->outer_scope_->scope_info_;
2703  }
2704
2705  if (scope->needs_private_name_context_chain_recalc()) {
2706    scope->RecalcPrivateNameContextChain();
2707  }
2708  scope->AllocateScopeInfosRecursively(isolate, outer_scope);
2709
2710  // The debugger expects all shared function infos to contain a scope info.
2711  // Since the top-most scope will end up in a shared function info, make sure
2712  // it has one, even if it doesn't need a scope info.
2713  // TODO(yangguo): Remove this requirement.
2714  if (scope->scope_info_.is_null()) {
2715    scope->scope_info_ =
2716        ScopeInfo::Create(isolate, scope->zone(), scope, outer_scope);
2717  }
2718
2719  // Ensuring that the outer script scope has a scope info avoids having
2720  // special case for native contexts vs other contexts.
2721  if (info->script_scope() && info->script_scope()->scope_info_.is_null()) {
2722    info->script_scope()->scope_info_ = isolate->factory()->empty_scope_info();
2723  }
2724}
2725
2726template V8_EXPORT_PRIVATE void DeclarationScope::AllocateScopeInfos(
2727    ParseInfo* info, Isolate* isolate);
2728template V8_EXPORT_PRIVATE void DeclarationScope::AllocateScopeInfos(
2729    ParseInfo* info, LocalIsolate* isolate);
2730
2731int Scope::ContextLocalCount() const {
2732  if (num_heap_slots() == 0) return 0;
2733  Variable* function =
2734      is_function_scope() ? AsDeclarationScope()->function_var() : nullptr;
2735  bool is_function_var_in_context =
2736      function != nullptr && function->IsContextSlot();
2737  return num_heap_slots() - ContextHeaderLength() -
2738         (is_function_var_in_context ? 1 : 0);
2739}
2740
2741VariableProxy* Scope::NewHomeObjectVariableProxy(AstNodeFactory* factory,
2742                                                 const AstRawString* name,
2743                                                 int start_pos) {
2744  // VariableProxies of the home object cannot be resolved like a normal
2745  // variable. Consider the case of a super.property usage in heritage position:
2746  //
2747  //   class C extends super.foo { m() { super.bar(); } }
2748  //
2749  // The super.foo property access is logically nested under C's class scope,
2750  // which also has a home object due to its own method m's usage of
2751  // super.bar(). However, super.foo must resolve super in C's outer scope.
2752  //
2753  // Because of the above, home object VariableProxies are always made directly
2754  // on the Scope that needs the home object instead of the innermost scope.
2755  DCHECK(needs_home_object());
2756  if (!scope_info_.is_null()) {
2757    // This is a lazy compile, so the home object's context slot is already
2758    // known.
2759    Variable* home_object = variables_.Lookup(name);
2760    if (home_object == nullptr) {
2761      VariableLookupResult lookup_result;
2762      int index = scope_info_->ContextSlotIndex(name->string(), &lookup_result);
2763      DCHECK_GE(index, 0);
2764      bool was_added;
2765      home_object = variables_.Declare(zone(), this, name, lookup_result.mode,
2766                                       NORMAL_VARIABLE, lookup_result.init_flag,
2767                                       lookup_result.maybe_assigned_flag,
2768                                       IsStaticFlag::kNotStatic, &was_added);
2769      DCHECK(was_added);
2770      home_object->AllocateTo(VariableLocation::CONTEXT, index);
2771    }
2772    return factory->NewVariableProxy(home_object, start_pos);
2773  }
2774  // This is not a lazy compile. Add the unresolved home object VariableProxy to
2775  // the unresolved list of the home object scope, which is not necessarily the
2776  // innermost scope.
2777  VariableProxy* proxy =
2778      factory->NewVariableProxy(name, NORMAL_VARIABLE, start_pos);
2779  AddUnresolved(proxy);
2780  return proxy;
2781}
2782
2783bool IsComplementaryAccessorPair(VariableMode a, VariableMode b) {
2784  switch (a) {
2785    case VariableMode::kPrivateGetterOnly:
2786      return b == VariableMode::kPrivateSetterOnly;
2787    case VariableMode::kPrivateSetterOnly:
2788      return b == VariableMode::kPrivateGetterOnly;
2789    default:
2790      return false;
2791  }
2792}
2793
2794void ClassScope::FinalizeReparsedClassScope(
2795    Isolate* isolate, MaybeHandle<ScopeInfo> maybe_scope_info,
2796    AstValueFactory* ast_value_factory, bool needs_allocation_fixup) {
2797  // Set this bit so that DelcarationScope::Analyze recognizes
2798  // the reparsed instance member initializer scope.
2799#ifdef DEBUG
2800  is_reparsed_class_scope_ = true;
2801#endif
2802
2803  if (!needs_allocation_fixup) {
2804    return;
2805  }
2806
2807  // Restore variable allocation results for context-allocated variables in
2808  // the class scope from ScopeInfo, so that we don't need to run
2809  // resolution and allocation on these variables again when generating
2810  // code for the initializer function.
2811  DCHECK(!maybe_scope_info.is_null());
2812  Handle<ScopeInfo> scope_info = maybe_scope_info.ToHandleChecked();
2813  DCHECK_EQ(scope_info->scope_type(), CLASS_SCOPE);
2814  DCHECK_EQ(scope_info->StartPosition(), start_position_);
2815
2816  int context_header_length = scope_info->ContextHeaderLength();
2817  DisallowGarbageCollection no_gc;
2818  for (auto it : ScopeInfo::IterateLocalNames(scope_info)) {
2819    int slot_index = context_header_length + it->index();
2820    DCHECK_LT(slot_index, scope_info->ContextLength());
2821
2822    const AstRawString* string = ast_value_factory->GetString(
2823        it->name(), SharedStringAccessGuardIfNeeded(isolate));
2824    Variable* var = string->IsPrivateName() ? LookupLocalPrivateName(string)
2825                                            : LookupLocal(string);
2826    DCHECK_NOT_NULL(var);
2827    var->AllocateTo(VariableLocation::CONTEXT, slot_index);
2828  }
2829  scope_info_ = scope_info;
2830}
2831
2832Variable* ClassScope::DeclarePrivateName(const AstRawString* name,
2833                                         VariableMode mode,
2834                                         IsStaticFlag is_static_flag,
2835                                         bool* was_added) {
2836  Variable* result = EnsureRareData()->private_name_map.Declare(
2837      zone(), this, name, mode, NORMAL_VARIABLE,
2838      InitializationFlag::kNeedsInitialization, MaybeAssignedFlag::kNotAssigned,
2839      is_static_flag, was_added);
2840  if (*was_added) {
2841    locals_.Add(result);
2842    has_static_private_methods_ |=
2843        (result->is_static() &&
2844         IsPrivateMethodOrAccessorVariableMode(result->mode()));
2845  } else if (IsComplementaryAccessorPair(result->mode(), mode) &&
2846             result->is_static_flag() == is_static_flag) {
2847    *was_added = true;
2848    result->set_mode(VariableMode::kPrivateGetterAndSetter);
2849  }
2850  result->ForceContextAllocation();
2851  return result;
2852}
2853
2854Variable* ClassScope::LookupLocalPrivateName(const AstRawString* name) {
2855  RareData* rare_data = GetRareData();
2856  if (rare_data == nullptr) {
2857    return nullptr;
2858  }
2859  return rare_data->private_name_map.Lookup(name);
2860}
2861
2862UnresolvedList::Iterator ClassScope::GetUnresolvedPrivateNameTail() {
2863  RareData* rare_data = GetRareData();
2864  if (rare_data == nullptr) {
2865    return UnresolvedList::Iterator();
2866  }
2867  return rare_data->unresolved_private_names.end();
2868}
2869
2870void ClassScope::ResetUnresolvedPrivateNameTail(UnresolvedList::Iterator tail) {
2871  RareData* rare_data = GetRareData();
2872  if (rare_data == nullptr ||
2873      rare_data->unresolved_private_names.end() == tail) {
2874    return;
2875  }
2876
2877  bool tail_is_empty = tail == UnresolvedList::Iterator();
2878  if (tail_is_empty) {
2879    // If the saved tail is empty, the list used to be empty, so clear it.
2880    rare_data->unresolved_private_names.Clear();
2881  } else {
2882    rare_data->unresolved_private_names.Rewind(tail);
2883  }
2884}
2885
2886void ClassScope::MigrateUnresolvedPrivateNameTail(
2887    AstNodeFactory* ast_node_factory, UnresolvedList::Iterator tail) {
2888  RareData* rare_data = GetRareData();
2889  if (rare_data == nullptr ||
2890      rare_data->unresolved_private_names.end() == tail) {
2891    return;
2892  }
2893  UnresolvedList migrated_names;
2894
2895  // If the saved tail is empty, the list used to be empty, so we should
2896  // migrate everything after the head.
2897  bool tail_is_empty = tail == UnresolvedList::Iterator();
2898  UnresolvedList::Iterator it =
2899      tail_is_empty ? rare_data->unresolved_private_names.begin() : tail;
2900
2901  for (; it != rare_data->unresolved_private_names.end(); ++it) {
2902    VariableProxy* proxy = *it;
2903    VariableProxy* copy = ast_node_factory->CopyVariableProxy(proxy);
2904    migrated_names.Add(copy);
2905  }
2906
2907  // Replace with the migrated copies.
2908  if (tail_is_empty) {
2909    rare_data->unresolved_private_names.Clear();
2910  } else {
2911    rare_data->unresolved_private_names.Rewind(tail);
2912  }
2913  rare_data->unresolved_private_names.Append(std::move(migrated_names));
2914}
2915
2916Variable* ClassScope::LookupPrivateNameInScopeInfo(const AstRawString* name) {
2917  DCHECK(!scope_info_.is_null());
2918  DCHECK_NULL(LookupLocalPrivateName(name));
2919  DisallowGarbageCollection no_gc;
2920
2921  VariableLookupResult lookup_result;
2922  int index = scope_info_->ContextSlotIndex(name->string(), &lookup_result);
2923  if (index < 0) {
2924    return nullptr;
2925  }
2926
2927  DCHECK(IsConstVariableMode(lookup_result.mode));
2928  DCHECK_EQ(lookup_result.init_flag, InitializationFlag::kNeedsInitialization);
2929  DCHECK_EQ(lookup_result.maybe_assigned_flag, MaybeAssignedFlag::kNotAssigned);
2930
2931  // Add the found private name to the map to speed up subsequent
2932  // lookups for the same name.
2933  bool was_added;
2934  Variable* var = DeclarePrivateName(name, lookup_result.mode,
2935                                     lookup_result.is_static_flag, &was_added);
2936  DCHECK(was_added);
2937  var->AllocateTo(VariableLocation::CONTEXT, index);
2938  return var;
2939}
2940
2941Variable* ClassScope::LookupPrivateName(VariableProxy* proxy) {
2942  DCHECK(!proxy->is_resolved());
2943
2944  for (PrivateNameScopeIterator scope_iter(this); !scope_iter.Done();
2945       scope_iter.Next()) {
2946    ClassScope* scope = scope_iter.GetScope();
2947    // Try finding it in the private name map first, if it can't be found,
2948    // try the deseralized scope info.
2949    Variable* var = scope->LookupLocalPrivateName(proxy->raw_name());
2950    if (var == nullptr && !scope->scope_info_.is_null()) {
2951      var = scope->LookupPrivateNameInScopeInfo(proxy->raw_name());
2952    }
2953    if (var != nullptr) {
2954      return var;
2955    }
2956  }
2957  return nullptr;
2958}
2959
2960bool ClassScope::ResolvePrivateNames(ParseInfo* info) {
2961  RareData* rare_data = GetRareData();
2962  if (rare_data == nullptr || rare_data->unresolved_private_names.is_empty()) {
2963    return true;
2964  }
2965
2966  UnresolvedList& list = rare_data->unresolved_private_names;
2967  for (VariableProxy* proxy : list) {
2968    Variable* var = LookupPrivateName(proxy);
2969    if (var == nullptr) {
2970      // It's only possible to fail to resolve private names here if
2971      // this is at the top level or the private name is accessed through eval.
2972      DCHECK(info->flags().is_eval() || outer_scope_->is_script_scope());
2973      Scanner::Location loc = proxy->location();
2974      info->pending_error_handler()->ReportMessageAt(
2975          loc.beg_pos, loc.end_pos,
2976          MessageTemplate::kInvalidPrivateFieldResolution, proxy->raw_name());
2977      return false;
2978    } else {
2979      proxy->BindTo(var);
2980    }
2981  }
2982
2983  // By now all unresolved private names should be resolved so
2984  // clear the list.
2985  list.Clear();
2986  return true;
2987}
2988
2989VariableProxy* ClassScope::ResolvePrivateNamesPartially() {
2990  RareData* rare_data = GetRareData();
2991  if (rare_data == nullptr || rare_data->unresolved_private_names.is_empty()) {
2992    return nullptr;
2993  }
2994
2995  PrivateNameScopeIterator private_name_scope_iter(this);
2996  private_name_scope_iter.Next();
2997  UnresolvedList& unresolved = rare_data->unresolved_private_names;
2998  bool has_private_names = rare_data->private_name_map.capacity() > 0;
2999
3000  // If the class itself does not have private names, nor does it have
3001  // an outer private name scope, then we are certain any private name access
3002  // inside cannot be resolved.
3003  if (!has_private_names && private_name_scope_iter.Done() &&
3004      !unresolved.is_empty()) {
3005    return unresolved.first();
3006  }
3007
3008  for (VariableProxy* proxy = unresolved.first(); proxy != nullptr;) {
3009    DCHECK(proxy->IsPrivateName());
3010    VariableProxy* next = proxy->next_unresolved();
3011    unresolved.Remove(proxy);
3012    Variable* var = nullptr;
3013
3014    // If we can find private name in the current class scope, we can bind
3015    // them immediately because it's going to shadow any outer private names.
3016    if (has_private_names) {
3017      var = LookupLocalPrivateName(proxy->raw_name());
3018      if (var != nullptr) {
3019        var->set_is_used();
3020        proxy->BindTo(var);
3021        // If the variable being accessed is a static private method, we need to
3022        // save the class variable in the context to check that the receiver is
3023        // the class during runtime.
3024        has_explicit_static_private_methods_access_ |=
3025            (var->is_static() &&
3026             IsPrivateMethodOrAccessorVariableMode(var->mode()));
3027      }
3028    }
3029
3030    // If the current scope does not have declared private names,
3031    // try looking from the outer class scope later.
3032    if (var == nullptr) {
3033      // There's no outer private name scope so we are certain that the variable
3034      // cannot be resolved later.
3035      if (private_name_scope_iter.Done()) {
3036        return proxy;
3037      }
3038
3039      // The private name may be found later in the outer private name scope, so
3040      // push it to the outer sopce.
3041      private_name_scope_iter.AddUnresolvedPrivateName(proxy);
3042    }
3043
3044    proxy = next;
3045  }
3046
3047  DCHECK(unresolved.is_empty());
3048  return nullptr;
3049}
3050
3051Variable* ClassScope::DeclareBrandVariable(AstValueFactory* ast_value_factory,
3052                                           IsStaticFlag is_static_flag,
3053                                           int class_token_pos) {
3054  DCHECK_IMPLIES(GetRareData() != nullptr, GetRareData()->brand == nullptr);
3055  bool was_added;
3056  Variable* brand = Declare(zone(), ast_value_factory->dot_brand_string(),
3057                            VariableMode::kConst, NORMAL_VARIABLE,
3058                            InitializationFlag::kNeedsInitialization,
3059                            MaybeAssignedFlag::kNotAssigned, &was_added);
3060  DCHECK(was_added);
3061  brand->set_is_static_flag(is_static_flag);
3062  brand->ForceContextAllocation();
3063  brand->set_is_used();
3064  EnsureRareData()->brand = brand;
3065  brand->set_initializer_position(class_token_pos);
3066  return brand;
3067}
3068
3069Variable* ClassScope::DeclareClassVariable(AstValueFactory* ast_value_factory,
3070                                           const AstRawString* name,
3071                                           int class_token_pos) {
3072  DCHECK_NULL(class_variable_);
3073  bool was_added;
3074  class_variable_ =
3075      Declare(zone(), name == nullptr ? ast_value_factory->dot_string() : name,
3076              VariableMode::kConst, NORMAL_VARIABLE,
3077              InitializationFlag::kNeedsInitialization,
3078              MaybeAssignedFlag::kMaybeAssigned, &was_added);
3079  DCHECK(was_added);
3080  class_variable_->set_initializer_position(class_token_pos);
3081  return class_variable_;
3082}
3083
3084PrivateNameScopeIterator::PrivateNameScopeIterator(Scope* start)
3085    : start_scope_(start), current_scope_(start) {
3086  if (!start->is_class_scope() || start->AsClassScope()->IsParsingHeritage()) {
3087    Next();
3088  }
3089}
3090
3091void PrivateNameScopeIterator::Next() {
3092  DCHECK(!Done());
3093  Scope* inner = current_scope_;
3094  Scope* scope = inner->outer_scope();
3095  while (scope != nullptr) {
3096    if (scope->is_class_scope()) {
3097      if (!inner->private_name_lookup_skips_outer_class()) {
3098        current_scope_ = scope;
3099        return;
3100      }
3101      skipped_any_scopes_ = true;
3102    }
3103    inner = scope;
3104    scope = scope->outer_scope();
3105  }
3106  current_scope_ = nullptr;
3107}
3108
3109void PrivateNameScopeIterator::AddUnresolvedPrivateName(VariableProxy* proxy) {
3110  // During a reparse, current_scope_->already_resolved_ may be true here,
3111  // because the class scope is deserialized while the function scope inside may
3112  // be new.
3113  DCHECK(!proxy->is_resolved());
3114  DCHECK(proxy->IsPrivateName());
3115  GetScope()->EnsureRareData()->unresolved_private_names.Add(proxy);
3116  // Any closure scope that contain uses of private names that skips over a
3117  // class scope due to heritage expressions need private name context chain
3118  // recalculation, since not all scopes require a Context or ScopeInfo. See
3119  // comment in DeclarationScope::RecalcPrivateNameContextChain.
3120  if (V8_UNLIKELY(skipped_any_scopes_)) {
3121    start_scope_->GetClosureScope()->RecordNeedsPrivateNameContextChainRecalc();
3122  }
3123}
3124
3125}  // namespace internal
3126}  // namespace v8
3127