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 <numeric> 9 10 #include "src/ast/ast.h" 11 #include "src/base/compiler-specific.h" 12 #include "src/base/hashmap.h" 13 #include "src/base/pointer-with-payload.h" 14 #include "src/base/threaded-list.h" 15 #include "src/common/globals.h" 16 #include "src/objects/function-kind.h" 17 #include "src/objects/objects.h" 18 #include "src/utils/utils.h" 19 #include "src/zone/zone-hashmap.h" 20 #include "src/zone/zone.h" 21 22 namespace v8 { 23 24 namespace internal { 25 class Scope; 26 } // namespace internal 27 28 namespace base { 29 template <> 30 struct PointerWithPayloadTraits<v8::internal::Scope> { 31 static constexpr int kAvailableBits = 1; 32 }; 33 } // namespace base 34 35 namespace internal { 36 37 class AstNodeFactory; 38 class AstValueFactory; 39 class AstRawString; 40 class Declaration; 41 class ParseInfo; 42 class Parser; 43 class PreparseDataBuilder; 44 class SloppyBlockFunctionStatement; 45 class Statement; 46 class StringSet; 47 class VariableProxy; 48 49 using UnresolvedList = 50 base::ThreadedList<VariableProxy, VariableProxy::UnresolvedNext>; 51 52 // A hash map to support fast variable declaration and lookup. 53 class VariableMap : public ZoneHashMap { 54 public: 55 explicit VariableMap(Zone* zone); 56 VariableMap(const VariableMap& other, Zone* zone); 57 58 VariableMap(VariableMap&& other) V8_NOEXCEPT : ZoneHashMap(std::move(other)) { 59 } 60 61 VariableMap& operator=(VariableMap&& other) V8_NOEXCEPT { 62 static_cast<ZoneHashMap&>(*this) = std::move(other); 63 return *this; 64 } 65 66 Variable* Declare(Zone* zone, Scope* scope, const AstRawString* name, 67 VariableMode mode, VariableKind kind, 68 InitializationFlag initialization_flag, 69 MaybeAssignedFlag maybe_assigned_flag, 70 IsStaticFlag is_static_flag, bool* was_added); 71 72 V8_EXPORT_PRIVATE Variable* Lookup(const AstRawString* name); 73 void Remove(Variable* var); 74 void Add(Variable* var); 75 76 Zone* zone() const { return allocator().zone(); } 77 }; 78 79 // Global invariants after AST construction: Each reference (i.e. identifier) 80 // to a JavaScript variable (including global properties) is represented by a 81 // VariableProxy node. Immediately after AST construction and before variable 82 // allocation, most VariableProxy nodes are "unresolved", i.e. not bound to a 83 // corresponding variable (though some are bound during parse time). Variable 84 // allocation binds each unresolved VariableProxy to one Variable and assigns 85 // a location. Note that many VariableProxy nodes may refer to the same Java- 86 // Script variable. 87 88 // JS environments are represented in the parser using Scope, DeclarationScope 89 // and ModuleScope. DeclarationScope is used for any scope that hosts 'var' 90 // declarations. This includes script, module, eval, varblock, and function 91 // scope. ModuleScope further specializes DeclarationScope. 92 class V8_EXPORT_PRIVATE Scope : public NON_EXPORTED_BASE(ZoneObject) { 93 public: 94 // --------------------------------------------------------------------------- 95 // Construction 96 97 Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type); 98 99 #ifdef DEBUG 100 // The scope name is only used for printing/debugging. 101 void SetScopeName(const AstRawString* scope_name) { 102 scope_name_ = scope_name; 103 } 104 #endif 105 106 DeclarationScope* AsDeclarationScope(); 107 const DeclarationScope* AsDeclarationScope() const; 108 ModuleScope* AsModuleScope(); 109 const ModuleScope* AsModuleScope() const; 110 ClassScope* AsClassScope(); 111 const ClassScope* AsClassScope() const; 112 113 class Snapshot final { 114 public: 115 inline explicit Snapshot(Scope* scope); 116 117 // Disallow copy and move. 118 Snapshot(const Snapshot&) = delete; 119 Snapshot(Snapshot&&) = delete; 120 121 ~Snapshot() { 122 // Restore eval flags from before the scope was active. 123 if (sloppy_eval_can_extend_vars_) { 124 declaration_scope_->sloppy_eval_can_extend_vars_ = true; 125 } 126 if (calls_eval_) { 127 outer_scope_->calls_eval_ = true; 128 } 129 } 130 131 void Reparent(DeclarationScope* new_parent); 132 133 private: 134 Scope* outer_scope_; 135 Scope* declaration_scope_; 136 Scope* top_inner_scope_; 137 UnresolvedList::Iterator top_unresolved_; 138 base::ThreadedList<Variable>::Iterator top_local_; 139 // While the scope is active, the scope caches the flag values for 140 // outer_scope_ / declaration_scope_ they can be used to know what happened 141 // while parsing the arrow head. If this turns out to be an arrow head, new 142 // values on the respective scopes will be cleared and moved to the inner 143 // scope. Otherwise the cached flags will be merged with the flags from the 144 // arrow head. 145 bool calls_eval_; 146 bool sloppy_eval_can_extend_vars_; 147 }; 148 149 enum class DeserializationMode { kIncludingVariables, kScopesOnly }; 150 151 template <typename IsolateT> 152 EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) 153 static Scope* DeserializeScopeChain(IsolateT* isolate, Zone* zone, 154 ScopeInfo scope_info, 155 DeclarationScope* script_scope, 156 AstValueFactory* ast_value_factory, 157 DeserializationMode deserialization_mode); 158 159 template <typename IsolateT> 160 EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) 161 static void SetScriptScopeInfo(IsolateT* isolate, 162 DeclarationScope* script_scope); 163 164 // Checks if the block scope is redundant, i.e. it does not contain any 165 // block scoped declarations. In that case it is removed from the scope 166 // tree and its children are reparented. 167 Scope* FinalizeBlockScope(); 168 169 // Inserts outer_scope into this scope's scope chain (and removes this 170 // from the current outer_scope_'s inner scope list). 171 // Assumes outer_scope_ is non-null. 172 void ReplaceOuterScope(Scope* outer_scope); 173 174 Zone* zone() const { return variables_.zone(); } 175 176 void SetMustUsePreparseData() { 177 if (must_use_preparsed_scope_data_) { 178 return; 179 } 180 must_use_preparsed_scope_data_ = true; 181 if (outer_scope_) { 182 outer_scope_->SetMustUsePreparseData(); 183 } 184 } 185 186 bool must_use_preparsed_scope_data() const { 187 return must_use_preparsed_scope_data_; 188 } 189 190 // --------------------------------------------------------------------------- 191 // Declarations 192 193 // Lookup a variable in this scope. Returns the variable or nullptr if not 194 // found. 195 Variable* LookupLocal(const AstRawString* name) { 196 DCHECK(scope_info_.is_null()); 197 return variables_.Lookup(name); 198 } 199 200 Variable* LookupInScopeInfo(const AstRawString* name, Scope* cache); 201 202 // Declare a local variable in this scope. If the variable has been 203 // declared before, the previously declared variable is returned. 204 Variable* DeclareLocal(const AstRawString* name, VariableMode mode, 205 VariableKind kind, bool* was_added, 206 InitializationFlag init_flag = kCreatedInitialized); 207 208 Variable* DeclareVariable(Declaration* declaration, const AstRawString* name, 209 int pos, VariableMode mode, VariableKind kind, 210 InitializationFlag init, bool* was_added, 211 bool* sloppy_mode_block_scope_function_redefinition, 212 bool* ok); 213 214 // Returns nullptr if there was a declaration conflict. 215 Variable* DeclareVariableName(const AstRawString* name, VariableMode mode, 216 bool* was_added, 217 VariableKind kind = NORMAL_VARIABLE); 218 Variable* DeclareCatchVariableName(const AstRawString* name); 219 220 Variable* DeclareHomeObjectVariable(AstValueFactory* ast_value_factory); 221 Variable* DeclareStaticHomeObjectVariable(AstValueFactory* ast_value_factory); 222 223 // Declarations list. 224 base::ThreadedList<Declaration>* declarations() { return &decls_; } 225 226 base::ThreadedList<Variable>* locals() { return &locals_; } 227 228 // Create a new unresolved variable. 229 VariableProxy* NewUnresolved(AstNodeFactory* factory, 230 const AstRawString* name, int start_pos, 231 VariableKind kind = NORMAL_VARIABLE) { 232 // Note that we must not share the unresolved variables with 233 // the same name because they may be removed selectively via 234 // RemoveUnresolved(). 235 DCHECK(!already_resolved_); 236 DCHECK_EQ(factory->zone(), zone()); 237 VariableProxy* proxy = factory->NewVariableProxy(name, kind, start_pos); 238 AddUnresolved(proxy); 239 return proxy; 240 } 241 242 void AddUnresolved(VariableProxy* proxy); 243 244 // Removes an unresolved variable from the list so it can be readded to 245 // another list. This is used to reparent parameter initializers that contain 246 // sloppy eval. 247 bool RemoveUnresolved(VariableProxy* var); 248 249 // Deletes an unresolved variable. The variable proxy cannot be reused for 250 // another list later. During parsing, an unresolved variable may have been 251 // added optimistically, but then only the variable name was used (typically 252 // for labels and arrow function parameters). If the variable was not 253 // declared, the addition introduced a new unresolved variable which may end 254 // up being allocated globally as a "ghost" variable. DeleteUnresolved removes 255 // such a variable again if it was added; otherwise this is a no-op. 256 void DeleteUnresolved(VariableProxy* var); 257 258 // Creates a new temporary variable in this scope's TemporaryScope. The 259 // name is only used for printing and cannot be used to find the variable. 260 // In particular, the only way to get hold of the temporary is by keeping the 261 // Variable* around. The name should not clash with a legitimate variable 262 // names. 263 // TODO(verwaest): Move to DeclarationScope? 264 Variable* NewTemporary(const AstRawString* name); 265 266 // Find variable with (variable->mode() <= |mode_limit|) that was declared in 267 // |scope|. This is used to catch patterns like `try{}catch(e){let e;}` and 268 // function([e]) { let e }, which are errors even though the two 'e's are each 269 // time declared in different scopes. Returns the first duplicate variable 270 // name if there is one, nullptr otherwise. 271 const AstRawString* FindVariableDeclaredIn(Scope* scope, 272 VariableMode mode_limit); 273 274 // --------------------------------------------------------------------------- 275 // Scope-specific info. 276 277 // Inform the scope and outer scopes that the corresponding code contains an 278 // eval call. 279 inline void RecordEvalCall(); 280 281 void RecordInnerScopeEvalCall() { 282 inner_scope_calls_eval_ = true; 283 for (Scope* scope = outer_scope(); scope != nullptr; 284 scope = scope->outer_scope()) { 285 if (scope->inner_scope_calls_eval_) return; 286 scope->inner_scope_calls_eval_ = true; 287 } 288 } 289 290 // Set the language mode flag (unless disabled by a global flag). 291 void SetLanguageMode(LanguageMode language_mode) { 292 DCHECK(!is_module_scope() || is_strict(language_mode)); 293 set_language_mode(language_mode); 294 } 295 296 // Inform the scope that the scope may execute declarations nonlinearly. 297 // Currently, the only nonlinear scope is a switch statement. The name is 298 // more general in case something else comes up with similar control flow, 299 // for example the ability to break out of something which does not have 300 // its own lexical scope. 301 // The bit does not need to be stored on the ScopeInfo because none of 302 // the three compilers will perform hole check elimination on a variable 303 // located in VariableLocation::CONTEXT. So, direct eval and closures 304 // will not expose holes. 305 void SetNonlinear() { scope_nonlinear_ = true; } 306 307 // Position in the source where this scope begins and ends. 308 // 309 // * For the scope of a with statement 310 // with (obj) stmt 311 // start position: start position of first token of 'stmt' 312 // end position: end position of last token of 'stmt' 313 // * For the scope of a block 314 // { stmts } 315 // start position: start position of '{' 316 // end position: end position of '}' 317 // * For the scope of a function literal or decalaration 318 // function fun(a,b) { stmts } 319 // start position: start position of '(' 320 // end position: end position of '}' 321 // * For the scope of a catch block 322 // try { stms } catch(e) { stmts } 323 // start position: start position of '(' 324 // end position: end position of ')' 325 // * For the scope of a for-statement 326 // for (let x ...) stmt 327 // start position: start position of '(' 328 // end position: end position of last token of 'stmt' 329 // * For the scope of a switch statement 330 // switch (tag) { cases } 331 // start position: start position of '{' 332 // end position: end position of '}' 333 int start_position() const { return start_position_; } 334 void set_start_position(int statement_pos) { 335 start_position_ = statement_pos; 336 } 337 int end_position() const { return end_position_; } 338 void set_end_position(int statement_pos) { end_position_ = statement_pos; } 339 340 // Scopes created for desugaring are hidden. I.e. not visible to the debugger. 341 bool is_hidden() const { return is_hidden_; } 342 void set_is_hidden() { is_hidden_ = true; } 343 344 void ForceContextAllocationForParameters() { 345 DCHECK(!already_resolved_); 346 force_context_allocation_for_parameters_ = true; 347 } 348 bool has_forced_context_allocation_for_parameters() const { 349 return force_context_allocation_for_parameters_; 350 } 351 352 // --------------------------------------------------------------------------- 353 // Predicates. 354 355 // Specific scope types. 356 bool is_eval_scope() const { return scope_type_ == EVAL_SCOPE; } 357 bool is_function_scope() const { return scope_type_ == FUNCTION_SCOPE; } 358 bool is_module_scope() const { return scope_type_ == MODULE_SCOPE; } 359 bool is_script_scope() const { return scope_type_ == SCRIPT_SCOPE; } 360 bool is_catch_scope() const { return scope_type_ == CATCH_SCOPE; } 361 bool is_block_scope() const { 362 return scope_type_ == BLOCK_SCOPE || scope_type_ == CLASS_SCOPE; 363 } 364 bool is_with_scope() const { return scope_type_ == WITH_SCOPE; } 365 bool is_declaration_scope() const { return is_declaration_scope_; } 366 bool is_class_scope() const { return scope_type_ == CLASS_SCOPE; } 367 bool is_home_object_scope() const { 368 return is_class_scope() || 369 (is_block_scope() && is_block_scope_for_object_literal_); 370 } 371 bool is_block_scope_for_object_literal() const { 372 DCHECK_IMPLIES(is_block_scope_for_object_literal_, is_block_scope()); 373 return is_block_scope_for_object_literal_; 374 } 375 void set_is_block_scope_for_object_literal() { 376 DCHECK(is_block_scope()); 377 is_block_scope_for_object_literal_ = true; 378 } 379 380 bool inner_scope_calls_eval() const { return inner_scope_calls_eval_; } 381 bool private_name_lookup_skips_outer_class() const { 382 return private_name_lookup_skips_outer_class_; 383 } 384 385 #if V8_ENABLE_WEBASSEMBLY 386 bool IsAsmModule() const; 387 // Returns true if this scope or any inner scopes that might be eagerly 388 // compiled are asm modules. 389 bool ContainsAsmModule() const; 390 #endif // V8_ENABLE_WEBASSEMBLY 391 392 // Does this scope have the potential to execute declarations non-linearly? 393 bool is_nonlinear() const { return scope_nonlinear_; } 394 // Returns if we need to force a context because the current scope is stricter 395 // than the outerscope. We need this to properly track the language mode using 396 // the context. This is required in ICs where we lookup the language mode 397 // from the context. 398 bool ForceContextForLanguageMode() const { 399 // For function scopes we need not force a context since the language mode 400 // can be obtained from the closure. Script scopes always have a context. 401 if (scope_type_ == FUNCTION_SCOPE || scope_type_ == SCRIPT_SCOPE) { 402 return false; 403 } 404 DCHECK_NOT_NULL(outer_scope_); 405 return (language_mode() > outer_scope_->language_mode()); 406 } 407 408 // Whether this needs to be represented by a runtime context. 409 bool NeedsContext() const { 410 // Catch scopes always have heap slots. 411 DCHECK_IMPLIES(is_catch_scope(), num_heap_slots() > 0); 412 DCHECK_IMPLIES(is_with_scope(), num_heap_slots() > 0); 413 DCHECK_IMPLIES(ForceContextForLanguageMode(), num_heap_slots() > 0); 414 return num_heap_slots() > 0; 415 } 416 417 #ifdef DEBUG 418 bool IsReparsedMemberInitializerScope() const; 419 #endif 420 // Use Scope::ForEach for depth first traversal of scopes. 421 // Before: 422 // void Scope::VisitRecursively() { 423 // DoSomething(); 424 // for (Scope* s = inner_scope_; s != nullptr; s = s->sibling_) { 425 // if (s->ShouldContinue()) continue; 426 // s->VisitRecursively(); 427 // } 428 // } 429 // 430 // After: 431 // void Scope::VisitIteratively() { 432 // this->ForEach([](Scope* s) { 433 // s->DoSomething(); 434 // return s->ShouldContinue() ? kContinue : kDescend; 435 // }); 436 // } 437 template <typename FunctionType> 438 V8_INLINE void ForEach(FunctionType callback); 439 enum Iteration { 440 // Continue the iteration on the same level, do not recurse/descent into 441 // inner scopes. 442 kContinue, 443 // Recurse/descend into inner scopes. 444 kDescend 445 }; 446 447 bool IsConstructorScope() const; 448 449 // Check is this scope is an outer scope of the given scope. 450 bool IsOuterScopeOf(Scope* other) const; 451 452 // --------------------------------------------------------------------------- 453 // Accessors. 454 455 // The type of this scope. 456 ScopeType scope_type() const { return scope_type_; } 457 458 // The language mode of this scope. 459 LanguageMode language_mode() const { 460 return is_strict_ ? LanguageMode::kStrict : LanguageMode::kSloppy; 461 } 462 463 // inner_scope() and sibling() together implement the inner scope list of a 464 // scope. Inner scope points to the an inner scope of the function, and 465 // "sibling" points to a next inner scope of the outer scope of this scope. 466 Scope* inner_scope() const { return inner_scope_; } 467 Scope* sibling() const { return sibling_; } 468 469 // The scope immediately surrounding this scope, or nullptr. 470 Scope* outer_scope() const { return outer_scope_; } 471 472 Variable* catch_variable() const { 473 DCHECK(is_catch_scope()); 474 DCHECK_EQ(1, num_var()); 475 return static_cast<Variable*>(variables_.Start()->value); 476 } 477 478 bool ShouldBanArguments(); 479 480 // --------------------------------------------------------------------------- 481 // Variable allocation. 482 483 // Result of variable allocation. 484 int num_stack_slots() const { return num_stack_slots_; } 485 int num_heap_slots() const { return num_heap_slots_; } 486 487 bool HasContextExtensionSlot() const { 488 switch (scope_type_) { 489 case MODULE_SCOPE: 490 case WITH_SCOPE: // DebugEvaluateContext as well 491 return true; 492 default: 493 DCHECK_IMPLIES(sloppy_eval_can_extend_vars_, 494 scope_type_ == FUNCTION_SCOPE || 495 scope_type_ == EVAL_SCOPE || 496 scope_type_ == BLOCK_SCOPE); 497 DCHECK_IMPLIES(sloppy_eval_can_extend_vars_, is_declaration_scope()); 498 return sloppy_eval_can_extend_vars_; 499 } 500 UNREACHABLE(); 501 } 502 int ContextHeaderLength() const { 503 return HasContextExtensionSlot() ? Context::MIN_CONTEXT_EXTENDED_SLOTS 504 : Context::MIN_CONTEXT_SLOTS; 505 } 506 507 int ContextLocalCount() const; 508 509 // Determine if we can parse a function literal in this scope lazily without 510 // caring about the unresolved variables within. 511 bool AllowsLazyParsingWithoutUnresolvedVariables(const Scope* outer) const; 512 513 // The number of contexts between this and scope; zero if this == scope. 514 int ContextChainLength(Scope* scope) const; 515 516 // The number of contexts between this and the outermost context that has a 517 // sloppy eval call. One if this->sloppy_eval_can_extend_vars(). 518 int ContextChainLengthUntilOutermostSloppyEval() const; 519 520 // Find the first function, script, eval or (declaration) block scope. This is 521 // the scope where var declarations will be hoisted to in the implementation. 522 DeclarationScope* GetDeclarationScope(); 523 524 // Find the first function, script, or (declaration) block scope. 525 // This is the scope where var declarations will be hoisted to in the 526 // implementation, including vars in direct sloppy eval calls. 527 // 528 // TODO(leszeks): Check how often we skip eval scopes in GetDeclarationScope, 529 // and possibly merge this with GetDeclarationScope. 530 DeclarationScope* GetNonEvalDeclarationScope(); 531 532 // Find the first non-block declaration scope. This should be either a script, 533 // function, or eval scope. Same as DeclarationScope(), but skips declaration 534 // "block" scopes. Used for differentiating associated function objects (i.e., 535 // the scope for which a function prologue allocates a context) or declaring 536 // temporaries. 537 DeclarationScope* GetClosureScope(); 538 const DeclarationScope* GetClosureScope() const; 539 540 // Find the first (non-arrow) function or script scope. This is where 541 // 'this' is bound, and what determines the function kind. 542 DeclarationScope* GetReceiverScope(); 543 544 // Find the first constructor scope. Its outer scope is where the instance 545 // members that should be initialized right after super() is called 546 // are declared. 547 DeclarationScope* GetConstructorScope(); 548 549 // Find the first class scope or object literal block scope. This is where 550 // 'super' is bound. 551 Scope* GetHomeObjectScope(); 552 553 DeclarationScope* GetScriptScope(); 554 555 // Find the innermost outer scope that needs a context. 556 Scope* GetOuterScopeWithContext(); 557 558 bool HasThisReference() const; 559 560 // Analyze() must have been called once to create the ScopeInfo. 561 Handle<ScopeInfo> scope_info() const { 562 DCHECK(!scope_info_.is_null()); 563 return scope_info_; 564 } 565 566 int num_var() const { return variables_.occupancy(); } 567 568 // --------------------------------------------------------------------------- 569 // Debugging. 570 571 #ifdef DEBUG 572 void Print(int n = 0); // n = indentation; n < 0 => don't print recursively 573 574 // Check that the scope has positions assigned. 575 void CheckScopePositions(); 576 577 // Check that all Scopes in the scope tree use the same Zone. 578 void CheckZones(); 579 #endif 580 581 // Retrieve `IsSimpleParameterList` of current or outer function. 582 bool HasSimpleParameters(); 583 void set_is_debug_evaluate_scope() { is_debug_evaluate_scope_ = true; } 584 bool is_debug_evaluate_scope() const { return is_debug_evaluate_scope_; } 585 bool IsSkippableFunctionScope(); 586 void set_is_repl_mode_scope() { is_repl_mode_scope_ = true; } 587 bool is_repl_mode_scope() const { 588 DCHECK_IMPLIES(is_repl_mode_scope_, is_script_scope()); 589 return is_repl_mode_scope_; 590 } 591 void set_deserialized_scope_uses_external_cache() { 592 deserialized_scope_uses_external_cache_ = true; 593 } 594 bool deserialized_scope_uses_external_cache() const { 595 return deserialized_scope_uses_external_cache_; 596 } 597 598 bool needs_home_object() const { 599 DCHECK(is_home_object_scope()); 600 return needs_home_object_; 601 } 602 603 void set_needs_home_object() { 604 DCHECK(is_home_object_scope()); 605 needs_home_object_ = true; 606 } 607 608 VariableProxy* NewHomeObjectVariableProxy(AstNodeFactory* factory, 609 const AstRawString* name, 610 int start_pos); 611 612 bool RemoveInnerScope(Scope* inner_scope) { 613 DCHECK_NOT_NULL(inner_scope); 614 if (inner_scope == inner_scope_) { 615 inner_scope_ = inner_scope_->sibling_; 616 return true; 617 } 618 for (Scope* scope = inner_scope_; scope != nullptr; 619 scope = scope->sibling_) { 620 if (scope->sibling_ == inner_scope) { 621 scope->sibling_ = scope->sibling_->sibling_; 622 return true; 623 } 624 } 625 return false; 626 } 627 628 Variable* LookupInScopeOrScopeInfo(const AstRawString* name, Scope* cache) { 629 Variable* var = variables_.Lookup(name); 630 if (var != nullptr || scope_info_.is_null()) return var; 631 return LookupInScopeInfo(name, cache); 632 } 633 634 Variable* LookupForTesting(const AstRawString* name) { 635 for (Scope* scope = this; scope != nullptr; scope = scope->outer_scope()) { 636 Variable* var = scope->LookupInScopeOrScopeInfo(name, scope); 637 if (var != nullptr) return var; 638 } 639 return nullptr; 640 } 641 642 protected: 643 explicit Scope(Zone* zone); 644 645 void set_language_mode(LanguageMode language_mode) { 646 is_strict_ = is_strict(language_mode); 647 } 648 649 private: 650 Variable* Declare(Zone* zone, const AstRawString* name, VariableMode mode, 651 VariableKind kind, InitializationFlag initialization_flag, 652 MaybeAssignedFlag maybe_assigned_flag, bool* was_added) { 653 // Static variables can only be declared using ClassScope methods. 654 Variable* result = variables_.Declare( 655 zone, this, name, mode, kind, initialization_flag, maybe_assigned_flag, 656 IsStaticFlag::kNotStatic, was_added); 657 if (*was_added) locals_.Add(result); 658 return result; 659 } 660 661 // This method should only be invoked on scopes created during parsing (i.e., 662 // not deserialized from a context). Also, since NeedsContext() is only 663 // returning a valid result after variables are resolved, NeedsScopeInfo() 664 // should also be invoked after resolution. 665 bool NeedsScopeInfo() const; 666 667 Variable* NewTemporary(const AstRawString* name, 668 MaybeAssignedFlag maybe_assigned); 669 670 // Walk the scope chain to find DeclarationScopes; call 671 // SavePreparseDataForDeclarationScope for each. 672 void SavePreparseData(Parser* parser); 673 674 // Create a non-local variable with a given name. 675 // These variables are looked up dynamically at runtime. 676 Variable* NonLocal(const AstRawString* name, VariableMode mode); 677 678 enum ScopeLookupMode { 679 kParsedScope, 680 kDeserializedScope, 681 }; 682 683 // Variable resolution. 684 // Lookup a variable reference given by name starting with this scope, and 685 // stopping when reaching the outer_scope_end scope. If the code is executed 686 // because of a call to 'eval', the context parameter should be set to the 687 // calling context of 'eval'. 688 template <ScopeLookupMode mode> 689 static Variable* Lookup(VariableProxy* proxy, Scope* scope, 690 Scope* outer_scope_end, Scope* cache_scope = nullptr, 691 bool force_context_allocation = false); 692 static Variable* LookupWith(VariableProxy* proxy, Scope* scope, 693 Scope* outer_scope_end, Scope* cache_scope, 694 bool force_context_allocation); 695 static Variable* LookupSloppyEval(VariableProxy* proxy, Scope* scope, 696 Scope* outer_scope_end, Scope* cache_scope, 697 bool force_context_allocation); 698 static void ResolvePreparsedVariable(VariableProxy* proxy, Scope* scope, 699 Scope* end); 700 void ResolveTo(VariableProxy* proxy, Variable* var); 701 void ResolveVariable(VariableProxy* proxy); 702 V8_WARN_UNUSED_RESULT bool ResolveVariablesRecursively(Scope* end); 703 704 // Finds free variables of this scope. This mutates the unresolved variables 705 // list along the way, so full resolution cannot be done afterwards. 706 void AnalyzePartially(DeclarationScope* max_outer_scope, 707 AstNodeFactory* ast_node_factory, 708 UnresolvedList* new_unresolved_list, 709 bool maybe_in_arrowhead); 710 void CollectNonLocals(DeclarationScope* max_outer_scope, Isolate* isolate, 711 Handle<StringSet>* non_locals); 712 713 // Predicates. 714 bool MustAllocate(Variable* var); 715 bool MustAllocateInContext(Variable* var); 716 717 // Variable allocation. 718 void AllocateStackSlot(Variable* var); 719 V8_INLINE void AllocateHeapSlot(Variable* var); 720 void AllocateNonParameterLocal(Variable* var); 721 void AllocateDeclaredGlobal(Variable* var); 722 V8_INLINE void AllocateNonParameterLocalsAndDeclaredGlobals(); 723 void AllocateVariablesRecursively(); 724 725 template <typename IsolateT> 726 void AllocateScopeInfosRecursively(IsolateT* isolate, 727 MaybeHandle<ScopeInfo> outer_scope); 728 729 void AllocateDebuggerScopeInfos(Isolate* isolate, 730 MaybeHandle<ScopeInfo> outer_scope); 731 732 // Construct a scope based on the scope info. 733 Scope(Zone* zone, ScopeType type, AstValueFactory* ast_value_factory, 734 Handle<ScopeInfo> scope_info); 735 736 // Construct a catch scope with a binding for the name. 737 Scope(Zone* zone, const AstRawString* catch_variable_name, 738 MaybeAssignedFlag maybe_assigned, Handle<ScopeInfo> scope_info); 739 740 void AddInnerScope(Scope* inner_scope) { 741 inner_scope->sibling_ = inner_scope_; 742 inner_scope_ = inner_scope; 743 inner_scope->outer_scope_ = this; 744 } 745 746 void SetDefaults(); 747 748 friend class DeclarationScope; 749 friend class ClassScope; 750 friend class ScopeTestHelper; 751 friend Zone; 752 753 // Scope tree. 754 Scope* outer_scope_; // the immediately enclosing outer scope, or nullptr 755 Scope* inner_scope_; // an inner scope of this scope 756 Scope* sibling_; // a sibling inner scope of the outer scope of this scope. 757 758 // The variables declared in this scope: 759 // 760 // All user-declared variables (incl. parameters). For script scopes 761 // variables may be implicitly 'declared' by being used (possibly in 762 // an inner scope) with no intervening with statements or eval calls. 763 VariableMap variables_; 764 // In case of non-scopeinfo-backed scopes, this contains the variables of the 765 // map above in order of addition. 766 base::ThreadedList<Variable> locals_; 767 // Unresolved variables referred to from this scope. The proxies themselves 768 // form a linked list of all unresolved proxies. 769 UnresolvedList unresolved_list_; 770 // Declarations. 771 base::ThreadedList<Declaration> decls_; 772 773 // Serialized scope info support. 774 Handle<ScopeInfo> scope_info_; 775 // Debugging support. 776 #ifdef DEBUG 777 const AstRawString* scope_name_; 778 779 // True if it doesn't need scope resolution (e.g., if the scope was 780 // constructed based on a serialized scope info or a catch context). 781 bool already_resolved_; 782 // True if this scope may contain objects from a temp zone that needs to be 783 // fixed up. 784 bool needs_migration_; 785 #endif 786 787 // Source positions. 788 int start_position_; 789 int end_position_; 790 791 // Computed via AllocateVariables. 792 int num_stack_slots_; 793 int num_heap_slots_; 794 795 // The scope type. 796 const ScopeType scope_type_; 797 798 // Scope-specific information computed during parsing. 799 // 800 // The language mode of this scope. 801 STATIC_ASSERT(LanguageModeSize == 2); 802 bool is_strict_ : 1; 803 // This scope contains an 'eval' call. 804 bool calls_eval_ : 1; 805 // The context associated with this scope can be extended by a sloppy eval 806 // called inside of it. 807 bool sloppy_eval_can_extend_vars_ : 1; 808 // This scope's declarations might not be executed in order (e.g., switch). 809 bool scope_nonlinear_ : 1; 810 bool is_hidden_ : 1; 811 // Temporary workaround that allows masking of 'this' in debug-evaluate 812 // scopes. 813 bool is_debug_evaluate_scope_ : 1; 814 815 // True if one of the inner scopes or the scope itself calls eval. 816 bool inner_scope_calls_eval_ : 1; 817 bool force_context_allocation_for_parameters_ : 1; 818 819 // True if it holds 'var' declarations. 820 bool is_declaration_scope_ : 1; 821 822 // True if the outer scope is a class scope and should be skipped when 823 // resolving private names, i.e. if the scope is in a class heritage 824 // expression. 825 bool private_name_lookup_skips_outer_class_ : 1; 826 827 bool must_use_preparsed_scope_data_ : 1; 828 829 // True if this is a script scope that originated from 830 // DebugEvaluate::GlobalREPL(). 831 bool is_repl_mode_scope_ : 1; 832 833 // True if this is a deserialized scope which caches its lookups on another 834 // Scope's variable map. This will be true for every scope above the first 835 // non-eval declaration scope above the compilation entry point, e.g. for 836 // 837 // function f() { 838 // let g; // prevent sloppy block function hoisting. 839 // with({}) { 840 // function g() { 841 // try { throw 0; } 842 // catch { eval("f"); } 843 // } 844 // g(); 845 // } 846 // } 847 // 848 // the compilation of the eval will have the "with" scope as the first scope 849 // with this flag enabled. 850 bool deserialized_scope_uses_external_cache_ : 1; 851 852 bool needs_home_object_ : 1; 853 bool is_block_scope_for_object_literal_ : 1; 854 }; 855 856 class V8_EXPORT_PRIVATE DeclarationScope : public Scope { 857 public: 858 DeclarationScope(Zone* zone, Scope* outer_scope, ScopeType scope_type, 859 FunctionKind function_kind = FunctionKind::kNormalFunction); 860 DeclarationScope(Zone* zone, ScopeType scope_type, 861 AstValueFactory* ast_value_factory, 862 Handle<ScopeInfo> scope_info); 863 // Creates a script scope. 864 DeclarationScope(Zone* zone, AstValueFactory* ast_value_factory, 865 REPLMode repl_mode = REPLMode::kNo); 866 867 FunctionKind function_kind() const { return function_kind_; } 868 869 // Inform the scope that the corresponding code uses "super". 870 Scope* RecordSuperPropertyUsage() { 871 DCHECK(IsConciseMethod(function_kind()) || 872 IsAccessorFunction(function_kind()) || 873 IsClassConstructor(function_kind())); 874 uses_super_property_ = true; 875 Scope* home_object_scope = GetHomeObjectScope(); 876 DCHECK_NOT_NULL(home_object_scope); 877 home_object_scope->set_needs_home_object(); 878 return home_object_scope; 879 } 880 881 bool uses_super_property() const { return uses_super_property_; } 882 883 bool is_arrow_scope() const { 884 return is_function_scope() && IsArrowFunction(function_kind_); 885 } 886 887 // Inform the scope and outer scopes that the corresponding code contains an 888 // eval call. 889 void RecordDeclarationScopeEvalCall() { 890 calls_eval_ = true; 891 892 // The caller already checked whether we're in sloppy mode. 893 CHECK(is_sloppy(language_mode())); 894 895 // Sloppy eval in script scopes can only introduce global variables anyway, 896 // so we don't care that it calls sloppy eval. 897 if (is_script_scope()) return; 898 899 // Sloppy eval in a eval scope can only introduce variables into the outer 900 // (non-eval) declaration scope, not into this eval scope. 901 if (is_eval_scope()) { 902 #ifdef DEBUG 903 // One of three things must be true: 904 // 1. The outer non-eval declaration scope should already be marked as 905 // being extendable by sloppy eval, by the current sloppy eval rather 906 // than the inner one, 907 // 2. The outer non-eval declaration scope is a script scope and thus 908 // isn't extendable anyway, or 909 // 3. This is a debug evaluate and all bets are off. 910 DeclarationScope* outer_decl_scope = outer_scope()->GetDeclarationScope(); 911 while (outer_decl_scope->is_eval_scope()) { 912 outer_decl_scope = outer_decl_scope->GetDeclarationScope(); 913 } 914 if (outer_decl_scope->is_debug_evaluate_scope()) { 915 // Don't check anything. 916 // TODO(9662): Figure out where variables declared by an eval inside a 917 // debug-evaluate actually go. 918 } else if (!outer_decl_scope->is_script_scope()) { 919 DCHECK(outer_decl_scope->sloppy_eval_can_extend_vars_); 920 } 921 #endif 922 923 return; 924 } 925 926 sloppy_eval_can_extend_vars_ = true; 927 } 928 929 bool sloppy_eval_can_extend_vars() const { 930 return sloppy_eval_can_extend_vars_; 931 } 932 933 bool was_lazily_parsed() const { return was_lazily_parsed_; } 934 935 Variable* LookupInModule(const AstRawString* name) { 936 DCHECK(is_module_scope()); 937 Variable* var = variables_.Lookup(name); 938 DCHECK_NOT_NULL(var); 939 return var; 940 } 941 942 void DeserializeReceiver(AstValueFactory* ast_value_factory); 943 944 #ifdef DEBUG 945 void set_is_being_lazily_parsed(bool is_being_lazily_parsed) { 946 is_being_lazily_parsed_ = is_being_lazily_parsed; 947 } 948 bool is_being_lazily_parsed() const { return is_being_lazily_parsed_; } 949 #endif 950 951 void set_zone(Zone* zone) { 952 #ifdef DEBUG 953 needs_migration_ = true; 954 #endif 955 // Migrate variables_' backing store to new zone. 956 variables_ = VariableMap(variables_, zone); 957 } 958 959 // --------------------------------------------------------------------------- 960 // Illegal redeclaration support. 961 962 // Check if the scope has conflicting var 963 // declarations, i.e. a var declaration that has been hoisted from a nested 964 // scope over a let binding of the same name. 965 Declaration* CheckConflictingVarDeclarations( 966 bool* allowed_catch_binding_var_redeclaration); 967 968 void set_has_checked_syntax(bool has_checked_syntax) { 969 has_checked_syntax_ = has_checked_syntax; 970 } 971 bool has_checked_syntax() const { return has_checked_syntax_; } 972 973 bool ShouldEagerCompile() const { 974 return force_eager_compilation_ || should_eager_compile_; 975 } 976 977 void set_should_eager_compile(); 978 979 void SetScriptScopeInfo(Handle<ScopeInfo> scope_info) { 980 DCHECK(is_script_scope()); 981 DCHECK(scope_info_.is_null()); 982 scope_info_ = scope_info; 983 } 984 985 #if V8_ENABLE_WEBASSEMBLY 986 bool is_asm_module() const { return is_asm_module_; } 987 void set_is_asm_module(); 988 #endif // V8_ENABLE_WEBASSEMBLY 989 990 bool should_ban_arguments() const { 991 return IsClassMembersInitializerFunction(function_kind()); 992 } 993 994 void set_is_async_module() { 995 DCHECK(IsModule(function_kind_)); 996 function_kind_ = FunctionKind::kAsyncModule; 997 } 998 999 void DeclareThis(AstValueFactory* ast_value_factory); 1000 void DeclareArguments(AstValueFactory* ast_value_factory); 1001 void DeclareDefaultFunctionVariables(AstValueFactory* ast_value_factory); 1002 1003 // Declare the function variable for a function literal. This variable 1004 // is in an intermediate scope between this function scope and the the 1005 // outer scope. Only possible for function scopes; at most one variable. 1006 // 1007 // This function needs to be called after all other variables have been 1008 // declared in the scope. It will add a variable for {name} to {variables_}; 1009 // either the function variable itself, or a non-local in case the function 1010 // calls sloppy eval. 1011 Variable* DeclareFunctionVar(const AstRawString* name, 1012 Scope* cache = nullptr); 1013 1014 // Declare some special internal variables which must be accessible to 1015 // Ignition without ScopeInfo. 1016 Variable* DeclareGeneratorObjectVar(const AstRawString* name); 1017 1018 // Declare a parameter in this scope. When there are duplicated 1019 // parameters the rightmost one 'wins'. However, the implementation 1020 // expects all parameters to be declared and from left to right. 1021 Variable* DeclareParameter(const AstRawString* name, VariableMode mode, 1022 bool is_optional, bool is_rest, 1023 AstValueFactory* ast_value_factory, int position); 1024 1025 // Makes sure that num_parameters_ and has_rest is correct for the preparser. 1026 void RecordParameter(bool is_rest); 1027 1028 // Declare an implicit global variable in this scope which must be a 1029 // script scope. The variable was introduced (possibly from an inner 1030 // scope) by a reference to an unresolved variable with no intervening 1031 // with statements or eval calls. 1032 Variable* DeclareDynamicGlobal(const AstRawString* name, 1033 VariableKind variable_kind, Scope* cache); 1034 1035 // The variable corresponding to the 'this' value. 1036 Variable* receiver() { 1037 DCHECK(has_this_declaration() || is_script_scope()); 1038 DCHECK_NOT_NULL(receiver_); 1039 return receiver_; 1040 } 1041 1042 bool has_this_declaration() const { return has_this_declaration_; } 1043 1044 // The variable corresponding to the 'new.target' value. 1045 Variable* new_target_var() { return new_target_; } 1046 1047 // The variable holding the function literal for named function 1048 // literals, or nullptr. Only valid for function scopes. 1049 Variable* function_var() const { return function_; } 1050 1051 // The variable holding the JSGeneratorObject for generator, async 1052 // and async generator functions, and modules. Only valid for 1053 // function, module and REPL mode script scopes. 1054 Variable* generator_object_var() const { 1055 DCHECK(is_function_scope() || is_module_scope() || is_repl_mode_scope()); 1056 return GetRareVariable(RareVariable::kGeneratorObject); 1057 } 1058 1059 // Parameters. The left-most parameter has index 0. 1060 // Only valid for function and module scopes. 1061 Variable* parameter(int index) const { 1062 DCHECK(is_function_scope() || is_module_scope()); 1063 DCHECK(!is_being_lazily_parsed_); 1064 return params_[index]; 1065 } 1066 1067 // Returns the number of formal parameters, excluding a possible rest 1068 // parameter. Examples: 1069 // function foo(a, b) {} ==> 2 1070 // function foo(a, b, ...c) {} ==> 2 1071 // function foo(a, b, c = 1) {} ==> 3 1072 int num_parameters() const { return num_parameters_; } 1073 1074 // The function's rest parameter (nullptr if there is none). 1075 Variable* rest_parameter() const { 1076 return has_rest_ ? params_[params_.length() - 1] : nullptr; 1077 } 1078 1079 bool has_simple_parameters() const { return has_simple_parameters_; } 1080 1081 // TODO(caitp): manage this state in a better way. PreParser must be able to 1082 // communicate that the scope is non-simple, without allocating any parameters 1083 // as the Parser does. This is necessary to ensure that TC39's proposed early 1084 // error can be reported consistently regardless of whether lazily parsed or 1085 // not. 1086 void SetHasNonSimpleParameters() { 1087 DCHECK(is_function_scope()); 1088 has_simple_parameters_ = false; 1089 } 1090 1091 void MakeParametersNonSimple() { 1092 SetHasNonSimpleParameters(); 1093 for (ZoneHashMap::Entry* p = variables_.Start(); p != nullptr; 1094 p = variables_.Next(p)) { 1095 Variable* var = reinterpret_cast<Variable*>(p->value); 1096 if (var->is_parameter()) var->MakeParameterNonSimple(); 1097 } 1098 } 1099 1100 // Returns whether the arguments object aliases formal parameters. 1101 CreateArgumentsType GetArgumentsType() const { 1102 DCHECK(is_function_scope()); 1103 DCHECK(!is_arrow_scope()); 1104 DCHECK_NOT_NULL(arguments_); 1105 return is_sloppy(language_mode()) && has_simple_parameters() 1106 ? CreateArgumentsType::kMappedArguments 1107 : CreateArgumentsType::kUnmappedArguments; 1108 } 1109 1110 // The local variable 'arguments' if we need to allocate it; nullptr 1111 // otherwise. 1112 Variable* arguments() const { 1113 DCHECK_IMPLIES(is_arrow_scope(), arguments_ == nullptr); 1114 return arguments_; 1115 } 1116 1117 Variable* this_function_var() const { 1118 Variable* this_function = GetRareVariable(RareVariable::kThisFunction); 1119 1120 // This is only used in derived constructors atm. 1121 DCHECK(this_function == nullptr || 1122 (is_function_scope() && (IsClassConstructor(function_kind()) || 1123 IsConciseMethod(function_kind()) || 1124 IsAccessorFunction(function_kind())))); 1125 return this_function; 1126 } 1127 1128 // Adds a local variable in this scope's locals list. This is for adjusting 1129 // the scope of temporaries and do-expression vars when desugaring parameter 1130 // initializers. 1131 void AddLocal(Variable* var); 1132 1133 void DeclareSloppyBlockFunction( 1134 SloppyBlockFunctionStatement* sloppy_block_function); 1135 1136 // Go through sloppy_block_functions_ and hoist those (into this scope) 1137 // which should be hoisted. 1138 void HoistSloppyBlockFunctions(AstNodeFactory* factory); 1139 1140 // Compute top scope and allocate variables. For lazy compilation the top 1141 // scope only contains the single lazily compiled function, so this 1142 // doesn't re-allocate variables repeatedly. 1143 // 1144 // Returns false if private names can not be resolved and 1145 // ParseInfo's pending_error_handler will be populated with an 1146 // error. Otherwise, returns true. 1147 V8_WARN_UNUSED_RESULT 1148 static bool Analyze(ParseInfo* info); 1149 1150 // To be called during parsing. Do just enough scope analysis that we can 1151 // discard the Scope contents for lazily compiled functions. In particular, 1152 // this records variables which cannot be resolved inside the Scope (we don't 1153 // yet know what they will resolve to since the outer Scopes are incomplete) 1154 // and recreates them with the correct Zone with ast_node_factory. 1155 void AnalyzePartially(Parser* parser, AstNodeFactory* ast_node_factory, 1156 bool maybe_in_arrowhead); 1157 1158 // Allocate ScopeInfos for top scope and any inner scopes that need them. 1159 // Does nothing if ScopeInfo is already allocated. 1160 template <typename IsolateT> 1161 V8_EXPORT_PRIVATE static void AllocateScopeInfos(ParseInfo* info, 1162 IsolateT* isolate); 1163 1164 Handle<StringSet> CollectNonLocals(Isolate* isolate, 1165 Handle<StringSet> non_locals); 1166 1167 // Determine if we can use lazy compilation for this scope. 1168 bool AllowsLazyCompilation() const; 1169 1170 // Make sure this closure and all outer closures are eagerly compiled. 1171 void ForceEagerCompilation() { 1172 DCHECK_EQ(this, GetClosureScope()); 1173 DeclarationScope* s; 1174 for (s = this; !s->is_script_scope(); 1175 s = s->outer_scope()->GetClosureScope()) { 1176 s->force_eager_compilation_ = true; 1177 } 1178 s->force_eager_compilation_ = true; 1179 } 1180 1181 #ifdef DEBUG 1182 void PrintParameters(); 1183 #endif 1184 1185 V8_INLINE void AllocateLocals(); 1186 V8_INLINE void AllocateParameterLocals(); 1187 V8_INLINE void AllocateReceiver(); 1188 1189 void ResetAfterPreparsing(AstValueFactory* ast_value_factory, bool aborted); 1190 1191 bool is_skipped_function() const { return is_skipped_function_; } 1192 void set_is_skipped_function(bool is_skipped_function) { 1193 is_skipped_function_ = is_skipped_function; 1194 } 1195 1196 bool has_inferred_function_name() const { 1197 return has_inferred_function_name_; 1198 } 1199 void set_has_inferred_function_name(bool value) { 1200 DCHECK(is_function_scope()); 1201 has_inferred_function_name_ = value; 1202 } 1203 1204 // Save data describing the context allocation of the variables in this scope 1205 // and its subscopes (except scopes at the laziness boundary). The data is 1206 // saved in produced_preparse_data_. 1207 void SavePreparseDataForDeclarationScope(Parser* parser); 1208 1209 void set_preparse_data_builder(PreparseDataBuilder* preparse_data_builder) { 1210 preparse_data_builder_ = preparse_data_builder; 1211 } 1212 1213 PreparseDataBuilder* preparse_data_builder() const { 1214 return preparse_data_builder_; 1215 } 1216 1217 void set_has_this_reference() { has_this_reference_ = true; } 1218 bool has_this_reference() const { return has_this_reference_; } 1219 void UsesThis() { 1220 set_has_this_reference(); 1221 GetReceiverScope()->receiver()->ForceContextAllocation(); 1222 } 1223 1224 bool needs_private_name_context_chain_recalc() const { 1225 return needs_private_name_context_chain_recalc_; 1226 } 1227 void RecordNeedsPrivateNameContextChainRecalc(); 1228 1229 // Re-writes the {VariableLocation} of top-level 'let' bindings from CONTEXT 1230 // to REPL_GLOBAL. Should only be called on REPL scripts. 1231 void RewriteReplGlobalVariables(); 1232 1233 void set_class_scope_has_private_brand(bool value) { 1234 class_scope_has_private_brand_ = value; 1235 } 1236 bool class_scope_has_private_brand() const { 1237 return class_scope_has_private_brand_; 1238 } 1239 1240 private: 1241 V8_INLINE void AllocateParameter(Variable* var, int index); 1242 1243 // Resolve and fill in the allocation information for all variables 1244 // in this scopes. Must be called *after* all scopes have been 1245 // processed (parsed) to ensure that unresolved variables can be 1246 // resolved properly. 1247 // 1248 // In the case of code compiled and run using 'eval', the context 1249 // parameter is the context in which eval was called. In all other 1250 // cases the context parameter is an empty handle. 1251 // 1252 // Returns false if private names can not be resolved. 1253 bool AllocateVariables(ParseInfo* info); 1254 1255 void SetDefaults(); 1256 1257 // Recalculate the private name context chain from the existing skip bit in 1258 // preparation for AllocateScopeInfos. Because the private name scope is 1259 // implemented with a skip bit for scopes in heritage position, that bit may 1260 // need to be recomputed due scopes that do not need contexts. 1261 void RecalcPrivateNameContextChain(); 1262 1263 bool has_simple_parameters_ : 1; 1264 #if V8_ENABLE_WEBASSEMBLY 1265 // This scope contains an "use asm" annotation. 1266 bool is_asm_module_ : 1; 1267 #endif // V8_ENABLE_WEBASSEMBLY 1268 bool force_eager_compilation_ : 1; 1269 // This function scope has a rest parameter. 1270 bool has_rest_ : 1; 1271 // This scope has a parameter called "arguments". 1272 bool has_arguments_parameter_ : 1; 1273 // This scope uses "super" property ('super.foo'). 1274 bool uses_super_property_ : 1; 1275 bool should_eager_compile_ : 1; 1276 // Set to true after we have finished lazy parsing the scope. 1277 bool was_lazily_parsed_ : 1; 1278 #if DEBUG 1279 bool is_being_lazily_parsed_ : 1; 1280 #endif 1281 bool is_skipped_function_ : 1; 1282 bool has_inferred_function_name_ : 1; 1283 bool has_checked_syntax_ : 1; 1284 bool has_this_reference_ : 1; 1285 bool has_this_declaration_ : 1; 1286 bool needs_private_name_context_chain_recalc_ : 1; 1287 bool class_scope_has_private_brand_ : 1; 1288 // If the scope is a function scope, this is the function kind. 1289 FunctionKind function_kind_; 1290 1291 int num_parameters_ = 0; 1292 1293 // Parameter list in source order. 1294 ZonePtrList<Variable> params_; 1295 // Map of function names to lists of functions defined in sloppy blocks 1296 base::ThreadedList<SloppyBlockFunctionStatement> sloppy_block_functions_; 1297 // Convenience variable. 1298 Variable* receiver_; 1299 // Function variable, if any; function scopes only. 1300 Variable* function_; 1301 // new.target variable, function scopes only. 1302 Variable* new_target_; 1303 // Convenience variable; function scopes only. 1304 Variable* arguments_; 1305 1306 // For producing the scope allocation data during preparsing. 1307 PreparseDataBuilder* preparse_data_builder_; 1308 1309 struct RareData : public ZoneObject { 1310 // Convenience variable; Subclass constructor only 1311 Variable* this_function = nullptr; 1312 1313 // Generator object, if any; generator function scopes and module scopes 1314 // only. 1315 Variable* generator_object = nullptr; 1316 }; 1317 1318 enum class RareVariable { 1319 kThisFunction = offsetof(RareData, this_function), 1320 kGeneratorObject = offsetof(RareData, generator_object), 1321 }; 1322 1323 V8_INLINE RareData* EnsureRareData() { 1324 if (rare_data_ == nullptr) { 1325 rare_data_ = zone()->New<RareData>(); 1326 } 1327 return rare_data_; 1328 } 1329 1330 V8_INLINE Variable* GetRareVariable(RareVariable id) const { 1331 if (rare_data_ == nullptr) return nullptr; 1332 return *reinterpret_cast<Variable**>( 1333 reinterpret_cast<uint8_t*>(rare_data_) + static_cast<ptrdiff_t>(id)); 1334 } 1335 1336 // Set `var` to null if it's non-null and Predicate (Variable*) -> bool 1337 // returns true. 1338 template <typename Predicate> 1339 V8_INLINE void NullifyRareVariableIf(RareVariable id, Predicate predicate) { 1340 if (V8_LIKELY(rare_data_ == nullptr)) return; 1341 Variable** var = reinterpret_cast<Variable**>( 1342 reinterpret_cast<uint8_t*>(rare_data_) + static_cast<ptrdiff_t>(id)); 1343 if (*var && predicate(*var)) *var = nullptr; 1344 } 1345 1346 RareData* rare_data_ = nullptr; 1347 }; 1348 1349 void Scope::RecordEvalCall() { 1350 calls_eval_ = true; 1351 if (is_sloppy(language_mode())) { 1352 GetDeclarationScope()->RecordDeclarationScopeEvalCall(); 1353 } 1354 RecordInnerScopeEvalCall(); 1355 // The eval contents might access "super" (if it's inside a function that 1356 // binds super). 1357 DeclarationScope* receiver_scope = GetReceiverScope(); 1358 DCHECK(!receiver_scope->is_arrow_scope()); 1359 FunctionKind function_kind = receiver_scope->function_kind(); 1360 if (BindsSuper(function_kind)) { 1361 receiver_scope->RecordSuperPropertyUsage(); 1362 } 1363 } 1364 1365 Scope::Snapshot::Snapshot(Scope* scope) 1366 : outer_scope_(scope), 1367 declaration_scope_(scope->GetDeclarationScope()), 1368 top_inner_scope_(scope->inner_scope_), 1369 top_unresolved_(scope->unresolved_list_.end()), 1370 top_local_(scope->GetClosureScope()->locals_.end()), 1371 calls_eval_(outer_scope_->calls_eval_), 1372 sloppy_eval_can_extend_vars_( 1373 declaration_scope_->sloppy_eval_can_extend_vars_) { 1374 // Reset in order to record (sloppy) eval calls during this Snapshot's 1375 // lifetime. 1376 outer_scope_->calls_eval_ = false; 1377 declaration_scope_->sloppy_eval_can_extend_vars_ = false; 1378 } 1379 1380 class ModuleScope final : public DeclarationScope { 1381 public: 1382 ModuleScope(DeclarationScope* script_scope, AstValueFactory* avfactory); 1383 1384 // Deserialization. Does not restore the module descriptor. 1385 ModuleScope(Handle<ScopeInfo> scope_info, AstValueFactory* avfactory); 1386 1387 // Returns nullptr in a deserialized scope. 1388 SourceTextModuleDescriptor* module() const { return module_descriptor_; } 1389 1390 // Set MODULE as VariableLocation for all variables that will live in a 1391 // module's export table. 1392 void AllocateModuleVariables(); 1393 1394 private: 1395 SourceTextModuleDescriptor* const module_descriptor_; 1396 }; 1397 1398 class V8_EXPORT_PRIVATE ClassScope : public Scope { 1399 public: 1400 ClassScope(Zone* zone, Scope* outer_scope, bool is_anonymous); 1401 // Deserialization. 1402 template <typename IsolateT> 1403 ClassScope(IsolateT* isolate, Zone* zone, AstValueFactory* ast_value_factory, 1404 Handle<ScopeInfo> scope_info); 1405 1406 struct HeritageParsingScope { 1407 explicit HeritageParsingScope(ClassScope* class_scope) 1408 : class_scope_(class_scope) { 1409 class_scope_->SetIsParsingHeritage(true); 1410 } 1411 ~HeritageParsingScope() { class_scope_->SetIsParsingHeritage(false); } 1412 1413 private: 1414 ClassScope* class_scope_; 1415 }; 1416 1417 // Declare a private name in the private name map and add it to the 1418 // local variables of this scope. 1419 Variable* DeclarePrivateName(const AstRawString* name, VariableMode mode, 1420 IsStaticFlag is_static_flag, bool* was_added); 1421 1422 // Try resolving all unresolved private names found in the current scope. 1423 // Called from DeclarationScope::AllocateVariables() when reparsing a 1424 // method to generate code or when eval() is called to access private names. 1425 // If there are any private names that cannot be resolved, returns false. 1426 V8_WARN_UNUSED_RESULT bool ResolvePrivateNames(ParseInfo* info); 1427 1428 // Called after the entire class literal is parsed. 1429 // - If we are certain a private name cannot be resolve, return that 1430 // variable proxy. 1431 // - If we find the private name in the scope chain, return nullptr. 1432 // If the name is found in the current class scope, resolve it 1433 // immediately. 1434 // - If we are not sure if the private name can be resolved or not yet, 1435 // return nullptr. 1436 VariableProxy* ResolvePrivateNamesPartially(); 1437 1438 // Get the current tail of unresolved private names to be used to 1439 // reset the tail. 1440 UnresolvedList::Iterator GetUnresolvedPrivateNameTail(); 1441 1442 // Reset the tail of unresolved private names, discard everything 1443 // between the tail passed into this method and the current tail. 1444 void ResetUnresolvedPrivateNameTail(UnresolvedList::Iterator tail); 1445 1446 // Migrate private names added between the tail passed into this method 1447 // and the current tail. 1448 void MigrateUnresolvedPrivateNameTail(AstNodeFactory* ast_node_factory, 1449 UnresolvedList::Iterator tail); 1450 Variable* DeclareBrandVariable(AstValueFactory* ast_value_factory, 1451 IsStaticFlag is_static_flag, 1452 int class_token_pos); 1453 1454 Variable* DeclareClassVariable(AstValueFactory* ast_value_factory, 1455 const AstRawString* name, int class_token_pos); 1456 1457 Variable* brand() { 1458 return GetRareData() == nullptr ? nullptr : GetRareData()->brand; 1459 } 1460 1461 Variable* class_variable() { return class_variable_; } 1462 1463 V8_INLINE bool IsParsingHeritage() { 1464 return rare_data_and_is_parsing_heritage_.GetPayload(); 1465 } 1466 1467 // Only maintained when the scope is parsed, not when the scope is 1468 // deserialized. 1469 bool has_static_private_methods() const { 1470 return has_static_private_methods_; 1471 } 1472 1473 // Returns whether the index of class variable of this class scope should be 1474 // recorded in the ScopeInfo. 1475 // If any inner scope accesses static private names directly, the class 1476 // variable will be forced to be context-allocated. 1477 // The inner scope may also calls eval which may results in access to 1478 // static private names. 1479 // Only maintained when the scope is parsed. 1480 bool should_save_class_variable_index() const { 1481 return should_save_class_variable_index_ || 1482 has_explicit_static_private_methods_access_ || 1483 (has_static_private_methods_ && inner_scope_calls_eval_); 1484 } 1485 1486 // Only maintained when the scope is parsed. 1487 bool is_anonymous_class() const { return is_anonymous_class_; } 1488 1489 // Overriden during reparsing 1490 void set_should_save_class_variable_index() { 1491 should_save_class_variable_index_ = true; 1492 } 1493 1494 // Finalize the reparsed class scope, called when reparsing the 1495 // class scope for the initializer member function. 1496 // If the reparsed scope declares any variable that needs allocation 1497 // fixup using the scope info, needs_allocation_fixup is true. 1498 void FinalizeReparsedClassScope(Isolate* isolate, 1499 MaybeHandle<ScopeInfo> outer_scope_info, 1500 AstValueFactory* ast_value_factory, 1501 bool needs_allocation_fixup); 1502 #ifdef DEBUG 1503 bool is_reparsed_class_scope() const { return is_reparsed_class_scope_; } 1504 #endif 1505 1506 private: 1507 friend class Scope; 1508 friend class PrivateNameScopeIterator; 1509 1510 // Find the private name declared in the private name map first, 1511 // if it cannot be found there, try scope info if there is any. 1512 // Returns nullptr if it cannot be found. 1513 Variable* LookupPrivateName(VariableProxy* proxy); 1514 // Lookup a private name from the local private name map of the current 1515 // scope. 1516 Variable* LookupLocalPrivateName(const AstRawString* name); 1517 // Lookup a private name from the scope info of the current scope. 1518 Variable* LookupPrivateNameInScopeInfo(const AstRawString* name); 1519 1520 struct RareData : public ZoneObject { 1521 explicit RareData(Zone* zone) : private_name_map(zone) {} 1522 UnresolvedList unresolved_private_names; 1523 VariableMap private_name_map; 1524 Variable* brand = nullptr; 1525 }; 1526 1527 V8_INLINE RareData* GetRareData() { 1528 return rare_data_and_is_parsing_heritage_.GetPointer(); 1529 } 1530 V8_INLINE RareData* EnsureRareData() { 1531 if (GetRareData() == nullptr) { 1532 rare_data_and_is_parsing_heritage_.SetPointer( 1533 zone()->New<RareData>(zone())); 1534 } 1535 return GetRareData(); 1536 } 1537 V8_INLINE void SetIsParsingHeritage(bool v) { 1538 rare_data_and_is_parsing_heritage_.SetPayload(v); 1539 } 1540 1541 base::PointerWithPayload<RareData, bool, 1> 1542 rare_data_and_is_parsing_heritage_; 1543 Variable* class_variable_ = nullptr; 1544 // These are only maintained when the scope is parsed, not when the 1545 // scope is deserialized. 1546 bool has_static_private_methods_ = false; 1547 bool has_explicit_static_private_methods_access_ = false; 1548 bool is_anonymous_class_ = false; 1549 // This is only maintained during reparsing, restored from the 1550 // preparsed data. 1551 bool should_save_class_variable_index_ = false; 1552 #ifdef DEBUG 1553 bool is_reparsed_class_scope_ = false; 1554 #endif 1555 }; 1556 1557 // Iterate over the private name scope chain. The iteration proceeds from the 1558 // innermost private name scope outwards. 1559 class PrivateNameScopeIterator { 1560 public: 1561 explicit PrivateNameScopeIterator(Scope* start); 1562 1563 bool Done() const { return current_scope_ == nullptr; } 1564 void Next(); 1565 1566 // Add an unresolved private name to the current scope. 1567 void AddUnresolvedPrivateName(VariableProxy* proxy); 1568 1569 ClassScope* GetScope() const { 1570 DCHECK(!Done()); 1571 return current_scope_->AsClassScope(); 1572 } 1573 1574 private: 1575 bool skipped_any_scopes_ = false; 1576 Scope* start_scope_; 1577 Scope* current_scope_; 1578 }; 1579 1580 } // namespace internal 1581 } // namespace v8 1582 1583 #endif // V8_AST_SCOPES_H_ 1584