scopes.h 32.1 KB
Newer Older
1
// Copyright 2012 the V8 project authors. All rights reserved.
2 3
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
4

5 6
#ifndef V8_AST_SCOPES_H_
#define V8_AST_SCOPES_H_
7

8
#include "src/ast/variables.h"
lpy's avatar
lpy committed
9
#include "src/base/hashmap.h"
yangguo's avatar
yangguo committed
10
#include "src/globals.h"
11
#include "src/zone.h"
12

13 14
namespace v8 {
namespace internal {
15

16 17 18 19
class AstNodeFactory;
class AstValueFactory;
class AstRawString;
class Declaration;
20
class ParseInfo;
21 22
class SloppyBlockFunctionStatement;
class VariableProxy;
23

24
// A hash map to support fast variable declaration and lookup.
25
class VariableMap: public ZoneHashMap {
26
 public:
27
  explicit VariableMap(Zone* zone);
28

verwaest's avatar
verwaest committed
29 30 31
  Variable* Declare(Zone* zone, Scope* scope, const AstRawString* name,
                    VariableMode mode, Variable::Kind kind,
                    InitializationFlag initialization_flag,
32 33
                    MaybeAssignedFlag maybe_assigned_flag = kNotAssigned,
                    bool* added = nullptr);
34

35
  Variable* Lookup(const AstRawString* name);
36 37
  void Remove(Variable* var);
  void Add(Zone* zone, Variable* var);
38 39 40
};


41 42 43 44
// Sloppy block-scoped function declarations to var-bind
class SloppyBlockFunctionMap : public ZoneHashMap {
 public:
  explicit SloppyBlockFunctionMap(Zone* zone);
verwaest's avatar
verwaest committed
45
  void Declare(Zone* zone, const AstRawString* name,
46 47 48
               SloppyBlockFunctionStatement* statement);
};

49
enum class AnalyzeMode { kRegular, kDebugger };
50

51 52 53 54 55 56 57 58 59
// Global invariants after AST construction: Each reference (i.e. identifier)
// to a JavaScript variable (including global properties) is represented by a
// VariableProxy node. Immediately after AST construction and before variable
// allocation, most VariableProxy nodes are "unresolved", i.e. not bound to a
// corresponding variable (though some are bound during parse time). Variable
// allocation binds each unresolved VariableProxy to one Variable and assigns
// a location. Note that many VariableProxy nodes may refer to the same Java-
// Script variable.

60 61 62 63
// JS environments are represented in the parser using Scope, DeclarationScope
// and ModuleScope. DeclarationScope is used for any scope that hosts 'var'
// declarations. This includes script, module, eval, varblock, and function
// scope. ModuleScope further specializes DeclarationScope.
64 65 66 67 68
class Scope: public ZoneObject {
 public:
  // ---------------------------------------------------------------------------
  // Construction

69 70 71 72 73 74 75 76 77 78 79 80 81 82
  Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type);

#ifdef DEBUG
  // The scope name is only used for printing/debugging.
  void SetScopeName(const AstRawString* scope_name) {
    scope_name_ = scope_name;
  }
#endif

  // TODO(verwaest): Is this needed on Scope?
  int num_parameters() const;

  DeclarationScope* AsDeclarationScope();
  const DeclarationScope* AsDeclarationScope() const;
83 84
  ModuleScope* AsModuleScope();
  const ModuleScope* AsModuleScope() const;
85

86 87
  class Snapshot final BASE_EMBEDDED {
   public:
88
    explicit Snapshot(Scope* scope);
89

90
    void Reparent(DeclarationScope* new_parent) const;
91 92 93 94 95

   private:
    Scope* outer_scope_;
    Scope* top_inner_scope_;
    VariableProxy* top_unresolved_;
96 97
    int top_local_;
    int top_decl_;
98 99
  };

100 101
  enum class DeserializationMode { kDeserializeOffHeap, kKeepScopeInfo };

102
  static Scope* DeserializeScopeChain(Isolate* isolate, Zone* zone,
103 104
                                      Context* context,
                                      DeclarationScope* script_scope,
105 106
                                      AstValueFactory* ast_value_factory,
                                      DeserializationMode deserialization_mode);
107

108 109 110 111 112
  // Checks if the block scope is redundant, i.e. it does not contain any
  // block scoped declarations. In that case it is removed from the scope
  // tree and its children are reparented.
  Scope* FinalizeBlockScope();

113
  // Inserts outer_scope into this scope's scope chain (and removes this
114
  // from the current outer_scope_'s inner scope list).
115 116 117
  // Assumes outer_scope_ is non-null.
  void ReplaceOuterScope(Scope* outer_scope);

118 119 120 121
  // Propagates any eagerly-gathered scope usage flags (such as calls_eval())
  // to the passed-in scope.
  void PropagateUsageFlagsToScope(Scope* other);

verwaest's avatar
verwaest committed
122
  Zone* zone() const { return zone_; }
123

124 125 126 127
  // ---------------------------------------------------------------------------
  // Declarations

  // Lookup a variable in this scope. Returns the variable or NULL if not found.
128
  Variable* LookupLocal(const AstRawString* name) {
129 130 131
    Variable* result = variables_.Lookup(name);
    if (result != nullptr || scope_info_.is_null()) return result;
    return LookupInScopeInfo(name);
132 133
  }

134 135
  Variable* LookupInScopeInfo(const AstRawString* name);

136 137
  // Lookup a variable in this scope or outer scopes.
  // Returns the variable or NULL if not found.
138
  Variable* Lookup(const AstRawString* name);
139

140
  // Declare a local variable in this scope. If the variable has been
141
  // declared before, the previously declared variable is returned.
142
  Variable* DeclareLocal(const AstRawString* name, VariableMode mode,
143
                         InitializationFlag init_flag, Variable::Kind kind,
144
                         MaybeAssignedFlag maybe_assigned_flag = kNotAssigned);
145

marja's avatar
marja committed
146 147 148 149 150 151
  Variable* DeclareVariable(Declaration* declaration, VariableMode mode,
                            InitializationFlag init,
                            bool allow_harmony_restrictive_generators,
                            bool* sloppy_mode_block_scope_function_redefinition,
                            bool* ok);

152 153
  // Declarations list.
  ZoneList<Declaration*>* declarations() { return &decls_; }
154

155 156
  ZoneList<Variable*>* locals() { return &locals_; }

157
  // Create a new unresolved variable.
158
  VariableProxy* NewUnresolved(AstNodeFactory* factory,
159
                               const AstRawString* name,
yangguo's avatar
yangguo committed
160
                               int start_position = kNoSourcePosition,
161
                               int end_position = kNoSourcePosition,
162
                               Variable::Kind kind = Variable::NORMAL);
163

164
  void AddUnresolved(VariableProxy* proxy);
165

166 167 168 169 170 171
  // Remove a unresolved variable. During parsing, an unresolved variable
  // may have been added optimistically, but then only the variable name
  // was used (typically for labels). If the variable was not declared, the
  // addition introduced a new unresolved variable which may end up being
  // allocated globally as a "ghost" variable. RemoveUnresolved removes
  // such a variable again if it was added; otherwise this is a no-op.
172
  bool RemoveUnresolved(VariableProxy* var);
173

174 175 176 177 178
  // Creates a new temporary variable in this scope's TemporaryScope.  The
  // name is only used for printing and cannot be used to find the variable.
  // In particular, the only way to get hold of the temporary is by keeping the
  // Variable* around.  The name should not clash with a legitimate variable
  // names.
179
  // TODO(verwaest): Move to DeclarationScope?
180
  Variable* NewTemporary(const AstRawString* name);
181 182 183 184

  // ---------------------------------------------------------------------------
  // Illegal redeclaration support.

185
  // Check if the scope has conflicting var
186 187 188
  // declarations, i.e. a var declaration that has been hoisted from a nested
  // scope over a let binding of the same name.
  Declaration* CheckConflictingVarDeclarations();
189

190 191 192 193 194 195 196 197
  // Check if the scope has a conflicting lexical declaration that has a name in
  // the given list. This is used to catch patterns like
  // `try{}catch(e){let e;}`,
  // which is an error even though the two 'e's are declared in different
  // scopes.
  Declaration* CheckLexDeclarationsConflictingWith(
      const ZoneList<const AstRawString*>& names);

198 199 200
  // ---------------------------------------------------------------------------
  // Scope-specific info.

201 202 203 204 205 206 207 208
  // Inform the scope and outer scopes that the corresponding code contains an
  // eval call.
  void RecordEvalCall() {
    scope_calls_eval_ = true;
    for (Scope* scope = this; scope != nullptr; scope = scope->outer_scope()) {
      scope->inner_scope_calls_eval_ = true;
    }
  }
209

210 211
  // Set the language mode flag (unless disabled by a global flag).
  void SetLanguageMode(LanguageMode language_mode) {
212
    DCHECK(!is_module_scope() || is_strict(language_mode));
213
    set_language_mode(language_mode);
214
  }
215

216 217 218 219 220 221 222 223 224 225 226
  // Inform the scope that the scope may execute declarations nonlinearly.
  // Currently, the only nonlinear scope is a switch statement. The name is
  // more general in case something else comes up with similar control flow,
  // for example the ability to break out of something which does not have
  // its own lexical scope.
  // The bit does not need to be stored on the ScopeInfo because none of
  // the three compilers will perform hole check elimination on a variable
  // located in VariableLocation::CONTEXT. So, direct eval and closures
  // will not expose holes.
  void SetNonlinear() { scope_nonlinear_ = true; }

227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248
  // Position in the source where this scope begins and ends.
  //
  // * For the scope of a with statement
  //     with (obj) stmt
  //   start position: start position of first token of 'stmt'
  //   end position: end position of last token of 'stmt'
  // * For the scope of a block
  //     { stmts }
  //   start position: start position of '{'
  //   end position: end position of '}'
  // * For the scope of a function literal or decalaration
  //     function fun(a,b) { stmts }
  //   start position: start position of '('
  //   end position: end position of '}'
  // * For the scope of a catch block
  //     try { stms } catch(e) { stmts }
  //   start position: start position of '('
  //   end position: end position of ')'
  // * For the scope of a for-statement
  //     for (let x ...) stmt
  //   start position: start position of '('
  //   end position: end position of last token of 'stmt'
249 250 251 252
  // * For the scope of a switch statement
  //     switch (tag) { cases }
  //   start position: start position of '{'
  //   end position: end position of '}'
253 254 255 256 257 258 259 260 261
  int start_position() const { return start_position_; }
  void set_start_position(int statement_pos) {
    start_position_ = statement_pos;
  }
  int end_position() const { return end_position_; }
  void set_end_position(int statement_pos) {
    end_position_ = statement_pos;
  }

262 263 264 265
  // Scopes created for desugaring are hidden. I.e. not visible to the debugger.
  bool is_hidden() const { return is_hidden_; }
  void set_is_hidden() { is_hidden_ = true; }

266 267
  // In some cases we want to force context allocation for a whole scope.
  void ForceContextAllocation() {
268
    DCHECK(!already_resolved_);
269 270 271 272 273 274
    force_context_allocation_ = true;
  }
  bool has_forced_context_allocation() const {
    return force_context_allocation_;
  }

275 276 277 278
  // ---------------------------------------------------------------------------
  // Predicates.

  // Specific scope types.
279
  bool is_eval_scope() const { return scope_type_ == EVAL_SCOPE; }
280
  bool is_function_scope() const { return scope_type_ == FUNCTION_SCOPE; }
281
  bool is_module_scope() const { return scope_type_ == MODULE_SCOPE; }
282
  bool is_script_scope() const { return scope_type_ == SCRIPT_SCOPE; }
283 284 285
  bool is_catch_scope() const { return scope_type_ == CATCH_SCOPE; }
  bool is_block_scope() const { return scope_type_ == BLOCK_SCOPE; }
  bool is_with_scope() const { return scope_type_ == WITH_SCOPE; }
286
  bool is_declaration_scope() const { return is_declaration_scope_; }
287

288
  // Information about which scopes calls eval.
289
  bool calls_eval() const { return scope_calls_eval_; }
290
  bool calls_sloppy_eval() const {
291
    return scope_calls_eval_ && is_sloppy(language_mode());
292
  }
293 294
  bool IsAsmModule() const;
  bool IsAsmFunction() const;
295 296
  // Does this scope have the potential to execute declarations non-linearly?
  bool is_nonlinear() const { return scope_nonlinear_; }
297

298
  // Whether this needs to be represented by a runtime context.
299
  bool NeedsContext() const {
300
    // Catch scopes always have heap slots.
301
    DCHECK(!is_catch_scope() || num_heap_slots() > 0);
302
    return num_heap_slots() > 0;
303
  }
304

305 306 307
  // ---------------------------------------------------------------------------
  // Accessors.

308
  // The type of this scope.
309
  ScopeType scope_type() const { return scope_type_; }
310

311
  // The language mode of this scope.
312
  LanguageMode language_mode() const { return is_strict_ ? STRICT : SLOPPY; }
313

314 315 316 317 318
  // inner_scope() and sibling() together implement the inner scope list of a
  // scope. Inner scope points to the an inner scope of the function, and
  // "sibling" points to a next inner scope of the outer scope of this scope.
  Scope* inner_scope() const { return inner_scope_; }
  Scope* sibling() const { return sibling_; }
319

320 321 322
  // The scope immediately surrounding this scope, or NULL.
  Scope* outer_scope() const { return outer_scope_; }

323 324
  const AstRawString* catch_variable_name() const {
    DCHECK(is_catch_scope());
325
    DCHECK_EQ(1, num_var());
326 327 328
    return static_cast<AstRawString*>(variables_.Start()->key);
  }

329 330 331 332
  // ---------------------------------------------------------------------------
  // Variable allocation.

  // Result of variable allocation.
333 334
  int num_stack_slots() const { return num_stack_slots_; }
  int num_heap_slots() const { return num_heap_slots_; }
335

336 337 338
  int StackLocalCount() const;
  int ContextLocalCount() const;

339 340 341
  // Determine if we can parse a function literal in this scope lazily.
  bool AllowsLazyParsing() const;

342
  // The number of contexts between this and scope; zero if this == scope.
343 344 345 346 347
  int ContextChainLength(Scope* scope) const;

  // The number of contexts between this and the outermost context that has a
  // sloppy eval call. One if this->calls_sloppy_eval().
  int ContextChainLengthUntilOutermostSloppyEval() const;
348

349 350 351 352
  // The maximum number of nested contexts required for this scope and any inner
  // scopes.
  int MaxNestedContextChainLength();

353 354
  // Find the first function, script, eval or (declaration) block scope. This is
  // the scope where var declarations will be hoisted to in the implementation.
355
  DeclarationScope* GetDeclarationScope();
356

357
  // Find the first non-block declaration scope. This should be either a script,
358 359 360 361 362
  // function, or eval scope. Same as DeclarationScope(), but skips declaration
  // "block" scopes. Used for differentiating associated function objects (i.e.,
  // the scope for which a function prologue allocates a context) or declaring
  // temporaries.
  DeclarationScope* GetClosureScope();
363

364 365
  // Find the first (non-arrow) function or script scope.  This is where
  // 'this' is bound, and what determines the function kind.
366
  DeclarationScope* GetReceiverScope();
367

368
  // Analyze() must have been called once to create the ScopeInfo.
369 370 371 372 373
  Handle<ScopeInfo> scope_info() {
    DCHECK(!scope_info_.is_null());
    return scope_info_;
  }

374 375
  // ---------------------------------------------------------------------------
  // Strict mode support.
376
  bool IsDeclared(const AstRawString* name) {
377 378 379 380 381 382 383 384
    // During formal parameter list parsing the scope only contains
    // two variables inserted at initialization: "this" and "arguments".
    // "this" is an invalid parameter name and "arguments" is invalid parameter
    // name in strict mode. Therefore looking up with the map which includes
    // "this" and "arguments" in addition to all formal parameters is safe.
    return variables_.Lookup(name) != NULL;
  }

385 386
  int num_var() const { return variables_.occupancy(); }

387 388 389 390 391
  // ---------------------------------------------------------------------------
  // Debugging.

#ifdef DEBUG
  void Print(int n = 0);  // n = indentation; n < 0 => don't print recursively
392 393 394

  // Check that the scope has positions assigned.
  void CheckScopePositions();
395 396 397

  // Check that all Scopes in the scope tree use the same Zone.
  void CheckZones();
398 399
#endif

400 401
  // Retrieve `IsSimpleParameterList` of current or outer function.
  bool HasSimpleParameters();
402
  void set_is_debug_evaluate_scope() { is_debug_evaluate_scope_ = true; }
403

404
 protected:
405
  explicit Scope(Zone* zone);
406

407
  void set_language_mode(LanguageMode language_mode) {
408
    is_strict_ = is_strict(language_mode);
409 410
  }

411
 private:
412 413 414 415 416 417 418 419
  Variable* Declare(Zone* zone, Scope* scope, const AstRawString* name,
                    VariableMode mode, Variable::Kind kind,
                    InitializationFlag initialization_flag,
                    MaybeAssignedFlag maybe_assigned_flag = kNotAssigned) {
    bool added;
    Variable* var =
        variables_.Declare(zone, scope, name, mode, kind, initialization_flag,
                           maybe_assigned_flag, &added);
420
    if (added) locals_.Add(var, zone);
421 422
    return var;
  }
423 424 425 426 427 428 429 430 431 432 433

  // This method should only be invoked on scopes created during parsing (i.e.,
  // not deserialized from a context). Also, since NeedsContext() is only
  // returning a valid result after variables are resolved, NeedsScopeInfo()
  // should also be invoked after resolution.
  bool NeedsScopeInfo() const {
    DCHECK(!already_resolved_);
    return NeedsContext() || is_script_scope() || is_function_scope() ||
           is_eval_scope() || is_module_scope();
  }

verwaest's avatar
verwaest committed
434 435
  Zone* zone_;

436 437
  // Scope tree.
  Scope* outer_scope_;  // the immediately enclosing outer scope, or NULL
438 439
  Scope* inner_scope_;  // an inner scope of this scope
  Scope* sibling_;  // a sibling inner scope of the outer scope of this scope.
440 441

  // The variables declared in this scope:
442
  //
443
  // All user-declared variables (incl. parameters).  For script scopes
444 445 446
  // variables may be implicitly 'declared' by being used (possibly in
  // an inner scope) with no intervening with statements or eval calls.
  VariableMap variables_;
447 448 449
  // In case of non-scopeinfo-backed scopes, this contains the variables of the
  // map above in order of addition.
  // TODO(verwaest): Thread through Variable.
450
  ZoneList<Variable*> locals_;
451 452 453
  // Unresolved variables referred to from this scope. The proxies themselves
  // form a linked list of all unresolved proxies.
  VariableProxy* unresolved_;
454
  // Declarations.
455 456
  ZoneList<Declaration*> decls_;

457 458 459 460 461
  // Serialized scope info support.
  Handle<ScopeInfo> scope_info_;
// Debugging support.
#ifdef DEBUG
  const AstRawString* scope_name_;
462 463 464 465

  // True if it doesn't need scope resolution (e.g., if the scope was
  // constructed based on a serialized scope info or a catch context).
  bool already_resolved_ : 1;
466 467 468 469 470 471
#endif

  // Source positions.
  int start_position_;
  int end_position_;

neis's avatar
neis committed
472
  // Computed via AllocateVariables.
473 474
  int num_stack_slots_;
  int num_heap_slots_;
475

476 477 478
  // The scope type.
  const ScopeType scope_type_;

479 480
  // Scope-specific information computed during parsing.
  //
481
  // The language mode of this scope.
482 483
  STATIC_ASSERT(LANGUAGE_END == 2);
  bool is_strict_ : 1;
484 485
  // This scope or a nested catch scope or with scope contain an 'eval' call. At
  // the 'eval' call site this scope is the declaration scope.
486
  bool scope_calls_eval_ : 1;
487
  // This scope's declarations might not be executed in order (e.g., switch).
488 489
  bool scope_nonlinear_ : 1;
  bool is_hidden_ : 1;
490 491
  // Temporary workaround that allows masking of 'this' in debug-evalute scopes.
  bool is_debug_evaluate_scope_ : 1;
492

493 494
  bool inner_scope_calls_eval_ : 1;
  bool force_context_allocation_ : 1;
495

496
  // True if it holds 'var' declarations.
497
  bool is_declaration_scope_ : 1;
498

499 500
  // Create a non-local variable with a given name.
  // These variables are looked up dynamically at runtime.
501
  Variable* NonLocal(const AstRawString* name, VariableMode mode);
502 503

  // Variable resolution.
504
  // Lookup a variable reference given by name recursively starting with this
verwaest's avatar
verwaest committed
505
  // scope, and stopping when reaching the outer_scope_end scope. If the code is
506 507
  // executed because of a call to 'eval', the context parameter should be set
  // to the calling context of 'eval'.
508 509 510 511 512 513 514 515
  // {declare_free} indicates whether nullptr should be returned for free
  // variables when falling off outer_scope_end, or whether they should be
  // declared automatically as non-locals.
  Variable* LookupRecursive(VariableProxy* proxy, bool declare_free,
                            Scope* outer_scope_end);
  void ResolveTo(ParseInfo* info, VariableProxy* proxy, Variable* var);
  void ResolveVariable(ParseInfo* info, VariableProxy* proxy);
  void ResolveVariablesRecursively(ParseInfo* info);
516

verwaest's avatar
verwaest committed
517 518 519 520 521 522
  // Finds free variables of this scope. This mutates the unresolved variables
  // list along the way, so full resolution cannot be done afterwards.
  // If a ParseInfo* is passed, non-free variables will be resolved.
  VariableProxy* FetchFreeVariables(DeclarationScope* max_outer_scope,
                                    ParseInfo* info = nullptr,
                                    VariableProxy* stack = nullptr);
523

524 525 526 527 528 529 530
  // Predicates.
  bool MustAllocate(Variable* var);
  bool MustAllocateInContext(Variable* var);

  // Variable allocation.
  void AllocateStackSlot(Variable* var);
  void AllocateHeapSlot(Variable* var);
531 532 533 534
  void AllocateNonParameterLocal(Variable* var);
  void AllocateDeclaredGlobal(Variable* var);
  void AllocateNonParameterLocalsAndDeclaredGlobals();
  void AllocateVariablesRecursively();
535

536
  void AllocateScopeInfosRecursively(Isolate* isolate, AnalyzeMode mode);
537

538
  // Construct a scope based on the scope info.
539
  Scope(Zone* zone, ScopeType type, Handle<ScopeInfo> scope_info);
540

541
  // Construct a catch scope with a binding for the name.
542 543
  Scope(Zone* zone, const AstRawString* catch_variable_name,
        Handle<ScopeInfo> scope_info);
544

545
  void AddInnerScope(Scope* inner_scope) {
546 547 548
    inner_scope->sibling_ = inner_scope_;
    inner_scope_ = inner_scope;
    inner_scope->outer_scope_ = this;
549 550
  }

551 552
  void RemoveInnerScope(Scope* inner_scope) {
    DCHECK_NOT_NULL(inner_scope);
553 554 555 556 557 558 559 560 561
    if (inner_scope == inner_scope_) {
      inner_scope_ = inner_scope_->sibling_;
      return;
    }
    for (Scope* scope = inner_scope_; scope != nullptr;
         scope = scope->sibling_) {
      if (scope->sibling_ == inner_scope) {
        scope->sibling_ = scope->sibling_->sibling_;
        return;
562 563 564 565
      }
    }
  }

566
  void SetDefaults();
567

568 569 570
  void DeserializeScopeInfo(Isolate* isolate,
                            AstValueFactory* ast_value_factory);

571 572 573 574 575 576 577
  friend class DeclarationScope;
};

class DeclarationScope : public Scope {
 public:
  DeclarationScope(Zone* zone, Scope* outer_scope, ScopeType scope_type,
                   FunctionKind function_kind = kNormalFunction);
578
  DeclarationScope(Zone* zone, ScopeType scope_type,
579
                   Handle<ScopeInfo> scope_info);
580
  // Creates a script scope.
581
  DeclarationScope(Zone* zone, AstValueFactory* ast_value_factory);
582 583 584 585 586 587 588 589 590 591 592 593 594 595

  bool IsDeclaredParameter(const AstRawString* name) {
    // If IsSimpleParameterList is false, duplicate parameters are not allowed,
    // however `arguments` may be allowed if function is not strict code. Thus,
    // the assumptions explained above do not hold.
    return params_.Contains(variables_.Lookup(name));
  }

  FunctionKind function_kind() const { return function_kind_; }

  bool is_arrow_scope() const {
    return is_function_scope() && IsArrowFunction(function_kind_);
  }

596 597 598 599 600
  // Inform the scope that the corresponding code uses "super".
  void RecordSuperPropertyUsage() { scope_uses_super_property_ = true; }
  // Does this scope access "super" property (super.foo).
  bool uses_super_property() const { return scope_uses_super_property_; }

601 602
  bool NeedsHomeObject() const {
    return scope_uses_super_property_ ||
603 604 605
           (inner_scope_calls_eval_ && (IsConciseMethod(function_kind()) ||
                                        IsAccessorFunction(function_kind()) ||
                                        IsClassConstructor(function_kind())));
606 607
  }

608 609 610 611 612 613
  void SetScriptScopeInfo(Handle<ScopeInfo> scope_info) {
    DCHECK(is_script_scope());
    DCHECK(scope_info_.is_null());
    scope_info_ = scope_info;
  }

614
  bool asm_module() const { return asm_module_; }
615
  void set_asm_module();
616 617 618
  bool asm_function() const { return asm_function_; }
  void set_asm_function() { asm_module_ = true; }

619 620 621 622 623 624 625
  void DeclareThis(AstValueFactory* ast_value_factory);
  void DeclareDefaultFunctionVariables(AstValueFactory* ast_value_factory);

  // This lookup corresponds to a lookup in the "intermediate" scope sitting
  // between this scope and the outer scope. (ECMA-262, 3rd., requires that
  // the name of named function literal is kept in an intermediate scope
  // in between this scope and the next outer scope.)
626
  Variable* LookupFunctionVar(const AstRawString* name);
627 628 629 630

  // Declare the function variable for a function literal. This variable
  // is in an intermediate scope between this function scope and the the
  // outer scope. Only possible for function scopes; at most one variable.
631
  Variable* DeclareFunctionVar(const AstRawString* name);
632 633 634 635 636 637 638 639 640 641 642 643

  // Declare a parameter in this scope.  When there are duplicated
  // parameters the rightmost one 'wins'.  However, the implementation
  // expects all parameters to be declared and from left to right.
  Variable* DeclareParameter(const AstRawString* name, VariableMode mode,
                             bool is_optional, bool is_rest, bool* is_duplicate,
                             AstValueFactory* ast_value_factory);

  // Declare an implicit global variable in this scope which must be a
  // script scope.  The variable was introduced (possibly from an inner
  // scope) by a reference to an unresolved variable with no intervening
  // with statements or eval calls.
644 645
  Variable* DeclareDynamicGlobal(const AstRawString* name,
                                 Variable::Kind variable_kind);
646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665

  // The variable corresponding to the 'this' value.
  Variable* receiver() {
    DCHECK(has_this_declaration());
    DCHECK_NOT_NULL(receiver_);
    return receiver_;
  }

  // TODO(wingo): Add a GLOBAL_SCOPE scope type which will lexically allocate
  // "this" (and no other variable) on the native context.  Script scopes then
  // will not have a "this" declaration.
  bool has_this_declaration() const {
    return (is_function_scope() && !is_arrow_scope()) || is_module_scope();
  }

  // The variable corresponding to the 'new.target' value.
  Variable* new_target_var() { return new_target_; }

  // The variable holding the function literal for named function
  // literals, or NULL.  Only valid for function scopes.
666
  Variable* function_var() const {
667 668 669 670 671 672 673 674 675 676 677 678 679 680
    DCHECK(is_function_scope());
    return function_;
  }

  // Parameters. The left-most parameter has index 0.
  // Only valid for function scopes.
  Variable* parameter(int index) const {
    DCHECK(is_function_scope());
    return params_[index];
  }

  // Returns the default function arity excluding default or rest parameters.
  int default_function_length() const { return arity_; }

681 682 683 684 685
  // Returns the number of formal parameters, excluding a possible rest
  // parameter.  Examples:
  //   function foo(a, b) {}         ==> 2
  //   function foo(a, b, ...c) {}   ==> 2
  //   function foo(a, b, c = 1) {}  ==> 3
686
  int num_parameters() const {
687
    return has_rest_ ? params_.length() - 1 : params_.length();
688 689
  }

690
  // The function's rest parameter (nullptr if there is none).
691
  Variable* rest_parameter() const {
692
    return has_rest_ ? params_[params_.length() - 1] : nullptr;
693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721
  }

  bool has_simple_parameters() const { return has_simple_parameters_; }

  // TODO(caitp): manage this state in a better way. PreParser must be able to
  // communicate that the scope is non-simple, without allocating any parameters
  // as the Parser does. This is necessary to ensure that TC39's proposed early
  // error can be reported consistently regardless of whether lazily parsed or
  // not.
  void SetHasNonSimpleParameters() {
    DCHECK(is_function_scope());
    has_simple_parameters_ = false;
  }

  // The local variable 'arguments' if we need to allocate it; NULL otherwise.
  Variable* arguments() const {
    DCHECK(!is_arrow_scope() || arguments_ == nullptr);
    return arguments_;
  }

  Variable* this_function_var() const {
    // This is only used in derived constructors atm.
    DCHECK(this_function_ == nullptr ||
           (is_function_scope() && (IsClassConstructor(function_kind()) ||
                                    IsConciseMethod(function_kind()) ||
                                    IsAccessorFunction(function_kind()))));
    return this_function_;
  }

722 723
  // Adds a local variable in this scope's locals list. This is for adjusting
  // the scope of temporaries and do-expression vars when desugaring parameter
724
  // initializers.
725
  void AddLocal(Variable* var) {
726
    DCHECK(!already_resolved_);
727 728
    // Temporaries are only placed in ClosureScopes.
    DCHECK_EQ(GetClosureScope(), this);
729
    locals_.Add(var, zone());
730 731
  }

verwaest's avatar
verwaest committed
732 733 734 735 736
  void DeclareSloppyBlockFunction(const AstRawString* name,
                                  SloppyBlockFunctionStatement* statement) {
    sloppy_block_function_map_.Declare(zone(), name, statement);
  }

737 738 739 740
  SloppyBlockFunctionMap* sloppy_block_function_map() {
    return &sloppy_block_function_map_;
  }

741 742 743
  // Compute top scope and allocate variables. For lazy compilation the top
  // scope only contains the single lazily compiled function, so this
  // doesn't re-allocate variables repeatedly.
744
  static void Analyze(ParseInfo* info, AnalyzeMode mode);
745 746 747 748 749 750 751 752 753

  // To be called during parsing. Do just enough scope analysis that we can
  // discard the Scope for lazily compiled functions. In particular, this
  // records variables which cannot be resolved inside the Scope (we don't yet
  // know what they will resolve to since the outer Scopes are incomplete) and
  // migrates them into migrate_to.
  void AnalyzePartially(DeclarationScope* migrate_to,
                        AstNodeFactory* ast_node_factory);

verwaest's avatar
verwaest committed
754 755 756
  Handle<StringSet> CollectNonLocals(ParseInfo* info,
                                     Handle<StringSet> non_locals);

757 758 759 760 761 762 763 764 765 766 767 768 769 770 771
  // Determine if we can use lazy compilation for this scope.
  bool AllowsLazyCompilation() const;

  // Determine if we can use lazy compilation for this scope without a context.
  bool AllowsLazyCompilationWithoutContext() const;

  // Make sure this closure and all outer closures are eagerly compiled.
  void ForceEagerCompilation() {
    DCHECK_EQ(this, GetClosureScope());
    for (DeclarationScope* s = this; !s->is_script_scope();
         s = s->outer_scope()->GetClosureScope()) {
      s->force_eager_compilation_ = true;
    }
  }

772 773 774 775
#ifdef DEBUG
  void PrintParameters();
#endif

776
  void AllocateLocals();
777 778 779 780 781 782
  void AllocateParameterLocals();
  void AllocateReceiver();

 private:
  void AllocateParameter(Variable* var, int index);

783 784 785 786 787 788 789 790
  // Resolve and fill in the allocation information for all variables
  // in this scopes. Must be called *after* all scopes have been
  // processed (parsed) to ensure that unresolved variables can be
  // resolved properly.
  //
  // In the case of code compiled and run using 'eval', the context
  // parameter is the context in which eval was called.  In all other
  // cases the context parameter is an empty handle.
791
  void AllocateVariables(ParseInfo* info, AnalyzeMode mode);
792

793 794 795 796 797 798
  void SetDefaults();

  // If the scope is a function scope, this is the function kind.
  const FunctionKind function_kind_;

  bool has_simple_parameters_ : 1;
799 800 801 802
  // This scope contains an "use asm" annotation.
  bool asm_module_ : 1;
  // This scope's outer context is an asm module.
  bool asm_function_ : 1;
803
  bool force_eager_compilation_ : 1;
804 805
  // This function scope has a rest parameter.
  bool has_rest_ : 1;
806 807
  // This scope has a parameter called "arguments".
  bool has_arguments_parameter_ : 1;
808 809
  // This scope uses "super" property ('super.foo').
  bool scope_uses_super_property_ : 1;
810 811 812 813 814 815 816 817 818 819

  // Info about the parameter list of a function.
  int arity_;
  // Parameter list in source order.
  ZoneList<Variable*> params_;
  // Map of function names to lists of functions defined in sloppy blocks
  SloppyBlockFunctionMap sloppy_block_function_map_;
  // Convenience variable.
  Variable* receiver_;
  // Function variable, if any; function scopes only.
820
  Variable* function_;
821 822 823 824 825 826
  // new.target variable, function scopes only.
  Variable* new_target_;
  // Convenience variable; function scopes only.
  Variable* arguments_;
  // Convenience variable; Subclass constructor only
  Variable* this_function_;
827 828 829 830
};

class ModuleScope final : public DeclarationScope {
 public:
831
  ModuleScope(DeclarationScope* script_scope,
832
              AstValueFactory* ast_value_factory);
833 834
  ModuleScope(Isolate* isolate, Handle<ScopeInfo> scope_info,
              AstValueFactory* ast_value_factory);
835 836 837 838 839 840 841 842 843 844 845

  ModuleDescriptor* module() const {
    DCHECK_NOT_NULL(module_descriptor_);
    return module_descriptor_;
  }

  // Set MODULE as VariableLocation for all variables that will live in some
  // module's export table.
  void AllocateModuleVariables();

 private:
846
  ModuleDescriptor* module_descriptor_;
847 848
};

849 850
}  // namespace internal
}  // namespace v8
851

852
#endif  // V8_AST_SCOPES_H_