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