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