• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef V8_AST_SCOPES_H_
6 #define V8_AST_SCOPES_H_
7 
8 #include "src/ast/ast.h"
9 #include "src/base/compiler-specific.h"
10 #include "src/base/hashmap.h"
11 #include "src/globals.h"
12 #include "src/objects.h"
13 #include "src/zone/zone.h"
14 
15 namespace v8 {
16 namespace internal {
17 
18 class AstNodeFactory;
19 class AstValueFactory;
20 class AstRawString;
21 class Declaration;
22 class ParseInfo;
23 class PreParsedScopeData;
24 class ProducedPreParsedScopeData;
25 class SloppyBlockFunctionStatement;
26 class Statement;
27 class StringSet;
28 class VariableProxy;
29 
30 // A hash map to support fast variable declaration and lookup.
31 class VariableMap: public ZoneHashMap {
32  public:
33   explicit VariableMap(Zone* zone);
34 
35   Variable* Declare(
36       Zone* zone, Scope* scope, const AstRawString* name, VariableMode mode,
37       VariableKind kind = NORMAL_VARIABLE,
38       InitializationFlag initialization_flag = kCreatedInitialized,
39       MaybeAssignedFlag maybe_assigned_flag = kNotAssigned,
40       bool* added = nullptr);
41 
42   // Records that "name" exists (if not recorded yet) but doesn't create a
43   // Variable. Useful for preparsing.
44   Variable* DeclareName(Zone* zone, const AstRawString* name,
45                         VariableMode mode);
46 
47   Variable* Lookup(const AstRawString* name);
48   void Remove(Variable* var);
49   void Add(Zone* zone, Variable* var);
50 };
51 
52 
53 // Sloppy block-scoped function declarations to var-bind
54 class SloppyBlockFunctionMap : public ZoneHashMap {
55  public:
56   class Delegate : public ZoneObject {
57    public:
Delegate(Scope * scope,SloppyBlockFunctionStatement * statement,int index)58     Delegate(Scope* scope, SloppyBlockFunctionStatement* statement, int index)
59         : scope_(scope), statement_(statement), next_(nullptr), index_(index) {}
60     void set_statement(Statement* statement);
set_next(Delegate * next)61     void set_next(Delegate* next) { next_ = next; }
next()62     Delegate* next() const { return next_; }
scope()63     Scope* scope() const { return scope_; }
index()64     int index() const { return index_; }
65 
66    private:
67     Scope* scope_;
68     SloppyBlockFunctionStatement* statement_;
69     Delegate* next_;
70     int index_;
71   };
72 
73   explicit SloppyBlockFunctionMap(Zone* zone);
74   void Declare(Zone* zone, const AstRawString* name, Scope* scope,
75                SloppyBlockFunctionStatement* statement);
76 
77  private:
78   int count_;
79 };
80 
81 // Global invariants after AST construction: Each reference (i.e. identifier)
82 // to a JavaScript variable (including global properties) is represented by a
83 // VariableProxy node. Immediately after AST construction and before variable
84 // allocation, most VariableProxy nodes are "unresolved", i.e. not bound to a
85 // corresponding variable (though some are bound during parse time). Variable
86 // allocation binds each unresolved VariableProxy to one Variable and assigns
87 // a location. Note that many VariableProxy nodes may refer to the same Java-
88 // Script variable.
89 
90 // JS environments are represented in the parser using Scope, DeclarationScope
91 // and ModuleScope. DeclarationScope is used for any scope that hosts 'var'
92 // declarations. This includes script, module, eval, varblock, and function
93 // scope. ModuleScope further specializes DeclarationScope.
NON_EXPORTED_BASE(ZoneObject)94 class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) {
95  public:
96   // ---------------------------------------------------------------------------
97   // Construction
98 
99   Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type);
100 
101 #ifdef DEBUG
102   // The scope name is only used for printing/debugging.
103   void SetScopeName(const AstRawString* scope_name) {
104     scope_name_ = scope_name;
105   }
106   void set_needs_migration() { needs_migration_ = true; }
107 #endif
108 
109   // TODO(verwaest): Is this needed on Scope?
110   int num_parameters() const;
111 
112   DeclarationScope* AsDeclarationScope();
113   const DeclarationScope* AsDeclarationScope() const;
114   ModuleScope* AsModuleScope();
115   const ModuleScope* AsModuleScope() const;
116 
117   class Snapshot final BASE_EMBEDDED {
118    public:
119     explicit Snapshot(Scope* scope);
120     ~Snapshot();
121 
122     void Reparent(DeclarationScope* new_parent) const;
123 
124    private:
125     Scope* outer_scope_;
126     Scope* top_inner_scope_;
127     VariableProxy* top_unresolved_;
128     ThreadedList<Variable>::Iterator top_local_;
129     ThreadedList<Declaration>::Iterator top_decl_;
130     const bool outer_scope_calls_eval_;
131   };
132 
133   enum class DeserializationMode { kIncludingVariables, kScopesOnly };
134 
135   static Scope* DeserializeScopeChain(Isolate* isolate, Zone* zone,
136                                       ScopeInfo* scope_info,
137                                       DeclarationScope* script_scope,
138                                       AstValueFactory* ast_value_factory,
139                                       DeserializationMode deserialization_mode);
140 
141   // Checks if the block scope is redundant, i.e. it does not contain any
142   // block scoped declarations. In that case it is removed from the scope
143   // tree and its children are reparented.
144   Scope* FinalizeBlockScope();
145 
146   bool HasBeenRemoved() const;
147 
148   // Find the first scope that hasn't been removed.
149   Scope* GetUnremovedScope();
150 
151   // Inserts outer_scope into this scope's scope chain (and removes this
152   // from the current outer_scope_'s inner scope list).
153   // Assumes outer_scope_ is non-null.
154   void ReplaceOuterScope(Scope* outer_scope);
155 
156   Zone* zone() const { return zone_; }
157 
158   void SetMustUsePreParsedScopeData() {
159     if (must_use_preparsed_scope_data_) {
160       return;
161     }
162     must_use_preparsed_scope_data_ = true;
163     if (outer_scope_) {
164       outer_scope_->SetMustUsePreParsedScopeData();
165     }
166   }
167 
168   bool must_use_preparsed_scope_data() const {
169     return must_use_preparsed_scope_data_;
170   }
171 
172   // ---------------------------------------------------------------------------
173   // Declarations
174 
175   // Lookup a variable in this scope. Returns the variable or nullptr if not
176   // found.
177   Variable* LookupLocal(const AstRawString* name) {
178     Variable* result = variables_.Lookup(name);
179     if (result != nullptr || scope_info_.is_null()) return result;
180     return LookupInScopeInfo(name);
181   }
182 
183   Variable* LookupInScopeInfo(const AstRawString* name);
184 
185   // Lookup a variable in this scope or outer scopes.
186   // Returns the variable or nullptr if not found.
187   Variable* Lookup(const AstRawString* name);
188 
189   // Declare a local variable in this scope. If the variable has been
190   // declared before, the previously declared variable is returned.
191   Variable* DeclareLocal(const AstRawString* name, VariableMode mode,
192                          InitializationFlag init_flag = kCreatedInitialized,
193                          VariableKind kind = NORMAL_VARIABLE,
194                          MaybeAssignedFlag maybe_assigned_flag = kNotAssigned);
195 
196   Variable* DeclareVariable(Declaration* declaration, VariableMode mode,
197                             InitializationFlag init,
198                             bool* sloppy_mode_block_scope_function_redefinition,
199                             bool* ok);
200 
201   // The return value is meaningful only if FLAG_preparser_scope_analysis is on.
202   Variable* DeclareVariableName(const AstRawString* name, VariableMode mode);
203   void DeclareCatchVariableName(const AstRawString* name);
204 
205   // Declarations list.
206   ThreadedList<Declaration>* declarations() { return &decls_; }
207 
208   ThreadedList<Variable>* locals() { return &locals_; }
209 
210   // Create a new unresolved variable.
211   VariableProxy* NewUnresolved(AstNodeFactory* factory,
212                                const AstRawString* name,
213                                int start_pos = kNoSourcePosition,
214                                VariableKind kind = NORMAL_VARIABLE) {
215     // Note that we must not share the unresolved variables with
216     // the same name because they may be removed selectively via
217     // RemoveUnresolved().
218     DCHECK(!already_resolved_);
219     DCHECK_EQ(factory->zone(), zone());
220     VariableProxy* proxy = factory->NewVariableProxy(name, kind, start_pos);
221     proxy->set_next_unresolved(unresolved_);
222     unresolved_ = proxy;
223     return proxy;
224   }
225 
226   void AddUnresolved(VariableProxy* proxy);
227 
228   // Remove a unresolved variable. During parsing, an unresolved variable
229   // may have been added optimistically, but then only the variable name
230   // was used (typically for labels). If the variable was not declared, the
231   // addition introduced a new unresolved variable which may end up being
232   // allocated globally as a "ghost" variable. RemoveUnresolved removes
233   // such a variable again if it was added; otherwise this is a no-op.
234   bool RemoveUnresolved(VariableProxy* var);
235 
236   // Creates a new temporary variable in this scope's TemporaryScope.  The
237   // name is only used for printing and cannot be used to find the variable.
238   // In particular, the only way to get hold of the temporary is by keeping the
239   // Variable* around.  The name should not clash with a legitimate variable
240   // names.
241   // TODO(verwaest): Move to DeclarationScope?
242   Variable* NewTemporary(const AstRawString* name);
243 
244   // ---------------------------------------------------------------------------
245   // Illegal redeclaration support.
246 
247   // Check if the scope has conflicting var
248   // declarations, i.e. a var declaration that has been hoisted from a nested
249   // scope over a let binding of the same name.
250   Declaration* CheckConflictingVarDeclarations();
251 
252   // Check if the scope has a conflicting lexical declaration that has a name in
253   // the given list. This is used to catch patterns like
254   // `try{}catch(e){let e;}`,
255   // which is an error even though the two 'e's are declared in different
256   // scopes.
257   Declaration* CheckLexDeclarationsConflictingWith(
258       const ZonePtrList<const AstRawString>& names);
259 
260   // ---------------------------------------------------------------------------
261   // Scope-specific info.
262 
263   // Inform the scope and outer scopes that the corresponding code contains an
264   // eval call.
265   void RecordEvalCall() {
266     scope_calls_eval_ = true;
267   }
268 
269   void RecordInnerScopeEvalCall() {
270     inner_scope_calls_eval_ = true;
271     for (Scope* scope = outer_scope(); scope != nullptr;
272          scope = scope->outer_scope()) {
273       if (scope->inner_scope_calls_eval_) {
274         return;
275       }
276       scope->inner_scope_calls_eval_ = true;
277     }
278   }
279 
280   // Set the language mode flag (unless disabled by a global flag).
281   void SetLanguageMode(LanguageMode language_mode) {
282     DCHECK(!is_module_scope() || is_strict(language_mode));
283     set_language_mode(language_mode);
284   }
285 
286   // Inform the scope that the scope may execute declarations nonlinearly.
287   // Currently, the only nonlinear scope is a switch statement. The name is
288   // more general in case something else comes up with similar control flow,
289   // for example the ability to break out of something which does not have
290   // its own lexical scope.
291   // The bit does not need to be stored on the ScopeInfo because none of
292   // the three compilers will perform hole check elimination on a variable
293   // located in VariableLocation::CONTEXT. So, direct eval and closures
294   // will not expose holes.
295   void SetNonlinear() { scope_nonlinear_ = true; }
296 
297   // Position in the source where this scope begins and ends.
298   //
299   // * For the scope of a with statement
300   //     with (obj) stmt
301   //   start position: start position of first token of 'stmt'
302   //   end position: end position of last token of 'stmt'
303   // * For the scope of a block
304   //     { stmts }
305   //   start position: start position of '{'
306   //   end position: end position of '}'
307   // * For the scope of a function literal or decalaration
308   //     function fun(a,b) { stmts }
309   //   start position: start position of '('
310   //   end position: end position of '}'
311   // * For the scope of a catch block
312   //     try { stms } catch(e) { stmts }
313   //   start position: start position of '('
314   //   end position: end position of ')'
315   // * For the scope of a for-statement
316   //     for (let x ...) stmt
317   //   start position: start position of '('
318   //   end position: end position of last token of 'stmt'
319   // * For the scope of a switch statement
320   //     switch (tag) { cases }
321   //   start position: start position of '{'
322   //   end position: end position of '}'
323   int start_position() const { return start_position_; }
324   void set_start_position(int statement_pos) {
325     start_position_ = statement_pos;
326   }
327   int end_position() const { return end_position_; }
328   void set_end_position(int statement_pos) {
329     end_position_ = statement_pos;
330   }
331 
332   // Scopes created for desugaring are hidden. I.e. not visible to the debugger.
333   bool is_hidden() const { return is_hidden_; }
334   void set_is_hidden() { is_hidden_ = true; }
335 
336   void ForceContextAllocationForParameters() {
337     DCHECK(!already_resolved_);
338     force_context_allocation_for_parameters_ = true;
339   }
340   bool has_forced_context_allocation_for_parameters() const {
341     return force_context_allocation_for_parameters_;
342   }
343 
344   // ---------------------------------------------------------------------------
345   // Predicates.
346 
347   // Specific scope types.
348   bool is_eval_scope() const { return scope_type_ == EVAL_SCOPE; }
349   bool is_function_scope() const { return scope_type_ == FUNCTION_SCOPE; }
350   bool is_module_scope() const { return scope_type_ == MODULE_SCOPE; }
351   bool is_script_scope() const { return scope_type_ == SCRIPT_SCOPE; }
352   bool is_catch_scope() const { return scope_type_ == CATCH_SCOPE; }
353   bool is_block_scope() const { return scope_type_ == BLOCK_SCOPE; }
354   bool is_with_scope() const { return scope_type_ == WITH_SCOPE; }
355   bool is_declaration_scope() const { return is_declaration_scope_; }
356 
357   bool inner_scope_calls_eval() const { return inner_scope_calls_eval_; }
358   bool IsAsmModule() const;
359   // Returns true if this scope or any inner scopes that might be eagerly
360   // compiled are asm modules.
361   bool ContainsAsmModule() const;
362   // Does this scope have the potential to execute declarations non-linearly?
363   bool is_nonlinear() const { return scope_nonlinear_; }
364 
365   // Whether this needs to be represented by a runtime context.
366   bool NeedsContext() const {
367     // Catch scopes always have heap slots.
368     DCHECK_IMPLIES(is_catch_scope(), num_heap_slots() > 0);
369     DCHECK_IMPLIES(is_with_scope(), num_heap_slots() > 0);
370     return num_heap_slots() > 0;
371   }
372 
373   // ---------------------------------------------------------------------------
374   // Accessors.
375 
376   // The type of this scope.
377   ScopeType scope_type() const { return scope_type_; }
378 
379   // The language mode of this scope.
380   LanguageMode language_mode() const {
381     return is_strict_ ? LanguageMode::kStrict : LanguageMode::kSloppy;
382   }
383 
384   // inner_scope() and sibling() together implement the inner scope list of a
385   // scope. Inner scope points to the an inner scope of the function, and
386   // "sibling" points to a next inner scope of the outer scope of this scope.
387   Scope* inner_scope() const { return inner_scope_; }
388   Scope* sibling() const { return sibling_; }
389 
390   // The scope immediately surrounding this scope, or nullptr.
391   Scope* outer_scope() const { return outer_scope_; }
392 
393   Variable* catch_variable() const {
394     DCHECK(is_catch_scope());
395     DCHECK_EQ(1, num_var());
396     return static_cast<Variable*>(variables_.Start()->value);
397   }
398 
399   bool ShouldBanArguments();
400 
401   // ---------------------------------------------------------------------------
402   // Variable allocation.
403 
404   // Result of variable allocation.
405   int num_stack_slots() const { return num_stack_slots_; }
406   int num_heap_slots() const { return num_heap_slots_; }
407 
408   int StackLocalCount() const;
409   int ContextLocalCount() const;
410 
411   // Determine if we can parse a function literal in this scope lazily without
412   // caring about the unresolved variables within.
413   bool AllowsLazyParsingWithoutUnresolvedVariables(const Scope* outer) const;
414 
415   // The number of contexts between this and scope; zero if this == scope.
416   int ContextChainLength(Scope* scope) const;
417 
418   // The number of contexts between this and the outermost context that has a
419   // sloppy eval call. One if this->calls_sloppy_eval().
420   int ContextChainLengthUntilOutermostSloppyEval() const;
421 
422   // Find the first function, script, eval or (declaration) block scope. This is
423   // the scope where var declarations will be hoisted to in the implementation.
424   DeclarationScope* GetDeclarationScope();
425 
426   // Find the first non-block declaration scope. This should be either a script,
427   // function, or eval scope. Same as DeclarationScope(), but skips declaration
428   // "block" scopes. Used for differentiating associated function objects (i.e.,
429   // the scope for which a function prologue allocates a context) or declaring
430   // temporaries.
431   DeclarationScope* GetClosureScope();
432   const DeclarationScope* GetClosureScope() const;
433 
434   // Find the first (non-arrow) function or script scope.  This is where
435   // 'this' is bound, and what determines the function kind.
436   DeclarationScope* GetReceiverScope();
437 
438   // Find the innermost outer scope that needs a context.
439   Scope* GetOuterScopeWithContext();
440 
441   // Analyze() must have been called once to create the ScopeInfo.
442   Handle<ScopeInfo> scope_info() const {
443     DCHECK(!scope_info_.is_null());
444     return scope_info_;
445   }
446 
447   int num_var() const { return variables_.occupancy(); }
448 
449   // ---------------------------------------------------------------------------
450   // Debugging.
451 
452 #ifdef DEBUG
453   void Print(int n = 0);  // n = indentation; n < 0 => don't print recursively
454 
455   // Check that the scope has positions assigned.
456   void CheckScopePositions();
457 
458   // Check that all Scopes in the scope tree use the same Zone.
459   void CheckZones();
460 #endif
461 
462   // Retrieve `IsSimpleParameterList` of current or outer function.
463   bool HasSimpleParameters();
464   void set_is_debug_evaluate_scope() { is_debug_evaluate_scope_ = true; }
465   bool is_debug_evaluate_scope() const { return is_debug_evaluate_scope_; }
466 
467   bool RemoveInnerScope(Scope* inner_scope) {
468     DCHECK_NOT_NULL(inner_scope);
469     if (inner_scope == inner_scope_) {
470       inner_scope_ = inner_scope_->sibling_;
471       return true;
472     }
473     for (Scope* scope = inner_scope_; scope != nullptr;
474          scope = scope->sibling_) {
475       if (scope->sibling_ == inner_scope) {
476         scope->sibling_ = scope->sibling_->sibling_;
477         return true;
478       }
479     }
480     return false;
481   }
482 
483  protected:
484   explicit Scope(Zone* zone);
485 
486   void set_language_mode(LanguageMode language_mode) {
487     is_strict_ = is_strict(language_mode);
488   }
489 
490  private:
491   Variable* Declare(
492       Zone* zone, const AstRawString* name, VariableMode mode,
493       VariableKind kind = NORMAL_VARIABLE,
494       InitializationFlag initialization_flag = kCreatedInitialized,
495       MaybeAssignedFlag maybe_assigned_flag = kNotAssigned);
496 
497   // This method should only be invoked on scopes created during parsing (i.e.,
498   // not deserialized from a context). Also, since NeedsContext() is only
499   // returning a valid result after variables are resolved, NeedsScopeInfo()
500   // should also be invoked after resolution.
501   bool NeedsScopeInfo() const;
502 
503   Variable* NewTemporary(const AstRawString* name,
504                          MaybeAssignedFlag maybe_assigned);
505 
506   // Walk the scope chain to find DeclarationScopes; call
507   // SavePreParsedScopeDataForDeclarationScope for each.
508   void SavePreParsedScopeData();
509 
510   Zone* zone_;
511 
512   // Scope tree.
513   Scope* outer_scope_;  // the immediately enclosing outer scope, or nullptr
514   Scope* inner_scope_;  // an inner scope of this scope
515   Scope* sibling_;  // a sibling inner scope of the outer scope of this scope.
516 
517   // The variables declared in this scope:
518   //
519   // All user-declared variables (incl. parameters).  For script scopes
520   // variables may be implicitly 'declared' by being used (possibly in
521   // an inner scope) with no intervening with statements or eval calls.
522   VariableMap variables_;
523   // In case of non-scopeinfo-backed scopes, this contains the variables of the
524   // map above in order of addition.
525   ThreadedList<Variable> locals_;
526   // Unresolved variables referred to from this scope. The proxies themselves
527   // form a linked list of all unresolved proxies.
528   VariableProxy* unresolved_;
529   // Declarations.
530   ThreadedList<Declaration> decls_;
531 
532   // Serialized scope info support.
533   Handle<ScopeInfo> scope_info_;
534 // Debugging support.
535 #ifdef DEBUG
536   const AstRawString* scope_name_;
537 
538   // True if it doesn't need scope resolution (e.g., if the scope was
539   // constructed based on a serialized scope info or a catch context).
540   bool already_resolved_;
541   // True if this scope may contain objects from a temp zone that needs to be
542   // fixed up.
543   bool needs_migration_;
544 #endif
545 
546   // Source positions.
547   int start_position_;
548   int end_position_;
549 
550   // Computed via AllocateVariables.
551   int num_stack_slots_;
552   int num_heap_slots_;
553 
554   // The scope type.
555   const ScopeType scope_type_;
556 
557   // Scope-specific information computed during parsing.
558   //
559   // The language mode of this scope.
560   STATIC_ASSERT(LanguageModeSize == 2);
561   bool is_strict_ : 1;
562   // This scope or a nested catch scope or with scope contain an 'eval' call. At
563   // the 'eval' call site this scope is the declaration scope.
564   bool scope_calls_eval_ : 1;
565   // This scope's declarations might not be executed in order (e.g., switch).
566   bool scope_nonlinear_ : 1;
567   bool is_hidden_ : 1;
568   // Temporary workaround that allows masking of 'this' in debug-evalute scopes.
569   bool is_debug_evaluate_scope_ : 1;
570 
571   // True if one of the inner scopes or the scope itself calls eval.
572   bool inner_scope_calls_eval_ : 1;
573   bool force_context_allocation_ : 1;
574   bool force_context_allocation_for_parameters_ : 1;
575 
576   // True if it holds 'var' declarations.
577   bool is_declaration_scope_ : 1;
578 
579   bool must_use_preparsed_scope_data_ : 1;
580 
581   // Create a non-local variable with a given name.
582   // These variables are looked up dynamically at runtime.
583   Variable* NonLocal(const AstRawString* name, VariableMode mode);
584 
585   // Variable resolution.
586   // Lookup a variable reference given by name recursively starting with this
587   // scope, and stopping when reaching the outer_scope_end scope. If the code is
588   // executed because of a call to 'eval', the context parameter should be set
589   // to the calling context of 'eval'.
590   Variable* LookupRecursive(ParseInfo* info, VariableProxy* proxy,
591                             Scope* outer_scope_end);
592   void ResolveTo(ParseInfo* info, VariableProxy* proxy, Variable* var);
593   V8_WARN_UNUSED_RESULT bool ResolveVariable(ParseInfo* info,
594                                              VariableProxy* proxy);
595   V8_WARN_UNUSED_RESULT bool ResolveVariablesRecursively(ParseInfo* info);
596 
597   // Finds free variables of this scope. This mutates the unresolved variables
598   // list along the way, so full resolution cannot be done afterwards.
599   // If a ParseInfo* is passed, non-free variables will be resolved.
600   VariableProxy* FetchFreeVariables(DeclarationScope* max_outer_scope,
601                                     ParseInfo* info = nullptr,
602                                     VariableProxy* stack = nullptr);
603 
604   // Predicates.
605   bool MustAllocate(Variable* var);
606   bool MustAllocateInContext(Variable* var);
607 
608   // Variable allocation.
609   void AllocateStackSlot(Variable* var);
610   void AllocateHeapSlot(Variable* var);
611   void AllocateNonParameterLocal(Variable* var);
612   void AllocateDeclaredGlobal(Variable* var);
613   void AllocateNonParameterLocalsAndDeclaredGlobals();
614   void AllocateVariablesRecursively();
615 
616   void AllocateScopeInfosRecursively(Isolate* isolate,
617                                      MaybeHandle<ScopeInfo> outer_scope);
618   void AllocateDebuggerScopeInfos(Isolate* isolate,
619                                   MaybeHandle<ScopeInfo> outer_scope);
620 
621   // Construct a scope based on the scope info.
622   Scope(Zone* zone, ScopeType type, Handle<ScopeInfo> scope_info);
623 
624   // Construct a catch scope with a binding for the name.
625   Scope(Zone* zone, const AstRawString* catch_variable_name,
626         MaybeAssignedFlag maybe_assigned, Handle<ScopeInfo> scope_info);
627 
628   void AddInnerScope(Scope* inner_scope) {
629     inner_scope->sibling_ = inner_scope_;
630     inner_scope_ = inner_scope;
631     inner_scope->outer_scope_ = this;
632   }
633 
634   void SetDefaults();
635 
636   friend class DeclarationScope;
637   friend class ScopeTestHelper;
638 };
639 
640 class V8_EXPORT_PRIVATE DeclarationScope : public Scope {
641  public:
642   DeclarationScope(Zone* zone, Scope* outer_scope, ScopeType scope_type,
643                    FunctionKind function_kind = kNormalFunction);
644   DeclarationScope(Zone* zone, ScopeType scope_type,
645                    Handle<ScopeInfo> scope_info);
646   // Creates a script scope.
647   DeclarationScope(Zone* zone, AstValueFactory* ast_value_factory);
648 
649   bool IsDeclaredParameter(const AstRawString* name);
650 
function_kind()651   FunctionKind function_kind() const { return function_kind_; }
652 
is_arrow_scope()653   bool is_arrow_scope() const {
654     return is_function_scope() && IsArrowFunction(function_kind_);
655   }
656 
657   // Inform the scope that the corresponding code uses "super".
RecordSuperPropertyUsage()658   void RecordSuperPropertyUsage() {
659     DCHECK(IsConciseMethod(function_kind()) ||
660            IsAccessorFunction(function_kind()) ||
661            IsClassConstructor(function_kind()));
662     scope_uses_super_property_ = true;
663   }
664 
665   // Does this scope access "super" property (super.foo).
NeedsHomeObject()666   bool NeedsHomeObject() const {
667     return scope_uses_super_property_ ||
668            (inner_scope_calls_eval_ && (IsConciseMethod(function_kind()) ||
669                                         IsAccessorFunction(function_kind()) ||
670                                         IsClassConstructor(function_kind())));
671   }
672 
calls_sloppy_eval()673   bool calls_sloppy_eval() const {
674     return scope_calls_eval_ && is_sloppy(language_mode());
675   }
676 
was_lazily_parsed()677   bool was_lazily_parsed() const { return was_lazily_parsed_; }
678 
679 #ifdef DEBUG
set_is_being_lazily_parsed(bool is_being_lazily_parsed)680   void set_is_being_lazily_parsed(bool is_being_lazily_parsed) {
681     is_being_lazily_parsed_ = is_being_lazily_parsed;
682   }
is_being_lazily_parsed()683   bool is_being_lazily_parsed() const { return is_being_lazily_parsed_; }
684 #endif
685 
686   bool ShouldEagerCompile() const;
687   void set_should_eager_compile();
688 
SetScriptScopeInfo(Handle<ScopeInfo> scope_info)689   void SetScriptScopeInfo(Handle<ScopeInfo> scope_info) {
690     DCHECK(is_script_scope());
691     DCHECK(scope_info_.is_null());
692     scope_info_ = scope_info;
693   }
694 
asm_module()695   bool asm_module() const { return asm_module_; }
696   void set_asm_module();
697 
should_ban_arguments()698   bool should_ban_arguments() const {
699     return IsClassFieldsInitializerFunction(function_kind());
700   }
701 
702   void DeclareThis(AstValueFactory* ast_value_factory);
703   void DeclareArguments(AstValueFactory* ast_value_factory);
704   void DeclareDefaultFunctionVariables(AstValueFactory* ast_value_factory);
705 
706   // Declare the function variable for a function literal. This variable
707   // is in an intermediate scope between this function scope and the the
708   // outer scope. Only possible for function scopes; at most one variable.
709   //
710   // This function needs to be called after all other variables have been
711   // declared in the scope. It will add a variable for {name} to {variables_};
712   // either the function variable itself, or a non-local in case the function
713   // calls sloppy eval.
714   Variable* DeclareFunctionVar(const AstRawString* name);
715 
716   // Declare some special internal variables which must be accessible to
717   // Ignition without ScopeInfo.
718   Variable* DeclareGeneratorObjectVar(const AstRawString* name);
719   Variable* DeclarePromiseVar(const AstRawString* name);
720 
721   // Declare a parameter in this scope.  When there are duplicated
722   // parameters the rightmost one 'wins'.  However, the implementation
723   // expects all parameters to be declared and from left to right.
724   Variable* DeclareParameter(const AstRawString* name, VariableMode mode,
725                              bool is_optional, bool is_rest, bool* is_duplicate,
726                              AstValueFactory* ast_value_factory, int position);
727 
728   // Declares that a parameter with the name exists. Creates a Variable and
729   // returns it if FLAG_preparser_scope_analysis is on.
730   Variable* DeclareParameterName(const AstRawString* name, bool is_rest,
731                                  AstValueFactory* ast_value_factory,
732                                  bool declare_local, bool add_parameter);
733 
734   // Declare an implicit global variable in this scope which must be a
735   // script scope.  The variable was introduced (possibly from an inner
736   // scope) by a reference to an unresolved variable with no intervening
737   // with statements or eval calls.
738   Variable* DeclareDynamicGlobal(const AstRawString* name,
739                                  VariableKind variable_kind);
740 
741   // The variable corresponding to the 'this' value.
receiver()742   Variable* receiver() {
743     DCHECK(has_this_declaration());
744     DCHECK_NOT_NULL(receiver_);
745     return receiver_;
746   }
747 
748   // TODO(wingo): Add a GLOBAL_SCOPE scope type which will lexically allocate
749   // "this" (and no other variable) on the native context.  Script scopes then
750   // will not have a "this" declaration.
has_this_declaration()751   bool has_this_declaration() const {
752     return (is_function_scope() && !is_arrow_scope()) || is_module_scope();
753   }
754 
755   // The variable corresponding to the 'new.target' value.
new_target_var()756   Variable* new_target_var() { return new_target_; }
757 
758   // The variable holding the function literal for named function
759   // literals, or nullptr.  Only valid for function scopes.
function_var()760   Variable* function_var() const { return function_; }
761 
generator_object_var()762   Variable* generator_object_var() const {
763     DCHECK(is_function_scope() || is_module_scope());
764     return GetRareVariable(RareVariable::kGeneratorObject);
765   }
766 
promise_var()767   Variable* promise_var() const {
768     DCHECK(is_function_scope());
769     DCHECK(IsAsyncFunction(function_kind_));
770     if (IsAsyncGeneratorFunction(function_kind_)) return nullptr;
771     return GetRareVariable(RareVariable::kPromise);
772   }
773 
774   // Parameters. The left-most parameter has index 0.
775   // Only valid for function and module scopes.
parameter(int index)776   Variable* parameter(int index) const {
777     DCHECK(is_function_scope() || is_module_scope());
778     return params_[index];
779   }
780 
781   // Returns the number of formal parameters, excluding a possible rest
782   // parameter.  Examples:
783   //   function foo(a, b) {}         ==> 2
784   //   function foo(a, b, ...c) {}   ==> 2
785   //   function foo(a, b, c = 1) {}  ==> 3
num_parameters()786   int num_parameters() const {
787     return has_rest_ ? params_.length() - 1 : params_.length();
788   }
789 
790   // The function's rest parameter (nullptr if there is none).
rest_parameter()791   Variable* rest_parameter() const {
792     return has_rest_ ? params_[params_.length() - 1] : nullptr;
793   }
794 
has_simple_parameters()795   bool has_simple_parameters() const { return has_simple_parameters_; }
796 
797   // TODO(caitp): manage this state in a better way. PreParser must be able to
798   // communicate that the scope is non-simple, without allocating any parameters
799   // as the Parser does. This is necessary to ensure that TC39's proposed early
800   // error can be reported consistently regardless of whether lazily parsed or
801   // not.
SetHasNonSimpleParameters()802   void SetHasNonSimpleParameters() {
803     DCHECK(is_function_scope());
804     has_simple_parameters_ = false;
805   }
806 
807   // Returns whether the arguments object aliases formal parameters.
GetArgumentsType()808   CreateArgumentsType GetArgumentsType() const {
809     DCHECK(is_function_scope());
810     DCHECK(!is_arrow_scope());
811     DCHECK_NOT_NULL(arguments_);
812     return is_sloppy(language_mode()) && has_simple_parameters()
813                ? CreateArgumentsType::kMappedArguments
814                : CreateArgumentsType::kUnmappedArguments;
815   }
816 
817   // The local variable 'arguments' if we need to allocate it; nullptr
818   // otherwise.
arguments()819   Variable* arguments() const {
820     DCHECK_IMPLIES(is_arrow_scope(), arguments_ == nullptr);
821     return arguments_;
822   }
823 
this_function_var()824   Variable* this_function_var() const {
825     Variable* this_function = GetRareVariable(RareVariable::kThisFunction);
826 
827     // This is only used in derived constructors atm.
828     DCHECK(this_function == nullptr ||
829            (is_function_scope() && (IsClassConstructor(function_kind()) ||
830                                     IsConciseMethod(function_kind()) ||
831                                     IsAccessorFunction(function_kind()))));
832     return this_function;
833   }
834 
835   // Adds a local variable in this scope's locals list. This is for adjusting
836   // the scope of temporaries and do-expression vars when desugaring parameter
837   // initializers.
838   void AddLocal(Variable* var);
839 
840   void DeclareSloppyBlockFunction(
841       const AstRawString* name, Scope* scope,
842       SloppyBlockFunctionStatement* statement = nullptr);
843 
844   // Go through sloppy_block_function_map_ and hoist those (into this scope)
845   // which should be hoisted.
846   void HoistSloppyBlockFunctions(AstNodeFactory* factory);
847 
sloppy_block_function_map()848   SloppyBlockFunctionMap* sloppy_block_function_map() {
849     return sloppy_block_function_map_;
850   }
851 
852   // Replaces the outer scope with the outer_scope_info in |info| if there is
853   // one.
854   void AttachOuterScopeInfo(ParseInfo* info, Isolate* isolate);
855 
856   // Compute top scope and allocate variables. For lazy compilation the top
857   // scope only contains the single lazily compiled function, so this
858   // doesn't re-allocate variables repeatedly.
859   //
860   // Returns false if private fields can not be resolved and
861   // ParseInfo's pending_error_handler will be populated with an
862   // error. Otherwise, returns true.
863   V8_WARN_UNUSED_RESULT
864   static bool Analyze(ParseInfo* info);
865 
866   // To be called during parsing. Do just enough scope analysis that we can
867   // discard the Scope contents for lazily compiled functions. In particular,
868   // this records variables which cannot be resolved inside the Scope (we don't
869   // yet know what they will resolve to since the outer Scopes are incomplete)
870   // and recreates them with the correct Zone with ast_node_factory.
871   void AnalyzePartially(AstNodeFactory* ast_node_factory);
872 
873   // Allocate ScopeInfos for top scope and any inner scopes that need them.
874   // Does nothing if ScopeInfo is already allocated.
875   static void AllocateScopeInfos(ParseInfo* info, Isolate* isolate);
876 
877   Handle<StringSet> CollectNonLocals(Isolate* isolate, ParseInfo* info,
878                                      Handle<StringSet> non_locals);
879 
880   // Determine if we can use lazy compilation for this scope.
881   bool AllowsLazyCompilation() const;
882 
883   // Make sure this closure and all outer closures are eagerly compiled.
ForceEagerCompilation()884   void ForceEagerCompilation() {
885     DCHECK_EQ(this, GetClosureScope());
886     DeclarationScope* s;
887     for (s = this; !s->is_script_scope();
888          s = s->outer_scope()->GetClosureScope()) {
889       s->force_eager_compilation_ = true;
890     }
891     s->force_eager_compilation_ = true;
892   }
893 
894 #ifdef DEBUG
895   void PrintParameters();
896 #endif
897 
898   void AllocateLocals();
899   void AllocateParameterLocals();
900   void AllocateReceiver();
901 
902   void ResetAfterPreparsing(AstValueFactory* ast_value_factory, bool aborted);
903 
is_skipped_function()904   bool is_skipped_function() const { return is_skipped_function_; }
set_is_skipped_function(bool is_skipped_function)905   void set_is_skipped_function(bool is_skipped_function) {
906     is_skipped_function_ = is_skipped_function;
907   }
908 
has_inferred_function_name()909   bool has_inferred_function_name() const {
910     return has_inferred_function_name_;
911   }
set_has_inferred_function_name(bool value)912   void set_has_inferred_function_name(bool value) {
913     DCHECK(is_function_scope());
914     has_inferred_function_name_ = value;
915   }
916 
917   // Save data describing the context allocation of the variables in this scope
918   // and its subscopes (except scopes at the laziness boundary). The data is
919   // saved in produced_preparsed_scope_data_.
920   void SavePreParsedScopeDataForDeclarationScope();
921 
set_produced_preparsed_scope_data(ProducedPreParsedScopeData * produced_preparsed_scope_data)922   void set_produced_preparsed_scope_data(
923       ProducedPreParsedScopeData* produced_preparsed_scope_data) {
924     produced_preparsed_scope_data_ = produced_preparsed_scope_data;
925   }
926 
produced_preparsed_scope_data()927   ProducedPreParsedScopeData* produced_preparsed_scope_data() const {
928     return produced_preparsed_scope_data_;
929   }
930 
931  private:
932   void AllocateParameter(Variable* var, int index);
933 
934   // Resolve and fill in the allocation information for all variables
935   // in this scopes. Must be called *after* all scopes have been
936   // processed (parsed) to ensure that unresolved variables can be
937   // resolved properly.
938   //
939   // In the case of code compiled and run using 'eval', the context
940   // parameter is the context in which eval was called.  In all other
941   // cases the context parameter is an empty handle.
942   //
943   // Returns false if private fields can not be resolved.
944   bool AllocateVariables(ParseInfo* info);
945 
946   void SetDefaults();
947 
948   // If the scope is a function scope, this is the function kind.
949   const FunctionKind function_kind_;
950 
951   bool has_simple_parameters_ : 1;
952   // This scope contains an "use asm" annotation.
953   bool asm_module_ : 1;
954   bool force_eager_compilation_ : 1;
955   // This function scope has a rest parameter.
956   bool has_rest_ : 1;
957   // This scope has a parameter called "arguments".
958   bool has_arguments_parameter_ : 1;
959   // This scope uses "super" property ('super.foo').
960   bool scope_uses_super_property_ : 1;
961   bool should_eager_compile_ : 1;
962   // Set to true after we have finished lazy parsing the scope.
963   bool was_lazily_parsed_ : 1;
964 #if DEBUG
965   bool is_being_lazily_parsed_ : 1;
966 #endif
967   bool is_skipped_function_ : 1;
968   bool has_inferred_function_name_ : 1;
969 
970   // Parameter list in source order.
971   ZonePtrList<Variable> params_;
972   // Map of function names to lists of functions defined in sloppy blocks
973   SloppyBlockFunctionMap* sloppy_block_function_map_;
974   // Convenience variable.
975   Variable* receiver_;
976   // Function variable, if any; function scopes only.
977   Variable* function_;
978   // new.target variable, function scopes only.
979   Variable* new_target_;
980   // Convenience variable; function scopes only.
981   Variable* arguments_;
982 
983   // For producing the scope allocation data during preparsing.
984   ProducedPreParsedScopeData* produced_preparsed_scope_data_;
985 
986   struct RareData : public ZoneObject {
987     // Convenience variable; Subclass constructor only
988     Variable* this_function = nullptr;
989 
990     // Generator object, if any; generator function scopes and module scopes
991     // only.
992     Variable* generator_object = nullptr;
993     // Promise, if any; async function scopes only.
994     Variable* promise = nullptr;
995   };
996 
997   enum class RareVariable {
998     kThisFunction = offsetof(RareData, this_function),
999     kGeneratorObject = offsetof(RareData, generator_object),
1000     kPromise = offsetof(RareData, promise)
1001   };
1002 
EnsureRareData()1003   V8_INLINE RareData* EnsureRareData() {
1004     if (rare_data_ == nullptr) {
1005       rare_data_ = new (zone_) RareData;
1006     }
1007     return rare_data_;
1008   }
1009 
GetRareVariable(RareVariable id)1010   V8_INLINE Variable* GetRareVariable(RareVariable id) const {
1011     if (rare_data_ == nullptr) return nullptr;
1012     return *reinterpret_cast<Variable**>(
1013         reinterpret_cast<uint8_t*>(rare_data_) + static_cast<ptrdiff_t>(id));
1014   }
1015 
1016   // Set `var` to null if it's non-null and Predicate (Variable*) -> bool
1017   // returns true.
1018   template <typename Predicate>
NullifyRareVariableIf(RareVariable id,Predicate predicate)1019   V8_INLINE void NullifyRareVariableIf(RareVariable id, Predicate predicate) {
1020     if (V8_LIKELY(rare_data_ == nullptr)) return;
1021     Variable** var = reinterpret_cast<Variable**>(
1022         reinterpret_cast<uint8_t*>(rare_data_) + static_cast<ptrdiff_t>(id));
1023     if (*var && predicate(*var)) *var = nullptr;
1024   }
1025 
1026   RareData* rare_data_ = nullptr;
1027 };
1028 
1029 class ModuleScope final : public DeclarationScope {
1030  public:
1031   ModuleScope(DeclarationScope* script_scope,
1032               AstValueFactory* ast_value_factory);
1033 
1034   // Deserialization.
1035   // The generated ModuleDescriptor does not preserve all information.  In
1036   // particular, its module_requests map will be empty because we no longer need
1037   // the map after parsing.
1038   ModuleScope(Isolate* isolate, Handle<ScopeInfo> scope_info,
1039               AstValueFactory* ast_value_factory);
1040 
module()1041   ModuleDescriptor* module() const {
1042     DCHECK_NOT_NULL(module_descriptor_);
1043     return module_descriptor_;
1044   }
1045 
1046   // Set MODULE as VariableLocation for all variables that will live in a
1047   // module's export table.
1048   void AllocateModuleVariables();
1049 
1050  private:
1051   ModuleDescriptor* module_descriptor_;
1052 };
1053 
1054 }  // namespace internal
1055 }  // namespace v8
1056 
1057 #endif  // V8_AST_SCOPES_H_
1058