From 98a79c9412accd4fc9b806b2e52870230cf24094 Mon Sep 17 00:00:00 2001 From: neis Date: Mon, 29 Aug 2016 02:15:02 -0700 Subject: [PATCH] [modules] Partial support for (de-)serializing module descriptor entries. This will be used for scope infos in a follow-up CL. R=adamk@chromium.org BUG=v8:1569 Review-Url: https://codereview.chromium.org/2277273002 Cr-Commit-Position: refs/heads/master@{#38969} --- src/ast/modules.cc | 62 ++++++++++++++++++++++++++++++++++------------ src/ast/modules.h | 35 ++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 16 deletions(-) diff --git a/src/ast/modules.cc b/src/ast/modules.cc index 1367942245..f0cb18bc62 100644 --- a/src/ast/modules.cc +++ b/src/ast/modules.cc @@ -12,16 +12,11 @@ namespace internal { void ModuleDescriptor::AddImport( const AstRawString* import_name, const AstRawString* local_name, const AstRawString* module_request, Scanner::Location loc, Zone* zone) { - DCHECK_NOT_NULL(import_name); - DCHECK_NOT_NULL(local_name); - DCHECK_NOT_NULL(module_request); Entry* entry = new (zone) Entry(loc); entry->local_name = local_name; entry->import_name = import_name; entry->module_request = module_request; - regular_imports_.insert(std::make_pair(entry->local_name, entry)); - // We don't care if there's already an entry for this local name, as in that - // case we will report an error when declaring the variable. + AddRegularImport(entry); } @@ -33,28 +28,25 @@ void ModuleDescriptor::AddStarImport( Entry* entry = new (zone) Entry(loc); entry->local_name = local_name; entry->module_request = module_request; - special_imports_.Add(entry, zone); + AddSpecialImport(entry, zone); } void ModuleDescriptor::AddEmptyImport( const AstRawString* module_request, Scanner::Location loc, Zone* zone) { - DCHECK_NOT_NULL(module_request); Entry* entry = new (zone) Entry(loc); entry->module_request = module_request; - special_imports_.Add(entry, zone); + AddSpecialImport(entry, zone); } void ModuleDescriptor::AddExport( const AstRawString* local_name, const AstRawString* export_name, Scanner::Location loc, Zone* zone) { - DCHECK_NOT_NULL(local_name); - DCHECK_NOT_NULL(export_name); Entry* entry = new (zone) Entry(loc); entry->export_name = export_name; entry->local_name = local_name; - regular_exports_.insert(std::make_pair(entry->local_name, entry)); + AddRegularExport(entry); } @@ -63,21 +55,59 @@ void ModuleDescriptor::AddExport( const AstRawString* module_request, Scanner::Location loc, Zone* zone) { DCHECK_NOT_NULL(import_name); DCHECK_NOT_NULL(export_name); - DCHECK_NOT_NULL(module_request); Entry* entry = new (zone) Entry(loc); entry->export_name = export_name; entry->import_name = import_name; entry->module_request = module_request; - special_exports_.Add(entry, zone); + AddSpecialExport(entry, zone); } void ModuleDescriptor::AddStarExport( const AstRawString* module_request, Scanner::Location loc, Zone* zone) { - DCHECK_NOT_NULL(module_request); Entry* entry = new (zone) Entry(loc); entry->module_request = module_request; - special_exports_.Add(entry, zone); + AddSpecialExport(entry, zone); +} + +namespace { + +Handle ToStringOrUndefined(Isolate* isolate, const AstRawString* s) { + return (s == nullptr) + ? Handle::cast(isolate->factory()->undefined_value()) + : Handle::cast(s->string()); +} + +const AstRawString* FromStringOrUndefined(Isolate* isolate, + AstValueFactory* avfactory, + Handle object) { + if (object->IsUndefined(isolate)) return nullptr; + return avfactory->GetString(Handle::cast(object)); +} + +} // namespace + +Handle ModuleDescriptor::Entry::Serialize(Isolate* isolate) const { + Handle result = isolate->factory()->NewFixedArray(4); + result->set(0, *ToStringOrUndefined(isolate, export_name)); + result->set(1, *ToStringOrUndefined(isolate, local_name)); + result->set(2, *ToStringOrUndefined(isolate, import_name)); + result->set(3, *ToStringOrUndefined(isolate, module_request)); + return result; +} + +ModuleDescriptor::Entry* ModuleDescriptor::Entry::Deserialize( + Isolate* isolate, AstValueFactory* avfactory, Handle data) { + Entry* entry = new (avfactory->zone()) Entry(Scanner::Location::invalid()); + entry->export_name = + FromStringOrUndefined(isolate, avfactory, handle(data->get(0), isolate)); + entry->local_name = + FromStringOrUndefined(isolate, avfactory, handle(data->get(1), isolate)); + entry->import_name = + FromStringOrUndefined(isolate, avfactory, handle(data->get(2), isolate)); + entry->module_request = + FromStringOrUndefined(isolate, avfactory, handle(data->get(3), isolate)); + return entry; } void ModuleDescriptor::MakeIndirectExportsExplicit(Zone* zone) { diff --git a/src/ast/modules.h b/src/ast/modules.h index 5b6a86cc2d..7e78ac2bad 100644 --- a/src/ast/modules.h +++ b/src/ast/modules.h @@ -24,6 +24,9 @@ class ModuleDescriptor : public ZoneObject { regular_exports_(zone), regular_imports_(zone) {} + // The following Add* methods are high-level convenience functions for use by + // the parser. + // import x from "foo.js"; // import {x} from "foo.js"; // import {x as y} from "foo.js"; @@ -83,6 +86,10 @@ class ModuleDescriptor : public ZoneObject { local_name(nullptr), import_name(nullptr), module_request(nullptr) {} + + Handle Serialize(Isolate* isolate) const; + static Entry* Deserialize(Isolate* isolate, AstValueFactory* avfactory, + Handle data); }; // Empty imports and namespace imports. @@ -105,6 +112,34 @@ class ModuleDescriptor : public ZoneObject { return regular_exports_; } + void AddRegularExport(Entry* entry) { + DCHECK_NOT_NULL(entry->export_name); + DCHECK_NOT_NULL(entry->local_name); + DCHECK_NULL(entry->import_name); + regular_exports_.insert(std::make_pair(entry->local_name, entry)); + } + + void AddSpecialExport(const Entry* entry, Zone* zone) { + DCHECK_NOT_NULL(entry->module_request); + special_exports_.Add(entry, zone); + } + + void AddRegularImport(const Entry* entry) { + DCHECK_NOT_NULL(entry->import_name); + DCHECK_NOT_NULL(entry->local_name); + DCHECK_NOT_NULL(entry->module_request); + DCHECK_NULL(entry->export_name); + regular_imports_.insert(std::make_pair(entry->local_name, entry)); + // We don't care if there's already an entry for this local name, as in that + // case we will report an error when declaring the variable. + } + + void AddSpecialImport(const Entry* entry, Zone* zone) { + DCHECK_NOT_NULL(entry->module_request); + DCHECK_NULL(entry->export_name); + special_imports_.Add(entry, zone); + } + private: // TODO(neis): Use STL datastructure instead of ZoneList? ZoneList special_exports_;