| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/ast/scopes.h" | 5 #include "src/ast/scopes.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 | 8 |
| 9 #include "src/accessors.h" | 9 #include "src/accessors.h" |
| 10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
| (...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 333 script_scope->PropagateScopeInfo(); | 333 script_scope->PropagateScopeInfo(); |
| 334 return innermost_scope; | 334 return innermost_scope; |
| 335 } | 335 } |
| 336 | 336 |
| 337 void Scope::DeserializeScopeInfo(Isolate* isolate, | 337 void Scope::DeserializeScopeInfo(Isolate* isolate, |
| 338 AstValueFactory* ast_value_factory) { | 338 AstValueFactory* ast_value_factory) { |
| 339 if (scope_info_.is_null()) return; | 339 if (scope_info_.is_null()) return; |
| 340 | 340 |
| 341 DCHECK(ThreadId::Current().Equals(isolate->thread_id())); | 341 DCHECK(ThreadId::Current().Equals(isolate->thread_id())); |
| 342 | 342 |
| 343 std::set<const AstRawString*> names_seen; | |
| 344 // Internalize context local & globals variables. | 343 // Internalize context local & globals variables. |
| 345 for (int var = 0; var < scope_info_->ContextLocalCount() + | 344 for (int var = 0; var < scope_info_->ContextLocalCount() + |
| 346 scope_info_->ContextGlobalCount(); | 345 scope_info_->ContextGlobalCount(); |
| 347 ++var) { | 346 ++var) { |
| 348 Handle<String> name_handle(scope_info_->ContextLocalName(var), isolate); | 347 Handle<String> name_handle(scope_info_->ContextLocalName(var), isolate); |
| 349 const AstRawString* name = ast_value_factory->GetString(name_handle); | 348 const AstRawString* name = ast_value_factory->GetString(name_handle); |
| 350 if (!names_seen.insert(name).second) continue; | |
| 351 int index = Context::MIN_CONTEXT_SLOTS + var; | 349 int index = Context::MIN_CONTEXT_SLOTS + var; |
| 352 VariableMode mode = scope_info_->ContextLocalMode(var); | 350 VariableMode mode = scope_info_->ContextLocalMode(var); |
| 353 InitializationFlag init_flag = scope_info_->ContextLocalInitFlag(var); | 351 InitializationFlag init_flag = scope_info_->ContextLocalInitFlag(var); |
| 354 MaybeAssignedFlag maybe_assigned_flag = | 352 MaybeAssignedFlag maybe_assigned_flag = |
| 355 scope_info_->ContextLocalMaybeAssignedFlag(var); | 353 scope_info_->ContextLocalMaybeAssignedFlag(var); |
| 356 VariableLocation location = var < scope_info_->ContextLocalCount() | 354 VariableLocation location = var < scope_info_->ContextLocalCount() |
| 357 ? VariableLocation::CONTEXT | 355 ? VariableLocation::CONTEXT |
| 358 : VariableLocation::GLOBAL; | 356 : VariableLocation::GLOBAL; |
| 359 Variable::Kind kind = Variable::NORMAL; | 357 Variable::Kind kind = Variable::NORMAL; |
| 360 if (index == scope_info_->ReceiverContextSlotIndex()) { | 358 if (index == scope_info_->ReceiverContextSlotIndex()) { |
| 361 kind = Variable::THIS; | 359 kind = Variable::THIS; |
| 362 } | 360 } |
| 363 | 361 |
| 364 Variable* result = variables_.Declare(zone(), this, name, mode, kind, | 362 Variable* result = variables_.Declare(zone(), this, name, mode, kind, |
| 365 init_flag, maybe_assigned_flag); | 363 init_flag, maybe_assigned_flag); |
| 366 result->AllocateTo(location, index); | 364 result->AllocateTo(location, index); |
| 367 } | 365 } |
| 368 | 366 |
| 369 // We must read parameters from the end since for multiply declared | |
| 370 // parameters the value of the last declaration of that parameter is used | |
| 371 // inside a function (and thus we need to look at the last index). Was bug# | |
| 372 // 1110337. | |
| 373 for (int index = scope_info_->ParameterCount() - 1; index >= 0; --index) { | |
| 374 Handle<String> name_handle(scope_info_->ParameterName(index), isolate); | |
| 375 const AstRawString* name = ast_value_factory->GetString(name_handle); | |
| 376 if (!names_seen.insert(name).second) continue; | |
| 377 | |
| 378 VariableMode mode = DYNAMIC; | |
| 379 InitializationFlag init_flag = kCreatedInitialized; | |
| 380 MaybeAssignedFlag maybe_assigned_flag = kMaybeAssigned; | |
| 381 VariableLocation location = VariableLocation::LOOKUP; | |
| 382 Variable::Kind kind = Variable::NORMAL; | |
| 383 | |
| 384 Variable* result = variables_.Declare(zone(), this, name, mode, kind, | |
| 385 init_flag, maybe_assigned_flag); | |
| 386 result->AllocateTo(location, index); | |
| 387 } | |
| 388 | |
| 389 // Internalize function proxy for this scope. | 367 // Internalize function proxy for this scope. |
| 390 if (scope_info_->HasFunctionName()) { | 368 if (scope_info_->HasFunctionName()) { |
| 391 Handle<String> name_handle(scope_info_->FunctionName(), isolate); | 369 Handle<String> name_handle(scope_info_->FunctionName(), isolate); |
| 392 const AstRawString* name = ast_value_factory->GetString(name_handle); | 370 const AstRawString* name = ast_value_factory->GetString(name_handle); |
| 393 VariableMode mode; | 371 VariableMode mode; |
| 394 int index = scope_info_->FunctionContextSlotIndex(*name_handle, &mode); | 372 int index = scope_info_->FunctionContextSlotIndex(*name_handle, &mode); |
| 395 if (index >= 0) { | 373 if (index >= 0) { |
| 396 Variable* result = AsDeclarationScope()->DeclareFunctionVar(name); | 374 Variable* result = AsDeclarationScope()->DeclareFunctionVar(name); |
| 397 DCHECK_EQ(mode, result->mode()); | 375 DCHECK_EQ(mode, result->mode()); |
| 398 result->AllocateTo(VariableLocation::CONTEXT, index); | 376 result->AllocateTo(VariableLocation::CONTEXT, index); |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 609 if (calls_eval()) other->RecordEvalCall(); | 587 if (calls_eval()) other->RecordEvalCall(); |
| 610 } | 588 } |
| 611 | 589 |
| 612 Variable* Scope::LookupInScopeInfo(const AstRawString* name) { | 590 Variable* Scope::LookupInScopeInfo(const AstRawString* name) { |
| 613 Handle<String> name_handle = name->string(); | 591 Handle<String> name_handle = name->string(); |
| 614 // The Scope is backed up by ScopeInfo. This means it cannot operate in a | 592 // The Scope is backed up by ScopeInfo. This means it cannot operate in a |
| 615 // heap-independent mode, and all strings must be internalized immediately. So | 593 // heap-independent mode, and all strings must be internalized immediately. So |
| 616 // it's ok to get the Handle<String> here. | 594 // it's ok to get the Handle<String> here. |
| 617 // If we have a serialized scope info, we might find the variable there. | 595 // If we have a serialized scope info, we might find the variable there. |
| 618 // There should be no local slot with the given name. | 596 // There should be no local slot with the given name. |
| 619 DCHECK(scope_info_->StackSlotIndex(*name_handle) < 0); | 597 DCHECK_LT(scope_info_->StackSlotIndex(*name_handle), 0); |
| 620 | 598 |
| 621 VariableMode mode; | 599 VariableMode mode; |
| 622 InitializationFlag init_flag; | 600 InitializationFlag init_flag; |
| 623 MaybeAssignedFlag maybe_assigned_flag; | 601 MaybeAssignedFlag maybe_assigned_flag; |
| 624 | 602 |
| 625 VariableLocation location = VariableLocation::CONTEXT; | 603 VariableLocation location = VariableLocation::CONTEXT; |
| 626 int index = ScopeInfo::ContextSlotIndex(scope_info_, name_handle, &mode, | 604 int index = ScopeInfo::ContextSlotIndex(scope_info_, name_handle, &mode, |
| 627 &init_flag, &maybe_assigned_flag); | 605 &init_flag, &maybe_assigned_flag); |
| 628 if (index < 0) { | 606 if (index < 0) { |
| 629 location = VariableLocation::GLOBAL; | 607 location = VariableLocation::GLOBAL; |
| 630 index = ScopeInfo::ContextGlobalSlotIndex(scope_info_, name_handle, &mode, | 608 index = ScopeInfo::ContextGlobalSlotIndex(scope_info_, name_handle, &mode, |
| 631 &init_flag, &maybe_assigned_flag); | 609 &init_flag, &maybe_assigned_flag); |
| 632 DCHECK(index < 0 || (is_script_scope() && mode == VAR)); | 610 DCHECK(index < 0 || (is_script_scope() && mode == VAR)); |
| 633 } | 611 } |
| 634 if (index < 0) { | |
| 635 location = VariableLocation::LOOKUP; | |
| 636 index = scope_info_->ParameterIndex(*name_handle); | |
| 637 if (index >= 0) { | |
| 638 mode = DYNAMIC; | |
| 639 init_flag = kCreatedInitialized; | |
| 640 // Be conservative and flag parameters as maybe assigned. Better | |
| 641 // information would require ScopeInfo to serialize the maybe_assigned bit | |
| 642 // also for parameters. | |
| 643 maybe_assigned_flag = kMaybeAssigned; | |
| 644 } | |
| 645 } | |
| 646 if (index < 0 && scope_type() == MODULE_SCOPE) { | 612 if (index < 0 && scope_type() == MODULE_SCOPE) { |
| 647 location = VariableLocation::MODULE; | 613 location = VariableLocation::MODULE; |
| 648 index = -1; // TODO(neis): Find module variables in scope info. | 614 index = -1; // TODO(neis): Find module variables in scope info. |
| 649 } | 615 } |
| 650 if (index < 0) return nullptr; // Nowhere found. | 616 if (index < 0) return nullptr; // Nowhere found. |
| 651 | 617 |
| 652 Variable::Kind kind = Variable::NORMAL; | 618 Variable::Kind kind = Variable::NORMAL; |
| 653 if (location == VariableLocation::CONTEXT && | 619 if (location == VariableLocation::CONTEXT && |
| 654 index == scope_info_->ReceiverContextSlotIndex()) { | 620 index == scope_info_->ReceiverContextSlotIndex()) { |
| 655 kind = Variable::THIS; | 621 kind = Variable::THIS; |
| (...skipping 994 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1650 function != nullptr && function->IsContextSlot(); | 1616 function != nullptr && function->IsContextSlot(); |
| 1651 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - | 1617 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - |
| 1652 (is_function_var_in_context ? 1 : 0); | 1618 (is_function_var_in_context ? 1 : 0); |
| 1653 } | 1619 } |
| 1654 | 1620 |
| 1655 | 1621 |
| 1656 int Scope::ContextGlobalCount() const { return num_global_slots(); } | 1622 int Scope::ContextGlobalCount() const { return num_global_slots(); } |
| 1657 | 1623 |
| 1658 } // namespace internal | 1624 } // namespace internal |
| 1659 } // namespace v8 | 1625 } // namespace v8 |
| OLD | NEW |