• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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