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#include "src/ast/scopes.h" 6 7#include <set> 8 9#include "src/accessors.h" 10#include "src/ast/ast.h" 11#include "src/bootstrapper.h" 12#include "src/messages.h" 13#include "src/parsing/parse-info.h" 14 15namespace v8 { 16namespace internal { 17 18// ---------------------------------------------------------------------------- 19// Implementation of LocalsMap 20// 21// Note: We are storing the handle locations as key values in the hash map. 22// When inserting a new variable via Declare(), we rely on the fact that 23// the handle location remains alive for the duration of that variable 24// use. Because a Variable holding a handle with the same location exists 25// this is ensured. 26 27VariableMap::VariableMap(Zone* zone) 28 : ZoneHashMap(8, ZoneAllocationPolicy(zone)) {} 29 30Variable* VariableMap::Declare(Zone* zone, Scope* scope, 31 const AstRawString* name, VariableMode mode, 32 VariableKind kind, 33 InitializationFlag initialization_flag, 34 MaybeAssignedFlag maybe_assigned_flag, 35 bool* added) { 36 // AstRawStrings are unambiguous, i.e., the same string is always represented 37 // by the same AstRawString*. 38 // FIXME(marja): fix the type of Lookup. 39 Entry* p = 40 ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->hash(), 41 ZoneAllocationPolicy(zone)); 42 if (added) *added = p->value == nullptr; 43 if (p->value == nullptr) { 44 // The variable has not been declared yet -> insert it. 45 DCHECK_EQ(name, p->key); 46 p->value = new (zone) Variable(scope, name, mode, kind, initialization_flag, 47 maybe_assigned_flag); 48 } 49 return reinterpret_cast<Variable*>(p->value); 50} 51 52void VariableMap::Remove(Variable* var) { 53 const AstRawString* name = var->raw_name(); 54 ZoneHashMap::Remove(const_cast<AstRawString*>(name), name->hash()); 55} 56 57void VariableMap::Add(Zone* zone, Variable* var) { 58 const AstRawString* name = var->raw_name(); 59 Entry* p = 60 ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->hash(), 61 ZoneAllocationPolicy(zone)); 62 DCHECK_NULL(p->value); 63 DCHECK_EQ(name, p->key); 64 p->value = var; 65} 66 67Variable* VariableMap::Lookup(const AstRawString* name) { 68 Entry* p = ZoneHashMap::Lookup(const_cast<AstRawString*>(name), name->hash()); 69 if (p != NULL) { 70 DCHECK(reinterpret_cast<const AstRawString*>(p->key) == name); 71 DCHECK(p->value != NULL); 72 return reinterpret_cast<Variable*>(p->value); 73 } 74 return NULL; 75} 76 77SloppyBlockFunctionMap::SloppyBlockFunctionMap(Zone* zone) 78 : ZoneHashMap(8, ZoneAllocationPolicy(zone)) {} 79 80void SloppyBlockFunctionMap::Declare(Zone* zone, const AstRawString* name, 81 SloppyBlockFunctionStatement* stmt) { 82 // AstRawStrings are unambiguous, i.e., the same string is always represented 83 // by the same AstRawString*. 84 Entry* p = 85 ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->hash(), 86 ZoneAllocationPolicy(zone)); 87 stmt->set_next(static_cast<SloppyBlockFunctionStatement*>(p->value)); 88 p->value = stmt; 89} 90 91 92// ---------------------------------------------------------------------------- 93// Implementation of Scope 94 95Scope::Scope(Zone* zone) 96 : zone_(zone), 97 outer_scope_(nullptr), 98 variables_(zone), 99 scope_type_(SCRIPT_SCOPE) { 100 SetDefaults(); 101} 102 103Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type) 104 : zone_(zone), 105 outer_scope_(outer_scope), 106 variables_(zone), 107 scope_type_(scope_type) { 108 DCHECK_NE(SCRIPT_SCOPE, scope_type); 109 SetDefaults(); 110 set_language_mode(outer_scope->language_mode()); 111 force_context_allocation_ = 112 !is_function_scope() && outer_scope->has_forced_context_allocation(); 113 outer_scope_->AddInnerScope(this); 114} 115 116Scope::Snapshot::Snapshot(Scope* scope) 117 : outer_scope_(scope), 118 top_inner_scope_(scope->inner_scope_), 119 top_unresolved_(scope->unresolved_), 120 top_local_(scope->GetClosureScope()->locals_.end()), 121 top_decl_(scope->GetClosureScope()->decls_.end()) {} 122 123DeclarationScope::DeclarationScope(Zone* zone, 124 AstValueFactory* ast_value_factory) 125 : Scope(zone), 126 function_kind_(kNormalFunction), 127 params_(4, zone), 128 sloppy_block_function_map_(zone) { 129 DCHECK_EQ(scope_type_, SCRIPT_SCOPE); 130 SetDefaults(); 131 132 // Make sure that if we don't find the global 'this', it won't be declared as 133 // a regular dynamic global by predeclaring it with the right variable kind. 134 DeclareDynamicGlobal(ast_value_factory->this_string(), THIS_VARIABLE); 135} 136 137DeclarationScope::DeclarationScope(Zone* zone, Scope* outer_scope, 138 ScopeType scope_type, 139 FunctionKind function_kind) 140 : Scope(zone, outer_scope, scope_type), 141 function_kind_(function_kind), 142 params_(4, zone), 143 sloppy_block_function_map_(zone) { 144 DCHECK_NE(scope_type, SCRIPT_SCOPE); 145 SetDefaults(); 146 asm_function_ = outer_scope_->IsAsmModule(); 147} 148 149ModuleScope::ModuleScope(DeclarationScope* script_scope, 150 AstValueFactory* ast_value_factory) 151 : DeclarationScope(ast_value_factory->zone(), script_scope, MODULE_SCOPE, 152 kModule) { 153 Zone* zone = ast_value_factory->zone(); 154 module_descriptor_ = new (zone) ModuleDescriptor(zone); 155 set_language_mode(STRICT); 156 DeclareThis(ast_value_factory); 157} 158 159ModuleScope::ModuleScope(Isolate* isolate, Handle<ScopeInfo> scope_info, 160 AstValueFactory* avfactory) 161 : DeclarationScope(avfactory->zone(), MODULE_SCOPE, scope_info) { 162 Zone* zone = avfactory->zone(); 163 Handle<ModuleInfo> module_info(scope_info->ModuleDescriptorInfo(), isolate); 164 165 set_language_mode(STRICT); 166 module_descriptor_ = new (zone) ModuleDescriptor(zone); 167 168 // Deserialize special exports. 169 Handle<FixedArray> special_exports(module_info->special_exports(), isolate); 170 for (int i = 0, n = special_exports->length(); i < n; ++i) { 171 Handle<ModuleInfoEntry> serialized_entry( 172 ModuleInfoEntry::cast(special_exports->get(i)), isolate); 173 module_descriptor_->AddSpecialExport( 174 ModuleDescriptor::Entry::Deserialize(isolate, avfactory, 175 serialized_entry), 176 avfactory->zone()); 177 } 178 179 // Deserialize regular exports. 180 module_descriptor_->DeserializeRegularExports(isolate, avfactory, 181 module_info); 182 183 // Deserialize namespace imports. 184 Handle<FixedArray> namespace_imports(module_info->namespace_imports(), 185 isolate); 186 for (int i = 0, n = namespace_imports->length(); i < n; ++i) { 187 Handle<ModuleInfoEntry> serialized_entry( 188 ModuleInfoEntry::cast(namespace_imports->get(i)), isolate); 189 module_descriptor_->AddNamespaceImport( 190 ModuleDescriptor::Entry::Deserialize(isolate, avfactory, 191 serialized_entry), 192 avfactory->zone()); 193 } 194 195 // Deserialize regular imports. 196 Handle<FixedArray> regular_imports(module_info->regular_imports(), isolate); 197 for (int i = 0, n = regular_imports->length(); i < n; ++i) { 198 Handle<ModuleInfoEntry> serialized_entry( 199 ModuleInfoEntry::cast(regular_imports->get(i)), isolate); 200 module_descriptor_->AddRegularImport(ModuleDescriptor::Entry::Deserialize( 201 isolate, avfactory, serialized_entry)); 202 } 203} 204 205Scope::Scope(Zone* zone, ScopeType scope_type, Handle<ScopeInfo> scope_info) 206 : zone_(zone), 207 outer_scope_(nullptr), 208 variables_(zone), 209 scope_info_(scope_info), 210 scope_type_(scope_type) { 211 DCHECK(!scope_info.is_null()); 212 SetDefaults(); 213#ifdef DEBUG 214 already_resolved_ = true; 215#endif 216 if (scope_info->CallsEval()) RecordEvalCall(); 217 set_language_mode(scope_info->language_mode()); 218 num_heap_slots_ = scope_info->ContextLength(); 219 DCHECK_LE(Context::MIN_CONTEXT_SLOTS, num_heap_slots_); 220} 221 222DeclarationScope::DeclarationScope(Zone* zone, ScopeType scope_type, 223 Handle<ScopeInfo> scope_info) 224 : Scope(zone, scope_type, scope_info), 225 function_kind_(scope_info->function_kind()), 226 params_(0, zone), 227 sloppy_block_function_map_(zone) { 228 DCHECK_NE(scope_type, SCRIPT_SCOPE); 229 SetDefaults(); 230} 231 232Scope::Scope(Zone* zone, const AstRawString* catch_variable_name, 233 Handle<ScopeInfo> scope_info) 234 : zone_(zone), 235 outer_scope_(nullptr), 236 variables_(zone), 237 scope_info_(scope_info), 238 scope_type_(CATCH_SCOPE) { 239 SetDefaults(); 240#ifdef DEBUG 241 already_resolved_ = true; 242#endif 243 // Cache the catch variable, even though it's also available via the 244 // scope_info, as the parser expects that a catch scope always has the catch 245 // variable as first and only variable. 246 Variable* variable = Declare(zone, this, catch_variable_name, VAR, 247 NORMAL_VARIABLE, kCreatedInitialized); 248 AllocateHeapSlot(variable); 249} 250 251void DeclarationScope::SetDefaults() { 252 is_declaration_scope_ = true; 253 has_simple_parameters_ = true; 254 asm_module_ = false; 255 asm_function_ = false; 256 force_eager_compilation_ = false; 257 has_arguments_parameter_ = false; 258 scope_uses_super_property_ = false; 259 has_rest_ = false; 260 receiver_ = nullptr; 261 new_target_ = nullptr; 262 function_ = nullptr; 263 arguments_ = nullptr; 264 this_function_ = nullptr; 265 should_eager_compile_ = false; 266 is_lazily_parsed_ = false; 267} 268 269void Scope::SetDefaults() { 270#ifdef DEBUG 271 scope_name_ = nullptr; 272 already_resolved_ = false; 273 needs_migration_ = false; 274#endif 275 inner_scope_ = nullptr; 276 sibling_ = nullptr; 277 unresolved_ = nullptr; 278 279 start_position_ = kNoSourcePosition; 280 end_position_ = kNoSourcePosition; 281 282 num_stack_slots_ = 0; 283 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; 284 285 set_language_mode(SLOPPY); 286 287 scope_calls_eval_ = false; 288 scope_nonlinear_ = false; 289 is_hidden_ = false; 290 is_debug_evaluate_scope_ = false; 291 292 inner_scope_calls_eval_ = false; 293 force_context_allocation_ = false; 294 295 is_declaration_scope_ = false; 296} 297 298bool Scope::HasSimpleParameters() { 299 DeclarationScope* scope = GetClosureScope(); 300 return !scope->is_function_scope() || scope->has_simple_parameters(); 301} 302 303bool DeclarationScope::ShouldEagerCompile() const { 304 return force_eager_compilation_ || should_eager_compile_; 305} 306 307void DeclarationScope::set_should_eager_compile() { 308 should_eager_compile_ = !is_lazily_parsed_; 309} 310 311void DeclarationScope::set_asm_module() { 312 asm_module_ = true; 313 // Mark any existing inner function scopes as asm function scopes. 314 for (Scope* inner = inner_scope_; inner != nullptr; inner = inner->sibling_) { 315 if (inner->is_function_scope()) { 316 inner->AsDeclarationScope()->set_asm_function(); 317 } 318 } 319} 320 321bool Scope::IsAsmModule() const { 322 return is_function_scope() && AsDeclarationScope()->asm_module(); 323} 324 325bool Scope::IsAsmFunction() const { 326 return is_function_scope() && AsDeclarationScope()->asm_function(); 327} 328 329Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone, 330 ScopeInfo* scope_info, 331 DeclarationScope* script_scope, 332 AstValueFactory* ast_value_factory, 333 DeserializationMode deserialization_mode) { 334 // Reconstruct the outer scope chain from a closure's context chain. 335 Scope* current_scope = nullptr; 336 Scope* innermost_scope = nullptr; 337 Scope* outer_scope = nullptr; 338 while (scope_info) { 339 if (scope_info->scope_type() == WITH_SCOPE) { 340 // For scope analysis, debug-evaluate is equivalent to a with scope. 341 outer_scope = new (zone) Scope(zone, WITH_SCOPE, handle(scope_info)); 342 343 // TODO(yangguo): Remove once debug-evaluate properly keeps track of the 344 // function scope in which we are evaluating. 345 if (scope_info->IsDebugEvaluateScope()) { 346 outer_scope->set_is_debug_evaluate_scope(); 347 } 348 } else if (scope_info->scope_type() == SCRIPT_SCOPE) { 349 // If we reach a script scope, it's the outermost scope. Install the 350 // scope info of this script context onto the existing script scope to 351 // avoid nesting script scopes. 352 if (deserialization_mode == DeserializationMode::kIncludingVariables) { 353 script_scope->SetScriptScopeInfo(handle(scope_info)); 354 } 355 DCHECK(!scope_info->HasOuterScopeInfo()); 356 break; 357 } else if (scope_info->scope_type() == FUNCTION_SCOPE || 358 scope_info->scope_type() == EVAL_SCOPE) { 359 // TODO(neis): For an eval scope, we currently create an ordinary function 360 // context. This is wrong and needs to be fixed. 361 // https://bugs.chromium.org/p/v8/issues/detail?id=5295 362 outer_scope = 363 new (zone) DeclarationScope(zone, FUNCTION_SCOPE, handle(scope_info)); 364 if (scope_info->IsAsmFunction()) 365 outer_scope->AsDeclarationScope()->set_asm_function(); 366 if (scope_info->IsAsmModule()) 367 outer_scope->AsDeclarationScope()->set_asm_module(); 368 } else if (scope_info->scope_type() == BLOCK_SCOPE) { 369 if (scope_info->is_declaration_scope()) { 370 outer_scope = 371 new (zone) DeclarationScope(zone, BLOCK_SCOPE, handle(scope_info)); 372 } else { 373 outer_scope = new (zone) Scope(zone, BLOCK_SCOPE, handle(scope_info)); 374 } 375 } else if (scope_info->scope_type() == MODULE_SCOPE) { 376 outer_scope = new (zone) 377 ModuleScope(isolate, handle(scope_info), ast_value_factory); 378 } else { 379 DCHECK_EQ(scope_info->scope_type(), CATCH_SCOPE); 380 DCHECK_EQ(scope_info->LocalCount(), 1); 381 String* name = scope_info->LocalName(0); 382 outer_scope = new (zone) 383 Scope(zone, ast_value_factory->GetString(handle(name, isolate)), 384 handle(scope_info)); 385 } 386 if (deserialization_mode == DeserializationMode::kScopesOnly) { 387 outer_scope->scope_info_ = Handle<ScopeInfo>::null(); 388 } 389 if (current_scope != nullptr) { 390 outer_scope->AddInnerScope(current_scope); 391 } 392 current_scope = outer_scope; 393 if (innermost_scope == nullptr) innermost_scope = current_scope; 394 scope_info = scope_info->HasOuterScopeInfo() ? scope_info->OuterScopeInfo() 395 : nullptr; 396 } 397 398 if (innermost_scope == nullptr) return script_scope; 399 script_scope->AddInnerScope(current_scope); 400 return innermost_scope; 401} 402 403DeclarationScope* Scope::AsDeclarationScope() { 404 DCHECK(is_declaration_scope()); 405 return static_cast<DeclarationScope*>(this); 406} 407 408const DeclarationScope* Scope::AsDeclarationScope() const { 409 DCHECK(is_declaration_scope()); 410 return static_cast<const DeclarationScope*>(this); 411} 412 413ModuleScope* Scope::AsModuleScope() { 414 DCHECK(is_module_scope()); 415 return static_cast<ModuleScope*>(this); 416} 417 418const ModuleScope* Scope::AsModuleScope() const { 419 DCHECK(is_module_scope()); 420 return static_cast<const ModuleScope*>(this); 421} 422 423int Scope::num_parameters() const { 424 return is_declaration_scope() ? AsDeclarationScope()->num_parameters() : 0; 425} 426 427void DeclarationScope::HoistSloppyBlockFunctions(AstNodeFactory* factory) { 428 DCHECK(is_sloppy(language_mode())); 429 DCHECK(is_function_scope() || is_eval_scope() || is_script_scope() || 430 (is_block_scope() && outer_scope()->is_function_scope())); 431 DCHECK(HasSimpleParameters() || is_block_scope()); 432 bool has_simple_parameters = HasSimpleParameters(); 433 // For each variable which is used as a function declaration in a sloppy 434 // block, 435 SloppyBlockFunctionMap* map = sloppy_block_function_map(); 436 for (ZoneHashMap::Entry* p = map->Start(); p != nullptr; p = map->Next(p)) { 437 AstRawString* name = static_cast<AstRawString*>(p->key); 438 439 // If the variable wouldn't conflict with a lexical declaration 440 // or parameter, 441 442 // Check if there's a conflict with a parameter. 443 // This depends on the fact that functions always have a scope solely to 444 // hold complex parameters, and the names local to that scope are 445 // precisely the names of the parameters. IsDeclaredParameter(name) does 446 // not hold for names declared by complex parameters, nor are those 447 // bindings necessarily declared lexically, so we have to check for them 448 // explicitly. On the other hand, if there are not complex parameters, 449 // it is sufficient to just check IsDeclaredParameter. 450 if (!has_simple_parameters) { 451 if (outer_scope_->LookupLocal(name) != nullptr) { 452 continue; 453 } 454 } else { 455 if (IsDeclaredParameter(name)) { 456 continue; 457 } 458 } 459 460 bool var_created = false; 461 462 // Write in assignments to var for each block-scoped function declaration 463 auto delegates = static_cast<SloppyBlockFunctionStatement*>(p->value); 464 465 DeclarationScope* decl_scope = this; 466 while (decl_scope->is_eval_scope()) { 467 decl_scope = decl_scope->outer_scope()->GetDeclarationScope(); 468 } 469 Scope* outer_scope = decl_scope->outer_scope(); 470 471 for (SloppyBlockFunctionStatement* delegate = delegates; 472 delegate != nullptr; delegate = delegate->next()) { 473 // Check if there's a conflict with a lexical declaration 474 Scope* query_scope = delegate->scope()->outer_scope(); 475 Variable* var = nullptr; 476 bool should_hoist = true; 477 478 // Note that we perform this loop for each delegate named 'name', 479 // which may duplicate work if those delegates share scopes. 480 // It is not sufficient to just do a Lookup on query_scope: for 481 // example, that does not prevent hoisting of the function in 482 // `{ let e; try {} catch (e) { function e(){} } }` 483 do { 484 var = query_scope->LookupLocal(name); 485 if (var != nullptr && IsLexicalVariableMode(var->mode())) { 486 should_hoist = false; 487 break; 488 } 489 query_scope = query_scope->outer_scope(); 490 } while (query_scope != outer_scope); 491 492 if (!should_hoist) continue; 493 494 // Declare a var-style binding for the function in the outer scope 495 if (!var_created) { 496 var_created = true; 497 VariableProxy* proxy = factory->NewVariableProxy(name, NORMAL_VARIABLE); 498 Declaration* declaration = 499 factory->NewVariableDeclaration(proxy, this, kNoSourcePosition); 500 // Based on the preceding check, it doesn't matter what we pass as 501 // allow_harmony_restrictive_generators and 502 // sloppy_mode_block_scope_function_redefinition. 503 bool ok = true; 504 DeclareVariable(declaration, VAR, 505 Variable::DefaultInitializationFlag(VAR), false, 506 nullptr, &ok); 507 CHECK(ok); // Based on the preceding check, this should not fail 508 } 509 510 Expression* assignment = factory->NewAssignment( 511 Token::ASSIGN, NewUnresolved(factory, name), 512 delegate->scope()->NewUnresolved(factory, name), kNoSourcePosition); 513 Statement* statement = 514 factory->NewExpressionStatement(assignment, kNoSourcePosition); 515 delegate->set_statement(statement); 516 } 517 } 518} 519 520void DeclarationScope::Analyze(ParseInfo* info, AnalyzeMode mode) { 521 DCHECK(info->literal() != NULL); 522 DeclarationScope* scope = info->literal()->scope(); 523 524 Handle<ScopeInfo> outer_scope_info; 525 if (info->maybe_outer_scope_info().ToHandle(&outer_scope_info)) { 526 if (scope->outer_scope()) { 527 DeclarationScope* script_scope = new (info->zone()) 528 DeclarationScope(info->zone(), info->ast_value_factory()); 529 info->set_script_scope(script_scope); 530 scope->ReplaceOuterScope(Scope::DeserializeScopeChain( 531 info->isolate(), info->zone(), *outer_scope_info, script_scope, 532 info->ast_value_factory(), 533 Scope::DeserializationMode::kIncludingVariables)); 534 } else { 535 DCHECK_EQ(outer_scope_info->scope_type(), SCRIPT_SCOPE); 536 scope->SetScriptScopeInfo(outer_scope_info); 537 } 538 } 539 540 if (scope->is_eval_scope() && is_sloppy(scope->language_mode())) { 541 AstNodeFactory factory(info->ast_value_factory()); 542 scope->HoistSloppyBlockFunctions(&factory); 543 } 544 545 // We are compiling one of three cases: 546 // 1) top-level code, 547 // 2) a function/eval/module on the top-level 548 // 3) a function/eval in a scope that was already resolved. 549 DCHECK(scope->scope_type() == SCRIPT_SCOPE || 550 scope->outer_scope()->scope_type() == SCRIPT_SCOPE || 551 scope->outer_scope()->already_resolved_); 552 553 // The outer scope is never lazy. 554 scope->set_should_eager_compile(); 555 556 scope->AllocateVariables(info, mode); 557 558 // Ensuring that the outer script scope has a scope info avoids having 559 // special case for native contexts vs other contexts. 560 if (info->script_scope()->scope_info_.is_null()) { 561 info->script_scope()->scope_info_ = 562 handle(ScopeInfo::Empty(info->isolate())); 563 } 564 565#ifdef DEBUG 566 if (info->script_is_native() ? FLAG_print_builtin_scopes 567 : FLAG_print_scopes) { 568 scope->Print(); 569 } 570 scope->CheckScopePositions(); 571 scope->CheckZones(); 572#endif 573} 574 575void DeclarationScope::DeclareThis(AstValueFactory* ast_value_factory) { 576 DCHECK(!already_resolved_); 577 DCHECK(is_declaration_scope()); 578 DCHECK(has_this_declaration()); 579 580 bool subclass_constructor = IsSubclassConstructor(function_kind_); 581 Variable* var = Declare( 582 zone(), this, ast_value_factory->this_string(), 583 subclass_constructor ? CONST : VAR, THIS_VARIABLE, 584 subclass_constructor ? kNeedsInitialization : kCreatedInitialized); 585 receiver_ = var; 586} 587 588void DeclarationScope::DeclareArguments(AstValueFactory* ast_value_factory) { 589 DCHECK(is_function_scope()); 590 DCHECK(!is_arrow_scope()); 591 592 arguments_ = LookupLocal(ast_value_factory->arguments_string()); 593 if (arguments_ == nullptr) { 594 // Declare 'arguments' variable which exists in all non arrow functions. 595 // Note that it might never be accessed, in which case it won't be 596 // allocated during variable allocation. 597 arguments_ = Declare(zone(), this, ast_value_factory->arguments_string(), 598 VAR, NORMAL_VARIABLE, kCreatedInitialized); 599 } else if (IsLexicalVariableMode(arguments_->mode())) { 600 // Check if there's lexically declared variable named arguments to avoid 601 // redeclaration. See ES#sec-functiondeclarationinstantiation, step 20. 602 arguments_ = nullptr; 603 } 604} 605 606void DeclarationScope::DeclareDefaultFunctionVariables( 607 AstValueFactory* ast_value_factory) { 608 DCHECK(is_function_scope()); 609 DCHECK(!is_arrow_scope()); 610 611 DeclareThis(ast_value_factory); 612 new_target_ = Declare(zone(), this, ast_value_factory->new_target_string(), 613 CONST, NORMAL_VARIABLE, kCreatedInitialized); 614 615 if (IsConciseMethod(function_kind_) || IsClassConstructor(function_kind_) || 616 IsAccessorFunction(function_kind_)) { 617 this_function_ = 618 Declare(zone(), this, ast_value_factory->this_function_string(), CONST, 619 NORMAL_VARIABLE, kCreatedInitialized); 620 } 621} 622 623Variable* DeclarationScope::DeclareFunctionVar(const AstRawString* name) { 624 DCHECK(is_function_scope()); 625 DCHECK_NULL(function_); 626 DCHECK_NULL(variables_.Lookup(name)); 627 VariableKind kind = is_sloppy(language_mode()) ? SLOPPY_FUNCTION_NAME_VARIABLE 628 : NORMAL_VARIABLE; 629 function_ = 630 new (zone()) Variable(this, name, CONST, kind, kCreatedInitialized); 631 if (calls_sloppy_eval()) { 632 NonLocal(name, DYNAMIC); 633 } else { 634 variables_.Add(zone(), function_); 635 } 636 return function_; 637} 638 639bool Scope::HasBeenRemoved() const { 640 // TODO(neis): Store this information somewhere instead of calculating it. 641 642 if (!is_block_scope()) return false; // Shortcut. 643 644 Scope* parent = outer_scope(); 645 if (parent == nullptr) { 646 DCHECK(is_script_scope()); 647 return false; 648 } 649 650 Scope* sibling = parent->inner_scope(); 651 for (; sibling != nullptr; sibling = sibling->sibling()) { 652 if (sibling == this) return false; 653 } 654 655 DCHECK_NULL(inner_scope_); 656 return true; 657} 658 659Scope* Scope::GetUnremovedScope() { 660 Scope* scope = this; 661 while (scope != nullptr && scope->HasBeenRemoved()) { 662 scope = scope->outer_scope(); 663 } 664 DCHECK_NOT_NULL(scope); 665 return scope; 666} 667 668Scope* Scope::FinalizeBlockScope() { 669 DCHECK(is_block_scope()); 670 671 if (variables_.occupancy() > 0 || 672 (is_declaration_scope() && calls_sloppy_eval())) { 673 return this; 674 } 675 676 // Remove this scope from outer scope. 677 outer_scope()->RemoveInnerScope(this); 678 679 // Reparent inner scopes. 680 if (inner_scope_ != nullptr) { 681 Scope* scope = inner_scope_; 682 scope->outer_scope_ = outer_scope(); 683 while (scope->sibling_ != nullptr) { 684 scope = scope->sibling_; 685 scope->outer_scope_ = outer_scope(); 686 } 687 scope->sibling_ = outer_scope()->inner_scope_; 688 outer_scope()->inner_scope_ = inner_scope_; 689 inner_scope_ = nullptr; 690 } 691 692 // Move unresolved variables 693 if (unresolved_ != nullptr) { 694 if (outer_scope()->unresolved_ != nullptr) { 695 VariableProxy* unresolved = unresolved_; 696 while (unresolved->next_unresolved() != nullptr) { 697 unresolved = unresolved->next_unresolved(); 698 } 699 unresolved->set_next_unresolved(outer_scope()->unresolved_); 700 } 701 outer_scope()->unresolved_ = unresolved_; 702 unresolved_ = nullptr; 703 } 704 705 PropagateUsageFlagsToScope(outer_scope_); 706 // This block does not need a context. 707 num_heap_slots_ = 0; 708 return NULL; 709} 710 711void DeclarationScope::AddLocal(Variable* var) { 712 DCHECK(!already_resolved_); 713 // Temporaries are only placed in ClosureScopes. 714 DCHECK_EQ(GetClosureScope(), this); 715 locals_.Add(var); 716} 717 718Variable* Scope::Declare(Zone* zone, Scope* scope, const AstRawString* name, 719 VariableMode mode, VariableKind kind, 720 InitializationFlag initialization_flag, 721 MaybeAssignedFlag maybe_assigned_flag) { 722 bool added; 723 Variable* var = 724 variables_.Declare(zone, scope, name, mode, kind, initialization_flag, 725 maybe_assigned_flag, &added); 726 if (added) locals_.Add(var); 727 return var; 728} 729 730void Scope::Snapshot::Reparent(DeclarationScope* new_parent) const { 731 DCHECK_EQ(new_parent, outer_scope_->inner_scope_); 732 DCHECK_EQ(new_parent->outer_scope_, outer_scope_); 733 DCHECK_EQ(new_parent, new_parent->GetClosureScope()); 734 DCHECK_NULL(new_parent->inner_scope_); 735 DCHECK_NULL(new_parent->unresolved_); 736 DCHECK(new_parent->locals_.is_empty()); 737 Scope* inner_scope = new_parent->sibling_; 738 if (inner_scope != top_inner_scope_) { 739 for (; inner_scope->sibling() != top_inner_scope_; 740 inner_scope = inner_scope->sibling()) { 741 inner_scope->outer_scope_ = new_parent; 742 DCHECK_NE(inner_scope, new_parent); 743 } 744 inner_scope->outer_scope_ = new_parent; 745 746 new_parent->inner_scope_ = new_parent->sibling_; 747 inner_scope->sibling_ = nullptr; 748 // Reset the sibling rather than the inner_scope_ since we 749 // want to keep new_parent there. 750 new_parent->sibling_ = top_inner_scope_; 751 } 752 753 if (outer_scope_->unresolved_ != top_unresolved_) { 754 VariableProxy* last = outer_scope_->unresolved_; 755 while (last->next_unresolved() != top_unresolved_) { 756 last = last->next_unresolved(); 757 } 758 last->set_next_unresolved(nullptr); 759 new_parent->unresolved_ = outer_scope_->unresolved_; 760 outer_scope_->unresolved_ = top_unresolved_; 761 } 762 763 // TODO(verwaest): This currently only moves do-expression declared variables 764 // in default arguments that weren't already previously declared with the same 765 // name in the closure-scope. See 766 // test/mjsunit/harmony/default-parameter-do-expression.js. 767 DeclarationScope* outer_closure = outer_scope_->GetClosureScope(); 768 769 new_parent->locals_.MoveTail(outer_closure->locals(), top_local_); 770 for (Variable* local : new_parent->locals_) { 771 DCHECK(local->mode() == TEMPORARY || local->mode() == VAR); 772 DCHECK_EQ(local->scope(), local->scope()->GetClosureScope()); 773 DCHECK_NE(local->scope(), new_parent); 774 local->set_scope(new_parent); 775 if (local->mode() == VAR) { 776 outer_closure->variables_.Remove(local); 777 new_parent->variables_.Add(new_parent->zone(), local); 778 } 779 } 780 outer_closure->locals_.Rewind(top_local_); 781 outer_closure->decls_.Rewind(top_decl_); 782} 783 784void Scope::ReplaceOuterScope(Scope* outer) { 785 DCHECK_NOT_NULL(outer); 786 DCHECK_NOT_NULL(outer_scope_); 787 DCHECK(!already_resolved_); 788 outer_scope_->RemoveInnerScope(this); 789 outer->AddInnerScope(this); 790 outer_scope_ = outer; 791} 792 793 794void Scope::PropagateUsageFlagsToScope(Scope* other) { 795 DCHECK_NOT_NULL(other); 796 DCHECK(!already_resolved_); 797 DCHECK(!other->already_resolved_); 798 if (calls_eval()) other->RecordEvalCall(); 799} 800 801Variable* Scope::LookupInScopeInfo(const AstRawString* name) { 802 Handle<String> name_handle = name->string(); 803 // The Scope is backed up by ScopeInfo. This means it cannot operate in a 804 // heap-independent mode, and all strings must be internalized immediately. So 805 // it's ok to get the Handle<String> here. 806 // If we have a serialized scope info, we might find the variable there. 807 // There should be no local slot with the given name. 808 DCHECK_LT(scope_info_->StackSlotIndex(*name_handle), 0); 809 810 bool found = false; 811 812 VariableLocation location; 813 int index; 814 VariableMode mode; 815 InitializationFlag init_flag; 816 MaybeAssignedFlag maybe_assigned_flag; 817 818 { 819 location = VariableLocation::CONTEXT; 820 index = ScopeInfo::ContextSlotIndex(scope_info_, name_handle, &mode, 821 &init_flag, &maybe_assigned_flag); 822 found = index >= 0; 823 } 824 825 if (!found && scope_type() == MODULE_SCOPE) { 826 location = VariableLocation::MODULE; 827 index = scope_info_->ModuleIndex(name_handle, &mode, &init_flag, 828 &maybe_assigned_flag); 829 found = index != 0; 830 } 831 832 if (!found) { 833 index = scope_info_->FunctionContextSlotIndex(*name_handle); 834 if (index < 0) return nullptr; // Nowhere found. 835 Variable* var = AsDeclarationScope()->DeclareFunctionVar(name); 836 DCHECK_EQ(CONST, var->mode()); 837 var->AllocateTo(VariableLocation::CONTEXT, index); 838 return variables_.Lookup(name); 839 } 840 841 VariableKind kind = NORMAL_VARIABLE; 842 if (location == VariableLocation::CONTEXT && 843 index == scope_info_->ReceiverContextSlotIndex()) { 844 kind = THIS_VARIABLE; 845 } 846 // TODO(marja, rossberg): Correctly declare FUNCTION, CLASS, NEW_TARGET, and 847 // ARGUMENTS bindings as their corresponding VariableKind. 848 849 Variable* var = variables_.Declare(zone(), this, name, mode, kind, init_flag, 850 maybe_assigned_flag); 851 var->AllocateTo(location, index); 852 return var; 853} 854 855Variable* Scope::Lookup(const AstRawString* name) { 856 for (Scope* scope = this; 857 scope != NULL; 858 scope = scope->outer_scope()) { 859 Variable* var = scope->LookupLocal(name); 860 if (var != NULL) return var; 861 } 862 return NULL; 863} 864 865Variable* DeclarationScope::DeclareParameter( 866 const AstRawString* name, VariableMode mode, bool is_optional, bool is_rest, 867 bool* is_duplicate, AstValueFactory* ast_value_factory) { 868 DCHECK(!already_resolved_); 869 DCHECK(is_function_scope() || is_module_scope()); 870 DCHECK(!has_rest_); 871 DCHECK(!is_optional || !is_rest); 872 Variable* var; 873 if (mode == TEMPORARY) { 874 var = NewTemporary(name); 875 } else { 876 var = 877 Declare(zone(), this, name, mode, NORMAL_VARIABLE, kCreatedInitialized); 878 // TODO(wingo): Avoid O(n^2) check. 879 *is_duplicate = IsDeclaredParameter(name); 880 } 881 has_rest_ = is_rest; 882 params_.Add(var, zone()); 883 if (name == ast_value_factory->arguments_string()) { 884 has_arguments_parameter_ = true; 885 } 886 return var; 887} 888 889Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode, 890 InitializationFlag init_flag, VariableKind kind, 891 MaybeAssignedFlag maybe_assigned_flag) { 892 DCHECK(!already_resolved_); 893 // This function handles VAR, LET, and CONST modes. DYNAMIC variables are 894 // introduced during variable allocation, and TEMPORARY variables are 895 // allocated via NewTemporary(). 896 DCHECK(IsDeclaredVariableMode(mode)); 897 return Declare(zone(), this, name, mode, kind, init_flag, 898 maybe_assigned_flag); 899} 900 901Variable* Scope::DeclareVariable( 902 Declaration* declaration, VariableMode mode, InitializationFlag init, 903 bool allow_harmony_restrictive_generators, 904 bool* sloppy_mode_block_scope_function_redefinition, bool* ok) { 905 DCHECK(IsDeclaredVariableMode(mode)); 906 DCHECK(!already_resolved_); 907 908 if (mode == VAR && !is_declaration_scope()) { 909 return GetDeclarationScope()->DeclareVariable( 910 declaration, mode, init, allow_harmony_restrictive_generators, 911 sloppy_mode_block_scope_function_redefinition, ok); 912 } 913 DCHECK(!is_catch_scope()); 914 DCHECK(!is_with_scope()); 915 DCHECK(is_declaration_scope() || 916 (IsLexicalVariableMode(mode) && is_block_scope())); 917 918 VariableProxy* proxy = declaration->proxy(); 919 DCHECK(proxy->raw_name() != NULL); 920 const AstRawString* name = proxy->raw_name(); 921 bool is_function_declaration = declaration->IsFunctionDeclaration(); 922 923 Variable* var = nullptr; 924 if (is_eval_scope() && is_sloppy(language_mode()) && mode == VAR) { 925 // In a var binding in a sloppy direct eval, pollute the enclosing scope 926 // with this new binding by doing the following: 927 // The proxy is bound to a lookup variable to force a dynamic declaration 928 // using the DeclareEvalVar or DeclareEvalFunction runtime functions. 929 VariableKind kind = NORMAL_VARIABLE; 930 // TODO(sigurds) figure out if kNotAssigned is OK here 931 var = new (zone()) Variable(this, name, mode, kind, init, kNotAssigned); 932 var->AllocateTo(VariableLocation::LOOKUP, -1); 933 } else { 934 // Declare the variable in the declaration scope. 935 var = LookupLocal(name); 936 if (var == NULL) { 937 // Declare the name. 938 VariableKind kind = NORMAL_VARIABLE; 939 if (is_function_declaration) { 940 kind = FUNCTION_VARIABLE; 941 } 942 var = DeclareLocal(name, mode, init, kind, kNotAssigned); 943 } else if (IsLexicalVariableMode(mode) || 944 IsLexicalVariableMode(var->mode())) { 945 // Allow duplicate function decls for web compat, see bug 4693. 946 bool duplicate_allowed = false; 947 if (is_sloppy(language_mode()) && is_function_declaration && 948 var->is_function()) { 949 DCHECK(IsLexicalVariableMode(mode) && 950 IsLexicalVariableMode(var->mode())); 951 // If the duplication is allowed, then the var will show up 952 // in the SloppyBlockFunctionMap and the new FunctionKind 953 // will be a permitted duplicate. 954 FunctionKind function_kind = 955 declaration->AsFunctionDeclaration()->fun()->kind(); 956 duplicate_allowed = 957 GetDeclarationScope()->sloppy_block_function_map()->Lookup( 958 const_cast<AstRawString*>(name), name->hash()) != nullptr && 959 !IsAsyncFunction(function_kind) && 960 !(allow_harmony_restrictive_generators && 961 IsGeneratorFunction(function_kind)); 962 } 963 if (duplicate_allowed) { 964 *sloppy_mode_block_scope_function_redefinition = true; 965 } else { 966 // The name was declared in this scope before; check for conflicting 967 // re-declarations. We have a conflict if either of the declarations 968 // is not a var (in script scope, we also have to ignore legacy const 969 // for compatibility). There is similar code in runtime.cc in the 970 // Declare functions. The function CheckConflictingVarDeclarations 971 // checks for var and let bindings from different scopes whereas this 972 // is a check for conflicting declarations within the same scope. This 973 // check also covers the special case 974 // 975 // function () { let x; { var x; } } 976 // 977 // because the var declaration is hoisted to the function scope where 978 // 'x' is already bound. 979 DCHECK(IsDeclaredVariableMode(var->mode())); 980 // In harmony we treat re-declarations as early errors. See 981 // ES5 16 for a definition of early errors. 982 *ok = false; 983 return nullptr; 984 } 985 } else if (mode == VAR) { 986 var->set_maybe_assigned(); 987 } 988 } 989 DCHECK_NOT_NULL(var); 990 991 // We add a declaration node for every declaration. The compiler 992 // will only generate code if necessary. In particular, declarations 993 // for inner local variables that do not represent functions won't 994 // result in any generated code. 995 // 996 // This will lead to multiple declaration nodes for the 997 // same variable if it is declared several times. This is not a 998 // semantic issue, but it may be a performance issue since it may 999 // lead to repeated DeclareEvalVar or DeclareEvalFunction calls. 1000 decls_.Add(declaration); 1001 proxy->BindTo(var); 1002 return var; 1003} 1004 1005VariableProxy* Scope::NewUnresolved(AstNodeFactory* factory, 1006 const AstRawString* name, 1007 int start_position, VariableKind kind) { 1008 // Note that we must not share the unresolved variables with 1009 // the same name because they may be removed selectively via 1010 // RemoveUnresolved(). 1011 DCHECK(!already_resolved_); 1012 DCHECK_EQ(!needs_migration_, factory->zone() == zone()); 1013 VariableProxy* proxy = factory->NewVariableProxy(name, kind, start_position); 1014 proxy->set_next_unresolved(unresolved_); 1015 unresolved_ = proxy; 1016 return proxy; 1017} 1018 1019void Scope::AddUnresolved(VariableProxy* proxy) { 1020 DCHECK(!already_resolved_); 1021 DCHECK(!proxy->is_resolved()); 1022 proxy->set_next_unresolved(unresolved_); 1023 unresolved_ = proxy; 1024} 1025 1026Variable* DeclarationScope::DeclareDynamicGlobal(const AstRawString* name, 1027 VariableKind kind) { 1028 DCHECK(is_script_scope()); 1029 return variables_.Declare(zone(), this, name, DYNAMIC_GLOBAL, kind, 1030 kCreatedInitialized); 1031} 1032 1033 1034bool Scope::RemoveUnresolved(VariableProxy* var) { 1035 if (unresolved_ == var) { 1036 unresolved_ = var->next_unresolved(); 1037 var->set_next_unresolved(nullptr); 1038 return true; 1039 } 1040 VariableProxy* current = unresolved_; 1041 while (current != nullptr) { 1042 VariableProxy* next = current->next_unresolved(); 1043 if (var == next) { 1044 current->set_next_unresolved(next->next_unresolved()); 1045 var->set_next_unresolved(nullptr); 1046 return true; 1047 } 1048 current = next; 1049 } 1050 return false; 1051} 1052 1053bool Scope::RemoveUnresolved(const AstRawString* name) { 1054 if (unresolved_ != nullptr && unresolved_->raw_name() == name) { 1055 VariableProxy* removed = unresolved_; 1056 unresolved_ = unresolved_->next_unresolved(); 1057 removed->set_next_unresolved(nullptr); 1058 return true; 1059 } 1060 VariableProxy* current = unresolved_; 1061 while (current != nullptr) { 1062 VariableProxy* next = current->next_unresolved(); 1063 if (next != nullptr && next->raw_name() == name) { 1064 current->set_next_unresolved(next->next_unresolved()); 1065 next->set_next_unresolved(nullptr); 1066 return true; 1067 } 1068 current = next; 1069 } 1070 return false; 1071} 1072 1073Variable* Scope::NewTemporary(const AstRawString* name) { 1074 DeclarationScope* scope = GetClosureScope(); 1075 Variable* var = new (zone()) 1076 Variable(scope, name, TEMPORARY, NORMAL_VARIABLE, kCreatedInitialized); 1077 scope->AddLocal(var); 1078 return var; 1079} 1080 1081Declaration* Scope::CheckConflictingVarDeclarations() { 1082 for (Declaration* decl : decls_) { 1083 VariableMode mode = decl->proxy()->var()->mode(); 1084 if (IsLexicalVariableMode(mode) && !is_block_scope()) continue; 1085 1086 // Iterate through all scopes until and including the declaration scope. 1087 Scope* previous = NULL; 1088 Scope* current = decl->scope(); 1089 // Lexical vs lexical conflicts within the same scope have already been 1090 // captured in Parser::Declare. The only conflicts we still need to check 1091 // are lexical vs VAR, or any declarations within a declaration block scope 1092 // vs lexical declarations in its surrounding (function) scope. 1093 if (IsLexicalVariableMode(mode)) current = current->outer_scope_; 1094 do { 1095 // There is a conflict if there exists a non-VAR binding. 1096 Variable* other_var = 1097 current->variables_.Lookup(decl->proxy()->raw_name()); 1098 if (other_var != NULL && IsLexicalVariableMode(other_var->mode())) { 1099 return decl; 1100 } 1101 previous = current; 1102 current = current->outer_scope_; 1103 } while (!previous->is_declaration_scope()); 1104 } 1105 return NULL; 1106} 1107 1108Declaration* Scope::CheckLexDeclarationsConflictingWith( 1109 const ZoneList<const AstRawString*>& names) { 1110 DCHECK(is_block_scope()); 1111 for (int i = 0; i < names.length(); ++i) { 1112 Variable* var = LookupLocal(names.at(i)); 1113 if (var != nullptr) { 1114 // Conflict; find and return its declaration. 1115 DCHECK(IsLexicalVariableMode(var->mode())); 1116 const AstRawString* name = names.at(i); 1117 for (Declaration* decl : decls_) { 1118 if (decl->proxy()->raw_name() == name) return decl; 1119 } 1120 DCHECK(false); 1121 } 1122 } 1123 return nullptr; 1124} 1125 1126void DeclarationScope::AllocateVariables(ParseInfo* info, AnalyzeMode mode) { 1127 // Module variables must be allocated before variable resolution 1128 // to ensure that AccessNeedsHoleCheck() can detect import variables. 1129 if (is_module_scope()) AsModuleScope()->AllocateModuleVariables(); 1130 1131 ResolveVariablesRecursively(info); 1132 AllocateVariablesRecursively(); 1133 1134 MaybeHandle<ScopeInfo> outer_scope; 1135 if (outer_scope_ != nullptr) outer_scope = outer_scope_->scope_info_; 1136 1137 AllocateScopeInfosRecursively(info->isolate(), outer_scope); 1138 if (mode == AnalyzeMode::kDebugger) { 1139 AllocateDebuggerScopeInfos(info->isolate(), outer_scope); 1140 } 1141 // The debugger expects all shared function infos to contain a scope info. 1142 // Since the top-most scope will end up in a shared function info, make sure 1143 // it has one, even if it doesn't need a scope info. 1144 // TODO(jochen|yangguo): Remove this requirement. 1145 if (scope_info_.is_null()) { 1146 scope_info_ = ScopeInfo::Create(info->isolate(), zone(), this, outer_scope); 1147 } 1148} 1149 1150bool Scope::AllowsLazyParsingWithoutUnresolvedVariables( 1151 const Scope* outer) const { 1152 // If none of the outer scopes need to decide whether to context allocate 1153 // specific variables, we can preparse inner functions without unresolved 1154 // variables. Otherwise we need to find unresolved variables to force context 1155 // allocation of the matching declarations. We can stop at the outer scope for 1156 // the parse, since context allocation of those variables is already 1157 // guaranteed to be correct. 1158 for (const Scope* s = this; s != outer; s = s->outer_scope_) { 1159 // Eval forces context allocation on all outer scopes, so we don't need to 1160 // look at those scopes. Sloppy eval makes all top-level variables dynamic, 1161 // whereas strict-mode requires context allocation. 1162 if (s->is_eval_scope()) return !is_strict(s->language_mode()); 1163 // Catch scopes force context allocation of all variables. 1164 if (s->is_catch_scope()) continue; 1165 // With scopes do not introduce variables that need allocation. 1166 if (s->is_with_scope()) continue; 1167 // If everything is guaranteed to be context allocated we can ignore the 1168 // scope. 1169 if (s->has_forced_context_allocation()) continue; 1170 // Only block scopes and function scopes should disallow preparsing. 1171 DCHECK(s->is_block_scope() || s->is_function_scope()); 1172 return false; 1173 } 1174 return true; 1175} 1176 1177bool DeclarationScope::AllowsLazyCompilation() const { 1178 return !force_eager_compilation_; 1179} 1180 1181int Scope::ContextChainLength(Scope* scope) const { 1182 int n = 0; 1183 for (const Scope* s = this; s != scope; s = s->outer_scope_) { 1184 DCHECK(s != NULL); // scope must be in the scope chain 1185 if (s->NeedsContext()) n++; 1186 } 1187 return n; 1188} 1189 1190int Scope::ContextChainLengthUntilOutermostSloppyEval() const { 1191 int result = 0; 1192 int length = 0; 1193 1194 for (const Scope* s = this; s != nullptr; s = s->outer_scope()) { 1195 if (!s->NeedsContext()) continue; 1196 length++; 1197 if (s->calls_sloppy_eval()) result = length; 1198 } 1199 1200 return result; 1201} 1202 1203int Scope::MaxNestedContextChainLength() { 1204 int max_context_chain_length = 0; 1205 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { 1206 if (scope->is_function_scope()) continue; 1207 max_context_chain_length = std::max(scope->MaxNestedContextChainLength(), 1208 max_context_chain_length); 1209 } 1210 if (NeedsContext()) { 1211 max_context_chain_length += 1; 1212 } 1213 return max_context_chain_length; 1214} 1215 1216DeclarationScope* Scope::GetDeclarationScope() { 1217 Scope* scope = this; 1218 while (!scope->is_declaration_scope()) { 1219 scope = scope->outer_scope(); 1220 } 1221 return scope->AsDeclarationScope(); 1222} 1223 1224const DeclarationScope* Scope::GetClosureScope() const { 1225 const Scope* scope = this; 1226 while (!scope->is_declaration_scope() || scope->is_block_scope()) { 1227 scope = scope->outer_scope(); 1228 } 1229 return scope->AsDeclarationScope(); 1230} 1231 1232DeclarationScope* Scope::GetClosureScope() { 1233 Scope* scope = this; 1234 while (!scope->is_declaration_scope() || scope->is_block_scope()) { 1235 scope = scope->outer_scope(); 1236 } 1237 return scope->AsDeclarationScope(); 1238} 1239 1240bool Scope::NeedsScopeInfo() const { 1241 DCHECK(!already_resolved_); 1242 DCHECK(GetClosureScope()->ShouldEagerCompile()); 1243 // The debugger expects all functions to have scope infos. 1244 // TODO(jochen|yangguo): Remove this requirement. 1245 if (is_function_scope()) return true; 1246 return NeedsContext(); 1247} 1248 1249ModuleScope* Scope::GetModuleScope() { 1250 Scope* scope = this; 1251 DCHECK(!scope->is_script_scope()); 1252 while (!scope->is_module_scope()) { 1253 scope = scope->outer_scope(); 1254 DCHECK_NOT_NULL(scope); 1255 } 1256 return scope->AsModuleScope(); 1257} 1258 1259DeclarationScope* Scope::GetReceiverScope() { 1260 Scope* scope = this; 1261 while (!scope->is_script_scope() && 1262 (!scope->is_function_scope() || 1263 scope->AsDeclarationScope()->is_arrow_scope())) { 1264 scope = scope->outer_scope(); 1265 } 1266 return scope->AsDeclarationScope(); 1267} 1268 1269Scope* Scope::GetOuterScopeWithContext() { 1270 Scope* scope = outer_scope_; 1271 while (scope && !scope->NeedsContext()) { 1272 scope = scope->outer_scope(); 1273 } 1274 return scope; 1275} 1276 1277Handle<StringSet> DeclarationScope::CollectNonLocals( 1278 ParseInfo* info, Handle<StringSet> non_locals) { 1279 VariableProxy* free_variables = FetchFreeVariables(this, true, info); 1280 for (VariableProxy* proxy = free_variables; proxy != nullptr; 1281 proxy = proxy->next_unresolved()) { 1282 non_locals = StringSet::Add(non_locals, proxy->name()); 1283 } 1284 return non_locals; 1285} 1286 1287void DeclarationScope::ResetAfterPreparsing(AstValueFactory* ast_value_factory, 1288 bool aborted) { 1289 DCHECK(is_function_scope()); 1290 1291 // Reset all non-trivial members. 1292 params_.Clear(); 1293 decls_.Clear(); 1294 locals_.Clear(); 1295 sloppy_block_function_map_.Clear(); 1296 variables_.Clear(); 1297 // Make sure we won't walk the scope tree from here on. 1298 inner_scope_ = nullptr; 1299 unresolved_ = nullptr; 1300 1301 if (aborted && !IsArrowFunction(function_kind_)) { 1302 DeclareDefaultFunctionVariables(ast_value_factory); 1303 } 1304 1305#ifdef DEBUG 1306 needs_migration_ = false; 1307#endif 1308 1309 is_lazily_parsed_ = !aborted; 1310} 1311 1312void DeclarationScope::AnalyzePartially(AstNodeFactory* ast_node_factory) { 1313 DCHECK(!force_eager_compilation_); 1314 VariableProxy* unresolved = nullptr; 1315 1316 if (!outer_scope_->is_script_scope()) { 1317 // Try to resolve unresolved variables for this Scope and migrate those 1318 // which cannot be resolved inside. It doesn't make sense to try to resolve 1319 // them in the outer Scopes here, because they are incomplete. 1320 for (VariableProxy* proxy = 1321 FetchFreeVariables(this, !FLAG_lazy_inner_functions); 1322 proxy != nullptr; proxy = proxy->next_unresolved()) { 1323 DCHECK(!proxy->is_resolved()); 1324 VariableProxy* copy = ast_node_factory->CopyVariableProxy(proxy); 1325 copy->set_next_unresolved(unresolved); 1326 unresolved = copy; 1327 } 1328 1329 // Clear arguments_ if unused. This is used as a signal for optimization. 1330 if (arguments_ != nullptr && 1331 !(MustAllocate(arguments_) && !has_arguments_parameter_)) { 1332 arguments_ = nullptr; 1333 } 1334 } 1335 1336 ResetAfterPreparsing(ast_node_factory->ast_value_factory(), false); 1337 1338 unresolved_ = unresolved; 1339} 1340 1341#ifdef DEBUG 1342static const char* Header(ScopeType scope_type, FunctionKind function_kind, 1343 bool is_declaration_scope) { 1344 switch (scope_type) { 1345 case EVAL_SCOPE: return "eval"; 1346 // TODO(adamk): Should we print concise method scopes specially? 1347 case FUNCTION_SCOPE: 1348 if (IsGeneratorFunction(function_kind)) return "function*"; 1349 if (IsAsyncFunction(function_kind)) return "async function"; 1350 if (IsArrowFunction(function_kind)) return "arrow"; 1351 return "function"; 1352 case MODULE_SCOPE: return "module"; 1353 case SCRIPT_SCOPE: return "global"; 1354 case CATCH_SCOPE: return "catch"; 1355 case BLOCK_SCOPE: return is_declaration_scope ? "varblock" : "block"; 1356 case WITH_SCOPE: return "with"; 1357 } 1358 UNREACHABLE(); 1359 return NULL; 1360} 1361 1362 1363static void Indent(int n, const char* str) { 1364 PrintF("%*s%s", n, "", str); 1365} 1366 1367 1368static void PrintName(const AstRawString* name) { 1369 PrintF("%.*s", name->length(), name->raw_data()); 1370} 1371 1372 1373static void PrintLocation(Variable* var) { 1374 switch (var->location()) { 1375 case VariableLocation::UNALLOCATED: 1376 break; 1377 case VariableLocation::PARAMETER: 1378 PrintF("parameter[%d]", var->index()); 1379 break; 1380 case VariableLocation::LOCAL: 1381 PrintF("local[%d]", var->index()); 1382 break; 1383 case VariableLocation::CONTEXT: 1384 PrintF("context[%d]", var->index()); 1385 break; 1386 case VariableLocation::LOOKUP: 1387 PrintF("lookup"); 1388 break; 1389 case VariableLocation::MODULE: 1390 PrintF("module"); 1391 break; 1392 } 1393} 1394 1395 1396static void PrintVar(int indent, Variable* var) { 1397 if (var->is_used() || !var->IsUnallocated()) { 1398 Indent(indent, VariableMode2String(var->mode())); 1399 PrintF(" "); 1400 if (var->raw_name()->IsEmpty()) 1401 PrintF(".%p", reinterpret_cast<void*>(var)); 1402 else 1403 PrintName(var->raw_name()); 1404 PrintF("; // "); 1405 PrintLocation(var); 1406 bool comma = !var->IsUnallocated(); 1407 if (var->has_forced_context_allocation()) { 1408 if (comma) PrintF(", "); 1409 PrintF("forced context allocation"); 1410 comma = true; 1411 } 1412 if (var->maybe_assigned() == kNotAssigned) { 1413 if (comma) PrintF(", "); 1414 PrintF("never assigned"); 1415 } 1416 PrintF("\n"); 1417 } 1418} 1419 1420static void PrintMap(int indent, VariableMap* map, bool locals) { 1421 for (VariableMap::Entry* p = map->Start(); p != nullptr; p = map->Next(p)) { 1422 Variable* var = reinterpret_cast<Variable*>(p->value); 1423 bool local = !IsDynamicVariableMode(var->mode()); 1424 if (locals ? local : !local) { 1425 if (var == nullptr) { 1426 Indent(indent, "<?>\n"); 1427 } else { 1428 PrintVar(indent, var); 1429 } 1430 } 1431 } 1432} 1433 1434void DeclarationScope::PrintParameters() { 1435 PrintF(" ("); 1436 for (int i = 0; i < params_.length(); i++) { 1437 if (i > 0) PrintF(", "); 1438 const AstRawString* name = params_[i]->raw_name(); 1439 if (name->IsEmpty()) 1440 PrintF(".%p", reinterpret_cast<void*>(params_[i])); 1441 else 1442 PrintName(name); 1443 } 1444 PrintF(")"); 1445} 1446 1447void Scope::Print(int n) { 1448 int n0 = (n > 0 ? n : 0); 1449 int n1 = n0 + 2; // indentation 1450 1451 // Print header. 1452 FunctionKind function_kind = is_function_scope() 1453 ? AsDeclarationScope()->function_kind() 1454 : kNormalFunction; 1455 Indent(n0, Header(scope_type_, function_kind, is_declaration_scope())); 1456 if (scope_name_ != nullptr && !scope_name_->IsEmpty()) { 1457 PrintF(" "); 1458 PrintName(scope_name_); 1459 } 1460 1461 // Print parameters, if any. 1462 Variable* function = nullptr; 1463 if (is_function_scope()) { 1464 AsDeclarationScope()->PrintParameters(); 1465 function = AsDeclarationScope()->function_var(); 1466 } 1467 1468 PrintF(" { // (%d, %d)\n", start_position(), end_position()); 1469 1470 // Function name, if any (named function literals, only). 1471 if (function != nullptr) { 1472 Indent(n1, "// (local) function name: "); 1473 PrintName(function->raw_name()); 1474 PrintF("\n"); 1475 } 1476 1477 // Scope info. 1478 if (is_strict(language_mode())) { 1479 Indent(n1, "// strict mode scope\n"); 1480 } 1481 if (IsAsmModule()) Indent(n1, "// scope is an asm module\n"); 1482 if (IsAsmFunction()) Indent(n1, "// scope is an asm function\n"); 1483 if (scope_calls_eval_) Indent(n1, "// scope calls 'eval'\n"); 1484 if (is_declaration_scope() && AsDeclarationScope()->uses_super_property()) { 1485 Indent(n1, "// scope uses 'super' property\n"); 1486 } 1487 if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n"); 1488 if (is_declaration_scope()) { 1489 DeclarationScope* scope = AsDeclarationScope(); 1490 if (scope->is_lazily_parsed()) Indent(n1, "// lazily parsed\n"); 1491 if (scope->ShouldEagerCompile()) Indent(n1, "// will be compiled\n"); 1492 } 1493 if (num_stack_slots_ > 0) { 1494 Indent(n1, "// "); 1495 PrintF("%d stack slots\n", num_stack_slots_); 1496 } 1497 if (num_heap_slots_ > 0) { 1498 Indent(n1, "// "); 1499 PrintF("%d heap slots\n", num_heap_slots_); 1500 } 1501 1502 // Print locals. 1503 if (function != nullptr) { 1504 Indent(n1, "// function var:\n"); 1505 PrintVar(n1, function); 1506 } 1507 1508 if (variables_.Start() != NULL) { 1509 Indent(n1, "// local vars:\n"); 1510 PrintMap(n1, &variables_, true); 1511 1512 Indent(n1, "// dynamic vars:\n"); 1513 PrintMap(n1, &variables_, false); 1514 } 1515 1516 // Print inner scopes (disable by providing negative n). 1517 if (n >= 0) { 1518 for (Scope* scope = inner_scope_; scope != nullptr; 1519 scope = scope->sibling_) { 1520 PrintF("\n"); 1521 scope->Print(n1); 1522 } 1523 } 1524 1525 Indent(n0, "}\n"); 1526} 1527 1528void Scope::CheckScopePositions() { 1529 // Visible leaf scopes must have real positions. 1530 if (!is_hidden() && inner_scope_ == nullptr) { 1531 CHECK_NE(kNoSourcePosition, start_position()); 1532 CHECK_NE(kNoSourcePosition, end_position()); 1533 } 1534 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { 1535 scope->CheckScopePositions(); 1536 } 1537} 1538 1539void Scope::CheckZones() { 1540 DCHECK(!needs_migration_); 1541 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { 1542 CHECK_EQ(scope->zone(), zone()); 1543 scope->CheckZones(); 1544 } 1545} 1546#endif // DEBUG 1547 1548Variable* Scope::NonLocal(const AstRawString* name, VariableMode mode) { 1549 // Declare a new non-local. 1550 DCHECK(IsDynamicVariableMode(mode)); 1551 Variable* var = variables_.Declare(zone(), NULL, name, mode, NORMAL_VARIABLE, 1552 kCreatedInitialized); 1553 // Allocate it by giving it a dynamic lookup. 1554 var->AllocateTo(VariableLocation::LOOKUP, -1); 1555 return var; 1556} 1557 1558Variable* Scope::LookupRecursive(VariableProxy* proxy, Scope* outer_scope_end) { 1559 DCHECK_NE(outer_scope_end, this); 1560 // Short-cut: whenever we find a debug-evaluate scope, just look everything up 1561 // dynamically. Debug-evaluate doesn't properly create scope info for the 1562 // lookups it does. It may not have a valid 'this' declaration, and anything 1563 // accessed through debug-evaluate might invalidly resolve to stack-allocated 1564 // variables. 1565 // TODO(yangguo): Remove once debug-evaluate creates proper ScopeInfo for the 1566 // scopes in which it's evaluating. 1567 if (is_debug_evaluate_scope_) return NonLocal(proxy->raw_name(), DYNAMIC); 1568 1569 // Try to find the variable in this scope. 1570 Variable* var = LookupLocal(proxy->raw_name()); 1571 1572 // We found a variable and we are done. (Even if there is an 'eval' in this 1573 // scope which introduces the same variable again, the resulting variable 1574 // remains the same.) 1575 if (var != nullptr) return var; 1576 1577 if (outer_scope_ == outer_scope_end) { 1578 // We may just be trying to find all free variables. In that case, don't 1579 // declare them in the outer scope. 1580 if (!is_script_scope()) return nullptr; 1581 // No binding has been found. Declare a variable on the global object. 1582 return AsDeclarationScope()->DeclareDynamicGlobal(proxy->raw_name(), 1583 NORMAL_VARIABLE); 1584 } 1585 1586 DCHECK(!is_script_scope()); 1587 1588 var = outer_scope_->LookupRecursive(proxy, outer_scope_end); 1589 1590 // The variable could not be resolved statically. 1591 if (var == nullptr) return var; 1592 1593 if (is_function_scope() && !var->is_dynamic()) { 1594 var->ForceContextAllocation(); 1595 } 1596 // "this" can't be shadowed by "eval"-introduced bindings or by "with" 1597 // scopes. 1598 // TODO(wingo): There are other variables in this category; add them. 1599 if (var->is_this()) return var; 1600 1601 if (is_with_scope()) { 1602 // The current scope is a with scope, so the variable binding can not be 1603 // statically resolved. However, note that it was necessary to do a lookup 1604 // in the outer scope anyway, because if a binding exists in an outer 1605 // scope, the associated variable has to be marked as potentially being 1606 // accessed from inside of an inner with scope (the property may not be in 1607 // the 'with' object). 1608 if (!var->is_dynamic() && var->IsUnallocated()) { 1609 DCHECK(!already_resolved_); 1610 var->set_is_used(); 1611 var->ForceContextAllocation(); 1612 if (proxy->is_assigned()) var->set_maybe_assigned(); 1613 } 1614 return NonLocal(proxy->raw_name(), DYNAMIC); 1615 } 1616 1617 if (calls_sloppy_eval() && is_declaration_scope()) { 1618 // A variable binding may have been found in an outer scope, but the current 1619 // scope makes a sloppy 'eval' call, so the found variable may not be the 1620 // correct one (the 'eval' may introduce a binding with the same name). In 1621 // that case, change the lookup result to reflect this situation. Only 1622 // scopes that can host var bindings (declaration scopes) need be considered 1623 // here (this excludes block and catch scopes), and variable lookups at 1624 // script scope are always dynamic. 1625 if (var->IsGlobalObjectProperty()) { 1626 return NonLocal(proxy->raw_name(), DYNAMIC_GLOBAL); 1627 } 1628 1629 if (var->is_dynamic()) return var; 1630 1631 Variable* invalidated = var; 1632 var = NonLocal(proxy->raw_name(), DYNAMIC_LOCAL); 1633 var->set_local_if_not_shadowed(invalidated); 1634 } 1635 1636 return var; 1637} 1638 1639void Scope::ResolveVariable(ParseInfo* info, VariableProxy* proxy) { 1640 DCHECK(info->script_scope()->is_script_scope()); 1641 DCHECK(!proxy->is_resolved()); 1642 Variable* var = LookupRecursive(proxy, nullptr); 1643 ResolveTo(info, proxy, var); 1644 1645 if (FLAG_lazy_inner_functions) { 1646 if (info != nullptr && info->is_native()) return; 1647 // Pessimistically force context allocation for all variables to which inner 1648 // scope variables could potentially resolve to. 1649 Scope* scope = GetClosureScope()->outer_scope_; 1650 while (scope != nullptr && scope->scope_info_.is_null()) { 1651 var = scope->LookupLocal(proxy->raw_name()); 1652 if (var != nullptr) { 1653 // Since we don't lazy parse inner arrow functions, inner functions 1654 // cannot refer to the outer "this". 1655 if (!var->is_dynamic() && !var->is_this() && 1656 !var->has_forced_context_allocation()) { 1657 var->ForceContextAllocation(); 1658 var->set_is_used(); 1659 // We don't know what the (potentially lazy parsed) inner function 1660 // does with the variable; pessimistically assume that it's assigned. 1661 var->set_maybe_assigned(); 1662 } 1663 } 1664 scope = scope->outer_scope_; 1665 } 1666 } 1667} 1668 1669namespace { 1670 1671bool AccessNeedsHoleCheck(Variable* var, VariableProxy* proxy, Scope* scope) { 1672 if (!var->binding_needs_init()) { 1673 return false; 1674 } 1675 1676 // It's impossible to eliminate module import hole checks here, because it's 1677 // unknown at compilation time whether the binding referred to in the 1678 // exporting module itself requires hole checks. 1679 if (var->location() == VariableLocation::MODULE && !var->IsExport()) { 1680 return true; 1681 } 1682 1683 // Check if the binding really needs an initialization check. The check 1684 // can be skipped in the following situation: we have a LET or CONST 1685 // binding, both the Variable and the VariableProxy have the same 1686 // declaration scope (i.e. they are both in global code, in the 1687 // same function or in the same eval code), the VariableProxy is in 1688 // the source physically located after the initializer of the variable, 1689 // and that the initializer cannot be skipped due to a nonlinear scope. 1690 // 1691 // The condition on the declaration scopes is a conservative check for 1692 // nested functions that access a binding and are called before the 1693 // binding is initialized: 1694 // function() { f(); let x = 1; function f() { x = 2; } } 1695 // 1696 // The check cannot be skipped on non-linear scopes, namely switch 1697 // scopes, to ensure tests are done in cases like the following: 1698 // switch (1) { case 0: let x = 2; case 1: f(x); } 1699 // The scope of the variable needs to be checked, in case the use is 1700 // in a sub-block which may be linear. 1701 if (var->scope()->GetDeclarationScope() != scope->GetDeclarationScope()) { 1702 return true; 1703 } 1704 1705 if (var->is_this()) { 1706 DCHECK( 1707 IsSubclassConstructor(scope->GetDeclarationScope()->function_kind())); 1708 // TODO(littledan): implement 'this' hole check elimination. 1709 return true; 1710 } 1711 1712 // We should always have valid source positions. 1713 DCHECK(var->initializer_position() != kNoSourcePosition); 1714 DCHECK(proxy->position() != kNoSourcePosition); 1715 1716 return var->scope()->is_nonlinear() || 1717 var->initializer_position() >= proxy->position(); 1718} 1719 1720} // anonymous namespace 1721 1722void Scope::ResolveTo(ParseInfo* info, VariableProxy* proxy, Variable* var) { 1723#ifdef DEBUG 1724 if (info->script_is_native()) { 1725 // To avoid polluting the global object in native scripts 1726 // - Variables must not be allocated to the global scope. 1727 CHECK_NOT_NULL(outer_scope()); 1728 // - Variables must be bound locally or unallocated. 1729 if (var->IsGlobalObjectProperty()) { 1730 // The following variable name may be minified. If so, disable 1731 // minification in js2c.py for better output. 1732 Handle<String> name = proxy->raw_name()->string(); 1733 V8_Fatal(__FILE__, __LINE__, "Unbound variable: '%s' in native script.", 1734 name->ToCString().get()); 1735 } 1736 VariableLocation location = var->location(); 1737 CHECK(location == VariableLocation::LOCAL || 1738 location == VariableLocation::CONTEXT || 1739 location == VariableLocation::PARAMETER || 1740 location == VariableLocation::UNALLOCATED); 1741 } 1742#endif 1743 1744 DCHECK_NOT_NULL(var); 1745 if (proxy->is_assigned()) var->set_maybe_assigned(); 1746 if (AccessNeedsHoleCheck(var, proxy, this)) proxy->set_needs_hole_check(); 1747 proxy->BindTo(var); 1748} 1749 1750void Scope::ResolveVariablesRecursively(ParseInfo* info) { 1751 DCHECK(info->script_scope()->is_script_scope()); 1752 1753 // Resolve unresolved variables for this scope. 1754 for (VariableProxy* proxy = unresolved_; proxy != nullptr; 1755 proxy = proxy->next_unresolved()) { 1756 ResolveVariable(info, proxy); 1757 } 1758 1759 // Resolve unresolved variables for inner scopes. 1760 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { 1761 scope->ResolveVariablesRecursively(info); 1762 } 1763} 1764 1765VariableProxy* Scope::FetchFreeVariables(DeclarationScope* max_outer_scope, 1766 bool try_to_resolve, ParseInfo* info, 1767 VariableProxy* stack) { 1768 for (VariableProxy *proxy = unresolved_, *next = nullptr; proxy != nullptr; 1769 proxy = next) { 1770 next = proxy->next_unresolved(); 1771 DCHECK(!proxy->is_resolved()); 1772 Variable* var = nullptr; 1773 if (try_to_resolve) { 1774 var = LookupRecursive(proxy, max_outer_scope->outer_scope()); 1775 } 1776 if (var == nullptr) { 1777 proxy->set_next_unresolved(stack); 1778 stack = proxy; 1779 } else if (info != nullptr) { 1780 ResolveTo(info, proxy, var); 1781 } else { 1782 var->set_is_used(); 1783 } 1784 } 1785 1786 // Clear unresolved_ as it's in an inconsistent state. 1787 unresolved_ = nullptr; 1788 1789 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { 1790 stack = 1791 scope->FetchFreeVariables(max_outer_scope, try_to_resolve, info, stack); 1792 } 1793 1794 return stack; 1795} 1796 1797bool Scope::MustAllocate(Variable* var) { 1798 DCHECK(var->location() != VariableLocation::MODULE); 1799 // Give var a read/write use if there is a chance it might be accessed 1800 // via an eval() call. This is only possible if the variable has a 1801 // visible name. 1802 if ((var->is_this() || !var->raw_name()->IsEmpty()) && 1803 (inner_scope_calls_eval_ || is_catch_scope() || is_script_scope())) { 1804 var->set_is_used(); 1805 if (inner_scope_calls_eval_) var->set_maybe_assigned(); 1806 } 1807 DCHECK(!var->has_forced_context_allocation() || var->is_used()); 1808 // Global variables do not need to be allocated. 1809 return !var->IsGlobalObjectProperty() && var->is_used(); 1810} 1811 1812 1813bool Scope::MustAllocateInContext(Variable* var) { 1814 // If var is accessed from an inner scope, or if there is a possibility 1815 // that it might be accessed from the current or an inner scope (through 1816 // an eval() call or a runtime with lookup), it must be allocated in the 1817 // context. 1818 // 1819 // Exceptions: If the scope as a whole has forced context allocation, all 1820 // variables will have context allocation, even temporaries. Otherwise 1821 // temporary variables are always stack-allocated. Catch-bound variables are 1822 // always context-allocated. 1823 if (has_forced_context_allocation()) return true; 1824 if (var->mode() == TEMPORARY) return false; 1825 if (is_catch_scope()) return true; 1826 if (is_script_scope() && IsLexicalVariableMode(var->mode())) return true; 1827 return var->has_forced_context_allocation() || inner_scope_calls_eval_; 1828} 1829 1830 1831void Scope::AllocateStackSlot(Variable* var) { 1832 if (is_block_scope()) { 1833 outer_scope()->GetDeclarationScope()->AllocateStackSlot(var); 1834 } else { 1835 var->AllocateTo(VariableLocation::LOCAL, num_stack_slots_++); 1836 } 1837} 1838 1839 1840void Scope::AllocateHeapSlot(Variable* var) { 1841 var->AllocateTo(VariableLocation::CONTEXT, num_heap_slots_++); 1842} 1843 1844void DeclarationScope::AllocateParameterLocals() { 1845 DCHECK(is_function_scope()); 1846 1847 bool uses_sloppy_arguments = false; 1848 1849 if (arguments_ != nullptr) { 1850 DCHECK(!is_arrow_scope()); 1851 // 'arguments' is used. Unless there is also a parameter called 1852 // 'arguments', we must be conservative and allocate all parameters to 1853 // the context assuming they will be captured by the arguments object. 1854 // If we have a parameter named 'arguments', a (new) value is always 1855 // assigned to it via the function invocation. Then 'arguments' denotes 1856 // that specific parameter value and cannot be used to access the 1857 // parameters, which is why we don't need to allocate an arguments 1858 // object in that case. 1859 if (MustAllocate(arguments_) && !has_arguments_parameter_) { 1860 // In strict mode 'arguments' does not alias formal parameters. 1861 // Therefore in strict mode we allocate parameters as if 'arguments' 1862 // were not used. 1863 // If the parameter list is not simple, arguments isn't sloppy either. 1864 uses_sloppy_arguments = 1865 is_sloppy(language_mode()) && has_simple_parameters(); 1866 } else { 1867 // 'arguments' is unused. Tell the code generator that it does not need to 1868 // allocate the arguments object by nulling out arguments_. 1869 arguments_ = nullptr; 1870 } 1871 } 1872 1873 // The same parameter may occur multiple times in the parameters_ list. 1874 // If it does, and if it is not copied into the context object, it must 1875 // receive the highest parameter index for that parameter; thus iteration 1876 // order is relevant! 1877 for (int i = num_parameters() - 1; i >= 0; --i) { 1878 Variable* var = params_[i]; 1879 DCHECK(!has_rest_ || var != rest_parameter()); 1880 DCHECK_EQ(this, var->scope()); 1881 if (uses_sloppy_arguments) { 1882 var->set_is_used(); 1883 var->ForceContextAllocation(); 1884 } 1885 AllocateParameter(var, i); 1886 } 1887} 1888 1889void DeclarationScope::AllocateParameter(Variable* var, int index) { 1890 if (MustAllocate(var)) { 1891 if (MustAllocateInContext(var)) { 1892 DCHECK(var->IsUnallocated() || var->IsContextSlot()); 1893 if (var->IsUnallocated()) { 1894 AllocateHeapSlot(var); 1895 } 1896 } else { 1897 DCHECK(var->IsUnallocated() || var->IsParameter()); 1898 if (var->IsUnallocated()) { 1899 var->AllocateTo(VariableLocation::PARAMETER, index); 1900 } 1901 } 1902 } 1903} 1904 1905void DeclarationScope::AllocateReceiver() { 1906 if (!has_this_declaration()) return; 1907 DCHECK_NOT_NULL(receiver()); 1908 DCHECK_EQ(receiver()->scope(), this); 1909 AllocateParameter(receiver(), -1); 1910} 1911 1912void Scope::AllocateNonParameterLocal(Variable* var) { 1913 DCHECK(var->scope() == this); 1914 if (var->IsUnallocated() && MustAllocate(var)) { 1915 if (MustAllocateInContext(var)) { 1916 AllocateHeapSlot(var); 1917 } else { 1918 AllocateStackSlot(var); 1919 } 1920 } 1921} 1922 1923void Scope::AllocateNonParameterLocalsAndDeclaredGlobals() { 1924 for (Variable* local : locals_) { 1925 AllocateNonParameterLocal(local); 1926 } 1927 1928 if (is_declaration_scope()) { 1929 AsDeclarationScope()->AllocateLocals(); 1930 } 1931} 1932 1933void DeclarationScope::AllocateLocals() { 1934 // For now, function_ must be allocated at the very end. If it gets 1935 // allocated in the context, it must be the last slot in the context, 1936 // because of the current ScopeInfo implementation (see 1937 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor). 1938 if (function_ != nullptr) { 1939 AllocateNonParameterLocal(function_); 1940 } 1941 1942 DCHECK(!has_rest_ || !MustAllocate(rest_parameter()) || 1943 !rest_parameter()->IsUnallocated()); 1944 1945 if (new_target_ != nullptr && !MustAllocate(new_target_)) { 1946 new_target_ = nullptr; 1947 } 1948 1949 if (this_function_ != nullptr && !MustAllocate(this_function_)) { 1950 this_function_ = nullptr; 1951 } 1952} 1953 1954void ModuleScope::AllocateModuleVariables() { 1955 for (const auto& it : module()->regular_imports()) { 1956 Variable* var = LookupLocal(it.first); 1957 var->AllocateTo(VariableLocation::MODULE, it.second->cell_index); 1958 DCHECK(!var->IsExport()); 1959 } 1960 1961 for (const auto& it : module()->regular_exports()) { 1962 Variable* var = LookupLocal(it.first); 1963 var->AllocateTo(VariableLocation::MODULE, it.second->cell_index); 1964 DCHECK(var->IsExport()); 1965 } 1966} 1967 1968void Scope::AllocateVariablesRecursively() { 1969 DCHECK(!already_resolved_); 1970 DCHECK_EQ(0, num_stack_slots_); 1971 // Don't allocate variables of preparsed scopes. 1972 if (is_declaration_scope() && AsDeclarationScope()->is_lazily_parsed()) { 1973 return; 1974 } 1975 1976 // Allocate variables for inner scopes. 1977 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { 1978 scope->AllocateVariablesRecursively(); 1979 } 1980 1981 DCHECK(!already_resolved_); 1982 DCHECK_EQ(Context::MIN_CONTEXT_SLOTS, num_heap_slots_); 1983 1984 // Allocate variables for this scope. 1985 // Parameters must be allocated first, if any. 1986 if (is_declaration_scope()) { 1987 if (is_function_scope()) { 1988 AsDeclarationScope()->AllocateParameterLocals(); 1989 } 1990 AsDeclarationScope()->AllocateReceiver(); 1991 } 1992 AllocateNonParameterLocalsAndDeclaredGlobals(); 1993 1994 // Force allocation of a context for this scope if necessary. For a 'with' 1995 // scope and for a function scope that makes an 'eval' call we need a context, 1996 // even if no local variables were statically allocated in the scope. 1997 // Likewise for modules. 1998 bool must_have_context = 1999 is_with_scope() || is_module_scope() || 2000 (is_function_scope() && calls_sloppy_eval()) || 2001 (is_block_scope() && is_declaration_scope() && calls_sloppy_eval()); 2002 2003 // If we didn't allocate any locals in the local context, then we only 2004 // need the minimal number of slots if we must have a context. 2005 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && !must_have_context) { 2006 num_heap_slots_ = 0; 2007 } 2008 2009 // Allocation done. 2010 DCHECK(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); 2011} 2012 2013void Scope::AllocateScopeInfosRecursively(Isolate* isolate, 2014 MaybeHandle<ScopeInfo> outer_scope) { 2015 DCHECK(scope_info_.is_null()); 2016 MaybeHandle<ScopeInfo> next_outer_scope = outer_scope; 2017 2018 if (NeedsScopeInfo()) { 2019 scope_info_ = ScopeInfo::Create(isolate, zone(), this, outer_scope); 2020 // The ScopeInfo chain should mirror the context chain, so we only link to 2021 // the next outer scope that needs a context. 2022 if (NeedsContext()) next_outer_scope = scope_info_; 2023 } 2024 2025 // Allocate ScopeInfos for inner scopes. 2026 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { 2027 if (!scope->is_function_scope() || 2028 scope->AsDeclarationScope()->ShouldEagerCompile()) { 2029 scope->AllocateScopeInfosRecursively(isolate, next_outer_scope); 2030 } 2031 } 2032} 2033 2034void Scope::AllocateDebuggerScopeInfos(Isolate* isolate, 2035 MaybeHandle<ScopeInfo> outer_scope) { 2036 if (scope_info_.is_null()) { 2037 scope_info_ = ScopeInfo::Create(isolate, zone(), this, outer_scope); 2038 } 2039 MaybeHandle<ScopeInfo> outer = NeedsContext() ? scope_info_ : outer_scope; 2040 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { 2041 if (scope->is_function_scope()) continue; 2042 scope->AllocateDebuggerScopeInfos(isolate, outer); 2043 } 2044} 2045 2046int Scope::StackLocalCount() const { 2047 Variable* function = 2048 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; 2049 return num_stack_slots() - 2050 (function != nullptr && function->IsStackLocal() ? 1 : 0); 2051} 2052 2053 2054int Scope::ContextLocalCount() const { 2055 if (num_heap_slots() == 0) return 0; 2056 Variable* function = 2057 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; 2058 bool is_function_var_in_context = 2059 function != nullptr && function->IsContextSlot(); 2060 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - 2061 (is_function_var_in_context ? 1 : 0); 2062} 2063 2064} // namespace internal 2065} // namespace v8 2066