modules.cc 4.04 KB
Newer Older
1 2 3 4
// Copyright 2012 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5 6
#include "src/ast/modules.h"
#include "src/ast/ast-value-factory.h"
7
#include "src/ast/scopes.h"
8 9 10 11 12

namespace v8 {
namespace internal {


13 14 15 16 17 18 19 20 21 22 23 24
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);
}
25 26


27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
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);
}
46 47


48 49 50 51 52 53 54 55 56
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);
57
}
58 59


60 61 62 63 64 65 66 67 68 69 70
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);
71 72 73
}


74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
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;
124
}
125 126
}  // namespace internal
}  // namespace v8