V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
module.h
1 // Copyright 2017 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_OBJECTS_MODULE_H_
6 #define V8_OBJECTS_MODULE_H_
7 
8 #include "src/objects.h"
9 #include "src/objects/fixed-array.h"
10 #include "src/objects/js-objects.h"
11 
12 // Has to be the last include (doesn't have include guards):
13 #include "src/objects/object-macros.h"
14 
15 namespace v8 {
16 namespace internal {
17 
18 template <typename T>
19 class Handle;
20 class Isolate;
21 class JSModuleNamespace;
22 class ModuleDescriptor;
23 class ModuleInfo;
24 class ModuleInfoEntry;
25 class String;
26 class Zone;
27 
28 // The runtime representation of an ECMAScript module.
29 class Module : public Struct, public NeverReadOnlySpaceObject {
30  public:
31  DECL_CAST(Module)
32  DECL_VERIFIER(Module)
33  DECL_PRINTER(Module)
34 
35  // The code representing this module, or an abstraction thereof.
36  // This is either a SharedFunctionInfo, a JSFunction, a JSGeneratorObject, or
37  // a ModuleInfo, depending on the state (status) the module is in. See
38  // Module::ModuleVerify() for the precise invariant.
39  DECL_ACCESSORS(code, Object)
40 
41  // Arrays of cells corresponding to regular exports and regular imports.
42  // A cell's position in the array is determined by the cell index of the
43  // associated module entry (which coincides with the variable index of the
44  // associated variable).
45  DECL_ACCESSORS2(regular_exports, FixedArray)
46  DECL_ACCESSORS2(regular_imports, FixedArray)
47 
48  // The complete export table, mapping an export name to its cell.
49  // TODO(neis): We may want to remove the regular exports from the table.
50  DECL_ACCESSORS2(exports, ObjectHashTable)
51 
52  // Hash for this object (a random non-zero Smi).
53  DECL_INT_ACCESSORS(hash)
54 
55  // Status.
56  DECL_INT_ACCESSORS(status)
57  enum Status {
58  // Order matters!
59  kUninstantiated,
60  kPreInstantiating,
61  kInstantiating,
62  kInstantiated,
63  kEvaluating,
64  kEvaluated,
65  kErrored
66  };
67 
68  // The exception in the case {status} is kErrored.
69  Object* GetException();
70 
71  // The shared function info in case {status} is not kEvaluating, kEvaluated or
72  // kErrored.
73  SharedFunctionInfo* GetSharedFunctionInfo() const;
74 
75  // The namespace object (or undefined).
76  DECL_ACCESSORS(module_namespace, HeapObject)
77 
78  // Modules imported or re-exported by this module.
79  // Corresponds 1-to-1 to the module specifier strings in
80  // ModuleInfo::module_requests.
81  DECL_ACCESSORS2(requested_modules, FixedArray)
82 
83  // [script]: Script from which the module originates.
84  DECL_ACCESSORS(script, Script)
85 
86  // The value of import.meta inside of this module.
87  // Lazily initialized on first access. It's the hole before first access and
88  // a JSObject afterwards.
89  DECL_ACCESSORS(import_meta, Object)
90 
91  // Get the ModuleInfo associated with the code.
92  inline ModuleInfo info() const;
93 
94  // Implementation of spec operation ModuleDeclarationInstantiation.
95  // Returns false if an exception occurred during instantiation, true
96  // otherwise. (In the case where the callback throws an exception, that
97  // exception is propagated.)
98  static V8_WARN_UNUSED_RESULT bool Instantiate(
99  Isolate* isolate, Handle<Module> module, v8::Local<v8::Context> context,
100  v8::Module::ResolveCallback callback);
101 
102  // Implementation of spec operation ModuleEvaluation.
103  static V8_WARN_UNUSED_RESULT MaybeHandle<Object> Evaluate(
104  Isolate* isolate, Handle<Module> module);
105 
106  Cell* GetCell(int cell_index);
107  static Handle<Object> LoadVariable(Isolate* isolate, Handle<Module> module,
108  int cell_index);
109  static void StoreVariable(Handle<Module> module, int cell_index,
110  Handle<Object> value);
111 
112  static int ImportIndex(int cell_index);
113  static int ExportIndex(int cell_index);
114 
115  // Get the namespace object for [module_request] of [module]. If it doesn't
116  // exist yet, it is created.
117  static Handle<JSModuleNamespace> GetModuleNamespace(Isolate* isolate,
118  Handle<Module> module,
119  int module_request);
120 
121  // Get the namespace object for [module]. If it doesn't exist yet, it is
122  // created.
123  static Handle<JSModuleNamespace> GetModuleNamespace(Isolate* isolate,
124  Handle<Module> module);
125 
126  static const int kCodeOffset = HeapObject::kHeaderSize;
127  static const int kExportsOffset = kCodeOffset + kPointerSize;
128  static const int kRegularExportsOffset = kExportsOffset + kPointerSize;
129  static const int kRegularImportsOffset = kRegularExportsOffset + kPointerSize;
130  static const int kHashOffset = kRegularImportsOffset + kPointerSize;
131  static const int kModuleNamespaceOffset = kHashOffset + kPointerSize;
132  static const int kRequestedModulesOffset =
133  kModuleNamespaceOffset + kPointerSize;
134  static const int kStatusOffset = kRequestedModulesOffset + kPointerSize;
135  static const int kDfsIndexOffset = kStatusOffset + kPointerSize;
136  static const int kDfsAncestorIndexOffset = kDfsIndexOffset + kPointerSize;
137  static const int kExceptionOffset = kDfsAncestorIndexOffset + kPointerSize;
138  static const int kScriptOffset = kExceptionOffset + kPointerSize;
139  static const int kImportMetaOffset = kScriptOffset + kPointerSize;
140  static const int kSize = kImportMetaOffset + kPointerSize;
141 
142  private:
143  friend class Factory;
144 
145  DECL_ACCESSORS(exception, Object)
146 
147  // TODO(neis): Don't store those in the module object?
148  DECL_INT_ACCESSORS(dfs_index)
149  DECL_INT_ACCESSORS(dfs_ancestor_index)
150 
151  // Helpers for Instantiate and Evaluate.
152 
153  static void CreateExport(Isolate* isolate, Handle<Module> module,
154  int cell_index, Handle<FixedArray> names);
155  static void CreateIndirectExport(Isolate* isolate, Handle<Module> module,
156  Handle<String> name,
158 
159  // The [must_resolve] argument indicates whether or not an exception should be
160  // thrown in case the module does not provide an export named [name]
161  // (including when a cycle is detected). An exception is always thrown in the
162  // case of conflicting star exports.
163  //
164  // If [must_resolve] is true, a null result indicates an exception. If
165  // [must_resolve] is false, a null result may or may not indicate an
166  // exception (so check manually!).
167  class ResolveSet;
168  static V8_WARN_UNUSED_RESULT MaybeHandle<Cell> ResolveExport(
169  Isolate* isolate, Handle<Module> module, Handle<String> module_specifier,
170  Handle<String> export_name, MessageLocation loc, bool must_resolve,
171  ResolveSet* resolve_set);
172  static V8_WARN_UNUSED_RESULT MaybeHandle<Cell> ResolveImport(
173  Isolate* isolate, Handle<Module> module, Handle<String> name,
174  int module_request, MessageLocation loc, bool must_resolve,
175  ResolveSet* resolve_set);
176 
177  static V8_WARN_UNUSED_RESULT MaybeHandle<Cell> ResolveExportUsingStarExports(
178  Isolate* isolate, Handle<Module> module, Handle<String> module_specifier,
179  Handle<String> export_name, MessageLocation loc, bool must_resolve,
180  ResolveSet* resolve_set);
181 
182  static V8_WARN_UNUSED_RESULT bool PrepareInstantiate(
183  Isolate* isolate, Handle<Module> module, v8::Local<v8::Context> context,
184  v8::Module::ResolveCallback callback);
185  static V8_WARN_UNUSED_RESULT bool FinishInstantiate(
186  Isolate* isolate, Handle<Module> module,
187  ZoneForwardList<Handle<Module>>* stack, unsigned* dfs_index, Zone* zone);
188  static V8_WARN_UNUSED_RESULT bool RunInitializationCode(
189  Isolate* isolate, Handle<Module> module);
190 
191  static V8_WARN_UNUSED_RESULT MaybeHandle<Object> Evaluate(
192  Isolate* isolate, Handle<Module> module,
193  ZoneForwardList<Handle<Module>>* stack, unsigned* dfs_index);
194 
195  static V8_WARN_UNUSED_RESULT bool MaybeTransitionComponent(
196  Isolate* isolate, Handle<Module> module,
197  ZoneForwardList<Handle<Module>>* stack, Status new_status);
198 
199  // Set module's status back to kUninstantiated and reset other internal state.
200  // This is used when instantiation fails.
201  static void Reset(Isolate* isolate, Handle<Module> module);
202  static void ResetGraph(Isolate* isolate, Handle<Module> module);
203 
204  // To set status to kErrored, RecordError should be used.
205  void SetStatus(Status status);
206  void RecordError(Isolate* isolate);
207 
208 #ifdef DEBUG
209  // For --trace-module-status.
210  void PrintStatusTransition(Status new_status);
211 #endif // DEBUG
212 
213  DISALLOW_IMPLICIT_CONSTRUCTORS(Module);
214 };
215 
216 // When importing a module namespace (import * as foo from "bar"), a
217 // JSModuleNamespace object (representing module "bar") is created and bound to
218 // the declared variable (foo). A module can have at most one namespace object.
219 class JSModuleNamespace : public JSObject {
220  public:
221  DECL_CAST(JSModuleNamespace)
222  DECL_PRINTER(JSModuleNamespace)
223  DECL_VERIFIER(JSModuleNamespace)
224 
225  // The actual module whose namespace is being represented.
226  DECL_ACCESSORS(module, Module)
227 
228  // Retrieve the value exported by [module] under the given [name]. If there is
229  // no such export, return Just(undefined). If the export is uninitialized,
230  // schedule an exception and return Nothing.
231  V8_WARN_UNUSED_RESULT MaybeHandle<Object> GetExport(Isolate* isolate,
232  Handle<String> name);
233 
234  // Return the (constant) property attributes for the referenced property,
235  // which is assumed to correspond to an export. If the export is
236  // uninitialized, schedule an exception and return Nothing.
237  static V8_WARN_UNUSED_RESULT Maybe<PropertyAttributes> GetPropertyAttributes(
238  LookupIterator* it);
239 
240  // In-object fields.
241  enum {
242  kToStringTagFieldIndex,
243  kInObjectFieldCount,
244  };
245 
246  static const int kModuleOffset = JSObject::kHeaderSize;
247  static const int kHeaderSize = kModuleOffset + kPointerSize;
248 
249  static const int kSize = kHeaderSize + kPointerSize * kInObjectFieldCount;
250 
251  private:
252  DISALLOW_IMPLICIT_CONSTRUCTORS(JSModuleNamespace);
253 };
254 
255 // ModuleInfo is to ModuleDescriptor what ScopeInfo is to Scope.
256 class ModuleInfo : public FixedArray {
257  public:
258  DECL_CAST2(ModuleInfo)
259 
260  static Handle<ModuleInfo> New(Isolate* isolate, Zone* zone,
261  ModuleDescriptor* descr);
262 
263  inline FixedArray module_requests() const;
264  inline FixedArray special_exports() const;
265  inline FixedArray regular_exports() const;
266  inline FixedArray regular_imports() const;
267  inline FixedArray namespace_imports() const;
268  inline FixedArray module_request_positions() const;
269 
270  // Accessors for [regular_exports].
271  int RegularExportCount() const;
272  String RegularExportLocalName(int i) const;
273  int RegularExportCellIndex(int i) const;
274  FixedArray RegularExportExportNames(int i) const;
275 
276 #ifdef DEBUG
277  inline bool Equals(ModuleInfo other) const;
278 #endif
279 
280  private:
281  friend class Factory;
282  friend class ModuleDescriptor;
283  enum {
284  kModuleRequestsIndex,
285  kSpecialExportsIndex,
286  kRegularExportsIndex,
287  kNamespaceImportsIndex,
288  kRegularImportsIndex,
289  kModuleRequestPositionsIndex,
290  kLength
291  };
292  enum {
293  kRegularExportLocalNameOffset,
294  kRegularExportCellIndexOffset,
295  kRegularExportExportNamesOffset,
296  kRegularExportLength
297  };
298  OBJECT_CONSTRUCTORS(ModuleInfo, FixedArray);
299 };
300 
301 class ModuleInfoEntry : public Struct {
302  public:
303  DECL_CAST(ModuleInfoEntry)
304  DECL_PRINTER(ModuleInfoEntry)
305  DECL_VERIFIER(ModuleInfoEntry)
306 
307  DECL_ACCESSORS(export_name, Object)
308  DECL_ACCESSORS(local_name, Object)
309  DECL_ACCESSORS(import_name, Object)
310  DECL_INT_ACCESSORS(module_request)
311  DECL_INT_ACCESSORS(cell_index)
312  DECL_INT_ACCESSORS(beg_pos)
313  DECL_INT_ACCESSORS(end_pos)
314 
315  static Handle<ModuleInfoEntry> New(Isolate* isolate,
316  Handle<Object> export_name,
317  Handle<Object> local_name,
318  Handle<Object> import_name,
319  int module_request, int cell_index,
320  int beg_pos, int end_pos);
321 
322  static const int kExportNameOffset = HeapObject::kHeaderSize;
323  static const int kLocalNameOffset = kExportNameOffset + kPointerSize;
324  static const int kImportNameOffset = kLocalNameOffset + kPointerSize;
325  static const int kModuleRequestOffset = kImportNameOffset + kPointerSize;
326  static const int kCellIndexOffset = kModuleRequestOffset + kPointerSize;
327  static const int kBegPosOffset = kCellIndexOffset + kPointerSize;
328  static const int kEndPosOffset = kBegPosOffset + kPointerSize;
329  static const int kSize = kEndPosOffset + kPointerSize;
330 
331  private:
332  DISALLOW_IMPLICIT_CONSTRUCTORS(ModuleInfoEntry);
333 };
334 
335 } // namespace internal
336 } // namespace v8
337 
338 #include "src/objects/object-macros-undef.h"
339 
340 #endif // V8_OBJECTS_MODULE_H_
Definition: v8.h:56
Definition: libplatform.h:13