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