Collect list of requested modules in ModuleDescriptor while parsing

BUG=v8:1569
LOG=n

Review URL: https://codereview.chromium.org/1078903002

Cr-Commit-Position: refs/heads/master@{#27724}
This commit is contained in:
adamk 2015-04-09 15:09:44 -07:00 committed by Commit bot
parent ae475b54c9
commit 52bbb4f609
4 changed files with 37 additions and 4 deletions

View File

@ -35,6 +35,15 @@ void ModuleDescriptor::AddLocalExport(const AstRawString* export_name,
} }
void ModuleDescriptor::AddModuleRequest(const AstRawString* module_specifier,
Zone* zone) {
// TODO(adamk): Avoid this O(N) operation on each insert by storing
// a HashMap, or by de-duping after parsing.
if (requested_modules_.Contains(module_specifier)) return;
requested_modules_.Add(module_specifier, zone);
}
const AstRawString* ModuleDescriptor::LookupLocalExport( const AstRawString* ModuleDescriptor::LookupLocalExport(
const AstRawString* export_name, Zone* zone) { const AstRawString* export_name, Zone* zone) {
if (exports_ == nullptr) return nullptr; if (exports_ == nullptr) return nullptr;

View File

@ -20,7 +20,7 @@ class ModuleDescriptor : public ZoneObject {
// Factory methods. // Factory methods.
static ModuleDescriptor* New(Zone* zone) { static ModuleDescriptor* New(Zone* zone) {
return new (zone) ModuleDescriptor(); return new (zone) ModuleDescriptor(zone);
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@ -31,6 +31,10 @@ class ModuleDescriptor : public ZoneObject {
void AddLocalExport(const AstRawString* export_name, void AddLocalExport(const AstRawString* export_name,
const AstRawString* local_name, Zone* zone, bool* ok); const AstRawString* local_name, Zone* zone, bool* ok);
// Add module_specifier to the list of requested modules,
// if not already present.
void AddModuleRequest(const AstRawString* module_specifier, Zone* zone);
// Do not allow any further refinements, directly or through unification. // Do not allow any further refinements, directly or through unification.
void Freeze() { frozen_ = true; } void Freeze() { frozen_ = true; }
@ -61,6 +65,10 @@ class ModuleDescriptor : public ZoneObject {
const AstRawString* LookupLocalExport(const AstRawString* export_name, const AstRawString* LookupLocalExport(const AstRawString* export_name,
Zone* zone); Zone* zone);
const ZoneList<const AstRawString*>& requested_modules() const {
return requested_modules_;
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Iterators. // Iterators.
@ -95,11 +103,16 @@ class ModuleDescriptor : public ZoneObject {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Implementation. // Implementation.
private: private:
explicit ModuleDescriptor(Zone* zone)
: frozen_(false),
exports_(NULL),
requested_modules_(1, zone),
index_(-1) {}
bool frozen_; bool frozen_;
ZoneHashMap* exports_; // Module exports and their types (allocated lazily) ZoneHashMap* exports_; // Module exports and their types (allocated lazily)
ZoneList<const AstRawString*> requested_modules_;
int index_; int index_;
ModuleDescriptor() : frozen_(false), exports_(NULL), index_(-1) {}
}; };
} } // namespace v8::internal } } // namespace v8::internal

View File

@ -1560,6 +1560,8 @@ Statement* Parser::ParseImportDeclaration(bool* ok) {
const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK); const AstRawString* module_specifier = ParseModuleSpecifier(CHECK_OK);
ExpectSemicolon(CHECK_OK); ExpectSemicolon(CHECK_OK);
scope_->module()->AddModuleRequest(module_specifier, zone());
if (module_instance_binding != NULL) { if (module_instance_binding != NULL) {
// TODO(ES6): Set the module specifier for the module namespace binding. // TODO(ES6): Set the module specifier for the module namespace binding.
} }
@ -1697,6 +1699,8 @@ Statement* Parser::ParseExportDeclaration(bool* ok) {
} }
} }
} else { } else {
scope_->module()->AddModuleRequest(indirect_export_module_specifier,
zone());
for (int i = 0; i < length; ++i) { for (int i = 0; i < length; ++i) {
// TODO(ES6): scope_->module()->AddIndirectExport(...);( // TODO(ES6): scope_->module()->AddIndirectExport(...);(
} }

View File

@ -5445,7 +5445,8 @@ TEST(ModuleParsingInternals) {
"let x = 5;" "let x = 5;"
"export { x as y };" "export { x as y };"
"import { q as z } from 'm.js';" "import { q as z } from 'm.js';"
"import n from 'n.js'"; "import n from 'n.js';"
"export { a as b } from 'm.js';";
i::Handle<i::String> source = factory->NewStringFromAsciiChecked(kSource); i::Handle<i::String> source = factory->NewStringFromAsciiChecked(kSource);
i::Handle<i::Script> script = factory->NewScript(source); i::Handle<i::Script> script = factory->NewScript(source);
i::Zone zone; i::Zone zone;
@ -5485,6 +5486,12 @@ TEST(ModuleParsingInternals) {
CHECK(import_decl->import_name()->IsOneByteEqualTo("default")); CHECK(import_decl->import_name()->IsOneByteEqualTo("default"));
CHECK(import_decl->proxy()->raw_name()->IsOneByteEqualTo("n")); CHECK(import_decl->proxy()->raw_name()->IsOneByteEqualTo("n"));
CHECK(import_decl->module_specifier()->IsOneByteEqualTo("n.js")); CHECK(import_decl->module_specifier()->IsOneByteEqualTo("n.js"));
// TODO(adamk): Add test for indirect exports once they're fully implemented.
const i::ZoneList<const i::AstRawString*>& requested_modules =
descriptor->requested_modules();
CHECK_EQ(2, requested_modules.length());
CHECK(requested_modules[0]->IsOneByteEqualTo("m.js"));
CHECK(requested_modules[1]->IsOneByteEqualTo("n.js"));
} }