| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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/scopeinfo.h" |
| 6 |
| 5 #include <stdlib.h> | 7 #include <stdlib.h> |
| 6 | 8 |
| 7 #include "src/ast/context-slot-cache.h" | 9 #include "src/ast/context-slot-cache.h" |
| 8 #include "src/ast/scopes.h" | 10 #include "src/ast/scopes.h" |
| 9 #include "src/bootstrapper.h" | 11 #include "src/bootstrapper.h" |
| 10 | 12 |
| 11 namespace v8 { | 13 namespace v8 { |
| 12 namespace internal { | 14 namespace internal { |
| 13 | 15 |
| 14 | 16 |
| 15 Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, | 17 Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, |
| 16 Scope* scope) { | 18 Scope* scope) { |
| 17 // Collect variables. | 19 // Collect variables. |
| 18 ZoneList<Variable*> stack_locals(scope->StackLocalCount(), zone); | 20 ZoneList<Variable*> stack_locals(scope->StackLocalCount(), zone); |
| 19 ZoneList<Variable*> context_locals(scope->ContextLocalCount(), zone); | 21 ZoneList<Variable*> context_locals(scope->ContextLocalCount(), zone); |
| 20 ZoneList<Variable*> context_globals(scope->ContextGlobalCount(), zone); | 22 ZoneList<Variable*> context_globals(scope->ContextGlobalCount(), zone); |
| 21 scope->CollectVariables(&stack_locals, &context_locals, &context_globals); | 23 ZoneList<Variable*> module_vars(0, zone); |
| 24 scope->CollectVariables(&stack_locals, &context_locals, &context_globals, |
| 25 &module_vars); |
| 22 const int stack_local_count = stack_locals.length(); | 26 const int stack_local_count = stack_locals.length(); |
| 23 const int context_local_count = context_locals.length(); | 27 const int context_local_count = context_locals.length(); |
| 24 const int context_global_count = context_globals.length(); | 28 const int context_global_count = context_globals.length(); |
| 25 // Make sure we allocate the correct amount. | 29 const int module_vars_count = module_vars.length(); |
| 26 DCHECK_EQ(scope->ContextLocalCount(), context_local_count); | 30 DCHECK_EQ(scope->ContextLocalCount(), context_local_count); |
| 27 DCHECK_EQ(scope->ContextGlobalCount(), context_global_count); | 31 DCHECK_EQ(scope->ContextGlobalCount(), context_global_count); |
| 32 DCHECK(module_vars_count == 0 || scope->is_module_scope()); |
| 28 | 33 |
| 29 // Determine use and location of the "this" binding if it is present. | 34 // Determine use and location of the "this" binding if it is present. |
| 30 VariableAllocationInfo receiver_info; | 35 VariableAllocationInfo receiver_info; |
| 31 if (scope->is_declaration_scope() && | 36 if (scope->is_declaration_scope() && |
| 32 scope->AsDeclarationScope()->has_this_declaration()) { | 37 scope->AsDeclarationScope()->has_this_declaration()) { |
| 33 Variable* var = scope->AsDeclarationScope()->receiver(); | 38 Variable* var = scope->AsDeclarationScope()->receiver(); |
| 34 if (!var->is_used()) { | 39 if (!var->is_used()) { |
| 35 receiver_info = UNUSED; | 40 receiver_info = UNUSED; |
| 36 } else if (var->IsContextSlot()) { | 41 } else if (var->IsContextSlot()) { |
| 37 receiver_info = CONTEXT; | 42 receiver_info = CONTEXT; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 66 function_name_info = NONE; | 71 function_name_info = NONE; |
| 67 function_variable_mode = VAR; | 72 function_variable_mode = VAR; |
| 68 } | 73 } |
| 69 DCHECK(context_global_count == 0 || scope->scope_type() == SCRIPT_SCOPE); | 74 DCHECK(context_global_count == 0 || scope->scope_type() == SCRIPT_SCOPE); |
| 70 | 75 |
| 71 const bool has_function_name = function_name_info != NONE; | 76 const bool has_function_name = function_name_info != NONE; |
| 72 const bool has_receiver = receiver_info == STACK || receiver_info == CONTEXT; | 77 const bool has_receiver = receiver_info == STACK || receiver_info == CONTEXT; |
| 73 const int parameter_count = scope->num_parameters(); | 78 const int parameter_count = scope->num_parameters(); |
| 74 const int length = kVariablePartIndex + parameter_count + | 79 const int length = kVariablePartIndex + parameter_count + |
| 75 (1 + stack_local_count) + 2 * context_local_count + | 80 (1 + stack_local_count) + 2 * context_local_count + |
| 76 2 * context_global_count + | 81 2 * context_global_count + (has_receiver ? 1 : 0) + |
| 77 (has_receiver ? 1 : 0) + (has_function_name ? 2 : 0); | 82 (has_function_name ? 2 : 0) + |
| 83 (scope->is_module_scope() ? 2 + 3 * module_vars_count : 0); |
| 78 | 84 |
| 79 Factory* factory = isolate->factory(); | 85 Factory* factory = isolate->factory(); |
| 80 Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length); | 86 Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length); |
| 81 | 87 |
| 82 bool has_simple_parameters = false; | 88 bool has_simple_parameters = false; |
| 83 bool asm_module = false; | 89 bool asm_module = false; |
| 84 bool asm_function = false; | 90 bool asm_function = false; |
| 85 FunctionKind function_kind = kNormalFunction; | 91 FunctionKind function_kind = kNormalFunction; |
| 86 if (scope->is_function_scope()) { | 92 if (scope->is_function_scope()) { |
| 87 DeclarationScope* function_scope = scope->AsDeclarationScope(); | 93 DeclarationScope* function_scope = scope->AsDeclarationScope(); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 98 DeclarationScopeField::encode(scope->is_declaration_scope()) | | 104 DeclarationScopeField::encode(scope->is_declaration_scope()) | |
| 99 ReceiverVariableField::encode(receiver_info) | | 105 ReceiverVariableField::encode(receiver_info) | |
| 100 HasNewTargetField::encode(has_new_target) | | 106 HasNewTargetField::encode(has_new_target) | |
| 101 FunctionVariableField::encode(function_name_info) | | 107 FunctionVariableField::encode(function_name_info) | |
| 102 FunctionVariableMode::encode(function_variable_mode) | | 108 FunctionVariableMode::encode(function_variable_mode) | |
| 103 AsmModuleField::encode(asm_module) | | 109 AsmModuleField::encode(asm_module) | |
| 104 AsmFunctionField::encode(asm_function) | | 110 AsmFunctionField::encode(asm_function) | |
| 105 HasSimpleParametersField::encode(has_simple_parameters) | | 111 HasSimpleParametersField::encode(has_simple_parameters) | |
| 106 FunctionKindField::encode(function_kind); | 112 FunctionKindField::encode(function_kind); |
| 107 scope_info->SetFlags(flags); | 113 scope_info->SetFlags(flags); |
| 114 |
| 108 scope_info->SetParameterCount(parameter_count); | 115 scope_info->SetParameterCount(parameter_count); |
| 109 scope_info->SetStackLocalCount(stack_local_count); | 116 scope_info->SetStackLocalCount(stack_local_count); |
| 110 scope_info->SetContextLocalCount(context_local_count); | 117 scope_info->SetContextLocalCount(context_local_count); |
| 111 scope_info->SetContextGlobalCount(context_global_count); | 118 scope_info->SetContextGlobalCount(context_global_count); |
| 112 | 119 |
| 113 int index = kVariablePartIndex; | 120 int index = kVariablePartIndex; |
| 114 // Add parameters. | 121 // Add parameters. |
| 115 DCHECK(index == scope_info->ParameterEntriesIndex()); | 122 DCHECK(index == scope_info->ParameterEntriesIndex()); |
| 116 if (scope->is_declaration_scope()) { | 123 if (scope->is_declaration_scope()) { |
| 117 for (int i = 0; i < parameter_count; ++i) { | 124 for (int i = 0; i < parameter_count; ++i) { |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 191 DCHECK(index == scope_info->FunctionNameEntryIndex()); | 198 DCHECK(index == scope_info->FunctionNameEntryIndex()); |
| 192 if (has_function_name) { | 199 if (has_function_name) { |
| 193 int var_index = scope->AsDeclarationScope()->function_var()->index(); | 200 int var_index = scope->AsDeclarationScope()->function_var()->index(); |
| 194 scope_info->set(index++, | 201 scope_info->set(index++, |
| 195 *scope->AsDeclarationScope()->function_var()->name()); | 202 *scope->AsDeclarationScope()->function_var()->name()); |
| 196 scope_info->set(index++, Smi::FromInt(var_index)); | 203 scope_info->set(index++, Smi::FromInt(var_index)); |
| 197 DCHECK(function_name_info != CONTEXT || | 204 DCHECK(function_name_info != CONTEXT || |
| 198 var_index == scope_info->ContextLength() - 1); | 205 var_index == scope_info->ContextLength() - 1); |
| 199 } | 206 } |
| 200 | 207 |
| 208 // Module-specific information (only for module scopes). |
| 209 // The first slot contains the ModuleInfo. |
| 210 // The next slot contains the number n of MODULE-allocated variables. |
| 211 // The remaining 3*n slots contain the metadata of those variables. |
| 212 DCHECK_EQ(index, scope_info->ModuleInfoEntryIndex()); |
| 213 if (scope->is_module_scope()) { |
| 214 scope_info->set(index++, Smi::FromInt(module_vars_count)); |
| 215 Handle<ModuleInfo> module_info = |
| 216 ModuleInfo::New(isolate, scope->AsModuleScope()->module()); |
| 217 scope_info->set(index++, *module_info); |
| 218 for (int i = 0; i < module_vars_count; ++i) { |
| 219 Variable* var = module_vars[i]; |
| 220 scope_info->set(index++, *var->name()); |
| 221 scope_info->set(index++, Smi::FromInt(var->index())); |
| 222 uint32_t value = VariableModeField::encode(var->mode()) | |
| 223 InitFlagField::encode(var->initialization_flag()) | |
| 224 MaybeAssignedFlagField::encode(var->maybe_assigned()); |
| 225 scope_info->set(index++, Smi::FromInt(value)); |
| 226 } |
| 227 } |
| 228 |
| 201 DCHECK(index == scope_info->length()); | 229 DCHECK(index == scope_info->length()); |
| 202 DCHECK(scope->num_parameters() == scope_info->ParameterCount()); | 230 DCHECK(scope->num_parameters() == scope_info->ParameterCount()); |
| 203 DCHECK(scope->num_heap_slots() == scope_info->ContextLength() || | 231 DCHECK(scope->num_heap_slots() == scope_info->ContextLength() || |
| 204 (scope->num_heap_slots() == kVariablePartIndex && | 232 (scope->num_heap_slots() == kVariablePartIndex && |
| 205 scope_info->ContextLength() == 0)); | 233 scope_info->ContextLength() == 0)); |
| 206 return scope_info; | 234 return scope_info; |
| 207 } | 235 } |
| 208 | 236 |
| 209 | 237 |
| 210 Handle<ScopeInfo> ScopeInfo::CreateGlobalThisBinding(Isolate* isolate) { | 238 Handle<ScopeInfo> ScopeInfo::CreateGlobalThisBinding(Isolate* isolate) { |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 382 bool ScopeInfo::HasContext() { | 410 bool ScopeInfo::HasContext() { |
| 383 return ContextLength() > 0; | 411 return ContextLength() > 0; |
| 384 } | 412 } |
| 385 | 413 |
| 386 | 414 |
| 387 String* ScopeInfo::FunctionName() { | 415 String* ScopeInfo::FunctionName() { |
| 388 DCHECK(HasFunctionName()); | 416 DCHECK(HasFunctionName()); |
| 389 return String::cast(get(FunctionNameEntryIndex())); | 417 return String::cast(get(FunctionNameEntryIndex())); |
| 390 } | 418 } |
| 391 | 419 |
| 420 ModuleInfo* ScopeInfo::ModuleDescriptorInfo() { |
| 421 DCHECK(scope_type() == MODULE_SCOPE); |
| 422 return static_cast<ModuleInfo*>(get(ModuleInfoEntryIndex())); |
| 423 } |
| 392 | 424 |
| 393 String* ScopeInfo::ParameterName(int var) { | 425 String* ScopeInfo::ParameterName(int var) { |
| 394 DCHECK(0 <= var && var < ParameterCount()); | 426 DCHECK(0 <= var && var < ParameterCount()); |
| 395 int info_index = ParameterEntriesIndex() + var; | 427 int info_index = ParameterEntriesIndex() + var; |
| 396 return String::cast(get(info_index)); | 428 return String::cast(get(info_index)); |
| 397 } | 429 } |
| 398 | 430 |
| 399 | 431 |
| 400 String* ScopeInfo::LocalName(int var) { | 432 String* ScopeInfo::LocalName(int var) { |
| 401 DCHECK(0 <= var && var < LocalCount()); | 433 DCHECK(0 <= var && var < LocalCount()); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 468 int end = start + StackLocalCount(); | 500 int end = start + StackLocalCount(); |
| 469 for (int i = start; i < end; ++i) { | 501 for (int i = start; i < end; ++i) { |
| 470 if (name == get(i)) { | 502 if (name == get(i)) { |
| 471 return i - start + first_slot_index; | 503 return i - start + first_slot_index; |
| 472 } | 504 } |
| 473 } | 505 } |
| 474 } | 506 } |
| 475 return -1; | 507 return -1; |
| 476 } | 508 } |
| 477 | 509 |
| 510 int ScopeInfo::ModuleIndex(Handle<ScopeInfo> scope_info, Handle<String> name, |
| 511 VariableMode* mode, InitializationFlag* init_flag, |
| 512 MaybeAssignedFlag* maybe_assigned_flag) { |
| 513 DCHECK_EQ(scope_info->scope_type(), MODULE_SCOPE); |
| 514 DCHECK(name->IsInternalizedString()); |
| 515 DCHECK_NOT_NULL(mode); |
| 516 DCHECK_NOT_NULL(init_flag); |
| 517 DCHECK_NOT_NULL(maybe_assigned_flag); |
| 518 |
| 519 int base = scope_info->ModuleInfoEntryIndex(); |
| 520 int module_vars_count = Smi::cast(scope_info->get(base + 1))->value(); |
| 521 int start = base + 2; |
| 522 int end = start + 3 * module_vars_count; |
| 523 for (int i = start; i < end; i += 3) { |
| 524 if (*name == scope_info->get(i)) { |
| 525 int index = Smi::cast(scope_info->get(i + 1))->value(); |
| 526 int properties = Smi::cast(scope_info->get(i + 2))->value(); |
| 527 *mode = VariableModeField::decode(properties); |
| 528 *init_flag = InitFlagField::decode(properties); |
| 529 *maybe_assigned_flag = MaybeAssignedFlagField::decode(properties); |
| 530 return index; |
| 531 } |
| 532 } |
| 533 |
| 534 return -1; |
| 535 } |
| 478 | 536 |
| 479 int ScopeInfo::ContextSlotIndex(Handle<ScopeInfo> scope_info, | 537 int ScopeInfo::ContextSlotIndex(Handle<ScopeInfo> scope_info, |
| 480 Handle<String> name, VariableMode* mode, | 538 Handle<String> name, VariableMode* mode, |
| 481 InitializationFlag* init_flag, | 539 InitializationFlag* init_flag, |
| 482 MaybeAssignedFlag* maybe_assigned_flag) { | 540 MaybeAssignedFlag* maybe_assigned_flag) { |
| 483 DCHECK(name->IsInternalizedString()); | 541 DCHECK(name->IsInternalizedString()); |
| 484 DCHECK_NOT_NULL(mode); | 542 DCHECK_NOT_NULL(mode); |
| 485 DCHECK_NOT_NULL(init_flag); | 543 DCHECK_NOT_NULL(init_flag); |
| 486 DCHECK_NOT_NULL(maybe_assigned_flag); | 544 DCHECK_NOT_NULL(maybe_assigned_flag); |
| 487 | 545 |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 643 | 701 |
| 644 int ScopeInfo::ReceiverEntryIndex() { | 702 int ScopeInfo::ReceiverEntryIndex() { |
| 645 return ContextGlobalInfoEntriesIndex() + ContextGlobalCount(); | 703 return ContextGlobalInfoEntriesIndex() + ContextGlobalCount(); |
| 646 } | 704 } |
| 647 | 705 |
| 648 | 706 |
| 649 int ScopeInfo::FunctionNameEntryIndex() { | 707 int ScopeInfo::FunctionNameEntryIndex() { |
| 650 return ReceiverEntryIndex() + (HasAllocatedReceiver() ? 1 : 0); | 708 return ReceiverEntryIndex() + (HasAllocatedReceiver() ? 1 : 0); |
| 651 } | 709 } |
| 652 | 710 |
| 711 int ScopeInfo::ModuleInfoEntryIndex() { |
| 712 return FunctionNameEntryIndex() + (HasFunctionName() ? 2 : 0); |
| 713 } |
| 714 |
| 653 #ifdef DEBUG | 715 #ifdef DEBUG |
| 654 | 716 |
| 655 static void PrintList(const char* list_name, | 717 static void PrintList(const char* list_name, |
| 656 int nof_internal_slots, | 718 int nof_internal_slots, |
| 657 int start, | 719 int start, |
| 658 int end, | 720 int end, |
| 659 ScopeInfo* scope_info) { | 721 ScopeInfo* scope_info) { |
| 660 if (start < end) { | 722 if (start < end) { |
| 661 PrintF("\n // %s\n", list_name); | 723 PrintF("\n // %s\n", list_name); |
| 662 if (nof_internal_slots > 0) { | 724 if (nof_internal_slots > 0) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 687 StackLocalEntriesIndex() + StackLocalCount(), this); | 749 StackLocalEntriesIndex() + StackLocalCount(), this); |
| 688 PrintList("context slots", Context::MIN_CONTEXT_SLOTS, | 750 PrintList("context slots", Context::MIN_CONTEXT_SLOTS, |
| 689 ContextLocalNameEntriesIndex(), | 751 ContextLocalNameEntriesIndex(), |
| 690 ContextLocalNameEntriesIndex() + ContextLocalCount(), this); | 752 ContextLocalNameEntriesIndex() + ContextLocalCount(), this); |
| 691 } | 753 } |
| 692 | 754 |
| 693 PrintF("}\n"); | 755 PrintF("}\n"); |
| 694 } | 756 } |
| 695 #endif // DEBUG | 757 #endif // DEBUG |
| 696 | 758 |
| 759 Handle<ModuleInfo> ModuleInfo::New(Isolate* isolate, ModuleDescriptor* descr) { |
| 760 // Serialize special exports. |
| 761 Handle<FixedArray> special_exports = |
| 762 isolate->factory()->NewFixedArray(descr->special_exports().length()); |
| 763 { |
| 764 int i = 0; |
| 765 for (auto entry : descr->special_exports()) { |
| 766 special_exports->set(i++, *entry->Serialize(isolate)); |
| 767 } |
| 768 } |
| 769 |
| 770 // Serialize regular exports. |
| 771 Handle<FixedArray> regular_exports = isolate->factory()->NewFixedArray( |
| 772 static_cast<int>(descr->regular_exports().size())); |
| 773 { |
| 774 int i = 0; |
| 775 for (const auto& it : descr->regular_exports()) { |
| 776 regular_exports->set(i++, *it.second->Serialize(isolate)); |
| 777 } |
| 778 } |
| 779 |
| 780 Handle<FixedArray> result = isolate->factory()->NewFixedArray(2); |
| 781 result->set(0, *special_exports); |
| 782 result->set(1, *regular_exports); |
| 783 return Handle<ModuleInfo>::cast(result); |
| 784 } |
| 697 | 785 |
| 698 } // namespace internal | 786 } // namespace internal |
| 699 } // namespace v8 | 787 } // namespace v8 |
| OLD | NEW |