GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: module_wrap.cc Lines: 390 433 90.1 %
Date: 2022-10-07 04:22:37 Branches: 172 293 58.7 %

Line Branch Exec Source
1
#include "module_wrap.h"
2
3
#include "env.h"
4
#include "memory_tracker-inl.h"
5
#include "node_contextify.h"
6
#include "node_errors.h"
7
#include "node_internals.h"
8
#include "node_process-inl.h"
9
#include "node_url.h"
10
#include "node_watchdog.h"
11
#include "util-inl.h"
12
13
#include <sys/stat.h>  // S_IFDIR
14
15
#include <algorithm>
16
17
namespace node {
18
namespace loader {
19
20
using errors::TryCatchScope;
21
22
using node::contextify::ContextifyContext;
23
using node::url::URL;
24
using node::url::URL_FLAGS_FAILED;
25
using v8::Array;
26
using v8::ArrayBufferView;
27
using v8::Context;
28
using v8::EscapableHandleScope;
29
using v8::FixedArray;
30
using v8::Function;
31
using v8::FunctionCallbackInfo;
32
using v8::FunctionTemplate;
33
using v8::HandleScope;
34
using v8::Int32;
35
using v8::Integer;
36
using v8::IntegrityLevel;
37
using v8::Isolate;
38
using v8::Local;
39
using v8::MaybeLocal;
40
using v8::MicrotaskQueue;
41
using v8::Module;
42
using v8::ModuleRequest;
43
using v8::Number;
44
using v8::Object;
45
using v8::PrimitiveArray;
46
using v8::Promise;
47
using v8::ScriptCompiler;
48
using v8::ScriptOrigin;
49
using v8::String;
50
using v8::UnboundModuleScript;
51
using v8::Undefined;
52
using v8::Value;
53
54
52027
ModuleWrap::ModuleWrap(Environment* env,
55
                       Local<Object> object,
56
                       Local<Module> module,
57
52027
                       Local<String> url)
58
  : BaseObject(env, object),
59
    module_(env->isolate(), module),
60
104054
    id_(env->get_next_module_id()) {
61
52027
  env->id_to_module_map.emplace(id_, this);
62
63
104054
  Local<Value> undefined = Undefined(env->isolate());
64
52027
  object->SetInternalField(kURLSlot, url);
65
52027
  object->SetInternalField(kSyntheticEvaluationStepsSlot, undefined);
66
52027
  object->SetInternalField(kContextObjectSlot, undefined);
67
52027
}
68
69
294072
ModuleWrap::~ModuleWrap() {
70
196048
  HandleScope scope(env()->isolate());
71
98024
  Local<Module> module = module_.Get(env()->isolate());
72
98024
  env()->id_to_module_map.erase(id_);
73
98024
  auto range = env()->hash_to_module_map.equal_range(module->GetIdentityHash());
74
98024
  for (auto it = range.first; it != range.second; ++it) {
75
98024
    if (it->second == this) {
76
98024
      env()->hash_to_module_map.erase(it);
77
98024
      break;
78
    }
79
  }
80
196048
}
81
82
104489
Local<Context> ModuleWrap::context() const {
83
313467
  Local<Value> obj = object()->GetInternalField(kContextObjectSlot);
84
104489
  if (obj.IsEmpty()) return {};
85
208978
  return obj.As<Object>()->GetCreationContext().ToLocalChecked();
86
}
87
88
52381
ModuleWrap* ModuleWrap::GetFromModule(Environment* env,
89
                                      Local<Module> module) {
90
52381
  auto range = env->hash_to_module_map.equal_range(module->GetIdentityHash());
91
52381
  for (auto it = range.first; it != range.second; ++it) {
92

104762
    if (it->second->module_ == module) {
93
52381
      return it->second;
94
    }
95
  }
96
  return nullptr;
97
}
98
99
274
ModuleWrap* ModuleWrap::GetFromID(Environment* env, uint32_t id) {
100
274
  auto module_wrap_it = env->id_to_module_map.find(id);
101
274
  if (module_wrap_it == env->id_to_module_map.end()) {
102
    return nullptr;
103
  }
104
274
  return module_wrap_it->second;
105
}
106
107
// new ModuleWrap(url, context, source, lineOffset, columnOffset)
108
// new ModuleWrap(url, context, exportNames, syntheticExecutionFunction)
109
52034
void ModuleWrap::New(const FunctionCallbackInfo<Value>& args) {
110
52034
  CHECK(args.IsConstructCall());
111
52034
  CHECK_GE(args.Length(), 3);
112
113
52034
  Environment* env = Environment::GetCurrent(args);
114
52034
  Isolate* isolate = env->isolate();
115
116
52034
  Local<Object> that = args.This();
117
118
104068
  CHECK(args[0]->IsString());
119
104068
  Local<String> url = args[0].As<String>();
120
121
  Local<Context> context;
122
52034
  ContextifyContext* contextify_context = nullptr;
123
104068
  if (args[1]->IsUndefined()) {
124
104024
    context = that->GetCreationContext().ToLocalChecked();
125
  } else {
126
22
    CHECK(args[1]->IsObject());
127
44
    contextify_context = ContextifyContext::ContextFromContextifiedSandbox(
128
44
        env, args[1].As<Object>());
129
22
    CHECK_NOT_NULL(contextify_context);
130
22
    context = contextify_context->context();
131
  }
132
133
52034
  int line_offset = 0;
134
52034
  int column_offset = 0;
135
136
52034
  bool synthetic = args[2]->IsArray();
137
52034
  if (synthetic) {
138
    // new ModuleWrap(url, context, exportNames, syntheticExecutionFunction)
139
51130
    CHECK(args[3]->IsFunction());
140
  } else {
141
    // new ModuleWrap(url, context, source, lineOffset, columOffset, cachedData)
142
1808
    CHECK(args[2]->IsString());
143
904
    CHECK(args[3]->IsNumber());
144
1808
    line_offset = args[3].As<Int32>()->Value();
145
904
    CHECK(args[4]->IsNumber());
146
1808
    column_offset = args[4].As<Int32>()->Value();
147
  }
148
149
  Local<PrimitiveArray> host_defined_options =
150
52034
      PrimitiveArray::New(isolate, HostDefinedOptions::kLength);
151
104068
  host_defined_options->Set(isolate, HostDefinedOptions::kType,
152
                            Number::New(isolate, ScriptType::kModule));
153
154
52034
  ShouldNotAbortOnUncaughtScope no_abort_scope(env);
155
52034
  TryCatchScope try_catch(env);
156
157
  Local<Module> module;
158
159
  {
160
52034
    Context::Scope context_scope(context);
161
52034
    if (synthetic) {
162
51130
      CHECK(args[2]->IsArray());
163
102260
      Local<Array> export_names_arr = args[2].As<Array>();
164
165
51130
      uint32_t len = export_names_arr->Length();
166
102260
      std::vector<Local<String>> export_names(len);
167
1666113
      for (uint32_t i = 0; i < len; i++) {
168
        Local<Value> export_name_val =
169
3229966
            export_names_arr->Get(context, i).ToLocalChecked();
170
3229966
        CHECK(export_name_val->IsString());
171
1614983
        export_names[i] = export_name_val.As<String>();
172
      }
173
174
      module = Module::CreateSyntheticModule(isolate, url, export_names,
175
51130
        SyntheticModuleEvaluationStepsCallback);
176
    } else {
177
904
      ScriptCompiler::CachedData* cached_data = nullptr;
178
2712
      if (!args[5]->IsUndefined()) {
179
2
        CHECK(args[5]->IsArrayBufferView());
180
6
        Local<ArrayBufferView> cached_data_buf = args[5].As<ArrayBufferView>();
181
        uint8_t* data =
182
4
            static_cast<uint8_t*>(cached_data_buf->Buffer()->Data());
183
2
        cached_data =
184
2
            new ScriptCompiler::CachedData(data + cached_data_buf->ByteOffset(),
185
2
                                           cached_data_buf->ByteLength());
186
      }
187
188
1808
      Local<String> source_text = args[2].As<String>();
189
      ScriptOrigin origin(isolate,
190
                          url,
191
                          line_offset,
192
                          column_offset,
193
                          true,                             // is cross origin
194
                          -1,                               // script id
195
                          Local<Value>(),                   // source map URL
196
                          false,                            // is opaque (?)
197
                          false,                            // is WASM
198
                          true,                             // is ES Module
199
1808
                          host_defined_options);
200
904
      ScriptCompiler::Source source(source_text, origin, cached_data);
201
      ScriptCompiler::CompileOptions options;
202
904
      if (source.GetCachedData() == nullptr) {
203
902
        options = ScriptCompiler::kNoCompileOptions;
204
      } else {
205
2
        options = ScriptCompiler::kConsumeCodeCache;
206
      }
207
904
      if (!ScriptCompiler::CompileModule(isolate, &source, options)
208
904
               .ToLocal(&module)) {
209

6
        if (try_catch.HasCaught() && !try_catch.HasTerminated()) {
210
12
          CHECK(!try_catch.Message().IsEmpty());
211
12
          CHECK(!try_catch.Exception().IsEmpty());
212
6
          AppendExceptionLine(env, try_catch.Exception(), try_catch.Message(),
213
                              ErrorHandlingMode::MODULE_ERROR);
214
6
          try_catch.ReThrow();
215
        }
216
6
        return;
217
      }
218

900
      if (options == ScriptCompiler::kConsumeCodeCache &&
219
2
          source.GetCachedData()->rejected) {
220
1
        THROW_ERR_VM_MODULE_CACHED_DATA_REJECTED(
221
            env, "cachedData buffer was rejected");
222
1
        try_catch.ReThrow();
223
1
        return;
224
      }
225
    }
226
  }
227
228

156081
  if (!that->Set(context, env->url_string(), url).FromMaybe(false)) {
229
    return;
230
  }
231
232
52027
  ModuleWrap* obj = new ModuleWrap(env, that, module, url);
233
234
52027
  if (synthetic) {
235
51130
    obj->synthetic_ = true;
236
153390
    obj->object()->SetInternalField(kSyntheticEvaluationStepsSlot, args[3]);
237
  }
238
239
  // Use the extras object as an object whose GetCreationContext() will be the
240
  // original `context`, since the `Context` itself strictly speaking cannot
241
  // be stored in an internal field.
242
156081
  obj->object()->SetInternalField(kContextObjectSlot,
243
      context->GetExtrasBindingObject());
244
52027
  obj->contextify_context_ = contextify_context;
245
246
52027
  env->hash_to_module_map.emplace(module->GetIdentityHash(), obj);
247
248
104054
  host_defined_options->Set(isolate, HostDefinedOptions::kID,
249
52027
                            Number::New(isolate, obj->id()));
250
251
52027
  that->SetIntegrityLevel(context, IntegrityLevel::kFrozen);
252
104054
  args.GetReturnValue().Set(that);
253
}
254
255
1528
static Local<Object> createImportAssertionContainer(Environment* env,
256
  Isolate* isolate, Local<FixedArray> raw_assertions) {
257
  Local<Object> assertions =
258
3056
        Object::New(isolate, v8::Null(env->isolate()), nullptr, nullptr, 0);
259
3100
  for (int i = 0; i < raw_assertions->Length(); i += 3) {
260
      assertions
261
44
          ->Set(env->context(),
262
44
                raw_assertions->Get(env->context(), i).As<String>(),
263
132
                raw_assertions->Get(env->context(), i + 1).As<Value>())
264
          .ToChecked();
265
  }
266
267
1528
  return assertions;
268
}
269
270
1491
void ModuleWrap::Link(const FunctionCallbackInfo<Value>& args) {
271
1491
  Environment* env = Environment::GetCurrent(args);
272
1491
  Isolate* isolate = args.GetIsolate();
273
274
1491
  CHECK_EQ(args.Length(), 1);
275
1491
  CHECK(args[0]->IsFunction());
276
277
1491
  Local<Object> that = args.This();
278
279
  ModuleWrap* obj;
280
1494
  ASSIGN_OR_RETURN_UNWRAP(&obj, that);
281
282
1491
  if (obj->linked_)
283
3
    return;
284
1488
  obj->linked_ = true;
285
286
1488
  Local<Function> resolver_arg = args[0].As<Function>();
287
288
1488
  Local<Context> mod_context = obj->context();
289
2976
  Local<Module> module = obj->module_.Get(isolate);
290
291
1488
  Local<FixedArray> module_requests = module->GetModuleRequests();
292
1488
  const int module_requests_length = module_requests->Length();
293
1488
  MaybeStackBuffer<Local<Value>, 16> promises(module_requests_length);
294
295
  // call the dependency resolve callbacks
296
2622
  for (int i = 0; i < module_requests_length; i++) {
297
    Local<ModuleRequest> module_request =
298
2268
      module_requests->Get(env->context(), i).As<ModuleRequest>();
299
1134
    Local<String> specifier = module_request->GetSpecifier();
300
1134
    Utf8Value specifier_utf8(env->isolate(), specifier);
301
2268
    std::string specifier_std(*specifier_utf8, specifier_utf8.length());
302
303
1134
    Local<FixedArray> raw_assertions = module_request->GetImportAssertions();
304
    Local<Object> assertions =
305
1134
      createImportAssertionContainer(env, isolate, raw_assertions);
306
307
    Local<Value> argv[] = {
308
        specifier,
309
        assertions,
310
1134
    };
311
312
    MaybeLocal<Value> maybe_resolve_return_value =
313
1134
        resolver_arg->Call(mod_context, that, arraysize(argv), argv);
314
1134
    if (maybe_resolve_return_value.IsEmpty()) {
315
      return;
316
    }
317
    Local<Value> resolve_return_value =
318
1134
        maybe_resolve_return_value.ToLocalChecked();
319
1134
    if (!resolve_return_value->IsPromise()) {
320
      THROW_ERR_VM_MODULE_LINK_FAILURE(
321
          env, "request for '%s' did not return promise", specifier_std);
322
      return;
323
    }
324
1134
    Local<Promise> resolve_promise = resolve_return_value.As<Promise>();
325
1134
    obj->resolve_cache_[specifier_std].Reset(env->isolate(), resolve_promise);
326
327
1134
    promises[i] = resolve_promise;
328
  }
329
330
2976
  args.GetReturnValue().Set(
331
      Array::New(isolate, promises.out(), promises.length()));
332
}
333
334
51490
void ModuleWrap::Instantiate(const FunctionCallbackInfo<Value>& args) {
335
51490
  Environment* env = Environment::GetCurrent(args);
336
51490
  Isolate* isolate = args.GetIsolate();
337
  ModuleWrap* obj;
338
51505
  ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
339
51490
  Local<Context> context = obj->context();
340
51490
  Local<Module> module = obj->module_.Get(isolate);
341
51490
  TryCatchScope try_catch(env);
342
51490
  USE(module->InstantiateModule(context, ResolveModuleCallback));
343
344
  // clear resolve cache on instantiate
345
51490
  obj->resolve_cache_.clear();
346
347

51490
  if (try_catch.HasCaught() && !try_catch.HasTerminated()) {
348
30
    CHECK(!try_catch.Message().IsEmpty());
349
30
    CHECK(!try_catch.Exception().IsEmpty());
350
15
    AppendExceptionLine(env, try_catch.Exception(), try_catch.Message(),
351
                        ErrorHandlingMode::MODULE_ERROR);
352
15
    try_catch.ReThrow();
353
15
    return;
354
  }
355
}
356
357
51511
void ModuleWrap::Evaluate(const FunctionCallbackInfo<Value>& args) {
358
51511
  Environment* env = Environment::GetCurrent(args);
359
51511
  Isolate* isolate = env->isolate();
360
  ModuleWrap* obj;
361
51521
  ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
362
51511
  Local<Context> context = obj->context();
363
51511
  Local<Module> module = obj->module_.Get(isolate);
364
365
51511
  ContextifyContext* contextify_context = obj->contextify_context_;
366
51511
  std::shared_ptr<MicrotaskQueue> microtask_queue;
367
51511
  if (contextify_context != nullptr)
368
4
      microtask_queue = contextify_context->microtask_queue();
369
370
  // module.evaluate(timeout, breakOnSigint)
371
51511
  CHECK_EQ(args.Length(), 2);
372
373
51511
  CHECK(args[0]->IsNumber());
374
103022
  int64_t timeout = args[0]->IntegerValue(env->context()).FromJust();
375
376
51511
  CHECK(args[1]->IsBoolean());
377
51511
  bool break_on_sigint = args[1]->IsTrue();
378
379
51511
  ShouldNotAbortOnUncaughtScope no_abort_scope(env);
380
51511
  TryCatchScope try_catch(env);
381
51511
  Isolate::SafeForTerminationScope safe_for_termination(env->isolate());
382
383
51511
  bool timed_out = false;
384
51511
  bool received_signal = false;
385
  MaybeLocal<Value> result;
386
51511
  auto run = [&]() {
387
51511
    MaybeLocal<Value> result = module->Evaluate(context);
388

51508
    if (!result.IsEmpty() && microtask_queue)
389
1
      microtask_queue->PerformCheckpoint(isolate);
390
51508
    return result;
391
51511
  };
392

51511
  if (break_on_sigint && timeout != -1) {
393
    Watchdog wd(isolate, timeout, &timed_out);
394
    SigintWatchdog swd(isolate, &received_signal);
395
    result = run();
396
51511
  } else if (break_on_sigint) {
397
    SigintWatchdog swd(isolate, &received_signal);
398
    result = run();
399
51511
  } else if (timeout != -1) {
400
6
    Watchdog wd(isolate, timeout, &timed_out);
401
3
    result = run();
402
  } else {
403
51508
    result = run();
404
  }
405
406
51508
  if (result.IsEmpty()) {
407
4
    CHECK(try_catch.HasCaught());
408
  }
409
410
  // Convert the termination exception into a regular exception.
411

51508
  if (timed_out || received_signal) {
412

3
    if (!env->is_main_thread() && env->is_stopping())
413
      return;
414
3
    env->isolate()->CancelTerminateExecution();
415
    // It is possible that execution was terminated by another timeout in
416
    // which this timeout is nested, so check whether one of the watchdogs
417
    // from this invocation is responsible for termination.
418
3
    if (timed_out) {
419
3
      THROW_ERR_SCRIPT_EXECUTION_TIMEOUT(env, timeout);
420
    } else if (received_signal) {
421
      THROW_ERR_SCRIPT_EXECUTION_INTERRUPTED(env);
422
    }
423
  }
424
425
51508
  if (try_catch.HasCaught()) {
426
10
    if (!try_catch.HasTerminated())
427
8
      try_catch.ReThrow();
428
10
    return;
429
  }
430
431
102996
  args.GetReturnValue().Set(result.ToLocalChecked());
432
}
433
434
489
void ModuleWrap::GetNamespace(const FunctionCallbackInfo<Value>& args) {
435
489
  Environment* env = Environment::GetCurrent(args);
436
489
  Isolate* isolate = args.GetIsolate();
437
  ModuleWrap* obj;
438
489
  ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
439
440
978
  Local<Module> module = obj->module_.Get(isolate);
441
442
489
  switch (module->GetStatus()) {
443
    case v8::Module::Status::kUninstantiated:
444
    case v8::Module::Status::kInstantiating:
445
      return env->ThrowError(
446
          "cannot get namespace, module has not been instantiated");
447
489
    case v8::Module::Status::kInstantiated:
448
    case v8::Module::Status::kEvaluating:
449
    case v8::Module::Status::kEvaluated:
450
    case v8::Module::Status::kErrored:
451
489
      break;
452
    default:
453
      UNREACHABLE();
454
  }
455
456
489
  Local<Value> result = module->GetModuleNamespace();
457
978
  args.GetReturnValue().Set(result);
458
}
459
460
219
void ModuleWrap::GetStatus(const FunctionCallbackInfo<Value>& args) {
461
219
  Isolate* isolate = args.GetIsolate();
462
  ModuleWrap* obj;
463
219
  ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
464
465
438
  Local<Module> module = obj->module_.Get(isolate);
466
467
438
  args.GetReturnValue().Set(module->GetStatus());
468
}
469
470
2
void ModuleWrap::GetStaticDependencySpecifiers(
471
    const FunctionCallbackInfo<Value>& args) {
472
2
  Environment* env = Environment::GetCurrent(args);
473
  ModuleWrap* obj;
474
2
  ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
475
476
4
  Local<Module> module = obj->module_.Get(env->isolate());
477
478
2
  Local<FixedArray> module_requests = module->GetModuleRequests();
479
2
  int count = module_requests->Length();
480
481
2
  MaybeStackBuffer<Local<Value>, 16> specifiers(count);
482
483
3
  for (int i = 0; i < count; i++) {
484
    Local<ModuleRequest> module_request =
485
2
      module_requests->Get(env->context(), i).As<ModuleRequest>();
486
2
    specifiers[i] = module_request->GetSpecifier();
487
  }
488
489
4
  args.GetReturnValue().Set(
490
      Array::New(env->isolate(), specifiers.out(), count));
491
}
492
493
2
void ModuleWrap::GetError(const FunctionCallbackInfo<Value>& args) {
494
2
  Isolate* isolate = args.GetIsolate();
495
  ModuleWrap* obj;
496
2
  ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
497
498
4
  Local<Module> module = obj->module_.Get(isolate);
499
4
  args.GetReturnValue().Set(module->GetException());
500
}
501
502
1088
MaybeLocal<Module> ModuleWrap::ResolveModuleCallback(
503
    Local<Context> context,
504
    Local<String> specifier,
505
    Local<FixedArray> import_assertions,
506
    Local<Module> referrer) {
507
1088
  Environment* env = Environment::GetCurrent(context);
508
1088
  if (env == nullptr) {
509
    Isolate* isolate = context->GetIsolate();
510
    THROW_ERR_EXECUTION_ENVIRONMENT_NOT_AVAILABLE(isolate);
511
    return MaybeLocal<Module>();
512
  }
513
514
1088
  Isolate* isolate = env->isolate();
515
516
2176
  Utf8Value specifier_utf8(isolate, specifier);
517
2176
  std::string specifier_std(*specifier_utf8, specifier_utf8.length());
518
519
1088
  ModuleWrap* dependent = GetFromModule(env, referrer);
520
1088
  if (dependent == nullptr) {
521
    THROW_ERR_VM_MODULE_LINK_FAILURE(
522
        env, "request for '%s' is from invalid module", specifier_std);
523
    return MaybeLocal<Module>();
524
  }
525
526
1088
  if (dependent->resolve_cache_.count(specifier_std) != 1) {
527
    THROW_ERR_VM_MODULE_LINK_FAILURE(
528
        env, "request for '%s' is not in cache", specifier_std);
529
    return MaybeLocal<Module>();
530
  }
531
532
  Local<Promise> resolve_promise =
533
2176
      dependent->resolve_cache_[specifier_std].Get(isolate);
534
535
1088
  if (resolve_promise->State() != Promise::kFulfilled) {
536
    THROW_ERR_VM_MODULE_LINK_FAILURE(
537
        env, "request for '%s' is not yet fulfilled", specifier_std);
538
    return MaybeLocal<Module>();
539
  }
540
541
2176
  Local<Object> module_object = resolve_promise->Result().As<Object>();
542

2176
  if (module_object.IsEmpty() || !module_object->IsObject()) {
543
    THROW_ERR_VM_MODULE_LINK_FAILURE(
544
        env, "request for '%s' did not return an object", specifier_std);
545
    return MaybeLocal<Module>();
546
  }
547
548
  ModuleWrap* module;
549
1088
  ASSIGN_OR_RETURN_UNWRAP(&module, module_object, MaybeLocal<Module>());
550
2176
  return module->module_.Get(isolate);
551
}
552
553
394
static MaybeLocal<Promise> ImportModuleDynamically(
554
    Local<Context> context,
555
    Local<v8::Data> host_defined_options,
556
    Local<Value> resource_name,
557
    Local<String> specifier,
558
    Local<FixedArray> import_assertions) {
559
394
  Isolate* isolate = context->GetIsolate();
560
394
  Environment* env = Environment::GetCurrent(context);
561
394
  if (env == nullptr) {
562
    THROW_ERR_EXECUTION_ENVIRONMENT_NOT_AVAILABLE(isolate);
563
    return MaybeLocal<Promise>();
564
  }
565
566
394
  EscapableHandleScope handle_scope(isolate);
567
568
  Local<Function> import_callback =
569
394
    env->host_import_module_dynamically_callback();
570
571
394
  Local<FixedArray> options = host_defined_options.As<FixedArray>();
572
394
  if (options->Length() != HostDefinedOptions::kLength) {
573
    Local<Promise::Resolver> resolver;
574
    if (!Promise::Resolver::New(context).ToLocal(&resolver)) return {};
575
    resolver
576
        ->Reject(context,
577
                 v8::Exception::TypeError(FIXED_ONE_BYTE_STRING(
578
                     context->GetIsolate(), "Invalid host defined options")))
579
        .ToChecked();
580
    return handle_scope.Escape(resolver->GetPromise());
581
  }
582
583
  Local<Value> object;
584
585
394
  int type = options->Get(context, HostDefinedOptions::kType)
586
394
                 .As<Number>()
587
394
                 ->Int32Value(context)
588
394
                 .ToChecked();
589
394
  uint32_t id = options->Get(context, HostDefinedOptions::kID)
590
394
                    .As<Number>()
591
394
                    ->Uint32Value(context)
592
394
                    .ToChecked();
593
394
  if (type == ScriptType::kScript) {
594
10
    contextify::ContextifyScript* wrap = env->id_to_script_map.find(id)->second;
595
20
    object = wrap->object();
596
384
  } else if (type == ScriptType::kModule) {
597
274
    ModuleWrap* wrap = ModuleWrap::GetFromID(env, id);
598
548
    object = wrap->object();
599
110
  } else if (type == ScriptType::kFunction) {
600
110
    auto it = env->id_to_function_map.find(id);
601
110
    CHECK_NE(it, env->id_to_function_map.end());
602
220
    object = it->second->object();
603
  } else {
604
    UNREACHABLE();
605
  }
606
607
  Local<Object> assertions =
608
394
    createImportAssertionContainer(env, isolate, import_assertions);
609
610
  Local<Value> import_args[] = {
611
    object,
612
    Local<Value>(specifier),
613
    assertions,
614
394
  };
615
616
  Local<Value> result;
617
788
  if (import_callback->Call(
618
        context,
619
        Undefined(isolate),
620
394
        arraysize(import_args),
621
1182
        import_args).ToLocal(&result)) {
622
394
    CHECK(result->IsPromise());
623
394
    return handle_scope.Escape(result.As<Promise>());
624
  }
625
626
  return MaybeLocal<Promise>();
627
}
628
629
6255
void ModuleWrap::SetImportModuleDynamicallyCallback(
630
    const FunctionCallbackInfo<Value>& args) {
631
6255
  Isolate* isolate = args.GetIsolate();
632
6255
  Environment* env = Environment::GetCurrent(args);
633
12510
  HandleScope handle_scope(isolate);
634
635
6255
  CHECK_EQ(args.Length(), 1);
636
6255
  CHECK(args[0]->IsFunction());
637
6255
  Local<Function> import_callback = args[0].As<Function>();
638
6255
  env->set_host_import_module_dynamically_callback(import_callback);
639
640
6255
  isolate->SetHostImportModuleDynamicallyCallback(ImportModuleDynamically);
641
6255
}
642
643
180
void ModuleWrap::HostInitializeImportMetaObjectCallback(
644
    Local<Context> context, Local<Module> module, Local<Object> meta) {
645
180
  Environment* env = Environment::GetCurrent(context);
646
180
  if (env == nullptr)
647
    return;
648
180
  ModuleWrap* module_wrap = GetFromModule(env, module);
649
650
180
  if (module_wrap == nullptr) {
651
    return;
652
  }
653
654
180
  Local<Object> wrap = module_wrap->object();
655
  Local<Function> callback =
656
180
      env->host_initialize_import_meta_object_callback();
657
180
  Local<Value> args[] = { wrap, meta };
658
360
  TryCatchScope try_catch(env);
659
180
  USE(callback->Call(
660
360
        context, Undefined(env->isolate()), arraysize(args), args));
661

180
  if (try_catch.HasCaught() && !try_catch.HasTerminated()) {
662
    try_catch.ReThrow();
663
  }
664
}
665
666
6255
void ModuleWrap::SetInitializeImportMetaObjectCallback(
667
    const FunctionCallbackInfo<Value>& args) {
668
6255
  Environment* env = Environment::GetCurrent(args);
669
6255
  Isolate* isolate = env->isolate();
670
671
6255
  CHECK_EQ(args.Length(), 1);
672
6255
  CHECK(args[0]->IsFunction());
673
6255
  Local<Function> import_meta_callback = args[0].As<Function>();
674
6255
  env->set_host_initialize_import_meta_object_callback(import_meta_callback);
675
676
6255
  isolate->SetHostInitializeImportMetaObjectCallback(
677
      HostInitializeImportMetaObjectCallback);
678
6255
}
679
680
51113
MaybeLocal<Value> ModuleWrap::SyntheticModuleEvaluationStepsCallback(
681
    Local<Context> context, Local<Module> module) {
682
51113
  Environment* env = Environment::GetCurrent(context);
683
51113
  Isolate* isolate = env->isolate();
684
685
51113
  ModuleWrap* obj = GetFromModule(env, module);
686
687
102226
  TryCatchScope try_catch(env);
688
  Local<Function> synthetic_evaluation_steps =
689
153339
      obj->object()->GetInternalField(kSyntheticEvaluationStepsSlot)
690
51113
          .As<Function>();
691
153339
  obj->object()->SetInternalField(
692
      kSyntheticEvaluationStepsSlot, Undefined(isolate));
693
  MaybeLocal<Value> ret = synthetic_evaluation_steps->Call(context,
694
102226
      obj->object(), 0, nullptr);
695
51113
  if (ret.IsEmpty()) {
696
5
    CHECK(try_catch.HasCaught());
697
  }
698

51113
  if (try_catch.HasCaught() && !try_catch.HasTerminated()) {
699
10
    CHECK(!try_catch.Message().IsEmpty());
700
10
    CHECK(!try_catch.Exception().IsEmpty());
701
5
    try_catch.ReThrow();
702
5
    return MaybeLocal<Value>();
703
  }
704
705
  Local<Promise::Resolver> resolver;
706
102216
  if (!Promise::Resolver::New(context).ToLocal(&resolver)) {
707
    return MaybeLocal<Value>();
708
  }
709
710
153324
  resolver->Resolve(context, Undefined(isolate)).ToChecked();
711
102216
  return resolver->GetPromise();
712
}
713
714
4501073
void ModuleWrap::SetSyntheticExport(const FunctionCallbackInfo<Value>& args) {
715
4501073
  Isolate* isolate = args.GetIsolate();
716
4501073
  Local<Object> that = args.This();
717
718
  ModuleWrap* obj;
719
4501073
  ASSIGN_OR_RETURN_UNWRAP(&obj, that);
720
721
4501073
  CHECK(obj->synthetic_);
722
723
4501073
  CHECK_EQ(args.Length(), 2);
724
725
9002146
  CHECK(args[0]->IsString());
726
9002146
  Local<String> export_name = args[0].As<String>();
727
728
4501073
  Local<Value> export_value = args[1];
729
730
9002146
  Local<Module> module = obj->module_.Get(isolate);
731
4501073
  USE(module->SetSyntheticModuleExport(isolate, export_name, export_value));
732
}
733
734
1
void ModuleWrap::CreateCachedData(const FunctionCallbackInfo<Value>& args) {
735
1
  Isolate* isolate = args.GetIsolate();
736
1
  Local<Object> that = args.This();
737
738
  ModuleWrap* obj;
739
1
  ASSIGN_OR_RETURN_UNWRAP(&obj, that);
740
741
1
  CHECK(!obj->synthetic_);
742
743
2
  Local<Module> module = obj->module_.Get(isolate);
744
745
1
  CHECK_LT(module->GetStatus(), v8::Module::Status::kEvaluating);
746
747
  Local<UnboundModuleScript> unbound_module_script =
748
1
      module->GetUnboundModuleScript();
749
  std::unique_ptr<ScriptCompiler::CachedData> cached_data(
750
2
      ScriptCompiler::CreateCodeCache(unbound_module_script));
751
1
  Environment* env = Environment::GetCurrent(args);
752
1
  if (!cached_data) {
753
    args.GetReturnValue().Set(Buffer::New(env, 0).ToLocalChecked());
754
  } else {
755
    MaybeLocal<Object> buf =
756
        Buffer::Copy(env,
757
2
                     reinterpret_cast<const char*>(cached_data->data),
758
1
                     cached_data->length);
759
2
    args.GetReturnValue().Set(buf.ToLocalChecked());
760
  }
761
}
762
763
6256
void ModuleWrap::Initialize(Local<Object> target,
764
                            Local<Value> unused,
765
                            Local<Context> context,
766
                            void* priv) {
767
6256
  Environment* env = Environment::GetCurrent(context);
768
6256
  Isolate* isolate = env->isolate();
769
770
6256
  Local<FunctionTemplate> tpl = NewFunctionTemplate(isolate, New);
771
12512
  tpl->InstanceTemplate()->SetInternalFieldCount(
772
      ModuleWrap::kInternalFieldCount);
773
6256
  tpl->Inherit(BaseObject::GetConstructorTemplate(env));
774
775
6256
  SetProtoMethod(isolate, tpl, "link", Link);
776
6256
  SetProtoMethod(isolate, tpl, "instantiate", Instantiate);
777
6256
  SetProtoMethod(isolate, tpl, "evaluate", Evaluate);
778
6256
  SetProtoMethod(isolate, tpl, "setExport", SetSyntheticExport);
779
6256
  SetProtoMethodNoSideEffect(
780
      isolate, tpl, "createCachedData", CreateCachedData);
781
6256
  SetProtoMethodNoSideEffect(isolate, tpl, "getNamespace", GetNamespace);
782
6256
  SetProtoMethodNoSideEffect(isolate, tpl, "getStatus", GetStatus);
783
6256
  SetProtoMethodNoSideEffect(isolate, tpl, "getError", GetError);
784
6256
  SetProtoMethodNoSideEffect(isolate,
785
                             tpl,
786
                             "getStaticDependencySpecifiers",
787
                             GetStaticDependencySpecifiers);
788
789
6256
  SetConstructorFunction(context, target, "ModuleWrap", tpl);
790
791
6256
  SetMethod(context,
792
            target,
793
            "setImportModuleDynamicallyCallback",
794
            SetImportModuleDynamicallyCallback);
795
6256
  SetMethod(context,
796
            target,
797
            "setInitializeImportMetaObjectCallback",
798
            SetInitializeImportMetaObjectCallback);
799
800
#define V(name)                                                                \
801
    target->Set(context,                                                       \
802
      FIXED_ONE_BYTE_STRING(env->isolate(), #name),                            \
803
      Integer::New(env->isolate(), Module::Status::name))                      \
804
        .FromJust()
805
25024
    V(kUninstantiated);
806
25024
    V(kInstantiating);
807
25024
    V(kInstantiated);
808
25024
    V(kEvaluating);
809
25024
    V(kEvaluated);
810
18768
    V(kErrored);
811
#undef V
812
6256
}
813
814
}  // namespace loader
815
}  // namespace node
816
817
5594
NODE_MODULE_CONTEXT_AWARE_INTERNAL(module_wrap,
818
                                   node::loader::ModuleWrap::Initialize)