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