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