v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
modules.h
Go to the documentation of this file.
1// Copyright 2012 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_AST_MODULES_H_
6#define V8_AST_MODULES_H_
7
9#include "src/parsing/scanner.h" // Only for Scanner::Location.
11
12namespace v8 {
13namespace internal {
14
15
16class AstRawString;
17class AstRawStringComparer;
18class ModuleRequest;
19class SourceTextModuleInfo;
20class SourceTextModuleInfoEntry;
21class PendingCompilationErrorHandler;
22
24 public:
26 : module_requests_(zone),
27 special_exports_(zone),
29 regular_exports_(zone),
30 regular_imports_(zone) {}
31
32 // The following Add* methods are high-level convenience functions for use by
33 // the parser.
34
35 // import x from "foo.js";
36 // import {x} from "foo.js";
37 // import {x as y} from "foo.js";
38 void AddImport(const AstRawString* import_name,
39 const AstRawString* local_name, const AstRawString* specifier,
40 const ModuleImportPhase import_phase,
41 const ImportAttributes* import_attributes,
42 const Scanner::Location loc,
43 const Scanner::Location specifier_loc, Zone* zone);
44
45 // import * as x from "foo.js";
46 void AddStarImport(const AstRawString* local_name,
47 const AstRawString* specifier,
48 const ImportAttributes* import_attributes,
49 const Scanner::Location loc,
50 const Scanner::Location specifier_loc, Zone* zone);
51
52 // import "foo.js";
53 // import {} from "foo.js";
54 // export {} from "foo.js"; (sic!)
55 void AddEmptyImport(const AstRawString* specifier,
56 const ImportAttributes* import_attributes,
57 const Scanner::Location specifier_loc, Zone* zone);
58
59 // export {x};
60 // export {x as y};
61 // export VariableStatement
62 // export Declaration
63 // export default ...
64 void AddExport(
65 const AstRawString* local_name, const AstRawString* export_name,
66 const Scanner::Location loc, Zone* zone);
67
68 // export {x} from "foo.js";
69 // export {x as y} from "foo.js";
70 void AddExport(const AstRawString* export_name,
71 const AstRawString* import_name, const AstRawString* specifier,
72 const ImportAttributes* import_attributes,
73 const Scanner::Location loc,
74 const Scanner::Location specifier_loc, Zone* zone);
75
76 // export * from "foo.js";
77 void AddStarExport(const AstRawString* specifier,
78 const ImportAttributes* import_attributes,
79 const Scanner::Location loc,
80 const Scanner::Location specifier_loc, Zone* zone);
81
82 // Check if module is well-formed and report error if not.
83 // Also canonicalize indirect exports.
84 bool Validate(ModuleScope* module_scope,
85 PendingCompilationErrorHandler* error_handler, Zone* zone);
86
87 struct Entry : public ZoneObject {
92
93 // The module_request value records the order in which modules are
94 // requested. It also functions as an index into the SourceTextModuleInfo's
95 // array of module specifiers and into the Module's array of requested
96 // modules. A negative value means no module request.
98
99 // Import/export entries that are associated with a MODULE-allocated
100 // variable (i.e. regular_imports and regular_exports after Validate) use
101 // the cell_index value to encode the location of their cell. During
102 // variable allocation, this will be be copied into the variable's index
103 // field.
104 // Entries that are not associated with a MODULE-allocated variable have
105 // GetCellIndexKind(cell_index) == kInvalid.
107
108 // TODO(neis): Remove local_name component?
110 : location(loc),
111 export_name(nullptr),
112 local_name(nullptr),
113 import_name(nullptr),
114 module_request(-1),
115 cell_index(0) {}
116
117 template <typename IsolateT>
118 DirectHandle<SourceTextModuleInfoEntry> Serialize(IsolateT* isolate) const;
119 };
120
122 static CellIndexKind GetCellIndexKind(int cell_index);
123
125 public:
135
136 template <typename IsolateT>
138 IsolateT* isolate) const;
139
140 const AstRawString* specifier() const { return specifier_; }
142 return import_attributes_;
143 }
144 ModuleImportPhase phase() const { return phase_; }
145
146 int position() const { return position_; }
147 int index() const { return index_; }
148
149 private:
153
154 // The JS source code position of the request, used for reporting errors.
156
157 // The index at which we will place the request in SourceTextModuleInfo's
158 // module_requests FixedArray.
160 };
161
162 // Custom content-based comparer for the below maps, to keep them stable
163 // across parses.
165 bool operator()(const AstRawString* lhs, const AstRawString* rhs) const;
166 };
167
169 bool operator()(const AstModuleRequest* lhs,
170 const AstModuleRequest* rhs) const;
171 };
172
179
180 // Module requests.
182
183 // Namespace imports.
187
188 // All the remaining imports, indexed by local name.
190
191 // Star exports and explicitly indirect exports.
195
196 // All the remaining exports, indexed by local name.
197 // After canonicalization (see Validate), these are exactly the local exports.
199
200 void AddRegularExport(Entry* entry) {
203 DCHECK_NULL(entry->import_name);
204 DCHECK_LT(entry->module_request, 0);
205 regular_exports_.insert(std::make_pair(entry->local_name, entry));
206 }
207
208 void AddSpecialExport(const Entry* entry, Zone* zone) {
209 DCHECK_NULL(entry->local_name);
210 DCHECK_LE(0, entry->module_request);
211 special_exports_.push_back(entry);
212 }
213
214 void AddRegularImport(Entry* entry) {
217 DCHECK_NULL(entry->export_name);
218 DCHECK_LE(0, entry->module_request);
219 regular_imports_.insert(std::make_pair(entry->local_name, entry));
220 // We don't care if there's already an entry for this local name, as in that
221 // case we will report an error when declaring the variable.
222 }
223
224 void AddNamespaceImport(const Entry* entry, Zone* zone) {
225 DCHECK_NULL(entry->import_name);
226 DCHECK_NULL(entry->export_name);
228 DCHECK_LE(0, entry->module_request);
229 namespace_imports_.push_back(entry);
230 }
231
232 template <typename IsolateT>
234 Zone* zone) const;
235
236 private:
242
243 // If there are multiple export entries with the same export name, return the
244 // last of them (in source order). Otherwise return nullptr.
245 const Entry* FindDuplicateExport(Zone* zone) const;
246
247 // Find any implicitly indirect exports and make them explicit.
248 //
249 // An explicitly indirect export is an export entry arising from an export
250 // statement of the following form:
251 // export {a as c} from "X";
252 // An implicitly indirect export corresponds to
253 // export {b as c};
254 // in the presence of an import statement of the form
255 // import {a as b} from "X";
256 // This function finds such implicitly indirect export entries and rewrites
257 // them by filling in the import name and module request, as well as nulling
258 // out the local name. Effectively, it turns
259 // import {a as b} from "X"; export {b as c};
260 // into:
261 // import {a as b} from "X"; export {a as c} from "X";
262 // (The import entry is never deleted.)
264
265 // Assign a cell_index of -1,-2,... to regular imports.
266 // Assign a cell_index of +1,+2,... to regular (local) exports.
267 // Assign a cell_index of 0 to anything else.
268 void AssignCellIndices();
269
270 int AddModuleRequest(const AstRawString* specifier,
271 const ModuleImportPhase import_phase,
272 const ImportAttributes* import_attributes,
273 Scanner::Location specifier_loc, Zone* zone) {
274 DCHECK_NOT_NULL(specifier);
275 int module_requests_count = static_cast<int>(module_requests_.size());
276 auto it = module_requests_
277 .insert(zone->New<AstModuleRequest>(
278 specifier, import_phase, import_attributes,
279 specifier_loc.beg_pos, module_requests_count))
280 .first;
281 return (*it)->index();
282 }
283};
284
285} // namespace internal
286} // namespace v8
287
288#endif // V8_AST_MODULES_H_
DirectHandle< v8::internal::ModuleRequest > Serialize(IsolateT *isolate) const
AstModuleRequest(const AstRawString *specifier, const ModuleImportPhase phase, const ImportAttributes *import_attributes, int position, int index)
Definition modules.h:126
const ImportAttributes * import_attributes() const
Definition modules.h:141
void AddStarExport(const AstRawString *specifier, const ImportAttributes *import_attributes, const Scanner::Location loc, const Scanner::Location specifier_loc, Zone *zone)
Definition modules.cc:115
bool Validate(ModuleScope *module_scope, PendingCompilationErrorHandler *error_handler, Zone *zone)
Definition modules.cc:352
void AddNamespaceImport(const Entry *entry, Zone *zone)
Definition modules.h:224
const Entry * FindDuplicateExport(Zone *zone) const
Definition modules.cc:338
void AddStarImport(const AstRawString *local_name, const AstRawString *specifier, const ImportAttributes *import_attributes, const Scanner::Location loc, const Scanner::Location specifier_loc, Zone *zone)
Definition modules.cc:71
static CellIndexKind GetCellIndexKind(int cell_index)
Definition modules.cc:279
int AddModuleRequest(const AstRawString *specifier, const ModuleImportPhase import_phase, const ImportAttributes *import_attributes, Scanner::Location specifier_loc, Zone *zone)
Definition modules.h:270
const RegularExportMap & regular_exports() const
Definition modules.h:198
DirectHandle< FixedArray > SerializeRegularExports(IsolateT *isolate, Zone *zone) const
Definition modules.cc:185
const ModuleRequestMap & module_requests() const
Definition modules.h:181
const RegularImportMap & regular_imports() const
Definition modules.h:189
void AddEmptyImport(const AstRawString *specifier, const ImportAttributes *import_attributes, const Scanner::Location specifier_loc, Zone *zone)
Definition modules.cc:83
ZoneVector< const Entry * > namespace_imports_
Definition modules.h:239
const ZoneVector< const Entry * > & namespace_imports() const
Definition modules.h:184
ZoneVector< const Entry * > special_exports_
Definition modules.h:238
void AddImport(const AstRawString *import_name, const AstRawString *local_name, const AstRawString *specifier, const ModuleImportPhase import_phase, const ImportAttributes *import_attributes, const Scanner::Location loc, const Scanner::Location specifier_loc, Zone *zone)
Definition modules.cc:58
void AddExport(const AstRawString *local_name, const AstRawString *export_name, const Scanner::Location loc, Zone *zone)
Definition modules.cc:90
void AddSpecialExport(const Entry *entry, Zone *zone)
Definition modules.h:208
const ZoneVector< const Entry * > & special_exports() const
Definition modules.h:192
T * New(Args &&... args)
Definition zone.h:114
ModuleImportPhase
#define DCHECK_LE(v1, v2)
Definition logging.h:490
#define DCHECK_NULL(val)
Definition logging.h:491
#define DCHECK_NOT_NULL(val)
Definition logging.h:492
#define DCHECK_LT(v1, v2)
Definition logging.h:489
#define V8_EXPORT_PRIVATE
Definition macros.h:460
DirectHandle< SourceTextModuleInfoEntry > Serialize(IsolateT *isolate) const
Definition modules.cc:171