• 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 "include/v8-script.h"
9 #include "src/objects/fixed-array.h"
10 #include "src/objects/js-objects.h"
11 #include "src/objects/objects.h"
12 #include "src/objects/struct.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 TorqueGeneratedModule<Module, HeapObject> {
36  public:
37   NEVER_READ_ONLY_SPACE
38   DECL_VERIFIER(Module)
39   DECL_PRINTER(Module)
40 
41   enum Status {
42     // Order matters!
43     kUnlinked,
44     kPreLinking,
45     kLinking,
46     kLinked,
47     kEvaluating,
48     kEvaluatingAsync,
49     kEvaluated,
50     kErrored
51   };
52 
53   // The exception in the case {status} is kErrored.
54   Object GetException();
55 
56   // Returns if this module or any transitively requested module is [[Async]],
57   // i.e. has a top-level await.
58   V8_WARN_UNUSED_RESULT bool IsGraphAsync(Isolate* isolate) const;
59 
60   // While deprecating v8::ResolveCallback in v8.h we still need to support the
61   // version of the API that uses it, but we can't directly reference the
62   // deprecated version because of the enusing build warnings.  So, we declare
63   // this matching typedef for temporary internal use.
64   // TODO(v8:10958) Delete this typedef and all references to it once
65   // v8::ResolveCallback is removed.
66   typedef MaybeLocal<v8::Module> (*DeprecatedResolveCallback)(
67       Local<v8::Context> context, Local<v8::String> specifier,
68       Local<v8::Module> referrer);
69 
70   // Implementation of spec operation ModuleDeclarationInstantiation.
71   // Returns false if an exception occurred during instantiation, true
72   // otherwise. (In the case where the callback throws an exception, that
73   // exception is propagated.)
74   static V8_WARN_UNUSED_RESULT bool Instantiate(
75       Isolate* isolate, Handle<Module> module, v8::Local<v8::Context> context,
76       v8::Module::ResolveModuleCallback callback,
77       DeprecatedResolveCallback callback_without_import_assertions);
78 
79   // Implementation of spec operation ModuleEvaluation.
80   static V8_WARN_UNUSED_RESULT MaybeHandle<Object> Evaluate(
81       Isolate* isolate, Handle<Module> module);
82 
83   // Get the namespace object for [module].  If it doesn't exist yet, it is
84   // created.
85   static Handle<JSModuleNamespace> GetModuleNamespace(Isolate* isolate,
86                                                       Handle<Module> module);
87 
88   using BodyDescriptor =
89       FixedBodyDescriptor<kExportsOffset, kHeaderSize, kHeaderSize>;
90 
91   struct Hash;
92 
93  protected:
94   friend class Factory;
95 
96   // The [must_resolve] argument indicates whether or not an exception should be
97   // thrown in case the module does not provide an export named [name]
98   // (including when a cycle is detected).  An exception is always thrown in the
99   // case of conflicting star exports.
100   //
101   // If [must_resolve] is true, a null result indicates an exception. If
102   // [must_resolve] is false, a null result may or may not indicate an
103   // exception (so check manually!).
104   class ResolveSet;
105   static V8_WARN_UNUSED_RESULT MaybeHandle<Cell> ResolveExport(
106       Isolate* isolate, Handle<Module> module, Handle<String> module_specifier,
107       Handle<String> export_name, MessageLocation loc, bool must_resolve,
108       ResolveSet* resolve_set);
109 
110   static V8_WARN_UNUSED_RESULT bool PrepareInstantiate(
111       Isolate* isolate, Handle<Module> module, v8::Local<v8::Context> context,
112       v8::Module::ResolveModuleCallback callback,
113       DeprecatedResolveCallback callback_without_import_assertions);
114   static V8_WARN_UNUSED_RESULT bool FinishInstantiate(
115       Isolate* isolate, Handle<Module> module,
116       ZoneForwardList<Handle<SourceTextModule>>* stack, unsigned* dfs_index,
117       Zone* zone);
118 
119   // Set module's status back to kUnlinked and reset other internal state.
120   // This is used when instantiation fails.
121   static void Reset(Isolate* isolate, Handle<Module> module);
122   static void ResetGraph(Isolate* isolate, Handle<Module> module);
123 
124   // To set status to kErrored, RecordError or RecordErrorUsingPendingException
125   // should be used.
126   void SetStatus(Status status);
127   static void RecordErrorUsingPendingException(Isolate* isolate,
128                                                Handle<Module>);
129   static void RecordError(Isolate* isolate, Handle<Module> module,
130                           Handle<Object> error);
131 
132   TQ_OBJECT_CONSTRUCTORS(Module)
133 };
134 
135 // When importing a module namespace (import * as foo from "bar"), a
136 // JSModuleNamespace object (representing module "bar") is created and bound to
137 // the declared variable (foo).  A module can have at most one namespace object.
138 class JSModuleNamespace
139     : public TorqueGeneratedJSModuleNamespace<JSModuleNamespace,
140                                               JSSpecialObject> {
141  public:
142   DECL_PRINTER(JSModuleNamespace)
143 
144   // Retrieve the value exported by [module] under the given [name]. If there is
145   // no such export, return Just(undefined). If the export is uninitialized,
146   // schedule an exception and return Nothing.
147   V8_WARN_UNUSED_RESULT MaybeHandle<Object> GetExport(Isolate* isolate,
148                                                       Handle<String> name);
149 
150   // Return the (constant) property attributes for the referenced property,
151   // which is assumed to correspond to an export. If the export is
152   // uninitialized, schedule an exception and return Nothing.
153   static V8_WARN_UNUSED_RESULT Maybe<PropertyAttributes> GetPropertyAttributes(
154       LookupIterator* it);
155 
156   static V8_WARN_UNUSED_RESULT Maybe<bool> DefineOwnProperty(
157       Isolate* isolate, Handle<JSModuleNamespace> o, Handle<Object> key,
158       PropertyDescriptor* desc, Maybe<ShouldThrow> should_throw);
159 
160   // In-object fields.
161   enum {
162     kToStringTagFieldIndex,
163     kInObjectFieldCount,
164   };
165 
166   // We need to include in-object fields
167   // TODO(v8:8944): improve handling of in-object fields
168   static constexpr int kSize =
169       kHeaderSize + (kTaggedSize * kInObjectFieldCount);
170 
171   TQ_OBJECT_CONSTRUCTORS(JSModuleNamespace)
172 };
173 
174 class ScriptOrModule
175     : public TorqueGeneratedScriptOrModule<ScriptOrModule, Struct> {
176  public:
177   DECL_PRINTER(ScriptOrModule)
178 
179   using BodyDescriptor = StructBodyDescriptor;
180 
181   TQ_OBJECT_CONSTRUCTORS(ScriptOrModule)
182 };
183 
184 }  // namespace internal
185 }  // namespace v8
186 
187 #include "src/objects/object-macros-undef.h"
188 
189 #endif  // V8_OBJECTS_MODULE_H_
190