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/fixed-array.h" 9 #include "src/objects/js-objects.h" 10 #include "src/objects/objects.h" 11 #include "src/objects/struct.h" 12 #include "torque-generated/field-offsets.h" 13 14 // Has to be the last include (doesn't have include guards): 15 #include "src/objects/object-macros.h" 16 17 namespace v8 { 18 namespace internal { 19 20 template <typename T> 21 class Handle; 22 class Isolate; 23 class JSModuleNamespace; 24 class SourceTextModuleDescriptor; 25 class SourceTextModuleInfo; 26 class SourceTextModuleInfoEntry; 27 class String; 28 class Zone; 29 30 #include "torque-generated/src/objects/module-tq.inc" 31 32 // Module is the base class for ECMAScript module types, roughly corresponding 33 // to Abstract Module Record. 34 // https://tc39.github.io/ecma262/#sec-abstract-module-records 35 class Module : public HeapObject { 36 public: 37 NEVER_READ_ONLY_SPACE 38 DECL_CAST(Module) 39 DECL_VERIFIER(Module) 40 DECL_PRINTER(Module) 41 42 // The complete export table, mapping an export name to its cell. 43 DECL_ACCESSORS(exports, ObjectHashTable) 44 45 // Hash for this object (a random non-zero Smi). 46 DECL_INT_ACCESSORS(hash) 47 48 // Status. 49 DECL_INT_ACCESSORS(status) 50 enum Status { 51 // Order matters! 52 kUninstantiated, 53 kPreInstantiating, 54 kInstantiating, 55 kInstantiated, 56 kEvaluating, 57 kEvaluated, 58 kErrored 59 }; 60 61 // The namespace object (or undefined). 62 DECL_ACCESSORS(module_namespace, HeapObject) 63 64 // The exception in the case {status} is kErrored. 65 Object GetException(); 66 DECL_ACCESSORS(exception, Object) 67 68 // Returns if this module or any transitively requested module is [[Async]], 69 // i.e. has a top-level await. 70 V8_WARN_UNUSED_RESULT bool IsGraphAsync(Isolate* isolate) const; 71 72 // Implementation of spec operation ModuleDeclarationInstantiation. 73 // Returns false if an exception occurred during instantiation, true 74 // otherwise. (In the case where the callback throws an exception, that 75 // exception is propagated.) 76 static V8_WARN_UNUSED_RESULT bool Instantiate( 77 Isolate* isolate, Handle<Module> module, v8::Local<v8::Context> context, 78 v8::Module::ResolveCallback callback); 79 80 // Implementation of spec operation ModuleEvaluation. 81 static V8_WARN_UNUSED_RESULT MaybeHandle<Object> Evaluate( 82 Isolate* isolate, Handle<Module> module); 83 84 // Get the namespace object for [module]. If it doesn't exist yet, it is 85 // created. 86 static Handle<JSModuleNamespace> GetModuleNamespace(Isolate* isolate, 87 Handle<Module> module); 88 89 // Layout description. 90 DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, 91 TORQUE_GENERATED_MODULE_FIELDS) 92 93 using BodyDescriptor = 94 FixedBodyDescriptor<kExportsOffset, kHeaderSize, kHeaderSize>; 95 96 struct Hash; 97 98 protected: 99 friend class Factory; 100 101 // The [must_resolve] argument indicates whether or not an exception should be 102 // thrown in case the module does not provide an export named [name] 103 // (including when a cycle is detected). An exception is always thrown in the 104 // case of conflicting star exports. 105 // 106 // If [must_resolve] is true, a null result indicates an exception. If 107 // [must_resolve] is false, a null result may or may not indicate an 108 // exception (so check manually!). 109 class ResolveSet; 110 static V8_WARN_UNUSED_RESULT MaybeHandle<Cell> ResolveExport( 111 Isolate* isolate, Handle<Module> module, Handle<String> module_specifier, 112 Handle<String> export_name, MessageLocation loc, bool must_resolve, 113 ResolveSet* resolve_set); 114 115 static V8_WARN_UNUSED_RESULT bool PrepareInstantiate( 116 Isolate* isolate, Handle<Module> module, v8::Local<v8::Context> context, 117 v8::Module::ResolveCallback callback); 118 static V8_WARN_UNUSED_RESULT bool FinishInstantiate( 119 Isolate* isolate, Handle<Module> module, 120 ZoneForwardList<Handle<SourceTextModule>>* stack, unsigned* dfs_index, 121 Zone* zone); 122 123 static V8_WARN_UNUSED_RESULT MaybeHandle<Object> InnerEvaluate( 124 Isolate* isolate, Handle<Module> module); 125 126 // Set module's status back to kUninstantiated and reset other internal state. 127 // This is used when instantiation fails. 128 static void Reset(Isolate* isolate, Handle<Module> module); 129 static void ResetGraph(Isolate* isolate, Handle<Module> module); 130 131 // To set status to kErrored, RecordError or RecordErrorUsingPendingException 132 // should be used. 133 void SetStatus(Status status); 134 static void RecordErrorUsingPendingException(Isolate* isolate, 135 Handle<Module>); 136 static void RecordError(Isolate* isolate, Handle<Module> module, 137 Handle<Object> error); 138 139 OBJECT_CONSTRUCTORS(Module, HeapObject); 140 }; 141 142 // When importing a module namespace (import * as foo from "bar"), a 143 // JSModuleNamespace object (representing module "bar") is created and bound to 144 // the declared variable (foo). A module can have at most one namespace object. 145 class JSModuleNamespace 146 : public TorqueGeneratedJSModuleNamespace<JSModuleNamespace, 147 JSSpecialObject> { 148 public: 149 DECL_PRINTER(JSModuleNamespace) 150 151 // Retrieve the value exported by [module] under the given [name]. If there is 152 // no such export, return Just(undefined). If the export is uninitialized, 153 // schedule an exception and return Nothing. 154 V8_WARN_UNUSED_RESULT MaybeHandle<Object> GetExport(Isolate* isolate, 155 Handle<String> name); 156 157 // Return the (constant) property attributes for the referenced property, 158 // which is assumed to correspond to an export. If the export is 159 // uninitialized, schedule an exception and return Nothing. 160 static V8_WARN_UNUSED_RESULT Maybe<PropertyAttributes> GetPropertyAttributes( 161 LookupIterator* it); 162 163 // In-object fields. 164 enum { 165 kToStringTagFieldIndex, 166 kInObjectFieldCount, 167 }; 168 169 // We need to include in-object fields 170 // TODO(v8:8944): improve handling of in-object fields 171 static constexpr int kSize = 172 kHeaderSize + (kTaggedSize * kInObjectFieldCount); 173 174 TQ_OBJECT_CONSTRUCTORS(JSModuleNamespace) 175 }; 176 177 } // namespace internal 178 } // namespace v8 179 180 #include "src/objects/object-macros-undef.h" 181 182 #endif // V8_OBJECTS_MODULE_H_ 183