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