1// Copyright 2012 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "src/ast/scopes.h"
6
7#include <set>
8
9#include "src/accessors.h"
10#include "src/ast/ast.h"
11#include "src/bootstrapper.h"
12#include "src/messages.h"
13#include "src/parsing/parse-info.h"
14
15namespace v8 {
16namespace internal {
17
18// ----------------------------------------------------------------------------
19// Implementation of LocalsMap
20//
21// Note: We are storing the handle locations as key values in the hash map.
22//       When inserting a new variable via Declare(), we rely on the fact that
23//       the handle location remains alive for the duration of that variable
24//       use. Because a Variable holding a handle with the same location exists
25//       this is ensured.
26
27VariableMap::VariableMap(Zone* zone)
28    : ZoneHashMap(8, ZoneAllocationPolicy(zone)) {}
29
30Variable* VariableMap::Declare(Zone* zone, Scope* scope,
31                               const AstRawString* name, VariableMode mode,
32                               VariableKind kind,
33                               InitializationFlag initialization_flag,
34                               MaybeAssignedFlag maybe_assigned_flag,
35                               bool* added) {
36  // AstRawStrings are unambiguous, i.e., the same string is always represented
37  // by the same AstRawString*.
38  // FIXME(marja): fix the type of Lookup.
39  Entry* p =
40      ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->hash(),
41                                  ZoneAllocationPolicy(zone));
42  if (added) *added = p->value == nullptr;
43  if (p->value == nullptr) {
44    // The variable has not been declared yet -> insert it.
45    DCHECK_EQ(name, p->key);
46    p->value = new (zone) Variable(scope, name, mode, kind, initialization_flag,
47                                   maybe_assigned_flag);
48  }
49  return reinterpret_cast<Variable*>(p->value);
50}
51
52void VariableMap::Remove(Variable* var) {
53  const AstRawString* name = var->raw_name();
54  ZoneHashMap::Remove(const_cast<AstRawString*>(name), name->hash());
55}
56
57void VariableMap::Add(Zone* zone, Variable* var) {
58  const AstRawString* name = var->raw_name();
59  Entry* p =
60      ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->hash(),
61                                  ZoneAllocationPolicy(zone));
62  DCHECK_NULL(p->value);
63  DCHECK_EQ(name, p->key);
64  p->value = var;
65}
66
67Variable* VariableMap::Lookup(const AstRawString* name) {
68  Entry* p = ZoneHashMap::Lookup(const_cast<AstRawString*>(name), name->hash());
69  if (p != NULL) {
70    DCHECK(reinterpret_cast<const AstRawString*>(p->key) == name);
71    DCHECK(p->value != NULL);
72    return reinterpret_cast<Variable*>(p->value);
73  }
74  return NULL;
75}
76
77SloppyBlockFunctionMap::SloppyBlockFunctionMap(Zone* zone)
78    : ZoneHashMap(8, ZoneAllocationPolicy(zone)) {}
79
80void SloppyBlockFunctionMap::Declare(Zone* zone, const AstRawString* name,
81                                     SloppyBlockFunctionStatement* stmt) {
82  // AstRawStrings are unambiguous, i.e., the same string is always represented
83  // by the same AstRawString*.
84  Entry* p =
85      ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->hash(),
86                                  ZoneAllocationPolicy(zone));
87  stmt->set_next(static_cast<SloppyBlockFunctionStatement*>(p->value));
88  p->value = stmt;
89}
90
91
92// ----------------------------------------------------------------------------
93// Implementation of Scope
94
95Scope::Scope(Zone* zone)
96    : zone_(zone),
97      outer_scope_(nullptr),
98      variables_(zone),
99      scope_type_(SCRIPT_SCOPE) {
100  SetDefaults();
101}
102
103Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type)
104    : zone_(zone),
105      outer_scope_(outer_scope),
106      variables_(zone),
107      scope_type_(scope_type) {
108  DCHECK_NE(SCRIPT_SCOPE, scope_type);
109  SetDefaults();
110  set_language_mode(outer_scope->language_mode());
111  force_context_allocation_ =
112      !is_function_scope() && outer_scope->has_forced_context_allocation();
113  outer_scope_->AddInnerScope(this);
114}
115
116Scope::Snapshot::Snapshot(Scope* scope)
117    : outer_scope_(scope),
118      top_inner_scope_(scope->inner_scope_),
119      top_unresolved_(scope->unresolved_),
120      top_local_(scope->GetClosureScope()->locals_.end()),
121      top_decl_(scope->GetClosureScope()->decls_.end()) {}
122
123DeclarationScope::DeclarationScope(Zone* zone,
124                                   AstValueFactory* ast_value_factory)
125    : Scope(zone),
126      function_kind_(kNormalFunction),
127      params_(4, zone),
128      sloppy_block_function_map_(zone) {
129  DCHECK_EQ(scope_type_, SCRIPT_SCOPE);
130  SetDefaults();
131
132  // Make sure that if we don't find the global 'this', it won't be declared as
133  // a regular dynamic global by predeclaring it with the right variable kind.
134  DeclareDynamicGlobal(ast_value_factory->this_string(), THIS_VARIABLE);
135}
136
137DeclarationScope::DeclarationScope(Zone* zone, Scope* outer_scope,
138                                   ScopeType scope_type,
139                                   FunctionKind function_kind)
140    : Scope(zone, outer_scope, scope_type),
141      function_kind_(function_kind),
142      params_(4, zone),
143      sloppy_block_function_map_(zone) {
144  DCHECK_NE(scope_type, SCRIPT_SCOPE);
145  SetDefaults();
146  asm_function_ = outer_scope_->IsAsmModule();
147}
148
149ModuleScope::ModuleScope(DeclarationScope* script_scope,
150                         AstValueFactory* ast_value_factory)
151    : DeclarationScope(ast_value_factory->zone(), script_scope, MODULE_SCOPE,
152                       kModule) {
153  Zone* zone = ast_value_factory->zone();
154  module_descriptor_ = new (zone) ModuleDescriptor(zone);
155  set_language_mode(STRICT);
156  DeclareThis(ast_value_factory);
157}
158
159ModuleScope::ModuleScope(Isolate* isolate, Handle<ScopeInfo> scope_info,
160                         AstValueFactory* avfactory)
161    : DeclarationScope(avfactory->zone(), MODULE_SCOPE, scope_info) {
162  Zone* zone = avfactory->zone();
163  Handle<ModuleInfo> module_info(scope_info->ModuleDescriptorInfo(), isolate);
164
165  set_language_mode(STRICT);
166  module_descriptor_ = new (zone) ModuleDescriptor(zone);
167
168  // Deserialize special exports.
169  Handle<FixedArray> special_exports(module_info->special_exports(), isolate);
170  for (int i = 0, n = special_exports->length(); i < n; ++i) {
171    Handle<ModuleInfoEntry> serialized_entry(
172        ModuleInfoEntry::cast(special_exports->get(i)), isolate);
173    module_descriptor_->AddSpecialExport(
174        ModuleDescriptor::Entry::Deserialize(isolate, avfactory,
175                                             serialized_entry),
176        avfactory->zone());
177  }
178
179  // Deserialize regular exports.
180  module_descriptor_->DeserializeRegularExports(isolate, avfactory,
181                                                module_info);
182
183  // Deserialize namespace imports.
184  Handle<FixedArray> namespace_imports(module_info->namespace_imports(),
185                                       isolate);
186  for (int i = 0, n = namespace_imports->length(); i < n; ++i) {
187    Handle<ModuleInfoEntry> serialized_entry(
188        ModuleInfoEntry::cast(namespace_imports->get(i)), isolate);
189    module_descriptor_->AddNamespaceImport(
190        ModuleDescriptor::Entry::Deserialize(isolate, avfactory,
191                                             serialized_entry),
192        avfactory->zone());
193  }
194
195  // Deserialize regular imports.
196  Handle<FixedArray> regular_imports(module_info->regular_imports(), isolate);
197  for (int i = 0, n = regular_imports->length(); i < n; ++i) {
198    Handle<ModuleInfoEntry> serialized_entry(
199        ModuleInfoEntry::cast(regular_imports->get(i)), isolate);
200    module_descriptor_->AddRegularImport(ModuleDescriptor::Entry::Deserialize(
201        isolate, avfactory, serialized_entry));
202  }
203}
204
205Scope::Scope(Zone* zone, ScopeType scope_type, Handle<ScopeInfo> scope_info)
206    : zone_(zone),
207      outer_scope_(nullptr),
208      variables_(zone),
209      scope_info_(scope_info),
210      scope_type_(scope_type) {
211  DCHECK(!scope_info.is_null());
212  SetDefaults();
213#ifdef DEBUG
214  already_resolved_ = true;
215#endif
216  if (scope_info->CallsEval()) RecordEvalCall();
217  set_language_mode(scope_info->language_mode());
218  num_heap_slots_ = scope_info->ContextLength();
219  DCHECK_LE(Context::MIN_CONTEXT_SLOTS, num_heap_slots_);
220}
221
222DeclarationScope::DeclarationScope(Zone* zone, ScopeType scope_type,
223                                   Handle<ScopeInfo> scope_info)
224    : Scope(zone, scope_type, scope_info),
225      function_kind_(scope_info->function_kind()),
226      params_(0, zone),
227      sloppy_block_function_map_(zone) {
228  DCHECK_NE(scope_type, SCRIPT_SCOPE);
229  SetDefaults();
230}
231
232Scope::Scope(Zone* zone, const AstRawString* catch_variable_name,
233             Handle<ScopeInfo> scope_info)
234    : zone_(zone),
235      outer_scope_(nullptr),
236      variables_(zone),
237      scope_info_(scope_info),
238      scope_type_(CATCH_SCOPE) {
239  SetDefaults();
240#ifdef DEBUG
241  already_resolved_ = true;
242#endif
243  // Cache the catch variable, even though it's also available via the
244  // scope_info, as the parser expects that a catch scope always has the catch
245  // variable as first and only variable.
246  Variable* variable = Declare(zone, this, catch_variable_name, VAR,
247                               NORMAL_VARIABLE, kCreatedInitialized);
248  AllocateHeapSlot(variable);
249}
250
251void DeclarationScope::SetDefaults() {
252  is_declaration_scope_ = true;
253  has_simple_parameters_ = true;
254  asm_module_ = false;
255  asm_function_ = false;
256  force_eager_compilation_ = false;
257  has_arguments_parameter_ = false;
258  scope_uses_super_property_ = false;
259  has_rest_ = false;
260  receiver_ = nullptr;
261  new_target_ = nullptr;
262  function_ = nullptr;
263  arguments_ = nullptr;
264  this_function_ = nullptr;
265  should_eager_compile_ = false;
266  is_lazily_parsed_ = false;
267}
268
269void Scope::SetDefaults() {
270#ifdef DEBUG
271  scope_name_ = nullptr;
272  already_resolved_ = false;
273  needs_migration_ = false;
274#endif
275  inner_scope_ = nullptr;
276  sibling_ = nullptr;
277  unresolved_ = nullptr;
278
279  start_position_ = kNoSourcePosition;
280  end_position_ = kNoSourcePosition;
281
282  num_stack_slots_ = 0;
283  num_heap_slots_ = Context::MIN_CONTEXT_SLOTS;
284
285  set_language_mode(SLOPPY);
286
287  scope_calls_eval_ = false;
288  scope_nonlinear_ = false;
289  is_hidden_ = false;
290  is_debug_evaluate_scope_ = false;
291
292  inner_scope_calls_eval_ = false;
293  force_context_allocation_ = false;
294
295  is_declaration_scope_ = false;
296}
297
298bool Scope::HasSimpleParameters() {
299  DeclarationScope* scope = GetClosureScope();
300  return !scope->is_function_scope() || scope->has_simple_parameters();
301}
302
303bool DeclarationScope::ShouldEagerCompile() const {
304  return force_eager_compilation_ || should_eager_compile_;
305}
306
307void DeclarationScope::set_should_eager_compile() {
308  should_eager_compile_ = !is_lazily_parsed_;
309}
310
311void DeclarationScope::set_asm_module() {
312  asm_module_ = true;
313  // Mark any existing inner function scopes as asm function scopes.
314  for (Scope* inner = inner_scope_; inner != nullptr; inner = inner->sibling_) {
315    if (inner->is_function_scope()) {
316      inner->AsDeclarationScope()->set_asm_function();
317    }
318  }
319}
320
321bool Scope::IsAsmModule() const {
322  return is_function_scope() && AsDeclarationScope()->asm_module();
323}
324
325bool Scope::IsAsmFunction() const {
326  return is_function_scope() && AsDeclarationScope()->asm_function();
327}
328
329Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone,
330                                    ScopeInfo* scope_info,
331                                    DeclarationScope* script_scope,
332                                    AstValueFactory* ast_value_factory,
333                                    DeserializationMode deserialization_mode) {
334  // Reconstruct the outer scope chain from a closure's context chain.
335  Scope* current_scope = nullptr;
336  Scope* innermost_scope = nullptr;
337  Scope* outer_scope = nullptr;
338  while (scope_info) {
339    if (scope_info->scope_type() == WITH_SCOPE) {
340      // For scope analysis, debug-evaluate is equivalent to a with scope.
341      outer_scope = new (zone) Scope(zone, WITH_SCOPE, handle(scope_info));
342
343      // TODO(yangguo): Remove once debug-evaluate properly keeps track of the
344      // function scope in which we are evaluating.
345      if (scope_info->IsDebugEvaluateScope()) {
346        outer_scope->set_is_debug_evaluate_scope();
347      }
348    } else if (scope_info->scope_type() == SCRIPT_SCOPE) {
349      // If we reach a script scope, it's the outermost scope. Install the
350      // scope info of this script context onto the existing script scope to
351      // avoid nesting script scopes.
352      if (deserialization_mode == DeserializationMode::kIncludingVariables) {
353        script_scope->SetScriptScopeInfo(handle(scope_info));
354      }
355      DCHECK(!scope_info->HasOuterScopeInfo());
356      break;
357    } else if (scope_info->scope_type() == FUNCTION_SCOPE ||
358               scope_info->scope_type() == EVAL_SCOPE) {
359      // TODO(neis): For an eval scope, we currently create an ordinary function
360      // context.  This is wrong and needs to be fixed.
361      // https://bugs.chromium.org/p/v8/issues/detail?id=5295
362      outer_scope =
363          new (zone) DeclarationScope(zone, FUNCTION_SCOPE, handle(scope_info));
364      if (scope_info->IsAsmFunction())
365        outer_scope->AsDeclarationScope()->set_asm_function();
366      if (scope_info->IsAsmModule())
367        outer_scope->AsDeclarationScope()->set_asm_module();
368    } else if (scope_info->scope_type() == BLOCK_SCOPE) {
369      if (scope_info->is_declaration_scope()) {
370        outer_scope =
371            new (zone) DeclarationScope(zone, BLOCK_SCOPE, handle(scope_info));
372      } else {
373        outer_scope = new (zone) Scope(zone, BLOCK_SCOPE, handle(scope_info));
374      }
375    } else if (scope_info->scope_type() == MODULE_SCOPE) {
376      outer_scope = new (zone)
377          ModuleScope(isolate, handle(scope_info), ast_value_factory);
378    } else {
379      DCHECK_EQ(scope_info->scope_type(), CATCH_SCOPE);
380      DCHECK_EQ(scope_info->LocalCount(), 1);
381      String* name = scope_info->LocalName(0);
382      outer_scope = new (zone)
383          Scope(zone, ast_value_factory->GetString(handle(name, isolate)),
384                handle(scope_info));
385    }
386    if (deserialization_mode == DeserializationMode::kScopesOnly) {
387      outer_scope->scope_info_ = Handle<ScopeInfo>::null();
388    }
389    if (current_scope != nullptr) {
390      outer_scope->AddInnerScope(current_scope);
391    }
392    current_scope = outer_scope;
393    if (innermost_scope == nullptr) innermost_scope = current_scope;
394    scope_info = scope_info->HasOuterScopeInfo() ? scope_info->OuterScopeInfo()
395                                                 : nullptr;
396  }
397
398  if (innermost_scope == nullptr) return script_scope;
399  script_scope->AddInnerScope(current_scope);
400  return innermost_scope;
401}
402
403DeclarationScope* Scope::AsDeclarationScope() {
404  DCHECK(is_declaration_scope());
405  return static_cast<DeclarationScope*>(this);
406}
407
408const DeclarationScope* Scope::AsDeclarationScope() const {
409  DCHECK(is_declaration_scope());
410  return static_cast<const DeclarationScope*>(this);
411}
412
413ModuleScope* Scope::AsModuleScope() {
414  DCHECK(is_module_scope());
415  return static_cast<ModuleScope*>(this);
416}
417
418const ModuleScope* Scope::AsModuleScope() const {
419  DCHECK(is_module_scope());
420  return static_cast<const ModuleScope*>(this);
421}
422
423int Scope::num_parameters() const {
424  return is_declaration_scope() ? AsDeclarationScope()->num_parameters() : 0;
425}
426
427void DeclarationScope::HoistSloppyBlockFunctions(AstNodeFactory* factory) {
428  DCHECK(is_sloppy(language_mode()));
429  DCHECK(is_function_scope() || is_eval_scope() || is_script_scope() ||
430         (is_block_scope() && outer_scope()->is_function_scope()));
431  DCHECK(HasSimpleParameters() || is_block_scope());
432  bool has_simple_parameters = HasSimpleParameters();
433  // For each variable which is used as a function declaration in a sloppy
434  // block,
435  SloppyBlockFunctionMap* map = sloppy_block_function_map();
436  for (ZoneHashMap::Entry* p = map->Start(); p != nullptr; p = map->Next(p)) {
437    AstRawString* name = static_cast<AstRawString*>(p->key);
438
439    // If the variable wouldn't conflict with a lexical declaration
440    // or parameter,
441
442    // Check if there's a conflict with a parameter.
443    // This depends on the fact that functions always have a scope solely to
444    // hold complex parameters, and the names local to that scope are
445    // precisely the names of the parameters. IsDeclaredParameter(name) does
446    // not hold for names declared by complex parameters, nor are those
447    // bindings necessarily declared lexically, so we have to check for them
448    // explicitly. On the other hand, if there are not complex parameters,
449    // it is sufficient to just check IsDeclaredParameter.
450    if (!has_simple_parameters) {
451      if (outer_scope_->LookupLocal(name) != nullptr) {
452        continue;
453      }
454    } else {
455      if (IsDeclaredParameter(name)) {
456        continue;
457      }
458    }
459
460    bool var_created = false;
461
462    // Write in assignments to var for each block-scoped function declaration
463    auto delegates = static_cast<SloppyBlockFunctionStatement*>(p->value);
464
465    DeclarationScope* decl_scope = this;
466    while (decl_scope->is_eval_scope()) {
467      decl_scope = decl_scope->outer_scope()->GetDeclarationScope();
468    }
469    Scope* outer_scope = decl_scope->outer_scope();
470
471    for (SloppyBlockFunctionStatement* delegate = delegates;
472         delegate != nullptr; delegate = delegate->next()) {
473      // Check if there's a conflict with a lexical declaration
474      Scope* query_scope = delegate->scope()->outer_scope();
475      Variable* var = nullptr;
476      bool should_hoist = true;
477
478      // Note that we perform this loop for each delegate named 'name',
479      // which may duplicate work if those delegates share scopes.
480      // It is not sufficient to just do a Lookup on query_scope: for
481      // example, that does not prevent hoisting of the function in
482      // `{ let e; try {} catch (e) { function e(){} } }`
483      do {
484        var = query_scope->LookupLocal(name);
485        if (var != nullptr && IsLexicalVariableMode(var->mode())) {
486          should_hoist = false;
487          break;
488        }
489        query_scope = query_scope->outer_scope();
490      } while (query_scope != outer_scope);
491
492      if (!should_hoist) continue;
493
494      // Declare a var-style binding for the function in the outer scope
495      if (!var_created) {
496        var_created = true;
497        VariableProxy* proxy = factory->NewVariableProxy(name, NORMAL_VARIABLE);
498        Declaration* declaration =
499            factory->NewVariableDeclaration(proxy, this, kNoSourcePosition);
500        // Based on the preceding check, it doesn't matter what we pass as
501        // allow_harmony_restrictive_generators and
502        // sloppy_mode_block_scope_function_redefinition.
503        bool ok = true;
504        DeclareVariable(declaration, VAR,
505                        Variable::DefaultInitializationFlag(VAR), false,
506                        nullptr, &ok);
507        CHECK(ok);  // Based on the preceding check, this should not fail
508      }
509
510      Expression* assignment = factory->NewAssignment(
511          Token::ASSIGN, NewUnresolved(factory, name),
512          delegate->scope()->NewUnresolved(factory, name), kNoSourcePosition);
513      Statement* statement =
514          factory->NewExpressionStatement(assignment, kNoSourcePosition);
515      delegate->set_statement(statement);
516    }
517  }
518}
519
520void DeclarationScope::Analyze(ParseInfo* info, AnalyzeMode mode) {
521  DCHECK(info->literal() != NULL);
522  DeclarationScope* scope = info->literal()->scope();
523
524  Handle<ScopeInfo> outer_scope_info;
525  if (info->maybe_outer_scope_info().ToHandle(&outer_scope_info)) {
526    if (scope->outer_scope()) {
527      DeclarationScope* script_scope = new (info->zone())
528          DeclarationScope(info->zone(), info->ast_value_factory());
529      info->set_script_scope(script_scope);
530      scope->ReplaceOuterScope(Scope::DeserializeScopeChain(
531          info->isolate(), info->zone(), *outer_scope_info, script_scope,
532          info->ast_value_factory(),
533          Scope::DeserializationMode::kIncludingVariables));
534    } else {
535      DCHECK_EQ(outer_scope_info->scope_type(), SCRIPT_SCOPE);
536      scope->SetScriptScopeInfo(outer_scope_info);
537    }
538  }
539
540  if (scope->is_eval_scope() && is_sloppy(scope->language_mode())) {
541    AstNodeFactory factory(info->ast_value_factory());
542    scope->HoistSloppyBlockFunctions(&factory);
543  }
544
545  // We are compiling one of three cases:
546  // 1) top-level code,
547  // 2) a function/eval/module on the top-level
548  // 3) a function/eval in a scope that was already resolved.
549  DCHECK(scope->scope_type() == SCRIPT_SCOPE ||
550         scope->outer_scope()->scope_type() == SCRIPT_SCOPE ||
551         scope->outer_scope()->already_resolved_);
552
553  // The outer scope is never lazy.
554  scope->set_should_eager_compile();
555
556  scope->AllocateVariables(info, mode);
557
558  // Ensuring that the outer script scope has a scope info avoids having
559  // special case for native contexts vs other contexts.
560  if (info->script_scope()->scope_info_.is_null()) {
561    info->script_scope()->scope_info_ =
562        handle(ScopeInfo::Empty(info->isolate()));
563  }
564
565#ifdef DEBUG
566  if (info->script_is_native() ? FLAG_print_builtin_scopes
567                               : FLAG_print_scopes) {
568    scope->Print();
569  }
570  scope->CheckScopePositions();
571  scope->CheckZones();
572#endif
573}
574
575void DeclarationScope::DeclareThis(AstValueFactory* ast_value_factory) {
576  DCHECK(!already_resolved_);
577  DCHECK(is_declaration_scope());
578  DCHECK(has_this_declaration());
579
580  bool subclass_constructor = IsSubclassConstructor(function_kind_);
581  Variable* var = Declare(
582      zone(), this, ast_value_factory->this_string(),
583      subclass_constructor ? CONST : VAR, THIS_VARIABLE,
584      subclass_constructor ? kNeedsInitialization : kCreatedInitialized);
585  receiver_ = var;
586}
587
588void DeclarationScope::DeclareArguments(AstValueFactory* ast_value_factory) {
589  DCHECK(is_function_scope());
590  DCHECK(!is_arrow_scope());
591
592  arguments_ = LookupLocal(ast_value_factory->arguments_string());
593  if (arguments_ == nullptr) {
594    // Declare 'arguments' variable which exists in all non arrow functions.
595    // Note that it might never be accessed, in which case it won't be
596    // allocated during variable allocation.
597    arguments_ = Declare(zone(), this, ast_value_factory->arguments_string(),
598                         VAR, NORMAL_VARIABLE, kCreatedInitialized);
599  } else if (IsLexicalVariableMode(arguments_->mode())) {
600    // Check if there's lexically declared variable named arguments to avoid
601    // redeclaration. See ES#sec-functiondeclarationinstantiation, step 20.
602    arguments_ = nullptr;
603  }
604}
605
606void DeclarationScope::DeclareDefaultFunctionVariables(
607    AstValueFactory* ast_value_factory) {
608  DCHECK(is_function_scope());
609  DCHECK(!is_arrow_scope());
610
611  DeclareThis(ast_value_factory);
612  new_target_ = Declare(zone(), this, ast_value_factory->new_target_string(),
613                        CONST, NORMAL_VARIABLE, kCreatedInitialized);
614
615  if (IsConciseMethod(function_kind_) || IsClassConstructor(function_kind_) ||
616      IsAccessorFunction(function_kind_)) {
617    this_function_ =
618        Declare(zone(), this, ast_value_factory->this_function_string(), CONST,
619                NORMAL_VARIABLE, kCreatedInitialized);
620  }
621}
622
623Variable* DeclarationScope::DeclareFunctionVar(const AstRawString* name) {
624  DCHECK(is_function_scope());
625  DCHECK_NULL(function_);
626  DCHECK_NULL(variables_.Lookup(name));
627  VariableKind kind = is_sloppy(language_mode()) ? SLOPPY_FUNCTION_NAME_VARIABLE
628                                                 : NORMAL_VARIABLE;
629  function_ =
630      new (zone()) Variable(this, name, CONST, kind, kCreatedInitialized);
631  if (calls_sloppy_eval()) {
632    NonLocal(name, DYNAMIC);
633  } else {
634    variables_.Add(zone(), function_);
635  }
636  return function_;
637}
638
639bool Scope::HasBeenRemoved() const {
640  // TODO(neis): Store this information somewhere instead of calculating it.
641
642  if (!is_block_scope()) return false;  // Shortcut.
643
644  Scope* parent = outer_scope();
645  if (parent == nullptr) {
646    DCHECK(is_script_scope());
647    return false;
648  }
649
650  Scope* sibling = parent->inner_scope();
651  for (; sibling != nullptr; sibling = sibling->sibling()) {
652    if (sibling == this) return false;
653  }
654
655  DCHECK_NULL(inner_scope_);
656  return true;
657}
658
659Scope* Scope::GetUnremovedScope() {
660  Scope* scope = this;
661  while (scope != nullptr && scope->HasBeenRemoved()) {
662    scope = scope->outer_scope();
663  }
664  DCHECK_NOT_NULL(scope);
665  return scope;
666}
667
668Scope* Scope::FinalizeBlockScope() {
669  DCHECK(is_block_scope());
670
671  if (variables_.occupancy() > 0 ||
672      (is_declaration_scope() && calls_sloppy_eval())) {
673    return this;
674  }
675
676  // Remove this scope from outer scope.
677  outer_scope()->RemoveInnerScope(this);
678
679  // Reparent inner scopes.
680  if (inner_scope_ != nullptr) {
681    Scope* scope = inner_scope_;
682    scope->outer_scope_ = outer_scope();
683    while (scope->sibling_ != nullptr) {
684      scope = scope->sibling_;
685      scope->outer_scope_ = outer_scope();
686    }
687    scope->sibling_ = outer_scope()->inner_scope_;
688    outer_scope()->inner_scope_ = inner_scope_;
689    inner_scope_ = nullptr;
690  }
691
692  // Move unresolved variables
693  if (unresolved_ != nullptr) {
694    if (outer_scope()->unresolved_ != nullptr) {
695      VariableProxy* unresolved = unresolved_;
696      while (unresolved->next_unresolved() != nullptr) {
697        unresolved = unresolved->next_unresolved();
698      }
699      unresolved->set_next_unresolved(outer_scope()->unresolved_);
700    }
701    outer_scope()->unresolved_ = unresolved_;
702    unresolved_ = nullptr;
703  }
704
705  PropagateUsageFlagsToScope(outer_scope_);
706  // This block does not need a context.
707  num_heap_slots_ = 0;
708  return NULL;
709}
710
711void DeclarationScope::AddLocal(Variable* var) {
712  DCHECK(!already_resolved_);
713  // Temporaries are only placed in ClosureScopes.
714  DCHECK_EQ(GetClosureScope(), this);
715  locals_.Add(var);
716}
717
718Variable* Scope::Declare(Zone* zone, Scope* scope, const AstRawString* name,
719                         VariableMode mode, VariableKind kind,
720                         InitializationFlag initialization_flag,
721                         MaybeAssignedFlag maybe_assigned_flag) {
722  bool added;
723  Variable* var =
724      variables_.Declare(zone, scope, name, mode, kind, initialization_flag,
725                         maybe_assigned_flag, &added);
726  if (added) locals_.Add(var);
727  return var;
728}
729
730void Scope::Snapshot::Reparent(DeclarationScope* new_parent) const {
731  DCHECK_EQ(new_parent, outer_scope_->inner_scope_);
732  DCHECK_EQ(new_parent->outer_scope_, outer_scope_);
733  DCHECK_EQ(new_parent, new_parent->GetClosureScope());
734  DCHECK_NULL(new_parent->inner_scope_);
735  DCHECK_NULL(new_parent->unresolved_);
736  DCHECK(new_parent->locals_.is_empty());
737  Scope* inner_scope = new_parent->sibling_;
738  if (inner_scope != top_inner_scope_) {
739    for (; inner_scope->sibling() != top_inner_scope_;
740         inner_scope = inner_scope->sibling()) {
741      inner_scope->outer_scope_ = new_parent;
742      DCHECK_NE(inner_scope, new_parent);
743    }
744    inner_scope->outer_scope_ = new_parent;
745
746    new_parent->inner_scope_ = new_parent->sibling_;
747    inner_scope->sibling_ = nullptr;
748    // Reset the sibling rather than the inner_scope_ since we
749    // want to keep new_parent there.
750    new_parent->sibling_ = top_inner_scope_;
751  }
752
753  if (outer_scope_->unresolved_ != top_unresolved_) {
754    VariableProxy* last = outer_scope_->unresolved_;
755    while (last->next_unresolved() != top_unresolved_) {
756      last = last->next_unresolved();
757    }
758    last->set_next_unresolved(nullptr);
759    new_parent->unresolved_ = outer_scope_->unresolved_;
760    outer_scope_->unresolved_ = top_unresolved_;
761  }
762
763  // TODO(verwaest): This currently only moves do-expression declared variables
764  // in default arguments that weren't already previously declared with the same
765  // name in the closure-scope. See
766  // test/mjsunit/harmony/default-parameter-do-expression.js.
767  DeclarationScope* outer_closure = outer_scope_->GetClosureScope();
768
769  new_parent->locals_.MoveTail(outer_closure->locals(), top_local_);
770  for (Variable* local : new_parent->locals_) {
771    DCHECK(local->mode() == TEMPORARY || local->mode() == VAR);
772    DCHECK_EQ(local->scope(), local->scope()->GetClosureScope());
773    DCHECK_NE(local->scope(), new_parent);
774    local->set_scope(new_parent);
775    if (local->mode() == VAR) {
776      outer_closure->variables_.Remove(local);
777      new_parent->variables_.Add(new_parent->zone(), local);
778    }
779  }
780  outer_closure->locals_.Rewind(top_local_);
781  outer_closure->decls_.Rewind(top_decl_);
782}
783
784void Scope::ReplaceOuterScope(Scope* outer) {
785  DCHECK_NOT_NULL(outer);
786  DCHECK_NOT_NULL(outer_scope_);
787  DCHECK(!already_resolved_);
788  outer_scope_->RemoveInnerScope(this);
789  outer->AddInnerScope(this);
790  outer_scope_ = outer;
791}
792
793
794void Scope::PropagateUsageFlagsToScope(Scope* other) {
795  DCHECK_NOT_NULL(other);
796  DCHECK(!already_resolved_);
797  DCHECK(!other->already_resolved_);
798  if (calls_eval()) other->RecordEvalCall();
799}
800
801Variable* Scope::LookupInScopeInfo(const AstRawString* name) {
802  Handle<String> name_handle = name->string();
803  // The Scope is backed up by ScopeInfo. This means it cannot operate in a
804  // heap-independent mode, and all strings must be internalized immediately. So
805  // it's ok to get the Handle<String> here.
806  // If we have a serialized scope info, we might find the variable there.
807  // There should be no local slot with the given name.
808  DCHECK_LT(scope_info_->StackSlotIndex(*name_handle), 0);
809
810  bool found = false;
811
812  VariableLocation location;
813  int index;
814  VariableMode mode;
815  InitializationFlag init_flag;
816  MaybeAssignedFlag maybe_assigned_flag;
817
818  {
819    location = VariableLocation::CONTEXT;
820    index = ScopeInfo::ContextSlotIndex(scope_info_, name_handle, &mode,
821                                        &init_flag, &maybe_assigned_flag);
822    found = index >= 0;
823  }
824
825  if (!found && scope_type() == MODULE_SCOPE) {
826    location = VariableLocation::MODULE;
827    index = scope_info_->ModuleIndex(name_handle, &mode, &init_flag,
828                                     &maybe_assigned_flag);
829    found = index != 0;
830  }
831
832  if (!found) {
833    index = scope_info_->FunctionContextSlotIndex(*name_handle);
834    if (index < 0) return nullptr;  // Nowhere found.
835    Variable* var = AsDeclarationScope()->DeclareFunctionVar(name);
836    DCHECK_EQ(CONST, var->mode());
837    var->AllocateTo(VariableLocation::CONTEXT, index);
838    return variables_.Lookup(name);
839  }
840
841  VariableKind kind = NORMAL_VARIABLE;
842  if (location == VariableLocation::CONTEXT &&
843      index == scope_info_->ReceiverContextSlotIndex()) {
844    kind = THIS_VARIABLE;
845  }
846  // TODO(marja, rossberg): Correctly declare FUNCTION, CLASS, NEW_TARGET, and
847  // ARGUMENTS bindings as their corresponding VariableKind.
848
849  Variable* var = variables_.Declare(zone(), this, name, mode, kind, init_flag,
850                                     maybe_assigned_flag);
851  var->AllocateTo(location, index);
852  return var;
853}
854
855Variable* Scope::Lookup(const AstRawString* name) {
856  for (Scope* scope = this;
857       scope != NULL;
858       scope = scope->outer_scope()) {
859    Variable* var = scope->LookupLocal(name);
860    if (var != NULL) return var;
861  }
862  return NULL;
863}
864
865Variable* DeclarationScope::DeclareParameter(
866    const AstRawString* name, VariableMode mode, bool is_optional, bool is_rest,
867    bool* is_duplicate, AstValueFactory* ast_value_factory) {
868  DCHECK(!already_resolved_);
869  DCHECK(is_function_scope() || is_module_scope());
870  DCHECK(!has_rest_);
871  DCHECK(!is_optional || !is_rest);
872  Variable* var;
873  if (mode == TEMPORARY) {
874    var = NewTemporary(name);
875  } else {
876    var =
877        Declare(zone(), this, name, mode, NORMAL_VARIABLE, kCreatedInitialized);
878    // TODO(wingo): Avoid O(n^2) check.
879    *is_duplicate = IsDeclaredParameter(name);
880  }
881  has_rest_ = is_rest;
882  params_.Add(var, zone());
883  if (name == ast_value_factory->arguments_string()) {
884    has_arguments_parameter_ = true;
885  }
886  return var;
887}
888
889Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode,
890                              InitializationFlag init_flag, VariableKind kind,
891                              MaybeAssignedFlag maybe_assigned_flag) {
892  DCHECK(!already_resolved_);
893  // This function handles VAR, LET, and CONST modes.  DYNAMIC variables are
894  // introduced during variable allocation, and TEMPORARY variables are
895  // allocated via NewTemporary().
896  DCHECK(IsDeclaredVariableMode(mode));
897  return Declare(zone(), this, name, mode, kind, init_flag,
898                 maybe_assigned_flag);
899}
900
901Variable* Scope::DeclareVariable(
902    Declaration* declaration, VariableMode mode, InitializationFlag init,
903    bool allow_harmony_restrictive_generators,
904    bool* sloppy_mode_block_scope_function_redefinition, bool* ok) {
905  DCHECK(IsDeclaredVariableMode(mode));
906  DCHECK(!already_resolved_);
907
908  if (mode == VAR && !is_declaration_scope()) {
909    return GetDeclarationScope()->DeclareVariable(
910        declaration, mode, init, allow_harmony_restrictive_generators,
911        sloppy_mode_block_scope_function_redefinition, ok);
912  }
913  DCHECK(!is_catch_scope());
914  DCHECK(!is_with_scope());
915  DCHECK(is_declaration_scope() ||
916         (IsLexicalVariableMode(mode) && is_block_scope()));
917
918  VariableProxy* proxy = declaration->proxy();
919  DCHECK(proxy->raw_name() != NULL);
920  const AstRawString* name = proxy->raw_name();
921  bool is_function_declaration = declaration->IsFunctionDeclaration();
922
923  Variable* var = nullptr;
924  if (is_eval_scope() && is_sloppy(language_mode()) && mode == VAR) {
925    // In a var binding in a sloppy direct eval, pollute the enclosing scope
926    // with this new binding by doing the following:
927    // The proxy is bound to a lookup variable to force a dynamic declaration
928    // using the DeclareEvalVar or DeclareEvalFunction runtime functions.
929    VariableKind kind = NORMAL_VARIABLE;
930    // TODO(sigurds) figure out if kNotAssigned is OK here
931    var = new (zone()) Variable(this, name, mode, kind, init, kNotAssigned);
932    var->AllocateTo(VariableLocation::LOOKUP, -1);
933  } else {
934    // Declare the variable in the declaration scope.
935    var = LookupLocal(name);
936    if (var == NULL) {
937      // Declare the name.
938      VariableKind kind = NORMAL_VARIABLE;
939      if (is_function_declaration) {
940        kind = FUNCTION_VARIABLE;
941      }
942      var = DeclareLocal(name, mode, init, kind, kNotAssigned);
943    } else if (IsLexicalVariableMode(mode) ||
944               IsLexicalVariableMode(var->mode())) {
945      // Allow duplicate function decls for web compat, see bug 4693.
946      bool duplicate_allowed = false;
947      if (is_sloppy(language_mode()) && is_function_declaration &&
948          var->is_function()) {
949        DCHECK(IsLexicalVariableMode(mode) &&
950               IsLexicalVariableMode(var->mode()));
951        // If the duplication is allowed, then the var will show up
952        // in the SloppyBlockFunctionMap and the new FunctionKind
953        // will be a permitted duplicate.
954        FunctionKind function_kind =
955            declaration->AsFunctionDeclaration()->fun()->kind();
956        duplicate_allowed =
957            GetDeclarationScope()->sloppy_block_function_map()->Lookup(
958                const_cast<AstRawString*>(name), name->hash()) != nullptr &&
959            !IsAsyncFunction(function_kind) &&
960            !(allow_harmony_restrictive_generators &&
961              IsGeneratorFunction(function_kind));
962      }
963      if (duplicate_allowed) {
964        *sloppy_mode_block_scope_function_redefinition = true;
965      } else {
966        // The name was declared in this scope before; check for conflicting
967        // re-declarations. We have a conflict if either of the declarations
968        // is not a var (in script scope, we also have to ignore legacy const
969        // for compatibility). There is similar code in runtime.cc in the
970        // Declare functions. The function CheckConflictingVarDeclarations
971        // checks for var and let bindings from different scopes whereas this
972        // is a check for conflicting declarations within the same scope. This
973        // check also covers the special case
974        //
975        // function () { let x; { var x; } }
976        //
977        // because the var declaration is hoisted to the function scope where
978        // 'x' is already bound.
979        DCHECK(IsDeclaredVariableMode(var->mode()));
980        // In harmony we treat re-declarations as early errors. See
981        // ES5 16 for a definition of early errors.
982        *ok = false;
983        return nullptr;
984      }
985    } else if (mode == VAR) {
986      var->set_maybe_assigned();
987    }
988  }
989  DCHECK_NOT_NULL(var);
990
991  // We add a declaration node for every declaration. The compiler
992  // will only generate code if necessary. In particular, declarations
993  // for inner local variables that do not represent functions won't
994  // result in any generated code.
995  //
996  // This will lead to multiple declaration nodes for the
997  // same variable if it is declared several times. This is not a
998  // semantic issue, but it may be a performance issue since it may
999  // lead to repeated DeclareEvalVar or DeclareEvalFunction calls.
1000  decls_.Add(declaration);
1001  proxy->BindTo(var);
1002  return var;
1003}
1004
1005VariableProxy* Scope::NewUnresolved(AstNodeFactory* factory,
1006                                    const AstRawString* name,
1007                                    int start_position, VariableKind kind) {
1008  // Note that we must not share the unresolved variables with
1009  // the same name because they may be removed selectively via
1010  // RemoveUnresolved().
1011  DCHECK(!already_resolved_);
1012  DCHECK_EQ(!needs_migration_, factory->zone() == zone());
1013  VariableProxy* proxy = factory->NewVariableProxy(name, kind, start_position);
1014  proxy->set_next_unresolved(unresolved_);
1015  unresolved_ = proxy;
1016  return proxy;
1017}
1018
1019void Scope::AddUnresolved(VariableProxy* proxy) {
1020  DCHECK(!already_resolved_);
1021  DCHECK(!proxy->is_resolved());
1022  proxy->set_next_unresolved(unresolved_);
1023  unresolved_ = proxy;
1024}
1025
1026Variable* DeclarationScope::DeclareDynamicGlobal(const AstRawString* name,
1027                                                 VariableKind kind) {
1028  DCHECK(is_script_scope());
1029  return variables_.Declare(zone(), this, name, DYNAMIC_GLOBAL, kind,
1030                            kCreatedInitialized);
1031}
1032
1033
1034bool Scope::RemoveUnresolved(VariableProxy* var) {
1035  if (unresolved_ == var) {
1036    unresolved_ = var->next_unresolved();
1037    var->set_next_unresolved(nullptr);
1038    return true;
1039  }
1040  VariableProxy* current = unresolved_;
1041  while (current != nullptr) {
1042    VariableProxy* next = current->next_unresolved();
1043    if (var == next) {
1044      current->set_next_unresolved(next->next_unresolved());
1045      var->set_next_unresolved(nullptr);
1046      return true;
1047    }
1048    current = next;
1049  }
1050  return false;
1051}
1052
1053bool Scope::RemoveUnresolved(const AstRawString* name) {
1054  if (unresolved_ != nullptr && unresolved_->raw_name() == name) {
1055    VariableProxy* removed = unresolved_;
1056    unresolved_ = unresolved_->next_unresolved();
1057    removed->set_next_unresolved(nullptr);
1058    return true;
1059  }
1060  VariableProxy* current = unresolved_;
1061  while (current != nullptr) {
1062    VariableProxy* next = current->next_unresolved();
1063    if (next != nullptr && next->raw_name() == name) {
1064      current->set_next_unresolved(next->next_unresolved());
1065      next->set_next_unresolved(nullptr);
1066      return true;
1067    }
1068    current = next;
1069  }
1070  return false;
1071}
1072
1073Variable* Scope::NewTemporary(const AstRawString* name) {
1074  DeclarationScope* scope = GetClosureScope();
1075  Variable* var = new (zone())
1076      Variable(scope, name, TEMPORARY, NORMAL_VARIABLE, kCreatedInitialized);
1077  scope->AddLocal(var);
1078  return var;
1079}
1080
1081Declaration* Scope::CheckConflictingVarDeclarations() {
1082  for (Declaration* decl : decls_) {
1083    VariableMode mode = decl->proxy()->var()->mode();
1084    if (IsLexicalVariableMode(mode) && !is_block_scope()) continue;
1085
1086    // Iterate through all scopes until and including the declaration scope.
1087    Scope* previous = NULL;
1088    Scope* current = decl->scope();
1089    // Lexical vs lexical conflicts within the same scope have already been
1090    // captured in Parser::Declare. The only conflicts we still need to check
1091    // are lexical vs VAR, or any declarations within a declaration block scope
1092    // vs lexical declarations in its surrounding (function) scope.
1093    if (IsLexicalVariableMode(mode)) current = current->outer_scope_;
1094    do {
1095      // There is a conflict if there exists a non-VAR binding.
1096      Variable* other_var =
1097          current->variables_.Lookup(decl->proxy()->raw_name());
1098      if (other_var != NULL && IsLexicalVariableMode(other_var->mode())) {
1099        return decl;
1100      }
1101      previous = current;
1102      current = current->outer_scope_;
1103    } while (!previous->is_declaration_scope());
1104  }
1105  return NULL;
1106}
1107
1108Declaration* Scope::CheckLexDeclarationsConflictingWith(
1109    const ZoneList<const AstRawString*>& names) {
1110  DCHECK(is_block_scope());
1111  for (int i = 0; i < names.length(); ++i) {
1112    Variable* var = LookupLocal(names.at(i));
1113    if (var != nullptr) {
1114      // Conflict; find and return its declaration.
1115      DCHECK(IsLexicalVariableMode(var->mode()));
1116      const AstRawString* name = names.at(i);
1117      for (Declaration* decl : decls_) {
1118        if (decl->proxy()->raw_name() == name) return decl;
1119      }
1120      DCHECK(false);
1121    }
1122  }
1123  return nullptr;
1124}
1125
1126void DeclarationScope::AllocateVariables(ParseInfo* info, AnalyzeMode mode) {
1127  // Module variables must be allocated before variable resolution
1128  // to ensure that AccessNeedsHoleCheck() can detect import variables.
1129  if (is_module_scope()) AsModuleScope()->AllocateModuleVariables();
1130
1131  ResolveVariablesRecursively(info);
1132  AllocateVariablesRecursively();
1133
1134  MaybeHandle<ScopeInfo> outer_scope;
1135  if (outer_scope_ != nullptr) outer_scope = outer_scope_->scope_info_;
1136
1137  AllocateScopeInfosRecursively(info->isolate(), outer_scope);
1138  if (mode == AnalyzeMode::kDebugger) {
1139    AllocateDebuggerScopeInfos(info->isolate(), outer_scope);
1140  }
1141  // The debugger expects all shared function infos to contain a scope info.
1142  // Since the top-most scope will end up in a shared function info, make sure
1143  // it has one, even if it doesn't need a scope info.
1144  // TODO(jochen|yangguo): Remove this requirement.
1145  if (scope_info_.is_null()) {
1146    scope_info_ = ScopeInfo::Create(info->isolate(), zone(), this, outer_scope);
1147  }
1148}
1149
1150bool Scope::AllowsLazyParsingWithoutUnresolvedVariables(
1151    const Scope* outer) const {
1152  // If none of the outer scopes need to decide whether to context allocate
1153  // specific variables, we can preparse inner functions without unresolved
1154  // variables. Otherwise we need to find unresolved variables to force context
1155  // allocation of the matching declarations. We can stop at the outer scope for
1156  // the parse, since context allocation of those variables is already
1157  // guaranteed to be correct.
1158  for (const Scope* s = this; s != outer; s = s->outer_scope_) {
1159    // Eval forces context allocation on all outer scopes, so we don't need to
1160    // look at those scopes. Sloppy eval makes all top-level variables dynamic,
1161    // whereas strict-mode requires context allocation.
1162    if (s->is_eval_scope()) return !is_strict(s->language_mode());
1163    // Catch scopes force context allocation of all variables.
1164    if (s->is_catch_scope()) continue;
1165    // With scopes do not introduce variables that need allocation.
1166    if (s->is_with_scope()) continue;
1167    // If everything is guaranteed to be context allocated we can ignore the
1168    // scope.
1169    if (s->has_forced_context_allocation()) continue;
1170    // Only block scopes and function scopes should disallow preparsing.
1171    DCHECK(s->is_block_scope() || s->is_function_scope());
1172    return false;
1173  }
1174  return true;
1175}
1176
1177bool DeclarationScope::AllowsLazyCompilation() const {
1178  return !force_eager_compilation_;
1179}
1180
1181int Scope::ContextChainLength(Scope* scope) const {
1182  int n = 0;
1183  for (const Scope* s = this; s != scope; s = s->outer_scope_) {
1184    DCHECK(s != NULL);  // scope must be in the scope chain
1185    if (s->NeedsContext()) n++;
1186  }
1187  return n;
1188}
1189
1190int Scope::ContextChainLengthUntilOutermostSloppyEval() const {
1191  int result = 0;
1192  int length = 0;
1193
1194  for (const Scope* s = this; s != nullptr; s = s->outer_scope()) {
1195    if (!s->NeedsContext()) continue;
1196    length++;
1197    if (s->calls_sloppy_eval()) result = length;
1198  }
1199
1200  return result;
1201}
1202
1203int Scope::MaxNestedContextChainLength() {
1204  int max_context_chain_length = 0;
1205  for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
1206    if (scope->is_function_scope()) continue;
1207    max_context_chain_length = std::max(scope->MaxNestedContextChainLength(),
1208                                        max_context_chain_length);
1209  }
1210  if (NeedsContext()) {
1211    max_context_chain_length += 1;
1212  }
1213  return max_context_chain_length;
1214}
1215
1216DeclarationScope* Scope::GetDeclarationScope() {
1217  Scope* scope = this;
1218  while (!scope->is_declaration_scope()) {
1219    scope = scope->outer_scope();
1220  }
1221  return scope->AsDeclarationScope();
1222}
1223
1224const DeclarationScope* Scope::GetClosureScope() const {
1225  const Scope* scope = this;
1226  while (!scope->is_declaration_scope() || scope->is_block_scope()) {
1227    scope = scope->outer_scope();
1228  }
1229  return scope->AsDeclarationScope();
1230}
1231
1232DeclarationScope* Scope::GetClosureScope() {
1233  Scope* scope = this;
1234  while (!scope->is_declaration_scope() || scope->is_block_scope()) {
1235    scope = scope->outer_scope();
1236  }
1237  return scope->AsDeclarationScope();
1238}
1239
1240bool Scope::NeedsScopeInfo() const {
1241  DCHECK(!already_resolved_);
1242  DCHECK(GetClosureScope()->ShouldEagerCompile());
1243  // The debugger expects all functions to have scope infos.
1244  // TODO(jochen|yangguo): Remove this requirement.
1245  if (is_function_scope()) return true;
1246  return NeedsContext();
1247}
1248
1249ModuleScope* Scope::GetModuleScope() {
1250  Scope* scope = this;
1251  DCHECK(!scope->is_script_scope());
1252  while (!scope->is_module_scope()) {
1253    scope = scope->outer_scope();
1254    DCHECK_NOT_NULL(scope);
1255  }
1256  return scope->AsModuleScope();
1257}
1258
1259DeclarationScope* Scope::GetReceiverScope() {
1260  Scope* scope = this;
1261  while (!scope->is_script_scope() &&
1262         (!scope->is_function_scope() ||
1263          scope->AsDeclarationScope()->is_arrow_scope())) {
1264    scope = scope->outer_scope();
1265  }
1266  return scope->AsDeclarationScope();
1267}
1268
1269Scope* Scope::GetOuterScopeWithContext() {
1270  Scope* scope = outer_scope_;
1271  while (scope && !scope->NeedsContext()) {
1272    scope = scope->outer_scope();
1273  }
1274  return scope;
1275}
1276
1277Handle<StringSet> DeclarationScope::CollectNonLocals(
1278    ParseInfo* info, Handle<StringSet> non_locals) {
1279  VariableProxy* free_variables = FetchFreeVariables(this, true, info);
1280  for (VariableProxy* proxy = free_variables; proxy != nullptr;
1281       proxy = proxy->next_unresolved()) {
1282    non_locals = StringSet::Add(non_locals, proxy->name());
1283  }
1284  return non_locals;
1285}
1286
1287void DeclarationScope::ResetAfterPreparsing(AstValueFactory* ast_value_factory,
1288                                            bool aborted) {
1289  DCHECK(is_function_scope());
1290
1291  // Reset all non-trivial members.
1292  params_.Clear();
1293  decls_.Clear();
1294  locals_.Clear();
1295  sloppy_block_function_map_.Clear();
1296  variables_.Clear();
1297  // Make sure we won't walk the scope tree from here on.
1298  inner_scope_ = nullptr;
1299  unresolved_ = nullptr;
1300
1301  if (aborted && !IsArrowFunction(function_kind_)) {
1302    DeclareDefaultFunctionVariables(ast_value_factory);
1303  }
1304
1305#ifdef DEBUG
1306  needs_migration_ = false;
1307#endif
1308
1309  is_lazily_parsed_ = !aborted;
1310}
1311
1312void DeclarationScope::AnalyzePartially(AstNodeFactory* ast_node_factory) {
1313  DCHECK(!force_eager_compilation_);
1314  VariableProxy* unresolved = nullptr;
1315
1316  if (!outer_scope_->is_script_scope()) {
1317    // Try to resolve unresolved variables for this Scope and migrate those
1318    // which cannot be resolved inside. It doesn't make sense to try to resolve
1319    // them in the outer Scopes here, because they are incomplete.
1320    for (VariableProxy* proxy =
1321             FetchFreeVariables(this, !FLAG_lazy_inner_functions);
1322         proxy != nullptr; proxy = proxy->next_unresolved()) {
1323      DCHECK(!proxy->is_resolved());
1324      VariableProxy* copy = ast_node_factory->CopyVariableProxy(proxy);
1325      copy->set_next_unresolved(unresolved);
1326      unresolved = copy;
1327    }
1328
1329    // Clear arguments_ if unused. This is used as a signal for optimization.
1330    if (arguments_ != nullptr &&
1331        !(MustAllocate(arguments_) && !has_arguments_parameter_)) {
1332      arguments_ = nullptr;
1333    }
1334  }
1335
1336  ResetAfterPreparsing(ast_node_factory->ast_value_factory(), false);
1337
1338  unresolved_ = unresolved;
1339}
1340
1341#ifdef DEBUG
1342static const char* Header(ScopeType scope_type, FunctionKind function_kind,
1343                          bool is_declaration_scope) {
1344  switch (scope_type) {
1345    case EVAL_SCOPE: return "eval";
1346    // TODO(adamk): Should we print concise method scopes specially?
1347    case FUNCTION_SCOPE:
1348      if (IsGeneratorFunction(function_kind)) return "function*";
1349      if (IsAsyncFunction(function_kind)) return "async function";
1350      if (IsArrowFunction(function_kind)) return "arrow";
1351      return "function";
1352    case MODULE_SCOPE: return "module";
1353    case SCRIPT_SCOPE: return "global";
1354    case CATCH_SCOPE: return "catch";
1355    case BLOCK_SCOPE: return is_declaration_scope ? "varblock" : "block";
1356    case WITH_SCOPE: return "with";
1357  }
1358  UNREACHABLE();
1359  return NULL;
1360}
1361
1362
1363static void Indent(int n, const char* str) {
1364  PrintF("%*s%s", n, "", str);
1365}
1366
1367
1368static void PrintName(const AstRawString* name) {
1369  PrintF("%.*s", name->length(), name->raw_data());
1370}
1371
1372
1373static void PrintLocation(Variable* var) {
1374  switch (var->location()) {
1375    case VariableLocation::UNALLOCATED:
1376      break;
1377    case VariableLocation::PARAMETER:
1378      PrintF("parameter[%d]", var->index());
1379      break;
1380    case VariableLocation::LOCAL:
1381      PrintF("local[%d]", var->index());
1382      break;
1383    case VariableLocation::CONTEXT:
1384      PrintF("context[%d]", var->index());
1385      break;
1386    case VariableLocation::LOOKUP:
1387      PrintF("lookup");
1388      break;
1389    case VariableLocation::MODULE:
1390      PrintF("module");
1391      break;
1392  }
1393}
1394
1395
1396static void PrintVar(int indent, Variable* var) {
1397  if (var->is_used() || !var->IsUnallocated()) {
1398    Indent(indent, VariableMode2String(var->mode()));
1399    PrintF(" ");
1400    if (var->raw_name()->IsEmpty())
1401      PrintF(".%p", reinterpret_cast<void*>(var));
1402    else
1403      PrintName(var->raw_name());
1404    PrintF(";  // ");
1405    PrintLocation(var);
1406    bool comma = !var->IsUnallocated();
1407    if (var->has_forced_context_allocation()) {
1408      if (comma) PrintF(", ");
1409      PrintF("forced context allocation");
1410      comma = true;
1411    }
1412    if (var->maybe_assigned() == kNotAssigned) {
1413      if (comma) PrintF(", ");
1414      PrintF("never assigned");
1415    }
1416    PrintF("\n");
1417  }
1418}
1419
1420static void PrintMap(int indent, VariableMap* map, bool locals) {
1421  for (VariableMap::Entry* p = map->Start(); p != nullptr; p = map->Next(p)) {
1422    Variable* var = reinterpret_cast<Variable*>(p->value);
1423    bool local = !IsDynamicVariableMode(var->mode());
1424    if (locals ? local : !local) {
1425      if (var == nullptr) {
1426        Indent(indent, "<?>\n");
1427      } else {
1428        PrintVar(indent, var);
1429      }
1430    }
1431  }
1432}
1433
1434void DeclarationScope::PrintParameters() {
1435  PrintF(" (");
1436  for (int i = 0; i < params_.length(); i++) {
1437    if (i > 0) PrintF(", ");
1438    const AstRawString* name = params_[i]->raw_name();
1439    if (name->IsEmpty())
1440      PrintF(".%p", reinterpret_cast<void*>(params_[i]));
1441    else
1442      PrintName(name);
1443  }
1444  PrintF(")");
1445}
1446
1447void Scope::Print(int n) {
1448  int n0 = (n > 0 ? n : 0);
1449  int n1 = n0 + 2;  // indentation
1450
1451  // Print header.
1452  FunctionKind function_kind = is_function_scope()
1453                                   ? AsDeclarationScope()->function_kind()
1454                                   : kNormalFunction;
1455  Indent(n0, Header(scope_type_, function_kind, is_declaration_scope()));
1456  if (scope_name_ != nullptr && !scope_name_->IsEmpty()) {
1457    PrintF(" ");
1458    PrintName(scope_name_);
1459  }
1460
1461  // Print parameters, if any.
1462  Variable* function = nullptr;
1463  if (is_function_scope()) {
1464    AsDeclarationScope()->PrintParameters();
1465    function = AsDeclarationScope()->function_var();
1466  }
1467
1468  PrintF(" { // (%d, %d)\n", start_position(), end_position());
1469
1470  // Function name, if any (named function literals, only).
1471  if (function != nullptr) {
1472    Indent(n1, "// (local) function name: ");
1473    PrintName(function->raw_name());
1474    PrintF("\n");
1475  }
1476
1477  // Scope info.
1478  if (is_strict(language_mode())) {
1479    Indent(n1, "// strict mode scope\n");
1480  }
1481  if (IsAsmModule()) Indent(n1, "// scope is an asm module\n");
1482  if (IsAsmFunction()) Indent(n1, "// scope is an asm function\n");
1483  if (scope_calls_eval_) Indent(n1, "// scope calls 'eval'\n");
1484  if (is_declaration_scope() && AsDeclarationScope()->uses_super_property()) {
1485    Indent(n1, "// scope uses 'super' property\n");
1486  }
1487  if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n");
1488  if (is_declaration_scope()) {
1489    DeclarationScope* scope = AsDeclarationScope();
1490    if (scope->is_lazily_parsed()) Indent(n1, "// lazily parsed\n");
1491    if (scope->ShouldEagerCompile()) Indent(n1, "// will be compiled\n");
1492  }
1493  if (num_stack_slots_ > 0) {
1494    Indent(n1, "// ");
1495    PrintF("%d stack slots\n", num_stack_slots_);
1496  }
1497  if (num_heap_slots_ > 0) {
1498    Indent(n1, "// ");
1499    PrintF("%d heap slots\n", num_heap_slots_);
1500  }
1501
1502  // Print locals.
1503  if (function != nullptr) {
1504    Indent(n1, "// function var:\n");
1505    PrintVar(n1, function);
1506  }
1507
1508  if (variables_.Start() != NULL) {
1509    Indent(n1, "// local vars:\n");
1510    PrintMap(n1, &variables_, true);
1511
1512    Indent(n1, "// dynamic vars:\n");
1513    PrintMap(n1, &variables_, false);
1514  }
1515
1516  // Print inner scopes (disable by providing negative n).
1517  if (n >= 0) {
1518    for (Scope* scope = inner_scope_; scope != nullptr;
1519         scope = scope->sibling_) {
1520      PrintF("\n");
1521      scope->Print(n1);
1522    }
1523  }
1524
1525  Indent(n0, "}\n");
1526}
1527
1528void Scope::CheckScopePositions() {
1529  // Visible leaf scopes must have real positions.
1530  if (!is_hidden() && inner_scope_ == nullptr) {
1531    CHECK_NE(kNoSourcePosition, start_position());
1532    CHECK_NE(kNoSourcePosition, end_position());
1533  }
1534  for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
1535    scope->CheckScopePositions();
1536  }
1537}
1538
1539void Scope::CheckZones() {
1540  DCHECK(!needs_migration_);
1541  for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
1542    CHECK_EQ(scope->zone(), zone());
1543    scope->CheckZones();
1544  }
1545}
1546#endif  // DEBUG
1547
1548Variable* Scope::NonLocal(const AstRawString* name, VariableMode mode) {
1549  // Declare a new non-local.
1550  DCHECK(IsDynamicVariableMode(mode));
1551  Variable* var = variables_.Declare(zone(), NULL, name, mode, NORMAL_VARIABLE,
1552                                     kCreatedInitialized);
1553  // Allocate it by giving it a dynamic lookup.
1554  var->AllocateTo(VariableLocation::LOOKUP, -1);
1555  return var;
1556}
1557
1558Variable* Scope::LookupRecursive(VariableProxy* proxy, Scope* outer_scope_end) {
1559  DCHECK_NE(outer_scope_end, this);
1560  // Short-cut: whenever we find a debug-evaluate scope, just look everything up
1561  // dynamically. Debug-evaluate doesn't properly create scope info for the
1562  // lookups it does. It may not have a valid 'this' declaration, and anything
1563  // accessed through debug-evaluate might invalidly resolve to stack-allocated
1564  // variables.
1565  // TODO(yangguo): Remove once debug-evaluate creates proper ScopeInfo for the
1566  // scopes in which it's evaluating.
1567  if (is_debug_evaluate_scope_) return NonLocal(proxy->raw_name(), DYNAMIC);
1568
1569  // Try to find the variable in this scope.
1570  Variable* var = LookupLocal(proxy->raw_name());
1571
1572  // We found a variable and we are done. (Even if there is an 'eval' in this
1573  // scope which introduces the same variable again, the resulting variable
1574  // remains the same.)
1575  if (var != nullptr) return var;
1576
1577  if (outer_scope_ == outer_scope_end) {
1578    // We may just be trying to find all free variables. In that case, don't
1579    // declare them in the outer scope.
1580    if (!is_script_scope()) return nullptr;
1581    // No binding has been found. Declare a variable on the global object.
1582    return AsDeclarationScope()->DeclareDynamicGlobal(proxy->raw_name(),
1583                                                      NORMAL_VARIABLE);
1584  }
1585
1586  DCHECK(!is_script_scope());
1587
1588  var = outer_scope_->LookupRecursive(proxy, outer_scope_end);
1589
1590  // The variable could not be resolved statically.
1591  if (var == nullptr) return var;
1592
1593  if (is_function_scope() && !var->is_dynamic()) {
1594    var->ForceContextAllocation();
1595  }
1596  // "this" can't be shadowed by "eval"-introduced bindings or by "with"
1597  // scopes.
1598  // TODO(wingo): There are other variables in this category; add them.
1599  if (var->is_this()) return var;
1600
1601  if (is_with_scope()) {
1602    // The current scope is a with scope, so the variable binding can not be
1603    // statically resolved. However, note that it was necessary to do a lookup
1604    // in the outer scope anyway, because if a binding exists in an outer
1605    // scope, the associated variable has to be marked as potentially being
1606    // accessed from inside of an inner with scope (the property may not be in
1607    // the 'with' object).
1608    if (!var->is_dynamic() && var->IsUnallocated()) {
1609      DCHECK(!already_resolved_);
1610      var->set_is_used();
1611      var->ForceContextAllocation();
1612      if (proxy->is_assigned()) var->set_maybe_assigned();
1613    }
1614    return NonLocal(proxy->raw_name(), DYNAMIC);
1615  }
1616
1617  if (calls_sloppy_eval() && is_declaration_scope()) {
1618    // A variable binding may have been found in an outer scope, but the current
1619    // scope makes a sloppy 'eval' call, so the found variable may not be the
1620    // correct one (the 'eval' may introduce a binding with the same name). In
1621    // that case, change the lookup result to reflect this situation. Only
1622    // scopes that can host var bindings (declaration scopes) need be considered
1623    // here (this excludes block and catch scopes), and variable lookups at
1624    // script scope are always dynamic.
1625    if (var->IsGlobalObjectProperty()) {
1626      return NonLocal(proxy->raw_name(), DYNAMIC_GLOBAL);
1627    }
1628
1629    if (var->is_dynamic()) return var;
1630
1631    Variable* invalidated = var;
1632    var = NonLocal(proxy->raw_name(), DYNAMIC_LOCAL);
1633    var->set_local_if_not_shadowed(invalidated);
1634  }
1635
1636  return var;
1637}
1638
1639void Scope::ResolveVariable(ParseInfo* info, VariableProxy* proxy) {
1640  DCHECK(info->script_scope()->is_script_scope());
1641  DCHECK(!proxy->is_resolved());
1642  Variable* var = LookupRecursive(proxy, nullptr);
1643  ResolveTo(info, proxy, var);
1644
1645  if (FLAG_lazy_inner_functions) {
1646    if (info != nullptr && info->is_native()) return;
1647    // Pessimistically force context allocation for all variables to which inner
1648    // scope variables could potentially resolve to.
1649    Scope* scope = GetClosureScope()->outer_scope_;
1650    while (scope != nullptr && scope->scope_info_.is_null()) {
1651      var = scope->LookupLocal(proxy->raw_name());
1652      if (var != nullptr) {
1653        // Since we don't lazy parse inner arrow functions, inner functions
1654        // cannot refer to the outer "this".
1655        if (!var->is_dynamic() && !var->is_this() &&
1656            !var->has_forced_context_allocation()) {
1657          var->ForceContextAllocation();
1658          var->set_is_used();
1659          // We don't know what the (potentially lazy parsed) inner function
1660          // does with the variable; pessimistically assume that it's assigned.
1661          var->set_maybe_assigned();
1662        }
1663      }
1664      scope = scope->outer_scope_;
1665    }
1666  }
1667}
1668
1669namespace {
1670
1671bool AccessNeedsHoleCheck(Variable* var, VariableProxy* proxy, Scope* scope) {
1672  if (!var->binding_needs_init()) {
1673    return false;
1674  }
1675
1676  // It's impossible to eliminate module import hole checks here, because it's
1677  // unknown at compilation time whether the binding referred to in the
1678  // exporting module itself requires hole checks.
1679  if (var->location() == VariableLocation::MODULE && !var->IsExport()) {
1680    return true;
1681  }
1682
1683  // Check if the binding really needs an initialization check. The check
1684  // can be skipped in the following situation: we have a LET or CONST
1685  // binding, both the Variable and the VariableProxy have the same
1686  // declaration scope (i.e. they are both in global code, in the
1687  // same function or in the same eval code), the VariableProxy is in
1688  // the source physically located after the initializer of the variable,
1689  // and that the initializer cannot be skipped due to a nonlinear scope.
1690  //
1691  // The condition on the declaration scopes is a conservative check for
1692  // nested functions that access a binding and are called before the
1693  // binding is initialized:
1694  //   function() { f(); let x = 1; function f() { x = 2; } }
1695  //
1696  // The check cannot be skipped on non-linear scopes, namely switch
1697  // scopes, to ensure tests are done in cases like the following:
1698  //   switch (1) { case 0: let x = 2; case 1: f(x); }
1699  // The scope of the variable needs to be checked, in case the use is
1700  // in a sub-block which may be linear.
1701  if (var->scope()->GetDeclarationScope() != scope->GetDeclarationScope()) {
1702    return true;
1703  }
1704
1705  if (var->is_this()) {
1706    DCHECK(
1707        IsSubclassConstructor(scope->GetDeclarationScope()->function_kind()));
1708    // TODO(littledan): implement 'this' hole check elimination.
1709    return true;
1710  }
1711
1712  // We should always have valid source positions.
1713  DCHECK(var->initializer_position() != kNoSourcePosition);
1714  DCHECK(proxy->position() != kNoSourcePosition);
1715
1716  return var->scope()->is_nonlinear() ||
1717         var->initializer_position() >= proxy->position();
1718}
1719
1720}  // anonymous namespace
1721
1722void Scope::ResolveTo(ParseInfo* info, VariableProxy* proxy, Variable* var) {
1723#ifdef DEBUG
1724  if (info->script_is_native()) {
1725    // To avoid polluting the global object in native scripts
1726    //  - Variables must not be allocated to the global scope.
1727    CHECK_NOT_NULL(outer_scope());
1728    //  - Variables must be bound locally or unallocated.
1729    if (var->IsGlobalObjectProperty()) {
1730      // The following variable name may be minified. If so, disable
1731      // minification in js2c.py for better output.
1732      Handle<String> name = proxy->raw_name()->string();
1733      V8_Fatal(__FILE__, __LINE__, "Unbound variable: '%s' in native script.",
1734               name->ToCString().get());
1735    }
1736    VariableLocation location = var->location();
1737    CHECK(location == VariableLocation::LOCAL ||
1738          location == VariableLocation::CONTEXT ||
1739          location == VariableLocation::PARAMETER ||
1740          location == VariableLocation::UNALLOCATED);
1741  }
1742#endif
1743
1744  DCHECK_NOT_NULL(var);
1745  if (proxy->is_assigned()) var->set_maybe_assigned();
1746  if (AccessNeedsHoleCheck(var, proxy, this)) proxy->set_needs_hole_check();
1747  proxy->BindTo(var);
1748}
1749
1750void Scope::ResolveVariablesRecursively(ParseInfo* info) {
1751  DCHECK(info->script_scope()->is_script_scope());
1752
1753  // Resolve unresolved variables for this scope.
1754  for (VariableProxy* proxy = unresolved_; proxy != nullptr;
1755       proxy = proxy->next_unresolved()) {
1756    ResolveVariable(info, proxy);
1757  }
1758
1759  // Resolve unresolved variables for inner scopes.
1760  for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
1761    scope->ResolveVariablesRecursively(info);
1762  }
1763}
1764
1765VariableProxy* Scope::FetchFreeVariables(DeclarationScope* max_outer_scope,
1766                                         bool try_to_resolve, ParseInfo* info,
1767                                         VariableProxy* stack) {
1768  for (VariableProxy *proxy = unresolved_, *next = nullptr; proxy != nullptr;
1769       proxy = next) {
1770    next = proxy->next_unresolved();
1771    DCHECK(!proxy->is_resolved());
1772    Variable* var = nullptr;
1773    if (try_to_resolve) {
1774      var = LookupRecursive(proxy, max_outer_scope->outer_scope());
1775    }
1776    if (var == nullptr) {
1777      proxy->set_next_unresolved(stack);
1778      stack = proxy;
1779    } else if (info != nullptr) {
1780      ResolveTo(info, proxy, var);
1781    } else {
1782      var->set_is_used();
1783    }
1784  }
1785
1786  // Clear unresolved_ as it's in an inconsistent state.
1787  unresolved_ = nullptr;
1788
1789  for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
1790    stack =
1791        scope->FetchFreeVariables(max_outer_scope, try_to_resolve, info, stack);
1792  }
1793
1794  return stack;
1795}
1796
1797bool Scope::MustAllocate(Variable* var) {
1798  DCHECK(var->location() != VariableLocation::MODULE);
1799  // Give var a read/write use if there is a chance it might be accessed
1800  // via an eval() call.  This is only possible if the variable has a
1801  // visible name.
1802  if ((var->is_this() || !var->raw_name()->IsEmpty()) &&
1803      (inner_scope_calls_eval_ || is_catch_scope() || is_script_scope())) {
1804    var->set_is_used();
1805    if (inner_scope_calls_eval_) var->set_maybe_assigned();
1806  }
1807  DCHECK(!var->has_forced_context_allocation() || var->is_used());
1808  // Global variables do not need to be allocated.
1809  return !var->IsGlobalObjectProperty() && var->is_used();
1810}
1811
1812
1813bool Scope::MustAllocateInContext(Variable* var) {
1814  // If var is accessed from an inner scope, or if there is a possibility
1815  // that it might be accessed from the current or an inner scope (through
1816  // an eval() call or a runtime with lookup), it must be allocated in the
1817  // context.
1818  //
1819  // Exceptions: If the scope as a whole has forced context allocation, all
1820  // variables will have context allocation, even temporaries.  Otherwise
1821  // temporary variables are always stack-allocated.  Catch-bound variables are
1822  // always context-allocated.
1823  if (has_forced_context_allocation()) return true;
1824  if (var->mode() == TEMPORARY) return false;
1825  if (is_catch_scope()) return true;
1826  if (is_script_scope() && IsLexicalVariableMode(var->mode())) return true;
1827  return var->has_forced_context_allocation() || inner_scope_calls_eval_;
1828}
1829
1830
1831void Scope::AllocateStackSlot(Variable* var) {
1832  if (is_block_scope()) {
1833    outer_scope()->GetDeclarationScope()->AllocateStackSlot(var);
1834  } else {
1835    var->AllocateTo(VariableLocation::LOCAL, num_stack_slots_++);
1836  }
1837}
1838
1839
1840void Scope::AllocateHeapSlot(Variable* var) {
1841  var->AllocateTo(VariableLocation::CONTEXT, num_heap_slots_++);
1842}
1843
1844void DeclarationScope::AllocateParameterLocals() {
1845  DCHECK(is_function_scope());
1846
1847  bool uses_sloppy_arguments = false;
1848
1849  if (arguments_ != nullptr) {
1850    DCHECK(!is_arrow_scope());
1851    // 'arguments' is used. Unless there is also a parameter called
1852    // 'arguments', we must be conservative and allocate all parameters to
1853    // the context assuming they will be captured by the arguments object.
1854    // If we have a parameter named 'arguments', a (new) value is always
1855    // assigned to it via the function invocation. Then 'arguments' denotes
1856    // that specific parameter value and cannot be used to access the
1857    // parameters, which is why we don't need to allocate an arguments
1858    // object in that case.
1859    if (MustAllocate(arguments_) && !has_arguments_parameter_) {
1860      // In strict mode 'arguments' does not alias formal parameters.
1861      // Therefore in strict mode we allocate parameters as if 'arguments'
1862      // were not used.
1863      // If the parameter list is not simple, arguments isn't sloppy either.
1864      uses_sloppy_arguments =
1865          is_sloppy(language_mode()) && has_simple_parameters();
1866    } else {
1867      // 'arguments' is unused. Tell the code generator that it does not need to
1868      // allocate the arguments object by nulling out arguments_.
1869      arguments_ = nullptr;
1870    }
1871  }
1872
1873  // The same parameter may occur multiple times in the parameters_ list.
1874  // If it does, and if it is not copied into the context object, it must
1875  // receive the highest parameter index for that parameter; thus iteration
1876  // order is relevant!
1877  for (int i = num_parameters() - 1; i >= 0; --i) {
1878    Variable* var = params_[i];
1879    DCHECK(!has_rest_ || var != rest_parameter());
1880    DCHECK_EQ(this, var->scope());
1881    if (uses_sloppy_arguments) {
1882      var->set_is_used();
1883      var->ForceContextAllocation();
1884    }
1885    AllocateParameter(var, i);
1886  }
1887}
1888
1889void DeclarationScope::AllocateParameter(Variable* var, int index) {
1890  if (MustAllocate(var)) {
1891    if (MustAllocateInContext(var)) {
1892      DCHECK(var->IsUnallocated() || var->IsContextSlot());
1893      if (var->IsUnallocated()) {
1894        AllocateHeapSlot(var);
1895      }
1896    } else {
1897      DCHECK(var->IsUnallocated() || var->IsParameter());
1898      if (var->IsUnallocated()) {
1899        var->AllocateTo(VariableLocation::PARAMETER, index);
1900      }
1901    }
1902  }
1903}
1904
1905void DeclarationScope::AllocateReceiver() {
1906  if (!has_this_declaration()) return;
1907  DCHECK_NOT_NULL(receiver());
1908  DCHECK_EQ(receiver()->scope(), this);
1909  AllocateParameter(receiver(), -1);
1910}
1911
1912void Scope::AllocateNonParameterLocal(Variable* var) {
1913  DCHECK(var->scope() == this);
1914  if (var->IsUnallocated() && MustAllocate(var)) {
1915    if (MustAllocateInContext(var)) {
1916      AllocateHeapSlot(var);
1917    } else {
1918      AllocateStackSlot(var);
1919    }
1920  }
1921}
1922
1923void Scope::AllocateNonParameterLocalsAndDeclaredGlobals() {
1924  for (Variable* local : locals_) {
1925    AllocateNonParameterLocal(local);
1926  }
1927
1928  if (is_declaration_scope()) {
1929    AsDeclarationScope()->AllocateLocals();
1930  }
1931}
1932
1933void DeclarationScope::AllocateLocals() {
1934  // For now, function_ must be allocated at the very end.  If it gets
1935  // allocated in the context, it must be the last slot in the context,
1936  // because of the current ScopeInfo implementation (see
1937  // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor).
1938  if (function_ != nullptr) {
1939    AllocateNonParameterLocal(function_);
1940  }
1941
1942  DCHECK(!has_rest_ || !MustAllocate(rest_parameter()) ||
1943         !rest_parameter()->IsUnallocated());
1944
1945  if (new_target_ != nullptr && !MustAllocate(new_target_)) {
1946    new_target_ = nullptr;
1947  }
1948
1949  if (this_function_ != nullptr && !MustAllocate(this_function_)) {
1950    this_function_ = nullptr;
1951  }
1952}
1953
1954void ModuleScope::AllocateModuleVariables() {
1955  for (const auto& it : module()->regular_imports()) {
1956    Variable* var = LookupLocal(it.first);
1957    var->AllocateTo(VariableLocation::MODULE, it.second->cell_index);
1958    DCHECK(!var->IsExport());
1959  }
1960
1961  for (const auto& it : module()->regular_exports()) {
1962    Variable* var = LookupLocal(it.first);
1963    var->AllocateTo(VariableLocation::MODULE, it.second->cell_index);
1964    DCHECK(var->IsExport());
1965  }
1966}
1967
1968void Scope::AllocateVariablesRecursively() {
1969  DCHECK(!already_resolved_);
1970  DCHECK_EQ(0, num_stack_slots_);
1971  // Don't allocate variables of preparsed scopes.
1972  if (is_declaration_scope() && AsDeclarationScope()->is_lazily_parsed()) {
1973    return;
1974  }
1975
1976  // Allocate variables for inner scopes.
1977  for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
1978    scope->AllocateVariablesRecursively();
1979  }
1980
1981  DCHECK(!already_resolved_);
1982  DCHECK_EQ(Context::MIN_CONTEXT_SLOTS, num_heap_slots_);
1983
1984  // Allocate variables for this scope.
1985  // Parameters must be allocated first, if any.
1986  if (is_declaration_scope()) {
1987    if (is_function_scope()) {
1988      AsDeclarationScope()->AllocateParameterLocals();
1989    }
1990    AsDeclarationScope()->AllocateReceiver();
1991  }
1992  AllocateNonParameterLocalsAndDeclaredGlobals();
1993
1994  // Force allocation of a context for this scope if necessary. For a 'with'
1995  // scope and for a function scope that makes an 'eval' call we need a context,
1996  // even if no local variables were statically allocated in the scope.
1997  // Likewise for modules.
1998  bool must_have_context =
1999      is_with_scope() || is_module_scope() ||
2000      (is_function_scope() && calls_sloppy_eval()) ||
2001      (is_block_scope() && is_declaration_scope() && calls_sloppy_eval());
2002
2003  // If we didn't allocate any locals in the local context, then we only
2004  // need the minimal number of slots if we must have a context.
2005  if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && !must_have_context) {
2006    num_heap_slots_ = 0;
2007  }
2008
2009  // Allocation done.
2010  DCHECK(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS);
2011}
2012
2013void Scope::AllocateScopeInfosRecursively(Isolate* isolate,
2014                                          MaybeHandle<ScopeInfo> outer_scope) {
2015  DCHECK(scope_info_.is_null());
2016  MaybeHandle<ScopeInfo> next_outer_scope = outer_scope;
2017
2018  if (NeedsScopeInfo()) {
2019    scope_info_ = ScopeInfo::Create(isolate, zone(), this, outer_scope);
2020    // The ScopeInfo chain should mirror the context chain, so we only link to
2021    // the next outer scope that needs a context.
2022    if (NeedsContext()) next_outer_scope = scope_info_;
2023  }
2024
2025  // Allocate ScopeInfos for inner scopes.
2026  for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
2027    if (!scope->is_function_scope() ||
2028        scope->AsDeclarationScope()->ShouldEagerCompile()) {
2029      scope->AllocateScopeInfosRecursively(isolate, next_outer_scope);
2030    }
2031  }
2032}
2033
2034void Scope::AllocateDebuggerScopeInfos(Isolate* isolate,
2035                                       MaybeHandle<ScopeInfo> outer_scope) {
2036  if (scope_info_.is_null()) {
2037    scope_info_ = ScopeInfo::Create(isolate, zone(), this, outer_scope);
2038  }
2039  MaybeHandle<ScopeInfo> outer = NeedsContext() ? scope_info_ : outer_scope;
2040  for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
2041    if (scope->is_function_scope()) continue;
2042    scope->AllocateDebuggerScopeInfos(isolate, outer);
2043  }
2044}
2045
2046int Scope::StackLocalCount() const {
2047  Variable* function =
2048      is_function_scope() ? AsDeclarationScope()->function_var() : nullptr;
2049  return num_stack_slots() -
2050         (function != nullptr && function->IsStackLocal() ? 1 : 0);
2051}
2052
2053
2054int Scope::ContextLocalCount() const {
2055  if (num_heap_slots() == 0) return 0;
2056  Variable* function =
2057      is_function_scope() ? AsDeclarationScope()->function_var() : nullptr;
2058  bool is_function_var_in_context =
2059      function != nullptr && function->IsContextSlot();
2060  return num_heap_slots() - Context::MIN_CONTEXT_SLOTS -
2061         (is_function_var_in_context ? 1 : 0);
2062}
2063
2064}  // namespace internal
2065}  // namespace v8
2066