GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: module_wrap.cc Lines: 389 432 90.0 %
Date: 2022-06-06 04:15:48 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
50388
ModuleWrap::ModuleWrap(Environment* env,
55
                       Local<Object> object,
56
                       Local<Module> module,
57
50388
                       Local<String> url)
58
  : BaseObject(env, object),
59
    module_(env->isolate(), module),
60
100776
    id_(env->get_next_module_id()) {
61
50388
  env->id_to_module_map.emplace(id_, this);
62
63
100776
  Local<Value> undefined = Undefined(env->isolate());
64
50388
  object->SetInternalField(kURLSlot, url);
65
50388
  object->SetInternalField(kSyntheticEvaluationStepsSlot, undefined);
66
50388
  object->SetInternalField(kContextObjectSlot, undefined);
67
50388
}
68
69
281118
ModuleWrap::~ModuleWrap() {
70
187412
  HandleScope scope(env()->isolate());
71
93706
  Local<Module> module = module_.Get(env()->isolate());
72
93706
  env()->id_to_module_map.erase(id_);
73
93706
  auto range = env()->hash_to_module_map.equal_range(module->GetIdentityHash());
74
93706
  for (auto it = range.first; it != range.second; ++it) {
75
93706
    if (it->second == this) {
76
93706
      env()->hash_to_module_map.erase(it);
77
93706
      break;
78
    }
79
  }
80
187412
}
81
82
101058
Local<Context> ModuleWrap::context() const {
83
303174
  Local<Value> obj = object()->GetInternalField(kContextObjectSlot);
84
101058
  if (obj.IsEmpty()) return {};
85
202116
  return obj.As<Object>()->GetCreationContext().ToLocalChecked();
86
}
87
88
50674
ModuleWrap* ModuleWrap::GetFromModule(Environment* env,
89
                                      Local<Module> module) {
90
50674
  auto range = env->hash_to_module_map.equal_range(module->GetIdentityHash());
91
50674
  for (auto it = range.first; it != range.second; ++it) {
92

101348
    if (it->second->module_ == module) {
93
50674
      return it->second;
94
    }
95
  }
96
  return nullptr;
97
}
98
99
258
ModuleWrap* ModuleWrap::GetFromID(Environment* env, uint32_t id) {
100
258
  auto module_wrap_it = env->id_to_module_map.find(id);
101
258
  if (module_wrap_it == env->id_to_module_map.end()) {
102
    return nullptr;
103
  }
104
258
  return module_wrap_it->second;
105
}
106
107
// new ModuleWrap(url, context, source, lineOffset, columnOffset)
108
// new ModuleWrap(url, context, exportNames, syntheticExecutionFunction)
109
50395
void ModuleWrap::New(const FunctionCallbackInfo<Value>& args) {
110
50395
  CHECK(args.IsConstructCall());
111
50395
  CHECK_GE(args.Length(), 3);
112
113
50395
  Environment* env = Environment::GetCurrent(args);
114
50395
  Isolate* isolate = env->isolate();
115
116
50395
  Local<Object> that = args.This();
117
118
100790
  CHECK(args[0]->IsString());
119
100790
  Local<String> url = args[0].As<String>();
120
121
  Local<Context> context;
122
50395
  ContextifyContext* contextify_context = nullptr;
123
100790
  if (args[1]->IsUndefined()) {
124
100746
    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
50395
  int line_offset = 0;
134
50395
  int column_offset = 0;
135
136
50395
  bool synthetic = args[2]->IsArray();
137
50395
  if (synthetic) {
138
    // new ModuleWrap(url, context, exportNames, syntheticExecutionFunction)
139
49561
    CHECK(args[3]->IsFunction());
140
  } else {
141
    // new ModuleWrap(url, context, source, lineOffset, columOffset, cachedData)
142
1668
    CHECK(args[2]->IsString());
143
834
    CHECK(args[3]->IsNumber());
144
1668
    line_offset = args[3].As<Int32>()->Value();
145
834
    CHECK(args[4]->IsNumber());
146
1668
    column_offset = args[4].As<Int32>()->Value();
147
  }
148
149
  Local<PrimitiveArray> host_defined_options =
150
50395
      PrimitiveArray::New(isolate, HostDefinedOptions::kLength);
151
100790
  host_defined_options->Set(isolate, HostDefinedOptions::kType,
152
                            Number::New(isolate, ScriptType::kModule));
153
154
50395
  ShouldNotAbortOnUncaughtScope no_abort_scope(env);
155
50395
  TryCatchScope try_catch(env);
156
157
  Local<Module> module;
158
159
  {
160
50395
    Context::Scope context_scope(context);
161
50395
    if (synthetic) {
162
49561
      CHECK(args[2]->IsArray());
163
99122
      Local<Array> export_names_arr = args[2].As<Array>();
164
165
49561
      uint32_t len = export_names_arr->Length();
166
99122
      std::vector<Local<String>> export_names(len);
167
1601146
      for (uint32_t i = 0; i < len; i++) {
168
        Local<Value> export_name_val =
169
3103170
            export_names_arr->Get(context, i).ToLocalChecked();
170
3103170
        CHECK(export_name_val->IsString());
171
1551585
        export_names[i] = export_name_val.As<String>();
172
      }
173
174
      module = Module::CreateSyntheticModule(isolate, url, export_names,
175
49561
        SyntheticModuleEvaluationStepsCallback);
176
    } else {
177
834
      ScriptCompiler::CachedData* cached_data = nullptr;
178
2502
      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 = static_cast<uint8_t*>(
182
4
            cached_data_buf->Buffer()->GetBackingStore()->Data());
183
2
        cached_data =
184
2
            new ScriptCompiler::CachedData(data + cached_data_buf->ByteOffset(),
185
2
                                           cached_data_buf->ByteLength());
186
      }
187
188
1668
      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
1668
                          host_defined_options);
200
834
      ScriptCompiler::Source source(source_text, origin, cached_data);
201
      ScriptCompiler::CompileOptions options;
202
834
      if (source.GetCachedData() == nullptr) {
203
832
        options = ScriptCompiler::kNoCompileOptions;
204
      } else {
205
2
        options = ScriptCompiler::kConsumeCodeCache;
206
      }
207
834
      if (!ScriptCompiler::CompileModule(isolate, &source, options)
208
834
               .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

830
      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

151164
  if (!that->Set(context, env->url_string(), url).FromMaybe(false)) {
229
    return;
230
  }
231
232
50388
  ModuleWrap* obj = new ModuleWrap(env, that, module, url);
233
234
50388
  if (synthetic) {
235
49561
    obj->synthetic_ = true;
236
148683
    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
151164
  obj->object()->SetInternalField(kContextObjectSlot,
243
      context->GetExtrasBindingObject());
244
50388
  obj->contextify_context_ = contextify_context;
245
246
50388
  env->hash_to_module_map.emplace(module->GetIdentityHash(), obj);
247
248
100776
  host_defined_options->Set(isolate, HostDefinedOptions::kID,
249
50388
                            Number::New(isolate, obj->id()));
250
251
50388
  that->SetIntegrityLevel(context, IntegrityLevel::kFrozen);
252
100776
  args.GetReturnValue().Set(that);
253
}
254
255
1384
static Local<Object> createImportAssertionContainer(Environment* env,
256
  Isolate* isolate, Local<FixedArray> raw_assertions) {
257
  Local<Object> assertions =
258
2768
        Object::New(isolate, v8::Null(env->isolate()), nullptr, nullptr, 0);
259
2812
  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
1384
  return assertions;
268
}
269
270
1295
void ModuleWrap::Link(const FunctionCallbackInfo<Value>& args) {
271
1295
  Environment* env = Environment::GetCurrent(args);
272
1295
  Isolate* isolate = args.GetIsolate();
273
274
1295
  CHECK_EQ(args.Length(), 1);
275
1295
  CHECK(args[0]->IsFunction());
276
277
1295
  Local<Object> that = args.This();
278
279
  ModuleWrap* obj;
280
1298
  ASSIGN_OR_RETURN_UNWRAP(&obj, that);
281
282
1295
  if (obj->linked_)
283
3
    return;
284
1292
  obj->linked_ = true;
285
286
1292
  Local<Function> resolver_arg = args[0].As<Function>();
287
288
1292
  Local<Context> mod_context = obj->context();
289
2584
  Local<Module> module = obj->module_.Get(isolate);
290
291
1292
  Local<FixedArray> module_requests = module->GetModuleRequests();
292
1292
  const int module_requests_length = module_requests->Length();
293
1292
  MaybeStackBuffer<Local<Value>, 16> promises(module_requests_length);
294
295
  // call the dependency resolve callbacks
296
2308
  for (int i = 0; i < module_requests_length; i++) {
297
    Local<ModuleRequest> module_request =
298
2032
      module_requests->Get(env->context(), i).As<ModuleRequest>();
299
1016
    Local<String> specifier = module_request->GetSpecifier();
300
1016
    Utf8Value specifier_utf8(env->isolate(), specifier);
301
2032
    std::string specifier_std(*specifier_utf8, specifier_utf8.length());
302
303
1016
    Local<FixedArray> raw_assertions = module_request->GetImportAssertions();
304
    Local<Object> assertions =
305
1016
      createImportAssertionContainer(env, isolate, raw_assertions);
306
307
    Local<Value> argv[] = {
308
        specifier,
309
        assertions,
310
1016
    };
311
312
    MaybeLocal<Value> maybe_resolve_return_value =
313
1016
        resolver_arg->Call(mod_context, that, arraysize(argv), argv);
314
1016
    if (maybe_resolve_return_value.IsEmpty()) {
315
      return;
316
    }
317
    Local<Value> resolve_return_value =
318
1016
        maybe_resolve_return_value.ToLocalChecked();
319
1016
    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
1016
    Local<Promise> resolve_promise = resolve_return_value.As<Promise>();
325
1016
    obj->resolve_cache_[specifier_std].Reset(env->isolate(), resolve_promise);
326
327
1016
    promises[i] = resolve_promise;
328
  }
329
330
2584
  args.GetReturnValue().Set(
331
      Array::New(isolate, promises.out(), promises.length()));
332
}
333
334
49878
void ModuleWrap::Instantiate(const FunctionCallbackInfo<Value>& args) {
335
49878
  Environment* env = Environment::GetCurrent(args);
336
49878
  Isolate* isolate = args.GetIsolate();
337
  ModuleWrap* obj;
338
49892
  ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
339
49878
  Local<Context> context = obj->context();
340
49878
  Local<Module> module = obj->module_.Get(isolate);
341
49878
  TryCatchScope try_catch(env);
342
49878
  USE(module->InstantiateModule(context, ResolveModuleCallback));
343
344
  // clear resolve cache on instantiate
345
49878
  obj->resolve_cache_.clear();
346
347

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

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

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

49885
  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
49885
  if (try_catch.HasCaught()) {
426
9
    if (!try_catch.HasTerminated())
427
8
      try_catch.ReThrow();
428
9
    return;
429
  }
430
431
99752
  args.GetReturnValue().Set(result.ToLocalChecked());
432
}
433
434
414
void ModuleWrap::GetNamespace(const FunctionCallbackInfo<Value>& args) {
435
414
  Environment* env = Environment::GetCurrent(args);
436
414
  Isolate* isolate = args.GetIsolate();
437
  ModuleWrap* obj;
438
414
  ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
439
440
828
  Local<Module> module = obj->module_.Get(isolate);
441
442
414
  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
414
    case v8::Module::Status::kInstantiated:
448
    case v8::Module::Status::kEvaluating:
449
    case v8::Module::Status::kEvaluated:
450
    case v8::Module::Status::kErrored:
451
414
      break;
452
    default:
453
      UNREACHABLE();
454
  }
455
456
414
  Local<Value> result = module->GetModuleNamespace();
457
828
  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
971
MaybeLocal<Module> ModuleWrap::ResolveModuleCallback(
503
    Local<Context> context,
504
    Local<String> specifier,
505
    Local<FixedArray> import_assertions,
506
    Local<Module> referrer) {
507
971
  Environment* env = Environment::GetCurrent(context);
508
971
  if (env == nullptr) {
509
    Isolate* isolate = context->GetIsolate();
510
    THROW_ERR_EXECUTION_ENVIRONMENT_NOT_AVAILABLE(isolate);
511
    return MaybeLocal<Module>();
512
  }
513
514
971
  Isolate* isolate = env->isolate();
515
516
1942
  Utf8Value specifier_utf8(isolate, specifier);
517
1942
  std::string specifier_std(*specifier_utf8, specifier_utf8.length());
518
519
971
  ModuleWrap* dependent = GetFromModule(env, referrer);
520
971
  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
971
  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
1942
      dependent->resolve_cache_[specifier_std].Get(isolate);
534
535
971
  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
1942
  Local<Object> module_object = resolve_promise->Result().As<Object>();
542

1942
  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
971
  ASSIGN_OR_RETURN_UNWRAP(&module, module_object, MaybeLocal<Module>());
550
1942
  return module->module_.Get(isolate);
551
}
552
553
368
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
368
  Isolate* isolate = context->GetIsolate();
560
368
  Environment* env = Environment::GetCurrent(context);
561
368
  if (env == nullptr) {
562
    THROW_ERR_EXECUTION_ENVIRONMENT_NOT_AVAILABLE(isolate);
563
    return MaybeLocal<Promise>();
564
  }
565
566
368
  EscapableHandleScope handle_scope(isolate);
567
568
  Local<Function> import_callback =
569
368
    env->host_import_module_dynamically_callback();
570
571
368
  Local<FixedArray> options = host_defined_options.As<FixedArray>();
572
368
  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
368
  int type = options->Get(context, HostDefinedOptions::kType)
586
368
                 .As<Number>()
587
368
                 ->Int32Value(context)
588
368
                 .ToChecked();
589
368
  uint32_t id = options->Get(context, HostDefinedOptions::kID)
590
368
                    .As<Number>()
591
368
                    ->Uint32Value(context)
592
368
                    .ToChecked();
593
368
  if (type == ScriptType::kScript) {
594
9
    contextify::ContextifyScript* wrap = env->id_to_script_map.find(id)->second;
595
18
    object = wrap->object();
596
359
  } else if (type == ScriptType::kModule) {
597
258
    ModuleWrap* wrap = ModuleWrap::GetFromID(env, id);
598
516
    object = wrap->object();
599
101
  } else if (type == ScriptType::kFunction) {
600
101
    auto it = env->id_to_function_map.find(id);
601
101
    CHECK_NE(it, env->id_to_function_map.end());
602
202
    object = it->second->object();
603
  } else {
604
    UNREACHABLE();
605
  }
606
607
  Local<Object> assertions =
608
368
    createImportAssertionContainer(env, isolate, import_assertions);
609
610
  Local<Value> import_args[] = {
611
    object,
612
    Local<Value>(specifier),
613
    assertions,
614
368
  };
615
616
  Local<Value> result;
617
736
  if (import_callback->Call(
618
        context,
619
        Undefined(isolate),
620
368
        arraysize(import_args),
621
1104
        import_args).ToLocal(&result)) {
622
368
    CHECK(result->IsPromise());
623
368
    return handle_scope.Escape(result.As<Promise>());
624
  }
625
626
  return MaybeLocal<Promise>();
627
}
628
629
6018
void ModuleWrap::SetImportModuleDynamicallyCallback(
630
    const FunctionCallbackInfo<Value>& args) {
631
6018
  Isolate* isolate = args.GetIsolate();
632
6018
  Environment* env = Environment::GetCurrent(args);
633
12036
  HandleScope handle_scope(isolate);
634
635
6018
  CHECK_EQ(args.Length(), 1);
636
6018
  CHECK(args[0]->IsFunction());
637
6018
  Local<Function> import_callback = args[0].As<Function>();
638
6018
  env->set_host_import_module_dynamically_callback(import_callback);
639
640
6018
  isolate->SetHostImportModuleDynamicallyCallback(ImportModuleDynamically);
641
6018
}
642
643
159
void ModuleWrap::HostInitializeImportMetaObjectCallback(
644
    Local<Context> context, Local<Module> module, Local<Object> meta) {
645
159
  Environment* env = Environment::GetCurrent(context);
646
159
  if (env == nullptr)
647
    return;
648
159
  ModuleWrap* module_wrap = GetFromModule(env, module);
649
650
159
  if (module_wrap == nullptr) {
651
    return;
652
  }
653
654
159
  Local<Object> wrap = module_wrap->object();
655
  Local<Function> callback =
656
159
      env->host_initialize_import_meta_object_callback();
657
159
  Local<Value> args[] = { wrap, meta };
658
318
  TryCatchScope try_catch(env);
659
159
  USE(callback->Call(
660
318
        context, Undefined(env->isolate()), arraysize(args), args));
661

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

49544
  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
99078
  if (!Promise::Resolver::New(context).ToLocal(&resolver)) {
707
    return MaybeLocal<Value>();
708
  }
709
710
148617
  resolver->Resolve(context, Undefined(isolate)).ToChecked();
711
99078
  return resolver->GetPromise();
712
}
713
714
4294121
void ModuleWrap::SetSyntheticExport(const FunctionCallbackInfo<Value>& args) {
715
4294121
  Isolate* isolate = args.GetIsolate();
716
4294121
  Local<Object> that = args.This();
717
718
  ModuleWrap* obj;
719
4294121
  ASSIGN_OR_RETURN_UNWRAP(&obj, that);
720
721
4294121
  CHECK(obj->synthetic_);
722
723
4294121
  CHECK_EQ(args.Length(), 2);
724
725
8588242
  CHECK(args[0]->IsString());
726
8588242
  Local<String> export_name = args[0].As<String>();
727
728
4294121
  Local<Value> export_value = args[1];
729
730
8588242
  Local<Module> module = obj->module_.Get(isolate);
731
4294121
  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
6019
void ModuleWrap::Initialize(Local<Object> target,
764
                            Local<Value> unused,
765
                            Local<Context> context,
766
                            void* priv) {
767
6019
  Environment* env = Environment::GetCurrent(context);
768
769
6019
  Local<FunctionTemplate> tpl = env->NewFunctionTemplate(New);
770
12038
  tpl->InstanceTemplate()->SetInternalFieldCount(
771
      ModuleWrap::kInternalFieldCount);
772
6019
  tpl->Inherit(BaseObject::GetConstructorTemplate(env));
773
774
6019
  env->SetProtoMethod(tpl, "link", Link);
775
6019
  env->SetProtoMethod(tpl, "instantiate", Instantiate);
776
6019
  env->SetProtoMethod(tpl, "evaluate", Evaluate);
777
6019
  env->SetProtoMethod(tpl, "setExport", SetSyntheticExport);
778
6019
  env->SetProtoMethodNoSideEffect(tpl, "createCachedData", CreateCachedData);
779
6019
  env->SetProtoMethodNoSideEffect(tpl, "getNamespace", GetNamespace);
780
6019
  env->SetProtoMethodNoSideEffect(tpl, "getStatus", GetStatus);
781
6019
  env->SetProtoMethodNoSideEffect(tpl, "getError", GetError);
782
6019
  env->SetProtoMethodNoSideEffect(tpl, "getStaticDependencySpecifiers",
783
                                  GetStaticDependencySpecifiers);
784
785
6019
  env->SetConstructorFunction(target, "ModuleWrap", tpl);
786
787
6019
  env->SetMethod(target,
788
                 "setImportModuleDynamicallyCallback",
789
                 SetImportModuleDynamicallyCallback);
790
6019
  env->SetMethod(target,
791
                 "setInitializeImportMetaObjectCallback",
792
                 SetInitializeImportMetaObjectCallback);
793
794
#define V(name)                                                                \
795
    target->Set(context,                                                       \
796
      FIXED_ONE_BYTE_STRING(env->isolate(), #name),                            \
797
      Integer::New(env->isolate(), Module::Status::name))                      \
798
        .FromJust()
799
24076
    V(kUninstantiated);
800
24076
    V(kInstantiating);
801
24076
    V(kInstantiated);
802
24076
    V(kEvaluating);
803
24076
    V(kEvaluated);
804
18057
    V(kErrored);
805
#undef V
806
6019
}
807
808
}  // namespace loader
809
}  // namespace node
810
811
5274
NODE_MODULE_CONTEXT_AWARE_INTERNAL(module_wrap,
812
                                   node::loader::ModuleWrap::Initialize)