Index: src/ast/modules.cc |
diff --git a/src/ast/modules.cc b/src/ast/modules.cc |
index f895756e4abc3339f97c95237761ce69b62bc1ca..7181b97f76ff6a7b5bbbb89e054d7ad8f884e478 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::AddEmptyImport( |
+ const AstRawString* module_request, Scanner::Location loc, Zone* zone) { |
+ DCHECK_NOT_NULL(module_request); |
+ ModuleEntry* entry = new (zone->New(sizeof(ModuleEntry))) ModuleEntry(loc); |
adamk
2016/07/13 18:38:21
If you make ModuleEntry a ZoneObject this gets cle
neis
2016/07/14 10:28:23
Done.
|
+ 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::AddNonStarImport( |
+ 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->New(sizeof(ModuleEntry))) ModuleEntry(loc); |
+ entry->local_name = local_name; |
+ entry->import_name = import_name; |
+ entry->module_request = module_request; |
+ imports_.Add(entry, zone); |
+} |
+ |
+ |
+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->New(sizeof(ModuleEntry))) ModuleEntry(loc); |
+ entry->local_name = local_name; |
+ 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::AddNonStarExport( |
+ 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->New(sizeof(ModuleEntry))) 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::AddNonStarExport( |
+ 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->New(sizeof(ModuleEntry))) 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->New(sizeof(ModuleEntry))) 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& it : exports_) { |
adamk
2016/07/13 18:38:21
"it" seems an odd name for this, as it's not an it
neis
2016/07/14 10:28:23
Thanks, I forgot to update this when the data stru
|
+ if (it->export_name == nullptr) continue; |
+ AstRawString* key = const_cast<AstRawString*>(it->export_name); |
+ ZoneHashMap::Entry* p = |
+ export_names->LookupOrInsert(key, key->hash(), allocator); |
+ DCHECK_NOT_NULL(p); |
+ if (p->value != nullptr) { |
+ error_handler->ReportMessageAt( |
+ it->location.beg_pos, it->location.end_pos, |
+ MessageTemplate::kDuplicateExport, it->export_name); |
+ return false; |
+ } |
+ p->value = key; // Anything but nullptr. |
+ } |
+ } |
+ |
+ // Report error iff there are exports of non-existent local names. |
+ for (auto& it : exports_) { |
+ if (it->local_name == nullptr) continue; |
+ if (module_scope->LookupLocal(it->local_name) == nullptr) { |
+ error_handler->ReportMessageAt( |
+ it->location.beg_pos, it->location.end_pos, |
+ MessageTemplate::kModuleExportUndefined, it->local_name); |
+ return false; |
+ } |
+ } |
+ |
+ return true; |
} |
} // namespace internal |
} // namespace v8 |