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