1 // Copyright 2019 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_SOURCE_TEXT_MODULE_H_
6 #define V8_OBJECTS_SOURCE_TEXT_MODULE_H_
7 
8 #include "src/objects/module.h"
9 #include "src/objects/promise.h"
10 #include "src/zone/zone-containers.h"
11 #include "torque-generated/bit-fields.h"
12 
13 // Has to be the last include (doesn't have include guards):
14 #include "src/objects/object-macros.h"
15 
16 namespace v8 {
17 namespace internal {
18 
19 class UnorderedModuleSet;
20 
21 #include "torque-generated/src/objects/source-text-module-tq.inc"
22 
23 // The runtime representation of an ECMAScript Source Text Module Record.
24 // https://tc39.github.io/ecma262/#sec-source-text-module-records
25 class SourceTextModule
26     : public TorqueGeneratedSourceTextModule<SourceTextModule, Module> {
27  public:
28   NEVER_READ_ONLY_SPACE
29   DECL_VERIFIER(SourceTextModule)
30   DECL_PRINTER(SourceTextModule)
31 
32   // The shared function info in case {status} is not kEvaluating, kEvaluated or
33   // kErrored.
34   SharedFunctionInfo GetSharedFunctionInfo() const;
35 
36   Script GetScript() const;
37 
38   // Whether or not this module is an async module. Set during module creation
39   // and does not change afterwards.
40   DECL_BOOLEAN_ACCESSORS(async)
41 
42   // Get the SourceTextModuleInfo associated with the code.
43   inline SourceTextModuleInfo info() const;
44 
45   Cell GetCell(int cell_index);
46   static Handle<Object> LoadVariable(Isolate* isolate,
47                                      Handle<SourceTextModule> module,
48                                      int cell_index);
49   static void StoreVariable(Handle<SourceTextModule> module, int cell_index,
50                             Handle<Object> value);
51 
52   static int ImportIndex(int cell_index);
53   static int ExportIndex(int cell_index);
54 
55   // Used by builtins to fulfill or reject the promise associated
56   // with async SourceTextModules.
57   static void AsyncModuleExecutionFulfilled(Isolate* isolate,
58                                             Handle<SourceTextModule> module);
59   static void AsyncModuleExecutionRejected(Isolate* isolate,
60                                            Handle<SourceTextModule> module,
61                                            Handle<Object> exception);
62 
63   // Get the namespace object for [module_request] of [module].  If it doesn't
64   // exist yet, it is created.
65   static Handle<JSModuleNamespace> GetModuleNamespace(
66       Isolate* isolate, Handle<SourceTextModule> module, int module_request);
67 
68   // Get the import.meta object of [module].  If it doesn't exist yet, it is
69   // created and passed to the embedder callback for initialization.
70   V8_EXPORT_PRIVATE static MaybeHandle<JSObject> GetImportMeta(
71       Isolate* isolate, Handle<SourceTextModule> module);
72 
73   using BodyDescriptor =
74       SubclassBodyDescriptor<Module::BodyDescriptor,
75                              FixedBodyDescriptor<kCodeOffset, kSize, kSize>>;
76 
77   static constexpr unsigned kFirstAsyncEvaluatingOrdinal = 2;
78 
79  private:
80   friend class Factory;
81   friend class Module;
82 
83   struct AsyncEvaluatingOrdinalCompare;
84   using AsyncParentCompletionSet =
85       ZoneSet<Handle<SourceTextModule>, AsyncEvaluatingOrdinalCompare>;
86 
87   // Appends a tuple of module and generator to the async parent modules
88   // ArrayList.
89   inline static void AddAsyncParentModule(Isolate* isolate,
90                                           Handle<SourceTextModule> module,
91                                           Handle<SourceTextModule> parent);
92 
93   // Get the non-hole cycle root. Only valid when status >= kEvaluated.
94   inline Handle<SourceTextModule> GetCycleRoot(Isolate* isolate) const;
95 
96   // Returns a SourceTextModule, the
97   // ith parent in depth first traversal order of a given async child.
98   inline Handle<SourceTextModule> GetAsyncParentModule(Isolate* isolate,
99                                                        int index);
100 
101   // Returns the number of async parent modules for a given async child.
102   inline int AsyncParentModuleCount();
103 
104   inline bool IsAsyncEvaluating() const;
105 
106   inline bool HasPendingAsyncDependencies();
107   inline void IncrementPendingAsyncDependencies();
108   inline void DecrementPendingAsyncDependencies();
109 
110   // Bits for flags.
111   DEFINE_TORQUE_GENERATED_SOURCE_TEXT_MODULE_FLAGS()
112 
113   // async_evaluating_ordinal, top_level_capability, pending_async_dependencies,
114   // and async_parent_modules are used exclusively during evaluation of async
115   // modules and the modules which depend on them.
116   //
117   // If >1, this module is async and evaluating or currently evaluating an async
118   // child. The integer is an ordinal for when this module first started async
119   // evaluation and is used for sorting async parent modules when determining
120   // which parent module can start executing after an async evaluation
121   // completes.
122   //
123   // If 1, this module has finished async evaluating.
124   //
125   // If 0, this module is not async or has not been async evaluated.
126   static constexpr unsigned kNotAsyncEvaluated = 0;
127   static constexpr unsigned kAsyncEvaluateDidFinish = 1;
128   STATIC_ASSERT(kNotAsyncEvaluated < kAsyncEvaluateDidFinish);
129   STATIC_ASSERT(kAsyncEvaluateDidFinish < kFirstAsyncEvaluatingOrdinal);
130   STATIC_ASSERT(kMaxModuleAsyncEvaluatingOrdinal ==
131                 AsyncEvaluatingOrdinalBits::kMax);
132   DECL_PRIMITIVE_ACCESSORS(async_evaluating_ordinal, unsigned)
133 
134   // The parent modules of a given async dependency, use async_parent_modules()
135   // to retrieve the ArrayList representation.
136   DECL_ACCESSORS(async_parent_modules, ArrayList)
137 
138   // Helpers for Instantiate and Evaluate.
139   static void CreateExport(Isolate* isolate, Handle<SourceTextModule> module,
140                            int cell_index, Handle<FixedArray> names);
141   static void CreateIndirectExport(Isolate* isolate,
142                                    Handle<SourceTextModule> module,
143                                    Handle<String> name,
144                                    Handle<SourceTextModuleInfoEntry> entry);
145 
146   static V8_WARN_UNUSED_RESULT MaybeHandle<Cell> ResolveExport(
147       Isolate* isolate, Handle<SourceTextModule> module,
148       Handle<String> module_specifier, Handle<String> export_name,
149       MessageLocation loc, bool must_resolve, ResolveSet* resolve_set);
150   static V8_WARN_UNUSED_RESULT MaybeHandle<Cell> ResolveImport(
151       Isolate* isolate, Handle<SourceTextModule> module, Handle<String> name,
152       int module_request_index, MessageLocation loc, bool must_resolve,
153       ResolveSet* resolve_set);
154 
155   static V8_WARN_UNUSED_RESULT MaybeHandle<Cell> ResolveExportUsingStarExports(
156       Isolate* isolate, Handle<SourceTextModule> module,
157       Handle<String> module_specifier, Handle<String> export_name,
158       MessageLocation loc, bool must_resolve, ResolveSet* resolve_set);
159 
160   static V8_WARN_UNUSED_RESULT bool PrepareInstantiate(
161       Isolate* isolate, Handle<SourceTextModule> module,
162       v8::Local<v8::Context> context,
163       v8::Module::ResolveModuleCallback callback,
164       Module::DeprecatedResolveCallback callback_without_import_assertions);
165   static V8_WARN_UNUSED_RESULT bool FinishInstantiate(
166       Isolate* isolate, Handle<SourceTextModule> module,
167       ZoneForwardList<Handle<SourceTextModule>>* stack, unsigned* dfs_index,
168       Zone* zone);
169   static V8_WARN_UNUSED_RESULT bool RunInitializationCode(
170       Isolate* isolate, Handle<SourceTextModule> module);
171 
172   static void FetchStarExports(Isolate* isolate,
173                                Handle<SourceTextModule> module, Zone* zone,
174                                UnorderedModuleSet* visited);
175 
176   static void GatherAsyncParentCompletions(Isolate* isolate, Zone* zone,
177                                            Handle<SourceTextModule> start,
178                                            AsyncParentCompletionSet* exec_list);
179 
180   // Implementation of spec concrete method Evaluate.
181   static V8_WARN_UNUSED_RESULT MaybeHandle<Object> EvaluateMaybeAsync(
182       Isolate* isolate, Handle<SourceTextModule> module);
183 
184   // Continued implementation of spec concrete method Evaluate.
185   static V8_WARN_UNUSED_RESULT MaybeHandle<Object> Evaluate(
186       Isolate* isolate, Handle<SourceTextModule> module);
187 
188   // Implementation of spec abstract operation InnerModuleEvaluation.
189   static V8_WARN_UNUSED_RESULT MaybeHandle<Object> InnerModuleEvaluation(
190       Isolate* isolate, Handle<SourceTextModule> module,
191       ZoneForwardList<Handle<SourceTextModule>>* stack, unsigned* dfs_index);
192 
193   static V8_WARN_UNUSED_RESULT bool MaybeTransitionComponent(
194       Isolate* isolate, Handle<SourceTextModule> module,
195       ZoneForwardList<Handle<SourceTextModule>>* stack, Status new_status);
196 
197   // Implementation of spec ExecuteModule is broken up into
198   // InnerExecuteAsyncModule for asynchronous modules and ExecuteModule
199   // for synchronous modules.
200   static V8_WARN_UNUSED_RESULT MaybeHandle<Object> InnerExecuteAsyncModule(
201       Isolate* isolate, Handle<SourceTextModule> module,
202       Handle<JSPromise> capability);
203 
204   static V8_WARN_UNUSED_RESULT MaybeHandle<Object> ExecuteModule(
205       Isolate* isolate, Handle<SourceTextModule> module);
206 
207   // Implementation of spec ExecuteAsyncModule.
208   static void ExecuteAsyncModule(Isolate* isolate,
209                                  Handle<SourceTextModule> module);
210 
211   static void Reset(Isolate* isolate, Handle<SourceTextModule> module);
212 
213   TQ_OBJECT_CONSTRUCTORS(SourceTextModule)
214 };
215 
216 // SourceTextModuleInfo is to SourceTextModuleDescriptor what ScopeInfo is to
217 // Scope.
218 class SourceTextModuleInfo : public FixedArray {
219  public:
220   DECL_CAST(SourceTextModuleInfo)
221 
222   template <typename IsolateT>
223   static Handle<SourceTextModuleInfo> New(IsolateT* isolate, Zone* zone,
224                                           SourceTextModuleDescriptor* descr);
225 
226   inline FixedArray module_requests() const;
227   inline FixedArray special_exports() const;
228   inline FixedArray regular_exports() const;
229   inline FixedArray regular_imports() const;
230   inline FixedArray namespace_imports() const;
231 
232   // Accessors for [regular_exports].
233   int RegularExportCount() const;
234   String RegularExportLocalName(int i) const;
235   int RegularExportCellIndex(int i) const;
236   FixedArray RegularExportExportNames(int i) const;
237 
238 #ifdef DEBUG
239   inline bool Equals(SourceTextModuleInfo other) const;
240 #endif
241 
242  private:
243   template <typename Impl>
244   friend class FactoryBase;
245   friend class SourceTextModuleDescriptor;
246   enum {
247     kModuleRequestsIndex,
248     kSpecialExportsIndex,
249     kRegularExportsIndex,
250     kNamespaceImportsIndex,
251     kRegularImportsIndex,
252     kLength
253   };
254   enum {
255     kRegularExportLocalNameOffset,
256     kRegularExportCellIndexOffset,
257     kRegularExportExportNamesOffset,
258     kRegularExportLength
259   };
260 
261   OBJECT_CONSTRUCTORS(SourceTextModuleInfo, FixedArray);
262 };
263 
264 class ModuleRequest
265     : public TorqueGeneratedModuleRequest<ModuleRequest, Struct> {
266  public:
267   NEVER_READ_ONLY_SPACE
268   DECL_VERIFIER(ModuleRequest)
269 
270   template <typename IsolateT>
271   static Handle<ModuleRequest> New(IsolateT* isolate, Handle<String> specifier,
272                                    Handle<FixedArray> import_assertions,
273                                    int position);
274 
275   // The number of entries in the import_assertions FixedArray that are used for
276   // a single assertion.
277   static const size_t kAssertionEntrySize = 3;
278 
279   TQ_OBJECT_CONSTRUCTORS(ModuleRequest)
280 };
281 
282 class SourceTextModuleInfoEntry
283     : public TorqueGeneratedSourceTextModuleInfoEntry<SourceTextModuleInfoEntry,
284                                                       Struct> {
285  public:
286   DECL_VERIFIER(SourceTextModuleInfoEntry)
287 
288   template <typename IsolateT>
289   static Handle<SourceTextModuleInfoEntry> New(
290       IsolateT* isolate, Handle<PrimitiveHeapObject> export_name,
291       Handle<PrimitiveHeapObject> local_name,
292       Handle<PrimitiveHeapObject> import_name, int module_request,
293       int cell_index, int beg_pos, int end_pos);
294 
295   TQ_OBJECT_CONSTRUCTORS(SourceTextModuleInfoEntry)
296 };
297 
298 }  // namespace internal
299 }  // namespace v8
300 
301 #include "src/objects/object-macros-undef.h"
302 
303 #endif  // V8_OBJECTS_SOURCE_TEXT_MODULE_H_
304