| Index: src/ast/modules.cc
|
| diff --git a/src/ast/modules.cc b/src/ast/modules.cc
|
| index f895756e4abc3339f97c95237761ce69b62bc1ca..286a117b3f506791c5ce1c02cd1100e1532dfdbb 100644
|
| --- a/src/ast/modules.cc
|
| +++ b/src/ast/modules.cc
|
| @@ -3,56 +3,124 @@
|
| // found in the LICENSE file.
|
|
|
| #include "src/ast/modules.h"
|
| -
|
| #include "src/ast/ast-value-factory.h"
|
| +#include "src/ast/scopes.h"
|
|
|
| namespace v8 {
|
| namespace internal {
|
|
|
|
|
| -void ModuleDescriptor::AddLocalExport(const AstRawString* export_name,
|
| - const AstRawString* local_name,
|
| - Zone* zone, bool* ok) {
|
| - void* key = const_cast<AstRawString*>(export_name);
|
| +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);
|
| + ModuleEntry* entry = new (zone) ModuleEntry(loc);
|
| + entry->local_name = local_name;
|
| + entry->import_name = import_name;
|
| + entry->module_request = module_request;
|
| + imports_.Add(entry, zone);
|
| +}
|
|
|
| - ZoneAllocationPolicy allocator(zone);
|
|
|
| - if (exports_ == nullptr) {
|
| - exports_ = new (zone->New(sizeof(ZoneHashMap)))
|
| - ZoneHashMap(ZoneHashMap::PointersMatch,
|
| - ZoneHashMap::kDefaultHashMapCapacity, allocator);
|
| - }
|
| +void ModuleDescriptor::AddStarImport(
|
| + const AstRawString* local_name, const AstRawString* module_request,
|
| + Scanner::Location loc, Zone* zone) {
|
| + DCHECK_NOT_NULL(local_name);
|
| + DCHECK_NOT_NULL(module_request);
|
| + ModuleEntry* entry = new (zone) ModuleEntry(loc);
|
| + entry->local_name = local_name;
|
| + entry->module_request = module_request;
|
| + imports_.Add(entry, zone);
|
| +}
|
| +
|
| +
|
| +void ModuleDescriptor::AddEmptyImport(
|
| + const AstRawString* module_request, Scanner::Location loc, Zone* zone) {
|
| + DCHECK_NOT_NULL(module_request);
|
| + ModuleEntry* entry = new (zone) ModuleEntry(loc);
|
| + entry->module_request = module_request;
|
| + imports_.Add(entry, zone);
|
| +}
|
|
|
| - ZoneHashMap::Entry* p =
|
| - exports_->LookupOrInsert(key, export_name->hash(), allocator);
|
| - DCHECK_NOT_NULL(p);
|
| - if (p->value != nullptr) {
|
| - // Duplicate export.
|
| - *ok = false;
|
| - return;
|
| - }
|
|
|
| - p->value = const_cast<AstRawString*>(local_name);
|
| +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);
|
| + ModuleEntry* entry = new (zone) ModuleEntry(loc);
|
| + entry->export_name = export_name;
|
| + entry->local_name = local_name;
|
| + exports_.Add(entry, zone);
|
| }
|
|
|
|
|
| -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);
|
| +void ModuleDescriptor::AddExport(
|
| + const AstRawString* import_name, const AstRawString* export_name,
|
| + const AstRawString* module_request, Scanner::Location loc, Zone* zone) {
|
| + DCHECK_NOT_NULL(import_name);
|
| + DCHECK_NOT_NULL(export_name);
|
| + DCHECK_NOT_NULL(module_request);
|
| + ModuleEntry* entry = new (zone) ModuleEntry(loc);
|
| + entry->export_name = export_name;
|
| + entry->import_name = import_name;
|
| + entry->module_request = module_request;
|
| + exports_.Add(entry, zone);
|
| }
|
|
|
|
|
| -const AstRawString* ModuleDescriptor::LookupLocalExport(
|
| - const AstRawString* export_name, Zone* zone) {
|
| - if (exports_ == nullptr) return nullptr;
|
| - ZoneHashMap::Entry* entry = exports_->Lookup(
|
| - const_cast<AstRawString*>(export_name), export_name->hash());
|
| - if (entry == nullptr) return nullptr;
|
| - DCHECK_NOT_NULL(entry->value);
|
| - return static_cast<const AstRawString*>(entry->value);
|
| +void ModuleDescriptor::AddStarExport(
|
| + const AstRawString* module_request, Scanner::Location loc, Zone* zone) {
|
| + DCHECK_NOT_NULL(module_request);
|
| + ModuleEntry* entry = new (zone) ModuleEntry(loc);
|
| + entry->module_request = module_request;
|
| + exports_.Add(entry, zone);
|
| +}
|
| +
|
| +
|
| +bool ModuleDescriptor::Validate(
|
| + Scope* module_scope, PendingCompilationErrorHandler* error_handler,
|
| + Zone* zone) const {
|
| + DCHECK(module_scope->is_module_scope());
|
| + DCHECK_EQ(this, module_scope->module());
|
| + DCHECK_NOT_NULL(error_handler);
|
| +
|
| + // Report error iff there are duplicate exports.
|
| + {
|
| + ZoneAllocationPolicy allocator(zone);
|
| + ZoneHashMap* export_names = new (zone->New(sizeof(ZoneHashMap)))
|
| + ZoneHashMap(ZoneHashMap::PointersMatch,
|
| + ZoneHashMap::kDefaultHashMapCapacity, allocator);
|
| + for (auto entry : exports_) {
|
| + if (entry->export_name == nullptr) continue;
|
| + AstRawString* key = const_cast<AstRawString*>(entry->export_name);
|
| + ZoneHashMap::Entry* p =
|
| + export_names->LookupOrInsert(key, key->hash(), allocator);
|
| + DCHECK_NOT_NULL(p);
|
| + if (p->value != nullptr) {
|
| + error_handler->ReportMessageAt(
|
| + entry->location.beg_pos, entry->location.end_pos,
|
| + MessageTemplate::kDuplicateExport, entry->export_name);
|
| + return false;
|
| + }
|
| + p->value = key; // Anything but nullptr.
|
| + }
|
| + }
|
| +
|
| + // Report error iff there are exports of non-existent local names.
|
| + for (auto entry : exports_) {
|
| + if (entry->local_name == nullptr) continue;
|
| + if (module_scope->LookupLocal(entry->local_name) == nullptr) {
|
| + error_handler->ReportMessageAt(
|
| + entry->location.beg_pos, entry->location.end_pos,
|
| + MessageTemplate::kModuleExportUndefined, entry->local_name);
|
| + return false;
|
| + }
|
| + }
|
| +
|
| + return true;
|
| }
|
| } // namespace internal
|
| } // namespace v8
|
|
|