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