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