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 |