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