GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: module_wrap.cc Lines: 390 433 90.1 %
Date: 2022-02-09 04:14:30 Branches: 173 295 58.6 %

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
47038
ModuleWrap::ModuleWrap(Environment* env,
55
                       Local<Object> object,
56
                       Local<Module> module,
57
47038
                       Local<String> url)
58
  : BaseObject(env, object),
59
    module_(env->isolate(), module),
60
94076
    id_(env->get_next_module_id()) {
61
47038
  env->id_to_module_map.emplace(id_, this);
62
63
94076
  Local<Value> undefined = Undefined(env->isolate());
64
47038
  object->SetInternalField(kURLSlot, url);
65
47038
  object->SetInternalField(kSyntheticEvaluationStepsSlot, undefined);
66
47038
  object->SetInternalField(kContextObjectSlot, undefined);
67
47038
}
68
69
261300
ModuleWrap::~ModuleWrap() {
70
174200
  HandleScope scope(env()->isolate());
71
87100
  Local<Module> module = module_.Get(env()->isolate());
72
87100
  env()->id_to_module_map.erase(id_);
73
87100
  auto range = env()->hash_to_module_map.equal_range(module->GetIdentityHash());
74
87100
  for (auto it = range.first; it != range.second; ++it) {
75
87100
    if (it->second == this) {
76
87100
      env()->hash_to_module_map.erase(it);
77
87100
      break;
78
    }
79
  }
80
174200
}
81
82
94220
Local<Context> ModuleWrap::context() const {
83
282660
  Local<Value> obj = object()->GetInternalField(kContextObjectSlot);
84
94220
  if (obj.IsEmpty()) return {};
85
188440
  return obj.As<Object>()->GetCreationContext().ToLocalChecked();
86
}
87
88
47343
ModuleWrap* ModuleWrap::GetFromModule(Environment* env,
89
                                      Local<Module> module) {
90
47343
  auto range = env->hash_to_module_map.equal_range(module->GetIdentityHash());
91
47343
  for (auto it = range.first; it != range.second; ++it) {
92

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

632
      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

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

46604
  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
46614
void ModuleWrap::Evaluate(const FunctionCallbackInfo<Value>& args) {
358
46614
  Environment* env = Environment::GetCurrent(args);
359
46614
  Isolate* isolate = env->isolate();
360
  ModuleWrap* obj;
361
46623
  ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
362
46614
  Local<Context> context = obj->context();
363
46614
  Local<Module> module = obj->module_.Get(isolate);
364
365
46614
  ContextifyContext* contextify_context = obj->contextify_context_;
366
46614
  std::shared_ptr<MicrotaskQueue> microtask_queue;
367
46614
  if (contextify_context != nullptr)
368
4
      microtask_queue = contextify_context->microtask_queue();
369
370
  // module.evaluate(timeout, breakOnSigint)
371
46614
  CHECK_EQ(args.Length(), 2);
372
373
46614
  CHECK(args[0]->IsNumber());
374
93228
  int64_t timeout = args[0]->IntegerValue(env->context()).FromJust();
375
376
46614
  CHECK(args[1]->IsBoolean());
377
46614
  bool break_on_sigint = args[1]->IsTrue();
378
379
46614
  ShouldNotAbortOnUncaughtScope no_abort_scope(env);
380
46614
  TryCatchScope try_catch(env);
381
46614
  Isolate::SafeForTerminationScope safe_for_termination(env->isolate());
382
383
46614
  bool timed_out = false;
384
46614
  bool received_signal = false;
385
  MaybeLocal<Value> result;
386
46614
  auto run = [&]() {
387
46614
    MaybeLocal<Value> result = module->Evaluate(context);
388

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

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

46611
  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
46611
  if (try_catch.HasCaught()) {
426
9
    if (!try_catch.HasTerminated())
427
8
      try_catch.ReThrow();
428
9
    return;
429
  }
430
431
  // If TLA is enabled, `result` is the evaluation's promise.
432
  // Otherwise, `result` is the last evaluated value of the module,
433
  // which could be a promise, which would result in it being incorrectly
434
  // unwrapped when the higher level code awaits the evaluation.
435
46602
  if (env->isolate_data()->options()->experimental_top_level_await) {
436
93204
    args.GetReturnValue().Set(result.ToLocalChecked());
437
  }
438
}
439
440
283
void ModuleWrap::GetNamespace(const FunctionCallbackInfo<Value>& args) {
441
283
  Environment* env = Environment::GetCurrent(args);
442
283
  Isolate* isolate = args.GetIsolate();
443
  ModuleWrap* obj;
444
283
  ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
445
446
566
  Local<Module> module = obj->module_.Get(isolate);
447
448
283
  switch (module->GetStatus()) {
449
    case v8::Module::Status::kUninstantiated:
450
    case v8::Module::Status::kInstantiating:
451
      return env->ThrowError(
452
          "cannot get namespace, module has not been instantiated");
453
283
    case v8::Module::Status::kInstantiated:
454
    case v8::Module::Status::kEvaluating:
455
    case v8::Module::Status::kEvaluated:
456
    case v8::Module::Status::kErrored:
457
283
      break;
458
    default:
459
      UNREACHABLE();
460
  }
461
462
283
  Local<Value> result = module->GetModuleNamespace();
463
566
  args.GetReturnValue().Set(result);
464
}
465
466
215
void ModuleWrap::GetStatus(const FunctionCallbackInfo<Value>& args) {
467
215
  Isolate* isolate = args.GetIsolate();
468
  ModuleWrap* obj;
469
215
  ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
470
471
430
  Local<Module> module = obj->module_.Get(isolate);
472
473
430
  args.GetReturnValue().Set(module->GetStatus());
474
}
475
476
2
void ModuleWrap::GetStaticDependencySpecifiers(
477
    const FunctionCallbackInfo<Value>& args) {
478
2
  Environment* env = Environment::GetCurrent(args);
479
  ModuleWrap* obj;
480
2
  ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
481
482
4
  Local<Module> module = obj->module_.Get(env->isolate());
483
484
2
  Local<FixedArray> module_requests = module->GetModuleRequests();
485
2
  int count = module_requests->Length();
486
487
2
  MaybeStackBuffer<Local<Value>, 16> specifiers(count);
488
489
3
  for (int i = 0; i < count; i++) {
490
    Local<ModuleRequest> module_request =
491
2
      module_requests->Get(env->context(), i).As<ModuleRequest>();
492
2
    specifiers[i] = module_request->GetSpecifier();
493
  }
494
495
4
  args.GetReturnValue().Set(
496
      Array::New(env->isolate(), specifiers.out(), count));
497
}
498
499
1
void ModuleWrap::GetError(const FunctionCallbackInfo<Value>& args) {
500
1
  Isolate* isolate = args.GetIsolate();
501
  ModuleWrap* obj;
502
1
  ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
503
504
2
  Local<Module> module = obj->module_.Get(isolate);
505
2
  args.GetReturnValue().Set(module->GetException());
506
}
507
508
825
MaybeLocal<Module> ModuleWrap::ResolveModuleCallback(
509
    Local<Context> context,
510
    Local<String> specifier,
511
    Local<FixedArray> import_assertions,
512
    Local<Module> referrer) {
513
825
  Environment* env = Environment::GetCurrent(context);
514
825
  if (env == nullptr) {
515
    Isolate* isolate = context->GetIsolate();
516
    THROW_ERR_EXECUTION_ENVIRONMENT_NOT_AVAILABLE(isolate);
517
    return MaybeLocal<Module>();
518
  }
519
520
825
  Isolate* isolate = env->isolate();
521
522
1650
  Utf8Value specifier_utf8(isolate, specifier);
523
1650
  std::string specifier_std(*specifier_utf8, specifier_utf8.length());
524
525
825
  ModuleWrap* dependent = GetFromModule(env, referrer);
526
825
  if (dependent == nullptr) {
527
    THROW_ERR_VM_MODULE_LINK_FAILURE(
528
        env, "request for '%s' is from invalid module", specifier_std);
529
    return MaybeLocal<Module>();
530
  }
531
532
825
  if (dependent->resolve_cache_.count(specifier_std) != 1) {
533
    THROW_ERR_VM_MODULE_LINK_FAILURE(
534
        env, "request for '%s' is not in cache", specifier_std);
535
    return MaybeLocal<Module>();
536
  }
537
538
  Local<Promise> resolve_promise =
539
1650
      dependent->resolve_cache_[specifier_std].Get(isolate);
540
541
825
  if (resolve_promise->State() != Promise::kFulfilled) {
542
    THROW_ERR_VM_MODULE_LINK_FAILURE(
543
        env, "request for '%s' is not yet fulfilled", specifier_std);
544
    return MaybeLocal<Module>();
545
  }
546
547
1650
  Local<Object> module_object = resolve_promise->Result().As<Object>();
548

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

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

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