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