[modules] Partial scope info support of modules
This introduces a new heap object ModuleInfo, which is to ModuleDescriptor what ScopeInfo is to Scope. When deserializing a scope info that contains a module info, we deserialize the module info into a module descriptor and put it into the synthesized module scope. Currently, module infos only store exports. R=adamk@chromium.org BUG=v8:1569 Review-Url: https://codereview.chromium.org/2277253003 Cr-Commit-Position: refs/heads/master@{#39049}
This commit is contained in:
parent
60a783c246
commit
840d1e84f7
@ -11,6 +11,13 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
// An entry in ModuleVariableEntries consists of several slots:
|
||||
enum ModuleVariableEntryOffset {
|
||||
kModuleVariableNameOffset,
|
||||
kModuleVariableIndexOffset,
|
||||
kModuleVariablePropertiesOffset,
|
||||
kModuleVariableEntryLength // Sentinel value.
|
||||
};
|
||||
|
||||
Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone,
|
||||
Scope* scope) {
|
||||
@ -18,6 +25,7 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone,
|
||||
ZoneList<Variable*>* locals = scope->locals();
|
||||
int stack_local_count = 0;
|
||||
int context_local_count = 0;
|
||||
int module_vars_count = 0;
|
||||
// Stack allocated block scope variables are allocated in the parent
|
||||
// declaration scope, but are recorded in the block scope's scope info. First
|
||||
// slot index indicates at which offset a particular scope starts in the
|
||||
@ -25,13 +33,22 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone,
|
||||
int first_slot_index = 0;
|
||||
for (int i = 0; i < locals->length(); i++) {
|
||||
Variable* var = locals->at(i);
|
||||
if (var->IsStackLocal()) {
|
||||
if (stack_local_count == 0) first_slot_index = var->index();
|
||||
stack_local_count++;
|
||||
} else if (var->IsContextSlot()) {
|
||||
context_local_count++;
|
||||
switch (var->location()) {
|
||||
case VariableLocation::LOCAL:
|
||||
if (stack_local_count == 0) first_slot_index = var->index();
|
||||
stack_local_count++;
|
||||
break;
|
||||
case VariableLocation::CONTEXT:
|
||||
context_local_count++;
|
||||
break;
|
||||
case VariableLocation::MODULE:
|
||||
module_vars_count++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
DCHECK(module_vars_count == 0 || scope->is_module_scope());
|
||||
|
||||
// Make sure we allocate the correct amount.
|
||||
DCHECK_EQ(scope->ContextLocalCount(), context_local_count);
|
||||
@ -82,7 +99,10 @@ 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 +
|
||||
(has_receiver ? 1 : 0) + (has_function_name ? 2 : 0);
|
||||
(has_receiver ? 1 : 0) + (has_function_name ? 2 : 0) +
|
||||
(scope->is_module_scope()
|
||||
? 2 + kModuleVariableEntryLength * module_vars_count
|
||||
: 0);
|
||||
|
||||
Factory* factory = isolate->factory();
|
||||
Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length);
|
||||
@ -113,6 +133,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);
|
||||
@ -127,10 +148,10 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone,
|
||||
}
|
||||
}
|
||||
|
||||
// Add stack locals' names, context locals' names and info. We are assuming
|
||||
// that the stack locals' slots are allocated in increasing order, so we can
|
||||
// simply add them to the ScopeInfo object. Context locals are added using
|
||||
// their index.
|
||||
// Add stack locals' names, context locals' names and info, module variables'
|
||||
// names and info. We are assuming that the stack locals' slots are allocated
|
||||
// in increasing order, so we can simply add them to the ScopeInfo object.
|
||||
// Context locals are added using their index.
|
||||
DCHECK_EQ(index, scope_info->StackLocalFirstSlotIndex());
|
||||
scope_info->set(index++, Smi::FromInt(first_slot_index));
|
||||
DCHECK_EQ(index, scope_info->StackLocalEntriesIndex());
|
||||
@ -138,26 +159,48 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone,
|
||||
int stack_local_base = index;
|
||||
int context_local_base = stack_local_base + stack_local_count;
|
||||
int context_local_info_base = context_local_base + context_local_count;
|
||||
int module_var_entry = scope_info->ModuleVariableEntriesIndex();
|
||||
|
||||
for (int i = 0; i < locals->length(); ++i) {
|
||||
Variable* var = locals->at(i);
|
||||
if (var->IsStackLocal()) {
|
||||
int local_index = var->index() - first_slot_index;
|
||||
DCHECK_LE(0, local_index);
|
||||
DCHECK_LT(local_index, stack_local_count);
|
||||
scope_info->set(stack_local_base + local_index, *var->name());
|
||||
} else if (var->IsContextSlot()) {
|
||||
// Due to duplicate parameters, context locals aren't guaranteed to come
|
||||
// in order.
|
||||
int local_index = var->index() - Context::MIN_CONTEXT_SLOTS;
|
||||
DCHECK_LE(0, local_index);
|
||||
DCHECK_LT(local_index, context_local_count);
|
||||
uint32_t info = VariableModeField::encode(var->mode()) |
|
||||
InitFlagField::encode(var->initialization_flag()) |
|
||||
MaybeAssignedFlagField::encode(var->maybe_assigned());
|
||||
scope_info->set(context_local_base + local_index, *var->name());
|
||||
scope_info->set(context_local_info_base + local_index,
|
||||
Smi::FromInt(info));
|
||||
switch (var->location()) {
|
||||
case VariableLocation::LOCAL: {
|
||||
int local_index = var->index() - first_slot_index;
|
||||
DCHECK_LE(0, local_index);
|
||||
DCHECK_LT(local_index, stack_local_count);
|
||||
scope_info->set(stack_local_base + local_index, *var->name());
|
||||
break;
|
||||
}
|
||||
case VariableLocation::CONTEXT: {
|
||||
// Due to duplicate parameters, context locals aren't guaranteed to come
|
||||
// in order.
|
||||
int local_index = var->index() - Context::MIN_CONTEXT_SLOTS;
|
||||
DCHECK_LE(0, local_index);
|
||||
DCHECK_LT(local_index, context_local_count);
|
||||
uint32_t info = VariableModeField::encode(var->mode()) |
|
||||
InitFlagField::encode(var->initialization_flag()) |
|
||||
MaybeAssignedFlagField::encode(var->maybe_assigned());
|
||||
scope_info->set(context_local_base + local_index, *var->name());
|
||||
scope_info->set(context_local_info_base + local_index,
|
||||
Smi::FromInt(info));
|
||||
break;
|
||||
}
|
||||
case VariableLocation::MODULE: {
|
||||
scope_info->set(module_var_entry + kModuleVariableNameOffset,
|
||||
*var->name());
|
||||
scope_info->set(module_var_entry + kModuleVariableIndexOffset,
|
||||
Smi::FromInt(var->index()));
|
||||
uint32_t properties =
|
||||
VariableModeField::encode(var->mode()) |
|
||||
InitFlagField::encode(var->initialization_flag()) |
|
||||
MaybeAssignedFlagField::encode(var->maybe_assigned());
|
||||
scope_info->set(module_var_entry + kModuleVariablePropertiesOffset,
|
||||
Smi::FromInt(properties));
|
||||
module_var_entry += kModuleVariableEntryLength;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -183,6 +226,19 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone,
|
||||
var_index == scope_info->ContextLength() - 1);
|
||||
}
|
||||
|
||||
// Module-specific information (only for module scopes).
|
||||
if (scope->is_module_scope()) {
|
||||
Handle<ModuleInfo> module_info =
|
||||
ModuleInfo::New(isolate, scope->AsModuleScope()->module());
|
||||
DCHECK_EQ(index, scope_info->ModuleInfoEntryIndex());
|
||||
scope_info->set(index++, *module_info);
|
||||
DCHECK_EQ(index, scope_info->ModuleVariableCountIndex());
|
||||
scope_info->set(index++, Smi::FromInt(module_vars_count));
|
||||
DCHECK_EQ(index, scope_info->ModuleVariableEntriesIndex());
|
||||
// The variable entries themselves have already been written above.
|
||||
index += kModuleVariableEntryLength * module_vars_count;
|
||||
}
|
||||
|
||||
DCHECK_EQ(index, scope_info->length());
|
||||
DCHECK_EQ(scope->num_parameters(), scope_info->ParameterCount());
|
||||
DCHECK_EQ(scope->num_heap_slots(), scope_info->ContextLength());
|
||||
@ -367,6 +423,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_LE(0, var);
|
||||
@ -461,6 +521,32 @@ int ScopeInfo::StackSlotIndex(String* name) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ScopeInfo::ModuleIndex(Handle<String> name, VariableMode* mode,
|
||||
InitializationFlag* init_flag,
|
||||
MaybeAssignedFlag* maybe_assigned_flag) {
|
||||
DCHECK_EQ(scope_type(), MODULE_SCOPE);
|
||||
DCHECK(name->IsInternalizedString());
|
||||
DCHECK_NOT_NULL(mode);
|
||||
DCHECK_NOT_NULL(init_flag);
|
||||
DCHECK_NOT_NULL(maybe_assigned_flag);
|
||||
|
||||
int module_vars_count = Smi::cast(get(ModuleVariableCountIndex()))->value();
|
||||
int entry = ModuleVariableEntriesIndex();
|
||||
for (int i = 0; i < module_vars_count; ++i) {
|
||||
if (*name == get(entry + kModuleVariableNameOffset)) {
|
||||
int index = Smi::cast(get(entry + kModuleVariableIndexOffset))->value();
|
||||
int properties =
|
||||
Smi::cast(get(entry + kModuleVariablePropertiesOffset))->value();
|
||||
*mode = VariableModeField::decode(properties);
|
||||
*init_flag = InitFlagField::decode(properties);
|
||||
*maybe_assigned_flag = MaybeAssignedFlagField::decode(properties);
|
||||
return index;
|
||||
}
|
||||
entry += kModuleVariableEntryLength;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ScopeInfo::ContextSlotIndex(Handle<ScopeInfo> scope_info,
|
||||
Handle<String> name, VariableMode* mode,
|
||||
@ -579,21 +665,28 @@ int ScopeInfo::ContextLocalNameEntriesIndex() {
|
||||
return StackLocalEntriesIndex() + StackLocalCount();
|
||||
}
|
||||
|
||||
|
||||
int ScopeInfo::ContextLocalInfoEntriesIndex() {
|
||||
return ContextLocalNameEntriesIndex() + ContextLocalCount();
|
||||
}
|
||||
|
||||
|
||||
int ScopeInfo::ReceiverEntryIndex() {
|
||||
return ContextLocalInfoEntriesIndex() + ContextLocalCount();
|
||||
}
|
||||
|
||||
|
||||
int ScopeInfo::FunctionNameEntryIndex() {
|
||||
return ReceiverEntryIndex() + (HasAllocatedReceiver() ? 1 : 0);
|
||||
}
|
||||
|
||||
int ScopeInfo::ModuleInfoEntryIndex() {
|
||||
return FunctionNameEntryIndex() + (HasFunctionName() ? 2 : 0);
|
||||
}
|
||||
|
||||
int ScopeInfo::ModuleVariableCountIndex() { return ModuleInfoEntryIndex() + 1; }
|
||||
|
||||
int ScopeInfo::ModuleVariableEntriesIndex() {
|
||||
return ModuleVariableCountIndex() + 1;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
static void PrintList(const char* list_name,
|
||||
@ -638,6 +731,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<ModuleInfo> result = isolate->factory()->NewModuleInfo();
|
||||
result->set(kSpecialExportsIndex, *special_exports);
|
||||
result->set(kRegularExportsIndex, *regular_exports);
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
@ -164,6 +164,36 @@ ModuleScope::ModuleScope(DeclarationScope* script_scope,
|
||||
DeclareThis(ast_value_factory);
|
||||
}
|
||||
|
||||
ModuleScope::ModuleScope(Isolate* isolate, Handle<ScopeInfo> scope_info,
|
||||
AstValueFactory* avfactory)
|
||||
: DeclarationScope(avfactory->zone(), MODULE_SCOPE, scope_info) {
|
||||
Zone* zone = avfactory->zone();
|
||||
ModuleInfo* module_info = scope_info->ModuleDescriptorInfo();
|
||||
|
||||
set_language_mode(STRICT);
|
||||
module_descriptor_ = new (zone) ModuleDescriptor(zone);
|
||||
|
||||
// Deserialize special exports.
|
||||
Handle<FixedArray> special_exports = handle(module_info->special_exports());
|
||||
for (int i = 0, n = special_exports->length(); i < n; ++i) {
|
||||
Handle<FixedArray> serialized_entry(
|
||||
FixedArray::cast(special_exports->get(i)), isolate);
|
||||
module_descriptor_->AddSpecialExport(
|
||||
ModuleDescriptor::Entry::Deserialize(isolate, avfactory,
|
||||
serialized_entry),
|
||||
avfactory->zone());
|
||||
}
|
||||
|
||||
// Deserialize regular exports.
|
||||
Handle<FixedArray> regular_exports = handle(module_info->regular_exports());
|
||||
for (int i = 0, n = regular_exports->length(); i < n; ++i) {
|
||||
Handle<FixedArray> serialized_entry(
|
||||
FixedArray::cast(regular_exports->get(i)), isolate);
|
||||
module_descriptor_->AddRegularExport(ModuleDescriptor::Entry::Deserialize(
|
||||
isolate, avfactory, serialized_entry));
|
||||
}
|
||||
}
|
||||
|
||||
Scope::Scope(Zone* zone, ScopeType scope_type, Handle<ScopeInfo> scope_info)
|
||||
: zone_(zone),
|
||||
outer_scope_(nullptr),
|
||||
@ -328,6 +358,11 @@ Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone,
|
||||
} else {
|
||||
outer_scope = new (zone) Scope(zone, BLOCK_SCOPE, scope_info);
|
||||
}
|
||||
} else if (context->IsModuleContext()) {
|
||||
ScopeInfo* scope_info = context->closure()->shared()->scope_info();
|
||||
DCHECK_EQ(scope_info->scope_type(), MODULE_SCOPE);
|
||||
outer_scope = new (zone) ModuleScope(
|
||||
isolate, Handle<ScopeInfo>(scope_info), ast_value_factory);
|
||||
} else {
|
||||
DCHECK(context->IsCatchContext());
|
||||
String* name = context->catch_name();
|
||||
@ -428,6 +463,12 @@ void DeclarationScope::Analyze(ParseInfo* info, AnalyzeMode mode) {
|
||||
scope->outer_scope()->scope_type() == SCRIPT_SCOPE ||
|
||||
scope->outer_scope()->already_resolved_);
|
||||
|
||||
// For modules, we want to start variable allocation at the surrounding script
|
||||
// scope.
|
||||
if (scope->is_module_scope()) {
|
||||
scope = scope->outer_scope()->AsDeclarationScope();
|
||||
}
|
||||
|
||||
scope->AllocateVariables(info, mode);
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -617,7 +658,8 @@ Variable* Scope::LookupInScopeInfo(const AstRawString* name) {
|
||||
&init_flag, &maybe_assigned_flag);
|
||||
if (index < 0 && scope_type() == MODULE_SCOPE) {
|
||||
location = VariableLocation::MODULE;
|
||||
index = -1; // TODO(neis): Find module variables in scope info.
|
||||
index = scope_info_->ModuleIndex(name_handle, &mode, &init_flag,
|
||||
&maybe_assigned_flag);
|
||||
}
|
||||
if (index < 0) return nullptr; // Nowhere found.
|
||||
|
||||
|
@ -839,6 +839,8 @@ class ModuleScope final : public DeclarationScope {
|
||||
public:
|
||||
ModuleScope(DeclarationScope* script_scope,
|
||||
AstValueFactory* ast_value_factory);
|
||||
ModuleScope(Isolate* isolate, Handle<ScopeInfo> scope_info,
|
||||
AstValueFactory* ast_value_factory);
|
||||
|
||||
ModuleDescriptor* module() const {
|
||||
DCHECK_NOT_NULL(module_descriptor_);
|
||||
|
@ -49,7 +49,8 @@ class Variable final : public ZoneObject {
|
||||
return ForceContextAllocationField::decode(bit_field_);
|
||||
}
|
||||
void ForceContextAllocation() {
|
||||
DCHECK(IsUnallocated() || IsContextSlot());
|
||||
DCHECK(IsUnallocated() || IsContextSlot() ||
|
||||
location() == VariableLocation::MODULE);
|
||||
bit_field_ = ForceContextAllocationField::update(bit_field_, true);
|
||||
}
|
||||
bool is_used() { return IsUsedField::decode(bit_field_); }
|
||||
|
@ -1393,6 +1393,12 @@ Handle<ScopeInfo> Factory::NewScopeInfo(int length) {
|
||||
return scope_info;
|
||||
}
|
||||
|
||||
Handle<ModuleInfo> Factory::NewModuleInfo() {
|
||||
Handle<FixedArray> array = NewFixedArray(ModuleInfo::kLength, TENURED);
|
||||
array->set_map_no_write_barrier(*module_info_map());
|
||||
Handle<ModuleInfo> module_info = Handle<ModuleInfo>::cast(array);
|
||||
return module_info;
|
||||
}
|
||||
|
||||
Handle<JSObject> Factory::NewExternal(void* value) {
|
||||
Handle<Foreign> foreign = NewForeign(static_cast<Address>(value));
|
||||
|
@ -557,6 +557,8 @@ class Factory final {
|
||||
// Create a serialized scope info.
|
||||
Handle<ScopeInfo> NewScopeInfo(int length);
|
||||
|
||||
Handle<ModuleInfo> NewModuleInfo();
|
||||
|
||||
// Create an External object for V8's external API.
|
||||
Handle<JSObject> NewExternal(void* value);
|
||||
|
||||
|
@ -2283,6 +2283,7 @@ bool Heap::CreateInitialMaps() {
|
||||
DCHECK_NE(fixed_array_map(), fixed_cow_array_map());
|
||||
|
||||
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, scope_info)
|
||||
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, module_info)
|
||||
ALLOCATE_PRIMITIVE_MAP(HEAP_NUMBER_TYPE, HeapNumber::kSize, heap_number,
|
||||
Context::NUMBER_FUNCTION_INDEX)
|
||||
ALLOCATE_MAP(MUTABLE_HEAP_NUMBER_TYPE, HeapNumber::kSize,
|
||||
|
@ -49,6 +49,7 @@ using v8::MemoryPressureLevel;
|
||||
V(Map, one_byte_string_map, OneByteStringMap) \
|
||||
V(Map, one_byte_internalized_string_map, OneByteInternalizedStringMap) \
|
||||
V(Map, scope_info_map, ScopeInfoMap) \
|
||||
V(Map, module_info_map, ModuleInfoMap) \
|
||||
V(Map, shared_function_info_map, SharedFunctionInfoMap) \
|
||||
V(Map, code_map, CodeMap) \
|
||||
V(Map, function_context_map, FunctionContextMap) \
|
||||
@ -275,6 +276,7 @@ using v8::MemoryPressureLevel;
|
||||
V(FixedArrayMap) \
|
||||
V(CodeMap) \
|
||||
V(ScopeInfoMap) \
|
||||
V(ModuleInfoMap) \
|
||||
V(FixedCOWArrayMap) \
|
||||
V(FixedDoubleArrayMap) \
|
||||
V(WeakCellMap) \
|
||||
|
@ -792,6 +792,9 @@ bool HeapObject::IsScopeInfo() const {
|
||||
return map() == GetHeap()->scope_info_map();
|
||||
}
|
||||
|
||||
bool HeapObject::IsModuleInfo() const {
|
||||
return map() == GetHeap()->module_info_map();
|
||||
}
|
||||
|
||||
TYPE_CHECKER(JSBoundFunction, JS_BOUND_FUNCTION_TYPE)
|
||||
TYPE_CHECKER(JSFunction, JS_FUNCTION_TYPE)
|
||||
@ -3281,6 +3284,7 @@ CAST_ACCESSOR(JSWeakMap)
|
||||
CAST_ACCESSOR(JSWeakSet)
|
||||
CAST_ACCESSOR(LayoutDescriptor)
|
||||
CAST_ACCESSOR(Map)
|
||||
CAST_ACCESSOR(ModuleInfo)
|
||||
CAST_ACCESSOR(Name)
|
||||
CAST_ACCESSOR(NameDictionary)
|
||||
CAST_ACCESSOR(NormalizedMapCache)
|
||||
@ -7916,6 +7920,13 @@ bool ScopeInfo::HasSimpleParameters() {
|
||||
FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(SCOPE_INFO_FIELD_ACCESSORS)
|
||||
#undef SCOPE_INFO_FIELD_ACCESSORS
|
||||
|
||||
FixedArray* ModuleInfo::special_exports() const {
|
||||
return FixedArray::cast(get(kSpecialExportsIndex));
|
||||
}
|
||||
|
||||
FixedArray* ModuleInfo::regular_exports() const {
|
||||
return FixedArray::cast(get(kRegularExportsIndex));
|
||||
}
|
||||
|
||||
void Map::ClearCodeCache(Heap* heap) {
|
||||
// No write barrier is needed since empty_fixed_array is not in new space.
|
||||
|
@ -94,6 +94,7 @@
|
||||
// - TemplateList
|
||||
// - TransitionArray
|
||||
// - ScopeInfo
|
||||
// - ModuleInfo
|
||||
// - ScriptContextTable
|
||||
// - WeakFixedArray
|
||||
// - FixedDoubleArray
|
||||
@ -879,6 +880,8 @@ class LayoutDescriptor;
|
||||
class LiteralsArray;
|
||||
class LookupIterator;
|
||||
class FieldType;
|
||||
class ModuleDescriptor;
|
||||
class ModuleInfo;
|
||||
class ObjectHashTable;
|
||||
class ObjectVisitor;
|
||||
class PropertyCell;
|
||||
@ -979,6 +982,7 @@ template <class C> inline bool Is(Object* obj);
|
||||
V(ScriptContextTable) \
|
||||
V(NativeContext) \
|
||||
V(ScopeInfo) \
|
||||
V(ModuleInfo) \
|
||||
V(JSBoundFunction) \
|
||||
V(JSFunction) \
|
||||
V(Code) \
|
||||
@ -4317,6 +4321,8 @@ class ScopeInfo : public FixedArray {
|
||||
// Return the function_name if present.
|
||||
String* FunctionName();
|
||||
|
||||
ModuleInfo* ModuleDescriptorInfo();
|
||||
|
||||
// Return the name of the given parameter.
|
||||
String* ParameterName(int var);
|
||||
|
||||
@ -4360,6 +4366,12 @@ class ScopeInfo : public FixedArray {
|
||||
VariableMode* mode, InitializationFlag* init_flag,
|
||||
MaybeAssignedFlag* maybe_assigned_flag);
|
||||
|
||||
// Lookup metadata of a MODULE-allocated variable. Return a negative value if
|
||||
// there is no module variable with the given name.
|
||||
int ModuleIndex(Handle<String> name, VariableMode* mode,
|
||||
InitializationFlag* init_flag,
|
||||
MaybeAssignedFlag* maybe_assigned_flag);
|
||||
|
||||
// Lookup the name of a certain context slot by its index.
|
||||
String* ContextSlotName(int slot_index);
|
||||
|
||||
@ -4394,11 +4406,10 @@ class ScopeInfo : public FixedArray {
|
||||
// The layout of the static part of a ScopeInfo is as follows. Each entry is
|
||||
// numeric and occupies one array slot.
|
||||
// 1. A set of properties of the scope
|
||||
// 2. The number of parameters. This only applies to function scopes. For
|
||||
// non-function scopes this is 0.
|
||||
// 3. The number of non-parameter variables allocated on the stack.
|
||||
// 4. The number of non-parameter and parameter variables allocated in the
|
||||
// context.
|
||||
// 2. The number of parameters. For non-function scopes this is 0.
|
||||
// 3. The number of non-parameter variables allocated on the stack.
|
||||
// 4. The number of non-parameter and parameter variables allocated in the
|
||||
// context.
|
||||
#define FOR_EACH_SCOPE_INFO_NUMERIC_FIELD(V) \
|
||||
V(Flags) \
|
||||
V(ParameterCount) \
|
||||
@ -4445,14 +4456,18 @@ class ScopeInfo : public FixedArray {
|
||||
// the context locals in ContextLocalNameEntries. One slot is used per
|
||||
// context local, so in total this part occupies ContextLocalCount()
|
||||
// slots in the array.
|
||||
// 6. RecieverEntryIndex:
|
||||
// 6. ReceiverEntry:
|
||||
// If the scope binds a "this" value, one slot is reserved to hold the
|
||||
// context or stack slot index for the variable.
|
||||
// 7. FunctionNameEntryIndex:
|
||||
// 7. FunctionNameEntry:
|
||||
// If the scope belongs to a named function expression this part contains
|
||||
// information about the function variable. It always occupies two array
|
||||
// slots: a. The name of the function variable.
|
||||
// b. The context or stack slot index for the variable.
|
||||
// 8. ModuleInfoEntry, ModuleVariableCount, and ModuleVariableEntries:
|
||||
// For a module scope, this part contains the ModuleInfo, the number of
|
||||
// MODULE-allocated variables, and the metadata of those variables. For
|
||||
// non-module scopes it is empty.
|
||||
int ParameterEntriesIndex();
|
||||
int StackLocalFirstSlotIndex();
|
||||
int StackLocalEntriesIndex();
|
||||
@ -4460,6 +4475,9 @@ class ScopeInfo : public FixedArray {
|
||||
int ContextLocalInfoEntriesIndex();
|
||||
int ReceiverEntryIndex();
|
||||
int FunctionNameEntryIndex();
|
||||
int ModuleInfoEntryIndex();
|
||||
int ModuleVariableCountIndex();
|
||||
int ModuleVariableEntriesIndex();
|
||||
|
||||
int Lookup(Handle<String> name, int start, int end, VariableMode* mode,
|
||||
VariableLocation* location, InitializationFlag* init_flag,
|
||||
@ -4502,6 +4520,18 @@ class ScopeInfo : public FixedArray {
|
||||
friend class ScopeIterator;
|
||||
};
|
||||
|
||||
// ModuleInfo is to ModuleDescriptor what ScopeInfo is to Scope.
|
||||
class ModuleInfo : public FixedArray {
|
||||
public:
|
||||
DECLARE_CAST(ModuleInfo)
|
||||
static Handle<ModuleInfo> New(Isolate* isolate, ModuleDescriptor* descr);
|
||||
inline FixedArray* special_exports() const;
|
||||
inline FixedArray* regular_exports() const;
|
||||
|
||||
private:
|
||||
friend class Factory;
|
||||
enum { kSpecialExportsIndex, kRegularExportsIndex, kLength };
|
||||
};
|
||||
|
||||
// The cache for maps used by normalized (dictionary mode) objects.
|
||||
// Such maps do not have property descriptors, so a typical program
|
||||
|
@ -566,6 +566,7 @@ void Parser::DeserializeScopeChain(
|
||||
scope = Scope::DeserializeScopeChain(info->isolate(), zone(), *context,
|
||||
script_scope, ast_value_factory(),
|
||||
deserialization_mode);
|
||||
DCHECK(!info->is_module() || scope->is_module_scope());
|
||||
if (info->context().is_null()) {
|
||||
DCHECK(deserialization_mode ==
|
||||
Scope::DeserializationMode::kDeserializeOffHeap);
|
||||
|
Loading…
Reference in New Issue
Block a user