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