GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: module_wrap.cc Lines: 405 448 90.4 %
Date: 2022-12-31 04:22:30 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_external_reference.h"
8
#include "node_internals.h"
9
#include "node_process-inl.h"
10
#include "node_url.h"
11
#include "node_watchdog.h"
12
#include "util-inl.h"
13
14
#include <sys/stat.h>  // S_IFDIR
15
16
#include <algorithm>
17
18
namespace node {
19
namespace loader {
20
21
using errors::TryCatchScope;
22
23
using node::contextify::ContextifyContext;
24
using node::url::URL;
25
using node::url::URL_FLAGS_FAILED;
26
using v8::Array;
27
using v8::ArrayBufferView;
28
using v8::Context;
29
using v8::EscapableHandleScope;
30
using v8::FixedArray;
31
using v8::Function;
32
using v8::FunctionCallbackInfo;
33
using v8::FunctionTemplate;
34
using v8::HandleScope;
35
using v8::Int32;
36
using v8::Integer;
37
using v8::IntegrityLevel;
38
using v8::Isolate;
39
using v8::Local;
40
using v8::MaybeLocal;
41
using v8::MicrotaskQueue;
42
using v8::Module;
43
using v8::ModuleRequest;
44
using v8::Number;
45
using v8::Object;
46
using v8::PrimitiveArray;
47
using v8::Promise;
48
using v8::ScriptCompiler;
49
using v8::ScriptOrigin;
50
using v8::String;
51
using v8::UnboundModuleScript;
52
using v8::Undefined;
53
using v8::Value;
54
55
53684
ModuleWrap::ModuleWrap(Environment* env,
56
                       Local<Object> object,
57
                       Local<Module> module,
58
53684
                       Local<String> url)
59
  : BaseObject(env, object),
60
    module_(env->isolate(), module),
61
107368
    id_(env->get_next_module_id()) {
62
53684
  env->id_to_module_map.emplace(id_, this);
63
64
107368
  Local<Value> undefined = Undefined(env->isolate());
65
53684
  object->SetInternalField(kURLSlot, url);
66
53684
  object->SetInternalField(kSyntheticEvaluationStepsSlot, undefined);
67
53684
  object->SetInternalField(kContextObjectSlot, undefined);
68
53684
}
69
70
302400
ModuleWrap::~ModuleWrap() {
71
201600
  HandleScope scope(env()->isolate());
72
100800
  Local<Module> module = module_.Get(env()->isolate());
73
100800
  env()->id_to_module_map.erase(id_);
74
100800
  auto range = env()->hash_to_module_map.equal_range(module->GetIdentityHash());
75
100800
  for (auto it = range.first; it != range.second; ++it) {
76
100800
    if (it->second == this) {
77
100800
      env()->hash_to_module_map.erase(it);
78
100800
      break;
79
    }
80
  }
81
201600
}
82
83
108208
Local<Context> ModuleWrap::context() const {
84
324624
  Local<Value> obj = object()->GetInternalField(kContextObjectSlot);
85
108208
  if (obj.IsEmpty()) return {};
86
216416
  return obj.As<Object>()->GetCreationContext().ToLocalChecked();
87
}
88
89
54042
ModuleWrap* ModuleWrap::GetFromModule(Environment* env,
90
                                      Local<Module> module) {
91
54042
  auto range = env->hash_to_module_map.equal_range(module->GetIdentityHash());
92
54042
  for (auto it = range.first; it != range.second; ++it) {
93

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

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

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

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

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

53281
    if (!result.IsEmpty() && microtask_queue)
390
1
      microtask_queue->PerformCheckpoint(isolate);
391
53281
    return result;
392
53284
  };
393

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

53281
  if (timed_out || received_signal) {
413

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

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

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

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