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