module.h 6.63 KB
Newer Older
1 2 3 4 5 6 7
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_OBJECTS_MODULE_H_
#define V8_OBJECTS_MODULE_H_

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 15 16 17 18 19 20 21 22 23

// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"

namespace v8 {
namespace internal {

template <typename T>
class Handle;
class Isolate;
class JSModuleNamespace;
24 25 26
class SourceTextModuleDescriptor;
class SourceTextModuleInfo;
class SourceTextModuleInfoEntry;
27 28 29
class String;
class Zone;

30 31
#include "torque-generated/src/objects/module-tq.inc"

32 33 34
// Module is the base class for ECMAScript module types, roughly corresponding
// to Abstract Module Record.
// 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 40 41 42
  DECL_PRINTER(Module)

  enum Status {
    // Order matters!
43 44 45 46
    kUnlinked,
    kPreLinking,
    kLinking,
    kLinked,
47
    kEvaluating,
48
    kEvaluatingAsync,
49 50 51 52
    kEvaluated,
    kErrored
  };

53 54
  // The exception in the case {status} is kErrored.
  Object GetException();
55

56 57
  // Returns if this module or any transitively requested module is [[Async]],
  // i.e. has a top-level await.
58
  V8_WARN_UNUSED_RESULT bool IsGraphAsync(Isolate* isolate) const;
59

60 61 62 63 64 65 66 67 68 69
  // While deprecating v8::ResolveCallback in v8.h we still need to support the
  // version of the API that uses it, but we can't directly reference the
  // deprecated version because of the enusing build warnings.  So, we declare
  // this matching typedef for temporary internal use.
  // TODO(v8:10958) Delete this typedef and all references to it once
  // v8::ResolveCallback is removed.
  typedef MaybeLocal<v8::Module> (*DeprecatedResolveCallback)(
      Local<v8::Context> context, Local<v8::String> specifier,
      Local<v8::Module> referrer);

70 71 72 73
  // Implementation of spec operation ModuleDeclarationInstantiation.
  // Returns false if an exception occurred during instantiation, true
  // otherwise. (In the case where the callback throws an exception, that
  // exception is propagated.)
74
  static V8_WARN_UNUSED_RESULT bool Instantiate(
75
      Isolate* isolate, Handle<Module> module, v8::Local<v8::Context> context,
76 77
      v8::Module::ResolveModuleCallback callback,
      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 84

  // Get the namespace object for [module].  If it doesn't exist yet, it is
  // created.
85 86
  static Handle<JSModuleNamespace> GetModuleNamespace(Isolate* isolate,
                                                      Handle<Module> module);
87

88 89
  using BodyDescriptor =
      FixedBodyDescriptor<kExportsOffset, kHeaderSize, kHeaderSize>;
90

91 92
  struct Hash;

93 94
 protected:
  friend class Factory;
95 96 97 98 99 100 101 102 103 104

  // The [must_resolve] argument indicates whether or not an exception should be
  // thrown in case the module does not provide an export named [name]
  // (including when a cycle is detected).  An exception is always thrown in the
  // case of conflicting star exports.
  //
  // If [must_resolve] is true, a null result indicates an exception. If
  // [must_resolve] is false, a null result may or may not indicate an
  // exception (so check manually!).
  class ResolveSet;
105
  static V8_WARN_UNUSED_RESULT MaybeHandle<Cell> ResolveExport(
106
      Isolate* isolate, Handle<Module> module, Handle<String> module_specifier,
107 108
      Handle<String> export_name, MessageLocation loc, bool must_resolve,
      ResolveSet* resolve_set);
109

110
  static V8_WARN_UNUSED_RESULT bool PrepareInstantiate(
111
      Isolate* isolate, Handle<Module> module, v8::Local<v8::Context> context,
112 113
      v8::Module::ResolveModuleCallback callback,
      DeprecatedResolveCallback callback_without_import_assertions);
114
  static V8_WARN_UNUSED_RESULT bool FinishInstantiate(
115
      Isolate* isolate, Handle<Module> module,
116 117
      ZoneForwardList<Handle<SourceTextModule>>* stack, unsigned* dfs_index,
      Zone* zone);
118

119
  // Set module's status back to kUnlinked and reset other internal state.
120
  // This is used when instantiation fails.
121 122
  static void Reset(Isolate* isolate, Handle<Module> module);
  static void ResetGraph(Isolate* isolate, Handle<Module> module);
123

124
  // To set status to kErrored, RecordError should be used.
125
  void SetStatus(Status status);
126
  void RecordError(Isolate* isolate, Object error);
127

128
  TQ_OBJECT_CONSTRUCTORS(Module)
129 130 131 132 133
};

// When importing a module namespace (import * as foo from "bar"), a
// JSModuleNamespace object (representing module "bar") is created and bound to
// the declared variable (foo).  A module can have at most one namespace object.
134
class JSModuleNamespace
135 136
    : public TorqueGeneratedJSModuleNamespace<JSModuleNamespace,
                                              JSSpecialObject> {
137
 public:
138
  DECL_PRINTER(JSModuleNamespace)
139 140 141 142

  // Retrieve the value exported by [module] under the given [name]. If there is
  // no such export, return Just(undefined). If the export is uninitialized,
  // schedule an exception and return Nothing.
143 144
  V8_WARN_UNUSED_RESULT MaybeHandle<Object> GetExport(Isolate* isolate,
                                                      Handle<String> name);
145

146 147
  bool HasExport(Isolate* isolate, Handle<String> name);

148 149 150
  // Return the (constant) property attributes for the referenced property,
  // which is assumed to correspond to an export. If the export is
  // uninitialized, schedule an exception and return Nothing.
151
  static V8_WARN_UNUSED_RESULT Maybe<PropertyAttributes> GetPropertyAttributes(
152 153
      LookupIterator* it);

154 155 156 157
  static V8_WARN_UNUSED_RESULT Maybe<bool> DefineOwnProperty(
      Isolate* isolate, Handle<JSModuleNamespace> o, Handle<Object> key,
      PropertyDescriptor* desc, Maybe<ShouldThrow> should_throw);

158
  // In-object fields.
159 160 161 162
  enum {
    kToStringTagFieldIndex,
    kInObjectFieldCount,
  };
163

164 165 166 167
  // We need to include in-object fields
  // TODO(v8:8944): improve handling of in-object fields
  static constexpr int kSize =
      kHeaderSize + (kTaggedSize * kInObjectFieldCount);
168

169
  TQ_OBJECT_CONSTRUCTORS(JSModuleNamespace)
170 171
};

172 173 174 175
class ScriptOrModule
    : public TorqueGeneratedScriptOrModule<ScriptOrModule, Struct> {
 public:
  DECL_PRINTER(ScriptOrModule)
176 177 178

  using BodyDescriptor = StructBodyDescriptor;

179 180 181
  TQ_OBJECT_CONSTRUCTORS(ScriptOrModule)
};

182 183 184 185 186 187
}  // namespace internal
}  // namespace v8

#include "src/objects/object-macros-undef.h"

#endif  // V8_OBJECTS_MODULE_H_