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/hashmap.h"
10 #include "src/pending-compilation-error-handler.h"
11 #include "src/zone.h"
12 
13 namespace v8 {
14 namespace internal {
15 
16 class ParseInfo;
17 
18 // A hash map to support fast variable declaration and lookup.
19 class VariableMap: public ZoneHashMap {
20  public:
21   explicit VariableMap(Zone* zone);
22 
23   virtual ~VariableMap();
24 
25   Variable* Declare(Scope* scope, const AstRawString* name, VariableMode mode,
26                     Variable::Kind kind, InitializationFlag initialization_flag,
27                     MaybeAssignedFlag maybe_assigned_flag = kNotAssigned,
28                     int declaration_group_start = -1);
29 
30   Variable* Lookup(const AstRawString* name);
31 
zone()32   Zone* zone() const { return zone_; }
33 
34  private:
35   Zone* zone_;
36 };
37 
38 
39 // The dynamic scope part holds hash maps for the variables that will
40 // be looked up dynamically from within eval and with scopes. The objects
41 // are allocated on-demand from Scope::NonLocal to avoid wasting memory
42 // and setup time for scopes that don't need them.
43 class DynamicScopePart : public ZoneObject {
44  public:
DynamicScopePart(Zone * zone)45   explicit DynamicScopePart(Zone* zone) {
46     for (int i = 0; i < 3; i++)
47       maps_[i] = new(zone->New(sizeof(VariableMap))) VariableMap(zone);
48   }
49 
GetMap(VariableMode mode)50   VariableMap* GetMap(VariableMode mode) {
51     int index = mode - DYNAMIC;
52     DCHECK(index >= 0 && index < 3);
53     return maps_[index];
54   }
55 
56  private:
57   VariableMap *maps_[3];
58 };
59 
60 
61 // Sloppy block-scoped function declarations to var-bind
62 class SloppyBlockFunctionMap : public ZoneHashMap {
63  public:
64   explicit SloppyBlockFunctionMap(Zone* zone);
65 
66   virtual ~SloppyBlockFunctionMap();
67 
68   void Declare(const AstRawString* name,
69                SloppyBlockFunctionStatement* statement);
70 
71   typedef ZoneVector<SloppyBlockFunctionStatement*> Vector;
72 
73  private:
74   Zone* zone_;
75 };
76 
77 
78 // Global invariants after AST construction: Each reference (i.e. identifier)
79 // to a JavaScript variable (including global properties) is represented by a
80 // VariableProxy node. Immediately after AST construction and before variable
81 // allocation, most VariableProxy nodes are "unresolved", i.e. not bound to a
82 // corresponding variable (though some are bound during parse time). Variable
83 // allocation binds each unresolved VariableProxy to one Variable and assigns
84 // a location. Note that many VariableProxy nodes may refer to the same Java-
85 // Script variable.
86 
87 class Scope: public ZoneObject {
88  public:
89   // ---------------------------------------------------------------------------
90   // Construction
91 
92   Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type,
93         AstValueFactory* value_factory,
94         FunctionKind function_kind = kNormalFunction);
95 
96   // Compute top scope and allocate variables. For lazy compilation the top
97   // scope only contains the single lazily compiled function, so this
98   // doesn't re-allocate variables repeatedly.
99   static bool Analyze(ParseInfo* info);
100 
101   static Scope* DeserializeScopeChain(Isolate* isolate, Zone* zone,
102                                       Context* context, Scope* script_scope);
103 
104   // The scope name is only used for printing/debugging.
SetScopeName(const AstRawString * scope_name)105   void SetScopeName(const AstRawString* scope_name) {
106     scope_name_ = scope_name;
107   }
108 
109   void Initialize();
110 
111   // Checks if the block scope is redundant, i.e. it does not contain any
112   // block scoped declarations. In that case it is removed from the scope
113   // tree and its children are reparented.
114   Scope* FinalizeBlockScope();
115 
116   // Inserts outer_scope into this scope's scope chain (and removes this
117   // from the current outer_scope_'s inner_scopes_).
118   // Assumes outer_scope_ is non-null.
119   void ReplaceOuterScope(Scope* outer_scope);
120 
121   // Propagates any eagerly-gathered scope usage flags (such as calls_eval())
122   // to the passed-in scope.
123   void PropagateUsageFlagsToScope(Scope* other);
124 
zone()125   Zone* zone() const { return zone_; }
126 
127   // ---------------------------------------------------------------------------
128   // Declarations
129 
130   // Lookup a variable in this scope. Returns the variable or NULL if not found.
131   Variable* LookupLocal(const AstRawString* name);
132 
133   // This lookup corresponds to a lookup in the "intermediate" scope sitting
134   // between this scope and the outer scope. (ECMA-262, 3rd., requires that
135   // the name of named function literal is kept in an intermediate scope
136   // in between this scope and the next outer scope.)
137   Variable* LookupFunctionVar(const AstRawString* name,
138                               AstNodeFactory* factory);
139 
140   // Lookup a variable in this scope or outer scopes.
141   // Returns the variable or NULL if not found.
142   Variable* Lookup(const AstRawString* name);
143 
144   // Declare the function variable for a function literal. This variable
145   // is in an intermediate scope between this function scope and the the
146   // outer scope. Only possible for function scopes; at most one variable.
DeclareFunctionVar(VariableDeclaration * declaration)147   void DeclareFunctionVar(VariableDeclaration* declaration) {
148     DCHECK(is_function_scope());
149     // Handle implicit declaration of the function name in named function
150     // expressions before other declarations.
151     decls_.InsertAt(0, declaration, zone());
152     function_ = declaration;
153   }
154 
155   // Declare a parameter in this scope.  When there are duplicated
156   // parameters the rightmost one 'wins'.  However, the implementation
157   // expects all parameters to be declared and from left to right.
158   Variable* DeclareParameter(
159       const AstRawString* name, VariableMode mode,
160       bool is_optional, bool is_rest, bool* is_duplicate);
161 
162   // Declare a local variable in this scope. If the variable has been
163   // declared before, the previously declared variable is returned.
164   Variable* DeclareLocal(const AstRawString* name, VariableMode mode,
165                          InitializationFlag init_flag, Variable::Kind kind,
166                          MaybeAssignedFlag maybe_assigned_flag = kNotAssigned,
167                          int declaration_group_start = -1);
168 
169   // Declare an implicit global variable in this scope which must be a
170   // script scope.  The variable was introduced (possibly from an inner
171   // scope) by a reference to an unresolved variable with no intervening
172   // with statements or eval calls.
173   Variable* DeclareDynamicGlobal(const AstRawString* name);
174 
175   // Create a new unresolved variable.
176   VariableProxy* NewUnresolved(AstNodeFactory* factory,
177                                const AstRawString* name,
178                                Variable::Kind kind = Variable::NORMAL,
179                                int start_position = RelocInfo::kNoPosition,
180                                int end_position = RelocInfo::kNoPosition) {
181     // Note that we must not share the unresolved variables with
182     // the same name because they may be removed selectively via
183     // RemoveUnresolved().
184     DCHECK(!already_resolved());
185     VariableProxy* proxy =
186         factory->NewVariableProxy(name, kind, start_position, end_position);
187     unresolved_.Add(proxy, zone_);
188     return proxy;
189   }
190 
AddUnresolved(VariableProxy * proxy)191   void AddUnresolved(VariableProxy* proxy) {
192     DCHECK(!already_resolved());
193     DCHECK(!proxy->is_resolved());
194     unresolved_.Add(proxy, zone_);
195   }
196 
197   // Remove a unresolved variable. During parsing, an unresolved variable
198   // may have been added optimistically, but then only the variable name
199   // was used (typically for labels). If the variable was not declared, the
200   // addition introduced a new unresolved variable which may end up being
201   // allocated globally as a "ghost" variable. RemoveUnresolved removes
202   // such a variable again if it was added; otherwise this is a no-op.
203   bool RemoveUnresolved(VariableProxy* var);
204 
205   // Creates a new temporary variable in this scope's TemporaryScope.  The
206   // name is only used for printing and cannot be used to find the variable.
207   // In particular, the only way to get hold of the temporary is by keeping the
208   // Variable* around.  The name should not clash with a legitimate variable
209   // names.
210   Variable* NewTemporary(const AstRawString* name);
211 
212   // Remove a temporary variable. This is for adjusting the scope of
213   // temporaries used when desugaring parameter initializers.
214   bool RemoveTemporary(Variable* var);
215 
216   // Adds a temporary variable in this scope's TemporaryScope. This is for
217   // adjusting the scope of temporaries used when desugaring parameter
218   // initializers.
AddTemporary(Variable * var)219   void AddTemporary(Variable* var) { temps_.Add(var, zone()); }
220 
221   // Adds the specific declaration node to the list of declarations in
222   // this scope. The declarations are processed as part of entering
223   // the scope; see codegen.cc:ProcessDeclarations.
224   void AddDeclaration(Declaration* declaration);
225 
226   // ---------------------------------------------------------------------------
227   // Illegal redeclaration support.
228 
229   // Set an expression node that will be executed when the scope is
230   // entered. We only keep track of one illegal redeclaration node per
231   // scope - the first one - so if you try to set it multiple times
232   // the additional requests will be silently ignored.
233   void SetIllegalRedeclaration(Expression* expression);
234 
235   // Retrieve the illegal redeclaration expression. Do not call if the
236   // scope doesn't have an illegal redeclaration node.
237   Expression* GetIllegalRedeclaration();
238 
239   // Check if the scope has (at least) one illegal redeclaration.
HasIllegalRedeclaration()240   bool HasIllegalRedeclaration() const { return illegal_redecl_ != NULL; }
241 
242   // For harmony block scoping mode: Check if the scope has conflicting var
243   // declarations, i.e. a var declaration that has been hoisted from a nested
244   // scope over a let binding of the same name.
245   Declaration* CheckConflictingVarDeclarations();
246 
247   // ---------------------------------------------------------------------------
248   // Scope-specific info.
249 
250   // Inform the scope that the corresponding code contains a with statement.
RecordWithStatement()251   void RecordWithStatement() { scope_contains_with_ = true; }
252 
253   // Inform the scope that the corresponding code contains an eval call.
RecordEvalCall()254   void RecordEvalCall() { scope_calls_eval_ = true; }
255 
256   // Inform the scope that the corresponding code uses "arguments".
RecordArgumentsUsage()257   void RecordArgumentsUsage() { scope_uses_arguments_ = true; }
258 
259   // Inform the scope that the corresponding code uses "super".
RecordSuperPropertyUsage()260   void RecordSuperPropertyUsage() { scope_uses_super_property_ = true; }
261 
262   // Set the language mode flag (unless disabled by a global flag).
SetLanguageMode(LanguageMode language_mode)263   void SetLanguageMode(LanguageMode language_mode) {
264     language_mode_ = language_mode;
265   }
266 
267   // Set the ASM module flag.
SetAsmModule()268   void SetAsmModule() { asm_module_ = true; }
269 
270   // Inform the scope that the scope may execute declarations nonlinearly.
271   // Currently, the only nonlinear scope is a switch statement. The name is
272   // more general in case something else comes up with similar control flow,
273   // for example the ability to break out of something which does not have
274   // its own lexical scope.
275   // The bit does not need to be stored on the ScopeInfo because none of
276   // the three compilers will perform hole check elimination on a variable
277   // located in VariableLocation::CONTEXT. So, direct eval and closures
278   // will not expose holes.
SetNonlinear()279   void SetNonlinear() { scope_nonlinear_ = true; }
280 
281   // Position in the source where this scope begins and ends.
282   //
283   // * For the scope of a with statement
284   //     with (obj) stmt
285   //   start position: start position of first token of 'stmt'
286   //   end position: end position of last token of 'stmt'
287   // * For the scope of a block
288   //     { stmts }
289   //   start position: start position of '{'
290   //   end position: end position of '}'
291   // * For the scope of a function literal or decalaration
292   //     function fun(a,b) { stmts }
293   //   start position: start position of '('
294   //   end position: end position of '}'
295   // * For the scope of a catch block
296   //     try { stms } catch(e) { stmts }
297   //   start position: start position of '('
298   //   end position: end position of ')'
299   // * For the scope of a for-statement
300   //     for (let x ...) stmt
301   //   start position: start position of '('
302   //   end position: end position of last token of 'stmt'
303   // * For the scope of a switch statement
304   //     switch (tag) { cases }
305   //   start position: start position of '{'
306   //   end position: end position of '}'
start_position()307   int start_position() const { return start_position_; }
set_start_position(int statement_pos)308   void set_start_position(int statement_pos) {
309     start_position_ = statement_pos;
310   }
end_position()311   int end_position() const { return end_position_; }
set_end_position(int statement_pos)312   void set_end_position(int statement_pos) {
313     end_position_ = statement_pos;
314   }
315 
316   // In some cases we want to force context allocation for a whole scope.
ForceContextAllocation()317   void ForceContextAllocation() {
318     DCHECK(!already_resolved());
319     force_context_allocation_ = true;
320   }
has_forced_context_allocation()321   bool has_forced_context_allocation() const {
322     return force_context_allocation_;
323   }
324 
325   // ---------------------------------------------------------------------------
326   // Predicates.
327 
328   // Specific scope types.
is_eval_scope()329   bool is_eval_scope() const { return scope_type_ == EVAL_SCOPE; }
is_function_scope()330   bool is_function_scope() const { return scope_type_ == FUNCTION_SCOPE; }
is_module_scope()331   bool is_module_scope() const { return scope_type_ == MODULE_SCOPE; }
is_script_scope()332   bool is_script_scope() const { return scope_type_ == SCRIPT_SCOPE; }
is_catch_scope()333   bool is_catch_scope() const { return scope_type_ == CATCH_SCOPE; }
is_block_scope()334   bool is_block_scope() const { return scope_type_ == BLOCK_SCOPE; }
is_with_scope()335   bool is_with_scope() const { return scope_type_ == WITH_SCOPE; }
is_arrow_scope()336   bool is_arrow_scope() const {
337     return is_function_scope() && IsArrowFunction(function_kind_);
338   }
is_declaration_scope()339   bool is_declaration_scope() const { return is_declaration_scope_; }
340 
set_is_declaration_scope()341   void set_is_declaration_scope() { is_declaration_scope_ = true; }
342 
343   // Information about which scopes calls eval.
calls_eval()344   bool calls_eval() const { return scope_calls_eval_; }
calls_sloppy_eval()345   bool calls_sloppy_eval() const {
346     return scope_calls_eval_ && is_sloppy(language_mode_);
347   }
outer_scope_calls_sloppy_eval()348   bool outer_scope_calls_sloppy_eval() const {
349     return outer_scope_calls_sloppy_eval_;
350   }
asm_module()351   bool asm_module() const { return asm_module_; }
asm_function()352   bool asm_function() const { return asm_function_; }
353 
354   // Is this scope inside a with statement.
inside_with()355   bool inside_with() const { return scope_inside_with_; }
356 
357   // Does this scope access "arguments".
uses_arguments()358   bool uses_arguments() const { return scope_uses_arguments_; }
359   // Does this scope access "super" property (super.foo).
uses_super_property()360   bool uses_super_property() const { return scope_uses_super_property_; }
361   // Does this scope have the potential to execute declarations non-linearly?
is_nonlinear()362   bool is_nonlinear() const { return scope_nonlinear_; }
363 
364   // Whether this needs to be represented by a runtime context.
NeedsContext()365   bool NeedsContext() const {
366     // Catch and module scopes always have heap slots.
367     DCHECK(!is_catch_scope() || num_heap_slots() > 0);
368     DCHECK(!is_module_scope() || num_heap_slots() > 0);
369     return is_with_scope() || num_heap_slots() > 0;
370   }
371 
NeedsHomeObject()372   bool NeedsHomeObject() const {
373     return scope_uses_super_property_ ||
374            ((scope_calls_eval_ || inner_scope_calls_eval_) &&
375             (IsConciseMethod(function_kind()) ||
376              IsAccessorFunction(function_kind()) ||
377              IsClassConstructor(function_kind())));
378   }
379 
NearestOuterEvalScope()380   const Scope* NearestOuterEvalScope() const {
381     if (is_eval_scope()) return this;
382     if (outer_scope() == nullptr) return nullptr;
383     return outer_scope()->NearestOuterEvalScope();
384   }
385 
386   // ---------------------------------------------------------------------------
387   // Accessors.
388 
389   // The type of this scope.
scope_type()390   ScopeType scope_type() const { return scope_type_; }
391 
function_kind()392   FunctionKind function_kind() const { return function_kind_; }
393 
394   // The language mode of this scope.
language_mode()395   LanguageMode language_mode() const { return language_mode_; }
396 
397   // The variable corresponding to the 'this' value.
receiver()398   Variable* receiver() {
399     DCHECK(has_this_declaration());
400     DCHECK_NOT_NULL(receiver_);
401     return receiver_;
402   }
403 
404   // TODO(wingo): Add a GLOBAL_SCOPE scope type which will lexically allocate
405   // "this" (and no other variable) on the native context.  Script scopes then
406   // will not have a "this" declaration.
has_this_declaration()407   bool has_this_declaration() const {
408     return (is_function_scope() && !is_arrow_scope()) || is_module_scope();
409   }
410 
411   // The variable corresponding to the 'new.target' value.
new_target_var()412   Variable* new_target_var() { return new_target_; }
413 
414   // The variable holding the function literal for named function
415   // literals, or NULL.  Only valid for function scopes.
function()416   VariableDeclaration* function() const {
417     DCHECK(is_function_scope());
418     return function_;
419   }
420 
421   // Parameters. The left-most parameter has index 0.
422   // Only valid for function scopes.
parameter(int index)423   Variable* parameter(int index) const {
424     DCHECK(is_function_scope());
425     return params_[index];
426   }
427 
428   // Returns the default function arity excluding default or rest parameters.
default_function_length()429   int default_function_length() const { return arity_; }
430 
num_parameters()431   int num_parameters() const { return params_.length(); }
432 
433   // A function can have at most one rest parameter. Returns Variable* or NULL.
rest_parameter(int * index)434   Variable* rest_parameter(int* index) const {
435     *index = rest_index_;
436     if (rest_index_ < 0) return NULL;
437     return rest_parameter_;
438   }
439 
has_rest_parameter()440   bool has_rest_parameter() const { return rest_index_ >= 0; }
441 
has_simple_parameters()442   bool has_simple_parameters() const {
443     return has_simple_parameters_;
444   }
445 
446   // TODO(caitp): manage this state in a better way. PreParser must be able to
447   // communicate that the scope is non-simple, without allocating any parameters
448   // as the Parser does. This is necessary to ensure that TC39's proposed early
449   // error can be reported consistently regardless of whether lazily parsed or
450   // not.
SetHasNonSimpleParameters()451   void SetHasNonSimpleParameters() {
452     DCHECK(is_function_scope());
453     has_simple_parameters_ = false;
454   }
455 
456   // Retrieve `IsSimpleParameterList` of current or outer function.
HasSimpleParameters()457   bool HasSimpleParameters() {
458     Scope* scope = ClosureScope();
459     return !scope->is_function_scope() || scope->has_simple_parameters();
460   }
461 
462   // The local variable 'arguments' if we need to allocate it; NULL otherwise.
arguments()463   Variable* arguments() const {
464     DCHECK(!is_arrow_scope() || arguments_ == nullptr);
465     return arguments_;
466   }
467 
this_function_var()468   Variable* this_function_var() const {
469     // This is only used in derived constructors atm.
470     DCHECK(this_function_ == nullptr ||
471            (is_function_scope() && (IsClassConstructor(function_kind()) ||
472                                     IsConciseMethod(function_kind()) ||
473                                     IsAccessorFunction(function_kind()))));
474     return this_function_;
475   }
476 
477   // Declarations list.
declarations()478   ZoneList<Declaration*>* declarations() { return &decls_; }
479 
480   // Inner scope list.
inner_scopes()481   ZoneList<Scope*>* inner_scopes() { return &inner_scopes_; }
482 
483   // The scope immediately surrounding this scope, or NULL.
outer_scope()484   Scope* outer_scope() const { return outer_scope_; }
485 
486   // The ModuleDescriptor for this scope; only for module scopes.
module()487   ModuleDescriptor* module() const { return module_descriptor_; }
488 
489 
set_class_declaration_group_start(int position)490   void set_class_declaration_group_start(int position) {
491     class_declaration_group_start_ = position;
492   }
493 
class_declaration_group_start()494   int class_declaration_group_start() const {
495     return class_declaration_group_start_;
496   }
497 
498   // ---------------------------------------------------------------------------
499   // Variable allocation.
500 
501   // Collect stack and context allocated local variables in this scope. Note
502   // that the function variable - if present - is not collected and should be
503   // handled separately.
504   void CollectStackAndContextLocals(
505       ZoneList<Variable*>* stack_locals, ZoneList<Variable*>* context_locals,
506       ZoneList<Variable*>* context_globals,
507       ZoneList<Variable*>* strong_mode_free_variables = nullptr);
508 
509   // Current number of var or const locals.
num_var_or_const()510   int num_var_or_const() { return num_var_or_const_; }
511 
512   // Result of variable allocation.
num_stack_slots()513   int num_stack_slots() const { return num_stack_slots_; }
num_heap_slots()514   int num_heap_slots() const { return num_heap_slots_; }
num_global_slots()515   int num_global_slots() const { return num_global_slots_; }
516 
517   int StackLocalCount() const;
518   int ContextLocalCount() const;
519   int ContextGlobalCount() const;
520 
521   // Make sure this scope and all outer scopes are eagerly compiled.
ForceEagerCompilation()522   void ForceEagerCompilation()  { force_eager_compilation_ = true; }
523 
524   // Determine if we can parse a function literal in this scope lazily.
525   bool AllowsLazyParsing() const;
526 
527   // Determine if we can use lazy compilation for this scope.
528   bool AllowsLazyCompilation() const;
529 
530   // Determine if we can use lazy compilation for this scope without a context.
531   bool AllowsLazyCompilationWithoutContext() const;
532 
533   // True if the outer context of this scope is always the native context.
534   bool HasTrivialOuterContext() const;
535 
536   // The number of contexts between this and scope; zero if this == scope.
537   int ContextChainLength(Scope* scope);
538 
539   // The maximum number of nested contexts required for this scope and any inner
540   // scopes.
541   int MaxNestedContextChainLength();
542 
543   // Find the first function, script, eval or (declaration) block scope. This is
544   // the scope where var declarations will be hoisted to in the implementation.
545   Scope* DeclarationScope();
546 
547   // Find the first non-block declaration scope. This should be either a script,
548   // function, or eval scope. Same as DeclarationScope(), but skips
549   // declaration "block" scopes. Used for differentiating associated
550   // function objects (i.e., the scope for which a function prologue allocates
551   // a context) or declaring temporaries.
552   Scope* ClosureScope();
553 
554   // Find the first (non-arrow) function or script scope.  This is where
555   // 'this' is bound, and what determines the function kind.
556   Scope* ReceiverScope();
557 
558   Handle<ScopeInfo> GetScopeInfo(Isolate* isolate);
559 
560   // Get the chain of nested scopes within this scope for the source statement
561   // position. The scopes will be added to the list from the outermost scope to
562   // the innermost scope. Only nested block, catch or with scopes are tracked
563   // and will be returned, but no inner function scopes.
564   void GetNestedScopeChain(Isolate* isolate, List<Handle<ScopeInfo> >* chain,
565                            int statement_position);
566 
567   void CollectNonLocals(HashMap* non_locals);
568 
569   // ---------------------------------------------------------------------------
570   // Strict mode support.
IsDeclared(const AstRawString * name)571   bool IsDeclared(const AstRawString* name) {
572     // During formal parameter list parsing the scope only contains
573     // two variables inserted at initialization: "this" and "arguments".
574     // "this" is an invalid parameter name and "arguments" is invalid parameter
575     // name in strict mode. Therefore looking up with the map which includes
576     // "this" and "arguments" in addition to all formal parameters is safe.
577     return variables_.Lookup(name) != NULL;
578   }
579 
IsDeclaredParameter(const AstRawString * name)580   bool IsDeclaredParameter(const AstRawString* name) {
581     // If IsSimpleParameterList is false, duplicate parameters are not allowed,
582     // however `arguments` may be allowed if function is not strict code. Thus,
583     // the assumptions explained above do not hold.
584     return params_.Contains(variables_.Lookup(name));
585   }
586 
sloppy_block_function_map()587   SloppyBlockFunctionMap* sloppy_block_function_map() {
588     return &sloppy_block_function_map_;
589   }
590 
591   // Error handling.
592   void ReportMessage(int start_position, int end_position,
593                      MessageTemplate::Template message,
594                      const AstRawString* arg);
595 
596   // ---------------------------------------------------------------------------
597   // Debugging.
598 
599 #ifdef DEBUG
600   void Print(int n = 0);  // n = indentation; n < 0 => don't print recursively
601 #endif
602 
603   // ---------------------------------------------------------------------------
604   // Implementation.
605  private:
606   // Scope tree.
607   Scope* outer_scope_;  // the immediately enclosing outer scope, or NULL
608   ZoneList<Scope*> inner_scopes_;  // the immediately enclosed inner scopes
609 
610   // The scope type.
611   ScopeType scope_type_;
612   // If the scope is a function scope, this is the function kind.
613   FunctionKind function_kind_;
614 
615   // Debugging support.
616   const AstRawString* scope_name_;
617 
618   // The variables declared in this scope:
619   //
620   // All user-declared variables (incl. parameters).  For script scopes
621   // variables may be implicitly 'declared' by being used (possibly in
622   // an inner scope) with no intervening with statements or eval calls.
623   VariableMap variables_;
624   // Compiler-allocated (user-invisible) temporaries.
625   ZoneList<Variable*> temps_;
626   // Parameter list in source order.
627   ZoneList<Variable*> params_;
628   // Variables that must be looked up dynamically.
629   DynamicScopePart* dynamics_;
630   // Unresolved variables referred to from this scope.
631   ZoneList<VariableProxy*> unresolved_;
632   // Declarations.
633   ZoneList<Declaration*> decls_;
634   // Convenience variable.
635   Variable* receiver_;
636   // Function variable, if any; function scopes only.
637   VariableDeclaration* function_;
638   // new.target variable, function scopes only.
639   Variable* new_target_;
640   // Convenience variable; function scopes only.
641   Variable* arguments_;
642   // Convenience variable; Subclass constructor only
643   Variable* this_function_;
644   // Module descriptor; module scopes only.
645   ModuleDescriptor* module_descriptor_;
646 
647   // Map of function names to lists of functions defined in sloppy blocks
648   SloppyBlockFunctionMap sloppy_block_function_map_;
649 
650   // Illegal redeclaration.
651   Expression* illegal_redecl_;
652 
653   // Scope-specific information computed during parsing.
654   //
655   // This scope is inside a 'with' of some outer scope.
656   bool scope_inside_with_;
657   // This scope contains a 'with' statement.
658   bool scope_contains_with_;
659   // This scope or a nested catch scope or with scope contain an 'eval' call. At
660   // the 'eval' call site this scope is the declaration scope.
661   bool scope_calls_eval_;
662   // This scope uses "arguments".
663   bool scope_uses_arguments_;
664   // This scope uses "super" property ('super.foo').
665   bool scope_uses_super_property_;
666   // This scope contains an "use asm" annotation.
667   bool asm_module_;
668   // This scope's outer context is an asm module.
669   bool asm_function_;
670   // This scope's declarations might not be executed in order (e.g., switch).
671   bool scope_nonlinear_;
672   // The language mode of this scope.
673   LanguageMode language_mode_;
674   // Source positions.
675   int start_position_;
676   int end_position_;
677 
678   // Computed via PropagateScopeInfo.
679   bool outer_scope_calls_sloppy_eval_;
680   bool inner_scope_calls_eval_;
681   bool force_eager_compilation_;
682   bool force_context_allocation_;
683 
684   // True if it doesn't need scope resolution (e.g., if the scope was
685   // constructed based on a serialized scope info or a catch context).
686   bool already_resolved_;
687 
688   // True if it holds 'var' declarations.
689   bool is_declaration_scope_;
690 
691   // Computed as variables are declared.
692   int num_var_or_const_;
693 
694   // Computed via AllocateVariables; function, block and catch scopes only.
695   int num_stack_slots_;
696   int num_heap_slots_;
697   int num_global_slots_;
698 
699   // Info about the parameter list of a function.
700   int arity_;
701   bool has_simple_parameters_;
702   Variable* rest_parameter_;
703   int rest_index_;
704 
705   // Serialized scope info support.
706   Handle<ScopeInfo> scope_info_;
already_resolved()707   bool already_resolved() { return already_resolved_; }
708 
709   // Create a non-local variable with a given name.
710   // These variables are looked up dynamically at runtime.
711   Variable* NonLocal(const AstRawString* name, VariableMode mode);
712 
713   // Variable resolution.
714   // Possible results of a recursive variable lookup telling if and how a
715   // variable is bound. These are returned in the output parameter *binding_kind
716   // of the LookupRecursive function.
717   enum BindingKind {
718     // The variable reference could be statically resolved to a variable binding
719     // which is returned. There is no 'with' statement between the reference and
720     // the binding and no scope between the reference scope (inclusive) and
721     // binding scope (exclusive) makes a sloppy 'eval' call.
722     BOUND,
723 
724     // The variable reference could be statically resolved to a variable binding
725     // which is returned. There is no 'with' statement between the reference and
726     // the binding, but some scope between the reference scope (inclusive) and
727     // binding scope (exclusive) makes a sloppy 'eval' call, that might
728     // possibly introduce variable bindings shadowing the found one. Thus the
729     // found variable binding is just a guess.
730     BOUND_EVAL_SHADOWED,
731 
732     // The variable reference could not be statically resolved to any binding
733     // and thus should be considered referencing a global variable. NULL is
734     // returned. The variable reference is not inside any 'with' statement and
735     // no scope between the reference scope (inclusive) and script scope
736     // (exclusive) makes a sloppy 'eval' call.
737     UNBOUND,
738 
739     // The variable reference could not be statically resolved to any binding
740     // NULL is returned. The variable reference is not inside any 'with'
741     // statement, but some scope between the reference scope (inclusive) and
742     // script scope (exclusive) makes a sloppy 'eval' call, that might
743     // possibly introduce a variable binding. Thus the reference should be
744     // considered referencing a global variable unless it is shadowed by an
745     // 'eval' introduced binding.
746     UNBOUND_EVAL_SHADOWED,
747 
748     // The variable could not be statically resolved and needs to be looked up
749     // dynamically. NULL is returned. There are two possible reasons:
750     // * A 'with' statement has been encountered and there is no variable
751     //   binding for the name between the variable reference and the 'with'.
752     //   The variable potentially references a property of the 'with' object.
753     // * The code is being executed as part of a call to 'eval' and the calling
754     //   context chain contains either a variable binding for the name or it
755     //   contains a 'with' context.
756     DYNAMIC_LOOKUP
757   };
758 
759   // Lookup a variable reference given by name recursively starting with this
760   // scope. If the code is executed because of a call to 'eval', the context
761   // parameter should be set to the calling context of 'eval'.
762   Variable* LookupRecursive(VariableProxy* proxy, BindingKind* binding_kind,
763                             AstNodeFactory* factory);
764   MUST_USE_RESULT
765   bool ResolveVariable(ParseInfo* info, VariableProxy* proxy,
766                        AstNodeFactory* factory);
767   MUST_USE_RESULT
768   bool ResolveVariablesRecursively(ParseInfo* info, AstNodeFactory* factory);
769 
770   bool CheckStrongModeDeclaration(VariableProxy* proxy, Variable* var);
771 
772   // If this scope is a method scope of a class, return the corresponding
773   // class variable, otherwise nullptr.
774   ClassVariable* ClassVariableForMethod() const;
775 
776   // Scope analysis.
777   void PropagateScopeInfo(bool outer_scope_calls_sloppy_eval);
778   bool HasTrivialContext() const;
779 
780   // Predicates.
781   bool MustAllocate(Variable* var);
782   bool MustAllocateInContext(Variable* var);
783   bool HasArgumentsParameter(Isolate* isolate);
784 
785   // Variable allocation.
786   void AllocateStackSlot(Variable* var);
787   void AllocateHeapSlot(Variable* var);
788   void AllocateParameterLocals(Isolate* isolate);
789   void AllocateNonParameterLocal(Isolate* isolate, Variable* var);
790   void AllocateDeclaredGlobal(Isolate* isolate, Variable* var);
791   void AllocateNonParameterLocalsAndDeclaredGlobals(Isolate* isolate);
792   void AllocateVariablesRecursively(Isolate* isolate);
793   void AllocateParameter(Variable* var, int index);
794   void AllocateReceiver();
795 
796   // Resolve and fill in the allocation information for all variables
797   // in this scopes. Must be called *after* all scopes have been
798   // processed (parsed) to ensure that unresolved variables can be
799   // resolved properly.
800   //
801   // In the case of code compiled and run using 'eval', the context
802   // parameter is the context in which eval was called.  In all other
803   // cases the context parameter is an empty handle.
804   MUST_USE_RESULT
805   bool AllocateVariables(ParseInfo* info, AstNodeFactory* factory);
806 
807   // Construct a scope based on the scope info.
808   Scope(Zone* zone, Scope* inner_scope, ScopeType type,
809         Handle<ScopeInfo> scope_info, AstValueFactory* value_factory);
810 
811   // Construct a catch scope with a binding for the name.
812   Scope(Zone* zone, Scope* inner_scope, const AstRawString* catch_variable_name,
813         AstValueFactory* value_factory);
814 
AddInnerScope(Scope * inner_scope)815   void AddInnerScope(Scope* inner_scope) {
816     if (inner_scope != NULL) {
817       inner_scopes_.Add(inner_scope, zone_);
818       inner_scope->outer_scope_ = this;
819     }
820   }
821 
RemoveInnerScope(Scope * inner_scope)822   void RemoveInnerScope(Scope* inner_scope) {
823     DCHECK_NOT_NULL(inner_scope);
824     for (int i = 0; i < inner_scopes_.length(); i++) {
825       if (inner_scopes_[i] == inner_scope) {
826         inner_scopes_.Remove(i);
827         break;
828       }
829     }
830   }
831 
832   void SetDefaults(ScopeType type, Scope* outer_scope,
833                    Handle<ScopeInfo> scope_info,
834                    FunctionKind function_kind = kNormalFunction);
835 
836   AstValueFactory* ast_value_factory_;
837   Zone* zone_;
838 
839   PendingCompilationErrorHandler pending_error_handler_;
840 
841   // For tracking which classes are declared consecutively. Needed for strong
842   // mode.
843   int class_declaration_group_start_;
844 };
845 
846 }  // namespace internal
847 }  // namespace v8
848 
849 #endif  // V8_AST_SCOPES_H_
850