GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage-daily/nodes/benchmark/out/../src/module_wrap.cc Lines: 374 417 89.7 %
Date: 2020-08-07 22:13:19 Branches: 155 261 59.4 %

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.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::Function;
30
using v8::FunctionCallbackInfo;
31
using v8::FunctionTemplate;
32
using v8::HandleScope;
33
using v8::Integer;
34
using v8::IntegrityLevel;
35
using v8::Isolate;
36
using v8::Local;
37
using v8::MaybeLocal;
38
using v8::MicrotaskQueue;
39
using v8::Module;
40
using v8::Number;
41
using v8::Object;
42
using v8::PrimitiveArray;
43
using v8::Promise;
44
using v8::ScriptCompiler;
45
using v8::ScriptOrigin;
46
using v8::ScriptOrModule;
47
using v8::String;
48
using v8::UnboundModuleScript;
49
using v8::Undefined;
50
using v8::Value;
51
52
31981
ModuleWrap::ModuleWrap(Environment* env,
53
                       Local<Object> object,
54
                       Local<Module> module,
55
31981
                       Local<String> url)
56
  : BaseObject(env, object),
57
    module_(env->isolate(), module),
58
63962
    id_(env->get_next_module_id()) {
59
31981
  env->id_to_module_map.emplace(id_, this);
60
61
31981
  Local<Value> undefined = Undefined(env->isolate());
62
31981
  object->SetInternalField(kURLSlot, url);
63
31981
  object->SetInternalField(kSyntheticEvaluationStepsSlot, undefined);
64
31981
  object->SetInternalField(kContextObjectSlot, undefined);
65
31981
}
66
67
118664
ModuleWrap::~ModuleWrap() {
68
59333
  HandleScope scope(env()->isolate());
69
59334
  Local<Module> module = module_.Get(env()->isolate());
70
29667
  env()->id_to_module_map.erase(id_);
71
29667
  auto range = env()->hash_to_module_map.equal_range(module->GetIdentityHash());
72
29666
  for (auto it = range.first; it != range.second; ++it) {
73
29666
    if (it->second == this) {
74
29666
      env()->hash_to_module_map.erase(it);
75
29667
      break;
76
    }
77
  }
78
59332
}
79
80
64064
Local<Context> ModuleWrap::context() const {
81
192192
  Local<Value> obj = object()->GetInternalField(kContextObjectSlot);
82
64064
  if (obj.IsEmpty()) return {};
83
128128
  return obj.As<Object>()->CreationContext();
84
}
85
86
32061
ModuleWrap* ModuleWrap::GetFromModule(Environment* env,
87
                                      Local<Module> module) {
88
32061
  auto range = env->hash_to_module_map.equal_range(module->GetIdentityHash());
89
32061
  for (auto it = range.first; it != range.second; ++it) {
90
64122
    if (it->second->module_ == module) {
91
32061
      return it->second;
92
    }
93
  }
94
  return nullptr;
95
}
96
97
73
ModuleWrap* ModuleWrap::GetFromID(Environment* env, uint32_t id) {
98
73
  auto module_wrap_it = env->id_to_module_map.find(id);
99
73
  if (module_wrap_it == env->id_to_module_map.end()) {
100
    return nullptr;
101
  }
102
73
  return module_wrap_it->second;
103
}
104
105
// new ModuleWrap(url, context, source, lineOffset, columnOffset)
106
// new ModuleWrap(url, context, exportNames, syntheticExecutionFunction)
107
31989
void ModuleWrap::New(const FunctionCallbackInfo<Value>& args) {
108
31989
  CHECK(args.IsConstructCall());
109
31989
  CHECK_GE(args.Length(), 3);
110
111
31989
  Environment* env = Environment::GetCurrent(args);
112
31989
  Isolate* isolate = env->isolate();
113
114
31989
  Local<Object> that = args.This();
115
116
95967
  CHECK(args[0]->IsString());
117
63978
  Local<String> url = args[0].As<String>();
118
119
  Local<Context> context;
120
31989
  ContextifyContext* contextify_context = nullptr;
121
95967
  if (args[1]->IsUndefined()) {
122
31980
    context = that->CreationContext();
123
  } else {
124
18
    CHECK(args[1]->IsObject());
125
9
    contextify_context = ContextifyContext::ContextFromContextifiedSandbox(
126
27
        env, args[1].As<Object>());
127
9
    CHECK_NOT_NULL(contextify_context);
128
9
    context = contextify_context->context();
129
  }
130
131
  Local<Integer> line_offset;
132
  Local<Integer> column_offset;
133
134
63978
  bool synthetic = args[2]->IsArray();
135
31989
  if (synthetic) {
136
    // new ModuleWrap(url, context, exportNames, syntheticExecutionFunction)
137
63292
    CHECK(args[3]->IsFunction());
138
  } else {
139
    // new ModuleWrap(url, context, source, lineOffset, columOffset, cachedData)
140
1029
    CHECK(args[2]->IsString());
141
686
    CHECK(args[3]->IsNumber());
142
686
    line_offset = args[3].As<Integer>();
143
686
    CHECK(args[4]->IsNumber());
144
686
    column_offset = args[4].As<Integer>();
145
  }
146
147
  Local<PrimitiveArray> host_defined_options =
148
31989
      PrimitiveArray::New(isolate, HostDefinedOptions::kLength);
149
95967
  host_defined_options->Set(isolate, HostDefinedOptions::kType,
150
31989
                            Number::New(isolate, ScriptType::kModule));
151
152
63970
  ShouldNotAbortOnUncaughtScope no_abort_scope(env);
153
63970
  TryCatchScope try_catch(env);
154
155
  Local<Module> module;
156
157
  {
158
31981
    Context::Scope context_scope(context);
159
31989
    if (synthetic) {
160
63292
      CHECK(args[2]->IsArray());
161
63292
      Local<Array> export_names_arr = args[2].As<Array>();
162
163
31646
      uint32_t len = export_names_arr->Length();
164
63292
      std::vector<Local<String>> export_names(len);
165
912421
      for (uint32_t i = 0; i < len; i++) {
166
        Local<Value> export_name_val =
167
1761550
            export_names_arr->Get(context, i).ToLocalChecked();
168
1761550
        CHECK(export_name_val->IsString());
169
1761550
        export_names[i] = export_name_val.As<String>();
170
      }
171
172
      module = Module::CreateSyntheticModule(isolate, url, export_names,
173
31646
        SyntheticModuleEvaluationStepsCallback);
174
    } else {
175
343
      ScriptCompiler::CachedData* cached_data = nullptr;
176
1029
      if (!args[5]->IsUndefined()) {
177
4
        CHECK(args[5]->IsArrayBufferView());
178
4
        Local<ArrayBufferView> cached_data_buf = args[5].As<ArrayBufferView>();
179
        uint8_t* data = static_cast<uint8_t*>(
180
4
            cached_data_buf->Buffer()->GetBackingStore()->Data());
181
2
        cached_data =
182
2
            new ScriptCompiler::CachedData(data + cached_data_buf->ByteOffset(),
183
2
                                           cached_data_buf->ByteLength());
184
      }
185
186
686
      Local<String> source_text = args[2].As<String>();
187
      ScriptOrigin origin(url,
188
                          line_offset,                      // line offset
189
                          column_offset,                    // column offset
190
                          True(isolate),                    // is cross origin
191
                          Local<Integer>(),                 // script id
192
                          Local<Value>(),                   // source map URL
193
                          False(isolate),                   // is opaque (?)
194
                          False(isolate),                   // is WASM
195
                          True(isolate),                    // is ES Module
196
343
                          host_defined_options);
197
335
      ScriptCompiler::Source source(source_text, origin, cached_data);
198
      ScriptCompiler::CompileOptions options;
199
343
      if (source.GetCachedData() == nullptr) {
200
341
        options = ScriptCompiler::kNoCompileOptions;
201
      } else {
202
2
        options = ScriptCompiler::kConsumeCodeCache;
203
      }
204
686
      if (!ScriptCompiler::CompileModule(isolate, &source, options)
205
343
               .ToLocal(&module)) {
206

7
        if (try_catch.HasCaught() && !try_catch.HasTerminated()) {
207
14
          CHECK(!try_catch.Message().IsEmpty());
208
14
          CHECK(!try_catch.Exception().IsEmpty());
209
7
          AppendExceptionLine(env, try_catch.Exception(), try_catch.Message(),
210
7
                              ErrorHandlingMode::MODULE_ERROR);
211
7
          try_catch.ReThrow();
212
        }
213
7
        return;
214
      }
215

338
      if (options == ScriptCompiler::kConsumeCodeCache &&
216
2
          source.GetCachedData()->rejected) {
217
        THROW_ERR_VM_MODULE_CACHED_DATA_REJECTED(
218
1
            env, "cachedData buffer was rejected");
219
1
        try_catch.ReThrow();
220
1
        return;
221
      }
222
    }
223
  }
224
225
127924
  if (!that->Set(context, env->url_string(), url).FromMaybe(false)) {
226
    return;
227
  }
228
229
31981
  ModuleWrap* obj = new ModuleWrap(env, that, module, url);
230
231
31981
  if (synthetic) {
232
31646
    obj->synthetic_ = true;
233
63292
    obj->object()->SetInternalField(kSyntheticEvaluationStepsSlot, args[3]);
234
  }
235
236
  // Use the extras object as an object whose CreationContext() will be the
237
  // original `context`, since the `Context` itself strictly speaking cannot
238
  // be stored in an internal field.
239
127924
  obj->object()->SetInternalField(kContextObjectSlot,
240
31981
      context->GetExtrasBindingObject());
241
31981
  obj->contextify_context_ = contextify_context;
242
243
31981
  env->hash_to_module_map.emplace(module->GetIdentityHash(), obj);
244
245
95943
  host_defined_options->Set(isolate, HostDefinedOptions::kID,
246
63962
                            Number::New(isolate, obj->id()));
247
248
31981
  that->SetIntegrityLevel(context, IntegrityLevel::kFrozen);
249
63962
  args.GetReturnValue().Set(that);
250
}
251
252
524
void ModuleWrap::Link(const FunctionCallbackInfo<Value>& args) {
253
524
  Environment* env = Environment::GetCurrent(args);
254
524
  Isolate* isolate = args.GetIsolate();
255
256
524
  CHECK_EQ(args.Length(), 1);
257
1048
  CHECK(args[0]->IsFunction());
258
259
524
  Local<Object> that = args.This();
260
261
  ModuleWrap* obj;
262
527
  ASSIGN_OR_RETURN_UNWRAP(&obj, that);
263
264
524
  if (obj->linked_)
265
3
    return;
266
521
  obj->linked_ = true;
267
268
1042
  Local<Function> resolver_arg = args[0].As<Function>();
269
270
521
  Local<Context> mod_context = obj->context();
271
1042
  Local<Module> module = obj->module_.Get(isolate);
272
273
521
  const int module_requests_length = module->GetModuleRequestsLength();
274
1042
  MaybeStackBuffer<Local<Value>, 16> promises(module_requests_length);
275
276
  // call the dependency resolve callbacks
277
892
  for (int i = 0; i < module_requests_length; i++) {
278
371
    Local<String> specifier = module->GetModuleRequest(i);
279
742
    Utf8Value specifier_utf8(env->isolate(), specifier);
280
742
    std::string specifier_std(*specifier_utf8, specifier_utf8.length());
281
282
    Local<Value> argv[] = {
283
      specifier
284
742
    };
285
286
    MaybeLocal<Value> maybe_resolve_return_value =
287
742
        resolver_arg->Call(mod_context, that, arraysize(argv), argv);
288
371
    if (maybe_resolve_return_value.IsEmpty()) {
289
      return;
290
    }
291
    Local<Value> resolve_return_value =
292
371
        maybe_resolve_return_value.ToLocalChecked();
293
371
    if (!resolve_return_value->IsPromise()) {
294
      env->ThrowError("linking error, expected resolver to return a promise");
295
    }
296
371
    Local<Promise> resolve_promise = resolve_return_value.As<Promise>();
297
371
    obj->resolve_cache_[specifier_std].Reset(env->isolate(), resolve_promise);
298
299
742
    promises[i] = resolve_promise;
300
  }
301
302
1563
  args.GetReturnValue().Set(
303
      Array::New(isolate, promises.out(), promises.length()));
304
}
305
306
31776
void ModuleWrap::Instantiate(const FunctionCallbackInfo<Value>& args) {
307
31776
  Environment* env = Environment::GetCurrent(args);
308
31776
  Isolate* isolate = args.GetIsolate();
309
  ModuleWrap* obj;
310
31786
  ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
311
31776
  Local<Context> context = obj->context();
312
63552
  Local<Module> module = obj->module_.Get(isolate);
313
63542
  TryCatchScope try_catch(env);
314
31776
  USE(module->InstantiateModule(context, ResolveCallback));
315
316
  // clear resolve cache on instantiate
317
31776
  obj->resolve_cache_.clear();
318
319

31776
  if (try_catch.HasCaught() && !try_catch.HasTerminated()) {
320
20
    CHECK(!try_catch.Message().IsEmpty());
321
20
    CHECK(!try_catch.Exception().IsEmpty());
322
10
    AppendExceptionLine(env, try_catch.Exception(), try_catch.Message(),
323
10
                        ErrorHandlingMode::MODULE_ERROR);
324
10
    try_catch.ReThrow();
325
10
    return;
326
  }
327
}
328
329
31767
void ModuleWrap::Evaluate(const FunctionCallbackInfo<Value>& args) {
330
31767
  Environment* env = Environment::GetCurrent(args);
331
31767
  Isolate* isolate = env->isolate();
332
  ModuleWrap* obj;
333
31771
  ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
334
31767
  Local<Context> context = obj->context();
335
63534
  Local<Module> module = obj->module_.Get(isolate);
336
337
31767
  ContextifyContext* contextify_context = obj->contextify_context_;
338
63529
  std::shared_ptr<MicrotaskQueue> microtask_queue;
339
31767
  if (contextify_context != nullptr)
340
3
      microtask_queue = contextify_context->microtask_queue();
341
342
  // module.evaluate(timeout, breakOnSigint)
343
31767
  CHECK_EQ(args.Length(), 2);
344
345
63534
  CHECK(args[0]->IsNumber());
346
127068
  int64_t timeout = args[0]->IntegerValue(env->context()).FromJust();
347
348
63534
  CHECK(args[1]->IsBoolean());
349
63534
  bool break_on_sigint = args[1]->IsTrue();
350
351
63529
  ShouldNotAbortOnUncaughtScope no_abort_scope(env);
352
63529
  TryCatchScope try_catch(env);
353
354
31767
  bool timed_out = false;
355
31767
  bool received_signal = false;
356
  MaybeLocal<Value> result;
357
31767
  auto run = [&]() {
358
63534
    MaybeLocal<Value> result = module->Evaluate(context);
359

31766
    if (!result.IsEmpty() && microtask_queue)
360
1
      microtask_queue->PerformCheckpoint(isolate);
361
31766
    return result;
362
31767
  };
363

31767
  if (break_on_sigint && timeout != -1) {
364
    Watchdog wd(isolate, timeout, &timed_out);
365
    SigintWatchdog swd(isolate, &received_signal);
366
    result = run();
367
31767
  } else if (break_on_sigint) {
368
    SigintWatchdog swd(isolate, &received_signal);
369
    result = run();
370
31767
  } else if (timeout != -1) {
371
6
    Watchdog wd(isolate, timeout, &timed_out);
372
3
    result = run();
373
  } else {
374
31764
    result = run();
375
  }
376
377
31766
  if (result.IsEmpty()) {
378
3
    CHECK(try_catch.HasCaught());
379
  }
380
381
  // Convert the termination exception into a regular exception.
382

31766
  if (timed_out || received_signal) {
383

3
    if (!env->is_main_thread() && env->is_stopping())
384
      return;
385
3
    env->isolate()->CancelTerminateExecution();
386
    // It is possible that execution was terminated by another timeout in
387
    // which this timeout is nested, so check whether one of the watchdogs
388
    // from this invocation is responsible for termination.
389
3
    if (timed_out) {
390
3
      THROW_ERR_SCRIPT_EXECUTION_TIMEOUT(env, timeout);
391
    } else if (received_signal) {
392
      THROW_ERR_SCRIPT_EXECUTION_INTERRUPTED(env);
393
    }
394
  }
395
396
31766
  if (try_catch.HasCaught()) {
397
4
    if (!try_catch.HasTerminated())
398
3
      try_catch.ReThrow();
399
4
    return;
400
  }
401
402
  // If TLA is enabled, `result` is the evaluation's promise.
403
  // Otherwise, `result` is the last evaluated value of the module,
404
  // which could be a promise, which would result in it being incorrectly
405
  // unwrapped when the higher level code awaits the evaluation.
406
31762
  if (env->isolate_data()->options()->experimental_top_level_await) {
407
63506
    args.GetReturnValue().Set(result.ToLocalChecked());
408
  }
409
}
410
411
162
void ModuleWrap::GetNamespace(const FunctionCallbackInfo<Value>& args) {
412
162
  Environment* env = Environment::GetCurrent(args);
413
162
  Isolate* isolate = args.GetIsolate();
414
  ModuleWrap* obj;
415
162
  ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
416
417
324
  Local<Module> module = obj->module_.Get(isolate);
418
419
162
  switch (module->GetStatus()) {
420
    case v8::Module::Status::kUninstantiated:
421
    case v8::Module::Status::kInstantiating:
422
      return env->ThrowError(
423
          "cannot get namespace, module has not been instantiated");
424
    case v8::Module::Status::kInstantiated:
425
    case v8::Module::Status::kEvaluating:
426
    case v8::Module::Status::kEvaluated:
427
    case v8::Module::Status::kErrored:
428
162
      break;
429
    default:
430
      UNREACHABLE();
431
  }
432
433
162
  Local<Value> result = module->GetModuleNamespace();
434
324
  args.GetReturnValue().Set(result);
435
}
436
437
211
void ModuleWrap::GetStatus(const FunctionCallbackInfo<Value>& args) {
438
211
  Isolate* isolate = args.GetIsolate();
439
  ModuleWrap* obj;
440
211
  ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
441
442
422
  Local<Module> module = obj->module_.Get(isolate);
443
444
633
  args.GetReturnValue().Set(module->GetStatus());
445
}
446
447
2
void ModuleWrap::GetStaticDependencySpecifiers(
448
    const FunctionCallbackInfo<Value>& args) {
449
2
  Environment* env = Environment::GetCurrent(args);
450
  ModuleWrap* obj;
451
2
  ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
452
453
4
  Local<Module> module = obj->module_.Get(env->isolate());
454
455
2
  int count = module->GetModuleRequestsLength();
456
457
4
  MaybeStackBuffer<Local<Value>, 16> specifiers(count);
458
459
3
  for (int i = 0; i < count; i++)
460
3
    specifiers[i] = module->GetModuleRequest(i);
461
462
6
  args.GetReturnValue().Set(
463
      Array::New(env->isolate(), specifiers.out(), count));
464
}
465
466
1
void ModuleWrap::GetError(const FunctionCallbackInfo<Value>& args) {
467
1
  Isolate* isolate = args.GetIsolate();
468
  ModuleWrap* obj;
469
1
  ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
470
471
2
  Local<Module> module = obj->module_.Get(isolate);
472
3
  args.GetReturnValue().Set(module->GetException());
473
}
474
475
352
MaybeLocal<Module> ModuleWrap::ResolveCallback(Local<Context> context,
476
                                               Local<String> specifier,
477
                                               Local<Module> referrer) {
478
352
  Environment* env = Environment::GetCurrent(context);
479
352
  if (env == nullptr) {
480
    Isolate* isolate = context->GetIsolate();
481
    THROW_ERR_EXECUTION_ENVIRONMENT_NOT_AVAILABLE(isolate);
482
    return MaybeLocal<Module>();
483
  }
484
485
352
  Isolate* isolate = env->isolate();
486
487
352
  ModuleWrap* dependent = GetFromModule(env, referrer);
488
352
  if (dependent == nullptr) {
489
    env->ThrowError("linking error, null dep");
490
    return MaybeLocal<Module>();
491
  }
492
493
704
  Utf8Value specifier_utf8(isolate, specifier);
494
704
  std::string specifier_std(*specifier_utf8, specifier_utf8.length());
495
496
352
  if (dependent->resolve_cache_.count(specifier_std) != 1) {
497
    env->ThrowError("linking error, not in local cache");
498
    return MaybeLocal<Module>();
499
  }
500
501
  Local<Promise> resolve_promise =
502
704
      dependent->resolve_cache_[specifier_std].Get(isolate);
503
504
352
  if (resolve_promise->State() != Promise::kFulfilled) {
505
    env->ThrowError("linking error, dependency promises must be resolved on "
506
                    "instantiate");
507
    return MaybeLocal<Module>();
508
  }
509
510
704
  Local<Object> module_object = resolve_promise->Result().As<Object>();
511

704
  if (module_object.IsEmpty() || !module_object->IsObject()) {
512
    env->ThrowError("linking error, expected a valid module object from "
513
                    "resolver");
514
    return MaybeLocal<Module>();
515
  }
516
517
  ModuleWrap* module;
518
352
  ASSIGN_OR_RETURN_UNWRAP(&module, module_object, MaybeLocal<Module>());
519
704
  return module->module_.Get(isolate);
520
}
521
522
132
static MaybeLocal<Promise> ImportModuleDynamically(
523
    Local<Context> context,
524
    Local<ScriptOrModule> referrer,
525
    Local<String> specifier) {
526
132
  Isolate* iso = context->GetIsolate();
527
132
  Environment* env = Environment::GetCurrent(context);
528
132
  if (env == nullptr) {
529
    THROW_ERR_EXECUTION_ENVIRONMENT_NOT_AVAILABLE(iso);
530
    return MaybeLocal<Promise>();
531
  }
532
533
132
  EscapableHandleScope handle_scope(iso);
534
535
  Local<Function> import_callback =
536
132
    env->host_import_module_dynamically_callback();
537
538
132
  Local<PrimitiveArray> options = referrer->GetHostDefinedOptions();
539
132
  if (options->Length() != HostDefinedOptions::kLength) {
540
    Local<Promise::Resolver> resolver;
541
    if (!Promise::Resolver::New(context).ToLocal(&resolver)) return {};
542
    resolver
543
        ->Reject(context,
544
                 v8::Exception::TypeError(FIXED_ONE_BYTE_STRING(
545
                     context->GetIsolate(), "Invalid host defined options")))
546
        .ToChecked();
547
    return handle_scope.Escape(resolver->GetPromise());
548
  }
549
550
  Local<Value> object;
551
552
264
  int type = options->Get(iso, HostDefinedOptions::kType)
553
264
                 .As<Number>()
554
264
                 ->Int32Value(context)
555
132
                 .ToChecked();
556
264
  uint32_t id = options->Get(iso, HostDefinedOptions::kID)
557
264
                    .As<Number>()
558
264
                    ->Uint32Value(context)
559
132
                    .ToChecked();
560
132
  if (type == ScriptType::kScript) {
561
7
    contextify::ContextifyScript* wrap = env->id_to_script_map.find(id)->second;
562
14
    object = wrap->object();
563
125
  } else if (type == ScriptType::kModule) {
564
73
    ModuleWrap* wrap = ModuleWrap::GetFromID(env, id);
565
146
    object = wrap->object();
566
52
  } else if (type == ScriptType::kFunction) {
567
52
    auto it = env->id_to_function_map.find(id);
568
52
    CHECK_NE(it, env->id_to_function_map.end());
569
104
    object = it->second->object();
570
  } else {
571
    UNREACHABLE();
572
  }
573
574
  Local<Value> import_args[] = {
575
    object,
576
    Local<Value>(specifier),
577
264
  };
578
579
  Local<Value> result;
580
396
  if (import_callback->Call(
581
        context,
582
        Undefined(iso),
583
132
        arraysize(import_args),
584
396
        import_args).ToLocal(&result)) {
585
132
    CHECK(result->IsPromise());
586
132
    return handle_scope.Escape(result.As<Promise>());
587
  }
588
589
  return MaybeLocal<Promise>();
590
}
591
592
4730
void ModuleWrap::SetImportModuleDynamicallyCallback(
593
    const FunctionCallbackInfo<Value>& args) {
594
4730
  Isolate* iso = args.GetIsolate();
595
4730
  Environment* env = Environment::GetCurrent(args);
596
9460
  HandleScope handle_scope(iso);
597
598
4730
  CHECK_EQ(args.Length(), 1);
599
9460
  CHECK(args[0]->IsFunction());
600
9460
  Local<Function> import_callback = args[0].As<Function>();
601
4730
  env->set_host_import_module_dynamically_callback(import_callback);
602
603
4730
  iso->SetHostImportModuleDynamicallyCallback(ImportModuleDynamically);
604
4730
}
605
606
77
void ModuleWrap::HostInitializeImportMetaObjectCallback(
607
    Local<Context> context, Local<Module> module, Local<Object> meta) {
608
77
  Environment* env = Environment::GetCurrent(context);
609
77
  if (env == nullptr)
610
    return;
611
77
  ModuleWrap* module_wrap = GetFromModule(env, module);
612
613
77
  if (module_wrap == nullptr) {
614
    return;
615
  }
616
617
77
  Local<Object> wrap = module_wrap->object();
618
  Local<Function> callback =
619
77
      env->host_initialize_import_meta_object_callback();
620
231
  Local<Value> args[] = { wrap, meta };
621
154
  TryCatchScope try_catch(env);
622
154
  USE(callback->Call(
623
308
        context, Undefined(env->isolate()), arraysize(args), args));
624

77
  if (try_catch.HasCaught() && !try_catch.HasTerminated()) {
625
    try_catch.ReThrow();
626
  }
627
}
628
629
4730
void ModuleWrap::SetInitializeImportMetaObjectCallback(
630
    const FunctionCallbackInfo<Value>& args) {
631
4730
  Environment* env = Environment::GetCurrent(args);
632
4730
  Isolate* isolate = env->isolate();
633
634
4730
  CHECK_EQ(args.Length(), 1);
635
9460
  CHECK(args[0]->IsFunction());
636
9460
  Local<Function> import_meta_callback = args[0].As<Function>();
637
4730
  env->set_host_initialize_import_meta_object_callback(import_meta_callback);
638
639
  isolate->SetHostInitializeImportMetaObjectCallback(
640
4730
      HostInitializeImportMetaObjectCallback);
641
4730
}
642
643
31632
MaybeLocal<Value> ModuleWrap::SyntheticModuleEvaluationStepsCallback(
644
    Local<Context> context, Local<Module> module) {
645
31632
  Environment* env = Environment::GetCurrent(context);
646
31632
  Isolate* isolate = env->isolate();
647
648
31632
  ModuleWrap* obj = GetFromModule(env, module);
649
650
63264
  TryCatchScope try_catch(env);
651
  Local<Function> synthetic_evaluation_steps =
652
126528
      obj->object()->GetInternalField(kSyntheticEvaluationStepsSlot)
653
31632
          .As<Function>();
654
94896
  obj->object()->SetInternalField(
655
31632
      kSyntheticEvaluationStepsSlot, Undefined(isolate));
656
  MaybeLocal<Value> ret = synthetic_evaluation_steps->Call(context,
657
63264
      obj->object(), 0, nullptr);
658
31632
  if (ret.IsEmpty()) {
659
    CHECK(try_catch.HasCaught());
660
  }
661

31632
  if (try_catch.HasCaught() && !try_catch.HasTerminated()) {
662
    CHECK(!try_catch.Message().IsEmpty());
663
    CHECK(!try_catch.Exception().IsEmpty());
664
    try_catch.ReThrow();
665
    return MaybeLocal<Value>();
666
  }
667
31632
  return Undefined(isolate);
668
}
669
670
2676690
void ModuleWrap::SetSyntheticExport(const FunctionCallbackInfo<Value>& args) {
671
2676690
  Isolate* isolate = args.GetIsolate();
672
2676690
  Local<Object> that = args.This();
673
674
  ModuleWrap* obj;
675
2676690
  ASSIGN_OR_RETURN_UNWRAP(&obj, that);
676
677
2676701
  CHECK(obj->synthetic_);
678
679
2676701
  CHECK_EQ(args.Length(), 2);
680
681
8030103
  CHECK(args[0]->IsString());
682
5353402
  Local<String> export_name = args[0].As<String>();
683
684
2676701
  Local<Value> export_value = args[1];
685
686
5353402
  Local<Module> module = obj->module_.Get(isolate);
687
2676701
  USE(module->SetSyntheticModuleExport(isolate, export_name, export_value));
688
}
689
690
1
void ModuleWrap::CreateCachedData(const FunctionCallbackInfo<Value>& args) {
691
1
  Isolate* isolate = args.GetIsolate();
692
1
  Local<Object> that = args.This();
693
694
  ModuleWrap* obj;
695
1
  ASSIGN_OR_RETURN_UNWRAP(&obj, that);
696
697
1
  CHECK(!obj->synthetic_);
698
699
2
  Local<Module> module = obj->module_.Get(isolate);
700
701
1
  CHECK_LT(module->GetStatus(), v8::Module::Status::kEvaluating);
702
703
  Local<UnboundModuleScript> unbound_module_script =
704
1
      module->GetUnboundModuleScript();
705
  std::unique_ptr<ScriptCompiler::CachedData> cached_data(
706
2
      ScriptCompiler::CreateCodeCache(unbound_module_script));
707
1
  Environment* env = Environment::GetCurrent(args);
708
1
  if (!cached_data) {
709
    args.GetReturnValue().Set(Buffer::New(env, 0).ToLocalChecked());
710
  } else {
711
    MaybeLocal<Object> buf =
712
        Buffer::Copy(env,
713
1
                     reinterpret_cast<const char*>(cached_data->data),
714
2
                     cached_data->length);
715
2
    args.GetReturnValue().Set(buf.ToLocalChecked());
716
  }
717
}
718
719
4731
void ModuleWrap::Initialize(Local<Object> target,
720
                            Local<Value> unused,
721
                            Local<Context> context,
722
                            void* priv) {
723
4731
  Environment* env = Environment::GetCurrent(context);
724
4731
  Isolate* isolate = env->isolate();
725
726
4731
  Local<FunctionTemplate> tpl = env->NewFunctionTemplate(New);
727
9462
  tpl->SetClassName(FIXED_ONE_BYTE_STRING(isolate, "ModuleWrap"));
728
14193
  tpl->InstanceTemplate()->SetInternalFieldCount(
729
4731
      ModuleWrap::kInternalFieldCount);
730
9462
  tpl->Inherit(BaseObject::GetConstructorTemplate(env));
731
732
4731
  env->SetProtoMethod(tpl, "link", Link);
733
4731
  env->SetProtoMethod(tpl, "instantiate", Instantiate);
734
4731
  env->SetProtoMethod(tpl, "evaluate", Evaluate);
735
4731
  env->SetProtoMethod(tpl, "setExport", SetSyntheticExport);
736
4731
  env->SetProtoMethodNoSideEffect(tpl, "createCachedData", CreateCachedData);
737
4731
  env->SetProtoMethodNoSideEffect(tpl, "getNamespace", GetNamespace);
738
4731
  env->SetProtoMethodNoSideEffect(tpl, "getStatus", GetStatus);
739
4731
  env->SetProtoMethodNoSideEffect(tpl, "getError", GetError);
740
  env->SetProtoMethodNoSideEffect(tpl, "getStaticDependencySpecifiers",
741
4731
                                  GetStaticDependencySpecifiers);
742
743
9462
  target->Set(env->context(), FIXED_ONE_BYTE_STRING(isolate, "ModuleWrap"),
744
23655
              tpl->GetFunction(context).ToLocalChecked()).Check();
745
  env->SetMethod(target,
746
                 "setImportModuleDynamicallyCallback",
747
4731
                 SetImportModuleDynamicallyCallback);
748
  env->SetMethod(target,
749
                 "setInitializeImportMetaObjectCallback",
750
4731
                 SetInitializeImportMetaObjectCallback);
751
752
#define V(name)                                                                \
753
    target->Set(context,                                                       \
754
      FIXED_ONE_BYTE_STRING(env->isolate(), #name),                            \
755
      Integer::New(env->isolate(), Module::Status::name))                      \
756
        .FromJust()
757
18924
    V(kUninstantiated);
758
18924
    V(kInstantiating);
759
18924
    V(kInstantiated);
760
18924
    V(kEvaluating);
761
18924
    V(kEvaluated);
762
18924
    V(kErrored);
763
#undef V
764
4731
}
765
766
}  // namespace loader
767
}  // namespace node
768
769

17763
NODE_MODULE_CONTEXT_AWARE_INTERNAL(module_wrap,
770
                                   node::loader::ModuleWrap::Initialize)