Index: src/ast/scopeinfo.cc |
diff --git a/src/ast/scopeinfo.cc b/src/ast/scopeinfo.cc |
index 9df15598723943eee7f9c0cae9bc84e1cb8fc984..cf49fe492c40c956bb419f975fa4c55f24c92a69 100644 |
--- a/src/ast/scopeinfo.cc |
+++ b/src/ast/scopeinfo.cc |
@@ -2,6 +2,8 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
+#include "src/ast/scopeinfo.h" |
+ |
#include <stdlib.h> |
#include "src/ast/context-slot-cache.h" |
@@ -18,13 +20,16 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, |
ZoneList<Variable*> stack_locals(scope->StackLocalCount(), zone); |
ZoneList<Variable*> context_locals(scope->ContextLocalCount(), zone); |
ZoneList<Variable*> context_globals(scope->ContextGlobalCount(), zone); |
- scope->CollectVariables(&stack_locals, &context_locals, &context_globals); |
+ ZoneList<Variable*> module_vars(0, zone); |
+ scope->CollectVariables(&stack_locals, &context_locals, &context_globals, |
+ &module_vars); |
const int stack_local_count = stack_locals.length(); |
const int context_local_count = context_locals.length(); |
const int context_global_count = context_globals.length(); |
- // Make sure we allocate the correct amount. |
+ const int module_vars_count = module_vars.length(); |
DCHECK_EQ(scope->ContextLocalCount(), context_local_count); |
DCHECK_EQ(scope->ContextGlobalCount(), context_global_count); |
+ DCHECK(module_vars_count == 0 || scope->is_module_scope()); |
// Determine use and location of the "this" binding if it is present. |
VariableAllocationInfo receiver_info; |
@@ -73,8 +78,9 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, |
const int parameter_count = scope->num_parameters(); |
const int length = kVariablePartIndex + parameter_count + |
(1 + stack_local_count) + 2 * context_local_count + |
- 2 * context_global_count + |
- (has_receiver ? 1 : 0) + (has_function_name ? 2 : 0); |
+ 2 * context_global_count + (has_receiver ? 1 : 0) + |
+ (has_function_name ? 2 : 0) + |
+ (scope->is_module_scope() ? 2 + 3 * module_vars_count : 0); |
Factory* factory = isolate->factory(); |
Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length); |
@@ -105,6 +111,7 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, |
HasSimpleParametersField::encode(has_simple_parameters) | |
FunctionKindField::encode(function_kind); |
scope_info->SetFlags(flags); |
+ |
scope_info->SetParameterCount(parameter_count); |
scope_info->SetStackLocalCount(stack_local_count); |
scope_info->SetContextLocalCount(context_local_count); |
@@ -198,6 +205,27 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, |
var_index == scope_info->ContextLength() - 1); |
} |
+ // Module-specific information (only for module scopes). |
+ // The first slot contains the ModuleInfo. |
+ // The next slot contains the number n of MODULE-allocated variables. |
+ // The remaining 3*n slots contain the metadata of those variables. |
+ DCHECK_EQ(index, scope_info->ModuleInfoEntryIndex()); |
+ if (scope->is_module_scope()) { |
+ scope_info->set(index++, Smi::FromInt(module_vars_count)); |
+ Handle<ModuleInfo> module_info = |
+ ModuleInfo::New(isolate, scope->AsModuleScope()->module()); |
+ scope_info->set(index++, *module_info); |
+ for (int i = 0; i < module_vars_count; ++i) { |
+ Variable* var = module_vars[i]; |
+ scope_info->set(index++, *var->name()); |
+ scope_info->set(index++, Smi::FromInt(var->index())); |
+ uint32_t value = VariableModeField::encode(var->mode()) | |
+ InitFlagField::encode(var->initialization_flag()) | |
+ MaybeAssignedFlagField::encode(var->maybe_assigned()); |
+ scope_info->set(index++, Smi::FromInt(value)); |
+ } |
+ } |
+ |
DCHECK(index == scope_info->length()); |
DCHECK(scope->num_parameters() == scope_info->ParameterCount()); |
DCHECK(scope->num_heap_slots() == scope_info->ContextLength() || |
@@ -389,6 +417,10 @@ String* ScopeInfo::FunctionName() { |
return String::cast(get(FunctionNameEntryIndex())); |
} |
+ModuleInfo* ScopeInfo::ModuleDescriptorInfo() { |
+ DCHECK(scope_type() == MODULE_SCOPE); |
+ return static_cast<ModuleInfo*>(get(ModuleInfoEntryIndex())); |
+} |
String* ScopeInfo::ParameterName(int var) { |
DCHECK(0 <= var && var < ParameterCount()); |
@@ -475,6 +507,32 @@ int ScopeInfo::StackSlotIndex(String* name) { |
return -1; |
} |
+int ScopeInfo::ModuleIndex(Handle<ScopeInfo> scope_info, Handle<String> name, |
+ VariableMode* mode, InitializationFlag* init_flag, |
+ MaybeAssignedFlag* maybe_assigned_flag) { |
+ DCHECK_EQ(scope_info->scope_type(), MODULE_SCOPE); |
+ DCHECK(name->IsInternalizedString()); |
+ DCHECK_NOT_NULL(mode); |
+ DCHECK_NOT_NULL(init_flag); |
+ DCHECK_NOT_NULL(maybe_assigned_flag); |
+ |
+ int base = scope_info->ModuleInfoEntryIndex(); |
+ int module_vars_count = Smi::cast(scope_info->get(base + 1))->value(); |
+ int start = base + 2; |
+ int end = start + 3 * module_vars_count; |
+ for (int i = start; i < end; i += 3) { |
+ if (*name == scope_info->get(i)) { |
+ int index = Smi::cast(scope_info->get(i + 1))->value(); |
+ int properties = Smi::cast(scope_info->get(i + 2))->value(); |
+ *mode = VariableModeField::decode(properties); |
+ *init_flag = InitFlagField::decode(properties); |
+ *maybe_assigned_flag = MaybeAssignedFlagField::decode(properties); |
+ return index; |
+ } |
+ } |
+ |
+ return -1; |
+} |
int ScopeInfo::ContextSlotIndex(Handle<ScopeInfo> scope_info, |
Handle<String> name, VariableMode* mode, |
@@ -650,6 +708,10 @@ int ScopeInfo::FunctionNameEntryIndex() { |
return ReceiverEntryIndex() + (HasAllocatedReceiver() ? 1 : 0); |
} |
+int ScopeInfo::ModuleInfoEntryIndex() { |
+ return FunctionNameEntryIndex() + (HasFunctionName() ? 2 : 0); |
+} |
+ |
#ifdef DEBUG |
static void PrintList(const char* list_name, |
@@ -694,6 +756,32 @@ void ScopeInfo::Print() { |
} |
#endif // DEBUG |
+Handle<ModuleInfo> ModuleInfo::New(Isolate* isolate, ModuleDescriptor* descr) { |
+ // Serialize special exports. |
+ Handle<FixedArray> special_exports = |
+ isolate->factory()->NewFixedArray(descr->special_exports().length()); |
+ { |
+ int i = 0; |
+ for (auto entry : descr->special_exports()) { |
+ special_exports->set(i++, *entry->Serialize(isolate)); |
+ } |
+ } |
+ |
+ // Serialize regular exports. |
+ Handle<FixedArray> regular_exports = isolate->factory()->NewFixedArray( |
+ static_cast<int>(descr->regular_exports().size())); |
+ { |
+ int i = 0; |
+ for (const auto& it : descr->regular_exports()) { |
+ regular_exports->set(i++, *it.second->Serialize(isolate)); |
+ } |
+ } |
+ |
+ Handle<FixedArray> result = isolate->factory()->NewFixedArray(2); |
+ result->set(0, *special_exports); |
+ result->set(1, *regular_exports); |
+ return Handle<ModuleInfo>::cast(result); |
+} |
} // namespace internal |
} // namespace v8 |