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