Commit 9d6c6e5a authored by neis's avatar neis Committed by Commit bot

[modules] Make handling of module info's regular exports more robust.

R=adamk@chromium.org
BUG=v8:1569

Review-Url: https://codereview.chromium.org/2473993002
Cr-Commit-Position: refs/heads/master@{#40795}
parent f354558c
......@@ -112,55 +112,61 @@ Handle<FixedArray> ModuleDescriptor::SerializeRegularExports(Isolate* isolate,
// local names and for each local name immediately access all its export
// names. (Regular exports have neither import name nor module request.)
ZoneVector<Handle<Object>> data(zone);
data.reserve(3 * regular_exports_.size());
ZoneVector<Handle<Object>> data(
ModuleInfo::kRegularExportLength * regular_exports_.size(), zone);
int index = 0;
for (auto it = regular_exports_.begin(); it != regular_exports_.end();) {
// Find out how many export names this local name has.
auto next = it;
int size = 0;
int count = 0;
do {
DCHECK_EQ(it->second->local_name, next->second->local_name);
DCHECK_EQ(it->second->cell_index, next->second->cell_index);
++next;
++size;
++count;
} while (next != regular_exports_.end() && next->first == it->first);
Handle<FixedArray> export_names = isolate->factory()->NewFixedArray(size);
data.push_back(it->second->local_name->string());
data.push_back(handle(Smi::FromInt(it->second->cell_index), isolate));
data.push_back(export_names);
Handle<FixedArray> export_names = isolate->factory()->NewFixedArray(count);
data[index + ModuleInfo::kRegularExportLocalNameOffset] =
it->second->local_name->string();
data[index + ModuleInfo::kRegularExportCellIndexOffset] =
handle(Smi::FromInt(it->second->cell_index), isolate);
data[index + ModuleInfo::kRegularExportExportNamesOffset] = export_names;
index += ModuleInfo::kRegularExportLength;
// Collect the export names.
int i = 0;
for (; it != next; ++it) {
export_names->set(i++, *it->second->export_name->string());
}
DCHECK_EQ(i, size);
DCHECK_EQ(i, count);
// Continue with the next distinct key.
DCHECK(it == next);
}
DCHECK_LE(index, static_cast<int>(data.size()));
data.resize(index);
// We cannot create the FixedArray earlier because we only now know the
// precise size (the number of unique keys in regular_exports).
int size = static_cast<int>(data.size());
Handle<FixedArray> result = isolate->factory()->NewFixedArray(size);
for (int i = 0; i < size; ++i) {
// precise size.
Handle<FixedArray> result = isolate->factory()->NewFixedArray(index);
for (int i = 0; i < index; ++i) {
result->set(i, *data[i]);
}
return result;
}
void ModuleDescriptor::DeserializeRegularExports(Isolate* isolate,
AstValueFactory* avfactory,
Handle<FixedArray> data) {
for (int i = 0, length_i = data->length(); i < length_i;) {
Handle<String> local_name(String::cast(data->get(i++)), isolate);
int cell_index = Smi::cast(data->get(i++))->value();
Handle<FixedArray> export_names(FixedArray::cast(data->get(i++)), isolate);
for (int j = 0, length_j = export_names->length(); j < length_j; ++j) {
void ModuleDescriptor::DeserializeRegularExports(
Isolate* isolate, AstValueFactory* avfactory,
Handle<ModuleInfo> module_info) {
for (int i = 0, count = module_info->RegularExportCount(); i < count; ++i) {
Handle<String> local_name(module_info->RegularExportLocalName(i), isolate);
int cell_index = module_info->RegularExportCellIndex(i);
Handle<FixedArray> export_names(module_info->RegularExportExportNames(i),
isolate);
for (int j = 0, length = export_names->length(); j < length; ++j) {
Handle<String> export_name(String::cast(export_names->get(j)), isolate);
Entry* entry =
......
......@@ -14,6 +14,7 @@ namespace internal {
class AstRawString;
class ModuleInfo;
class ModuleInfoEntry;
class ModuleDescriptor : public ZoneObject {
......@@ -169,7 +170,7 @@ class ModuleDescriptor : public ZoneObject {
Handle<FixedArray> SerializeRegularExports(Isolate* isolate,
Zone* zone) const;
void DeserializeRegularExports(Isolate* isolate, AstValueFactory* avfactory,
Handle<FixedArray> data);
Handle<ModuleInfo> module_info);
private:
// TODO(neis): Use STL datastructure instead of ZoneList?
......
......@@ -935,6 +935,27 @@ Handle<ModuleInfo> ModuleInfo::New(Isolate* isolate, Zone* zone,
return result;
}
int ModuleInfo::RegularExportCount() const {
DCHECK_EQ(regular_exports()->length() % kRegularExportLength, 0);
return regular_exports()->length() / kRegularExportLength;
}
String* ModuleInfo::RegularExportLocalName(int i) const {
return String::cast(regular_exports()->get(i * kRegularExportLength +
kRegularExportLocalNameOffset));
}
int ModuleInfo::RegularExportCellIndex(int i) const {
return Smi::cast(regular_exports()->get(i * kRegularExportLength +
kRegularExportCellIndexOffset))
->value();
}
FixedArray* ModuleInfo::RegularExportExportNames(int i) const {
return FixedArray::cast(regular_exports()->get(
i * kRegularExportLength + kRegularExportExportNamesOffset));
}
Handle<ModuleInfoEntry> ModuleInfo::LookupRegularImport(
Handle<ModuleInfo> info, Handle<String> local_name) {
Isolate* isolate = info->GetIsolate();
......
......@@ -160,7 +160,7 @@ 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();
Handle<ModuleInfo> module_info(scope_info->ModuleDescriptorInfo(), isolate);
set_language_mode(STRICT);
module_descriptor_ = new (zone) ModuleDescriptor(zone);
......@@ -177,9 +177,8 @@ ModuleScope::ModuleScope(Isolate* isolate, Handle<ScopeInfo> scope_info,
}
// Deserialize regular exports.
Handle<FixedArray> regular_exports(module_info->regular_exports(), isolate);
module_descriptor_->DeserializeRegularExports(isolate, avfactory,
regular_exports);
module_info);
// Deserialize namespace imports.
Handle<FixedArray> namespace_imports(module_info->namespace_imports(),
......
......@@ -1816,7 +1816,7 @@ Handle<Module> Factory::NewModule(Handle<SharedFunctionInfo> code) {
Handle<ModuleInfo> module_info(code->scope_info()->ModuleDescriptorInfo(),
isolate());
Handle<ObjectHashTable> exports =
ObjectHashTable::New(isolate(), module_info->regular_exports()->length());
ObjectHashTable::New(isolate(), module_info->RegularExportCount());
int requested_modules_length = module_info->module_requests()->length();
Handle<FixedArray> requested_modules =
requested_modules_length > 0 ? NewFixedArray(requested_modules_length)
......
......@@ -20021,11 +20021,9 @@ bool Module::Instantiate(Handle<Module> module, v8::Local<v8::Context> context,
isolate);
// Set up local exports.
Handle<FixedArray> regular_exports(module_info->regular_exports(), isolate);
for (int i = 0, n = regular_exports->length(); i < n; i += 3) {
// TODO(neis): Make this more robust.
Handle<FixedArray> export_names(
FixedArray::cast(regular_exports->get(i + 2)), isolate);
for (int i = 0, n = module_info->RegularExportCount(); i < n; ++i) {
Handle<FixedArray> export_names(module_info->RegularExportExportNames(i),
isolate);
CreateExport(module, export_names);
}
......
......@@ -8109,6 +8109,12 @@ class ModuleInfo : public FixedArray {
inline FixedArray* namespace_imports() const;
inline FixedArray* regular_imports() const;
// Accessors for [regular_exports].
int RegularExportCount() const;
String* RegularExportLocalName(int i) const;
int RegularExportCellIndex(int i) const;
FixedArray* RegularExportExportNames(int i) const;
static Handle<ModuleInfoEntry> LookupRegularImport(Handle<ModuleInfo> info,
Handle<String> local_name);
......@@ -8118,6 +8124,7 @@ class ModuleInfo : public FixedArray {
private:
friend class Factory;
friend class ModuleDescriptor;
enum {
kModuleRequestsIndex,
kSpecialExportsIndex,
......@@ -8126,6 +8133,12 @@ class ModuleInfo : public FixedArray {
kRegularImportsIndex,
kLength
};
enum {
kRegularExportLocalNameOffset,
kRegularExportCellIndexOffset,
kRegularExportExportNamesOffset,
kRegularExportLength
};
DISALLOW_IMPLICIT_CONSTRUCTORS(ModuleInfo);
};
// When importing a module namespace (import * as foo from "bar"), a
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment