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-17 22:13:26 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
32056
ModuleWrap::ModuleWrap(Environment* env,
53
                       Local<Object> object,
54
                       Local<Module> module,
55
32056
                       Local<String> url)
56
  : BaseObject(env, object),
57
    module_(env->isolate(), module),
58
64112
    id_(env->get_next_module_id()) {
59
32056
  env->id_to_module_map.emplace(id_, this);
60
61
32056
  Local<Value> undefined = Undefined(env->isolate());
62
32056
  object->SetInternalField(kURLSlot, url);
63
32056
  object->SetInternalField(kSyntheticEvaluationStepsSlot, undefined);
64
32056
  object->SetInternalField(kContextObjectSlot, undefined);
65
32056
}
66
67
119150
ModuleWrap::~ModuleWrap() {
68
59575
  HandleScope scope(env()->isolate());
69
59576
  Local<Module> module = module_.Get(env()->isolate());
70
29788
  env()->id_to_module_map.erase(id_);
71
29788
  auto range = env()->hash_to_module_map.equal_range(module->GetIdentityHash());
72
29788
  for (auto it = range.first; it != range.second; ++it) {
73
29788
    if (it->second == this) {
74
29788
      env()->hash_to_module_map.erase(it);
75
29787
      break;
76
    }
77
  }
78
59576
}
79
80
64227
Local<Context> ModuleWrap::context() const {
81
192681
  Local<Value> obj = object()->GetInternalField(kContextObjectSlot);
82
64227
  if (obj.IsEmpty()) return {};
83
128454
  return obj.As<Object>()->CreationContext();
84
}
85
86
32138
ModuleWrap* ModuleWrap::GetFromModule(Environment* env,
87
                                      Local<Module> module) {
88
32138
  auto range = env->hash_to_module_map.equal_range(module->GetIdentityHash());
89
32138
  for (auto it = range.first; it != range.second; ++it) {
90
64276
    if (it->second->module_ == module) {
91
32138
      return it->second;
92
    }
93
  }
94
  return nullptr;
95
}
96
97
74
ModuleWrap* ModuleWrap::GetFromID(Environment* env, uint32_t id) {
98
74
  auto module_wrap_it = env->id_to_module_map.find(id);
99
74
  if (module_wrap_it == env->id_to_module_map.end()) {
100
    return nullptr;
101
  }
102
74
  return module_wrap_it->second;
103
}
104
105
// new ModuleWrap(url, context, source, lineOffset, columnOffset)
106
// new ModuleWrap(url, context, exportNames, syntheticExecutionFunction)
107
32064
void ModuleWrap::New(const FunctionCallbackInfo<Value>& args) {
108
32064
  CHECK(args.IsConstructCall());
109
32064
  CHECK_GE(args.Length(), 3);
110
111
32064
  Environment* env = Environment::GetCurrent(args);
112
32064
  Isolate* isolate = env->isolate();
113
114
32064
  Local<Object> that = args.This();
115
116
96192
  CHECK(args[0]->IsString());
117
64128
  Local<String> url = args[0].As<String>();
118
119
  Local<Context> context;
120
32064
  ContextifyContext* contextify_context = nullptr;
121
96192
  if (args[1]->IsUndefined()) {
122
32055
    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
64128
  bool synthetic = args[2]->IsArray();
135
32064
  if (synthetic) {
136
    // new ModuleWrap(url, context, exportNames, syntheticExecutionFunction)
137
63416
    CHECK(args[3]->IsFunction());
138
  } else {
139
    // new ModuleWrap(url, context, source, lineOffset, columOffset, cachedData)
140
1068
    CHECK(args[2]->IsString());
141
712
    CHECK(args[3]->IsNumber());
142
712
    line_offset = args[3].As<Integer>();
143
712
    CHECK(args[4]->IsNumber());
144
712
    column_offset = args[4].As<Integer>();
145
  }
146
147
  Local<PrimitiveArray> host_defined_options =
148
32064
      PrimitiveArray::New(isolate, HostDefinedOptions::kLength);
149
96192
  host_defined_options->Set(isolate, HostDefinedOptions::kType,
150
32064
                            Number::New(isolate, ScriptType::kModule));
151
152
64120
  ShouldNotAbortOnUncaughtScope no_abort_scope(env);
153
64120
  TryCatchScope try_catch(env);
154
155
  Local<Module> module;
156
157
  {
158
32056
    Context::Scope context_scope(context);
159
32064
    if (synthetic) {
160
63416
      CHECK(args[2]->IsArray());
161
63416
      Local<Array> export_names_arr = args[2].As<Array>();
162
163
31708
      uint32_t len = export_names_arr->Length();
164
63416
      std::vector<Local<String>> export_names(len);
165
918539
      for (uint32_t i = 0; i < len; i++) {
166
        Local<Value> export_name_val =
167
1773662
            export_names_arr->Get(context, i).ToLocalChecked();
168
1773662
        CHECK(export_name_val->IsString());
169
1773662
        export_names[i] = export_name_val.As<String>();
170
      }
171
172
      module = Module::CreateSyntheticModule(isolate, url, export_names,
173
31708
        SyntheticModuleEvaluationStepsCallback);
174
    } else {
175
356
      ScriptCompiler::CachedData* cached_data = nullptr;
176
1068
      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
712
      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
356
                          host_defined_options);
197
348
      ScriptCompiler::Source source(source_text, origin, cached_data);
198
      ScriptCompiler::CompileOptions options;
199
356
      if (source.GetCachedData() == nullptr) {
200
354
        options = ScriptCompiler::kNoCompileOptions;
201
      } else {
202
2
        options = ScriptCompiler::kConsumeCodeCache;
203
      }
204
712
      if (!ScriptCompiler::CompileModule(isolate, &source, options)
205
356
               .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

351
      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
128224
  if (!that->Set(context, env->url_string(), url).FromMaybe(false)) {
226
    return;
227
  }
228
229
32056
  ModuleWrap* obj = new ModuleWrap(env, that, module, url);
230
231
32056
  if (synthetic) {
232
31708
    obj->synthetic_ = true;
233
63416
    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
128224
  obj->object()->SetInternalField(kContextObjectSlot,
240
32056
      context->GetExtrasBindingObject());
241
32056
  obj->contextify_context_ = contextify_context;
242
243
32056
  env->hash_to_module_map.emplace(module->GetIdentityHash(), obj);
244
245
96168
  host_defined_options->Set(isolate, HostDefinedOptions::kID,
246
64112
                            Number::New(isolate, obj->id()));
247
248
32056
  that->SetIntegrityLevel(context, IntegrityLevel::kFrozen);
249
64112
  args.GetReturnValue().Set(that);
250
}
251
252
545
void ModuleWrap::Link(const FunctionCallbackInfo<Value>& args) {
253
545
  Environment* env = Environment::GetCurrent(args);
254
545
  Isolate* isolate = args.GetIsolate();
255
256
545
  CHECK_EQ(args.Length(), 1);
257
1090
  CHECK(args[0]->IsFunction());
258
259
545
  Local<Object> that = args.This();
260
261
  ModuleWrap* obj;
262
548
  ASSIGN_OR_RETURN_UNWRAP(&obj, that);
263
264
545
  if (obj->linked_)
265
3
    return;
266
542
  obj->linked_ = true;
267
268
1084
  Local<Function> resolver_arg = args[0].As<Function>();
269
270
542
  Local<Context> mod_context = obj->context();
271
1084
  Local<Module> module = obj->module_.Get(isolate);
272
273
542
  const int module_requests_length = module->GetModuleRequestsLength();
274
1084
  MaybeStackBuffer<Local<Value>, 16> promises(module_requests_length);
275
276
  // call the dependency resolve callbacks
277
925
  for (int i = 0; i < module_requests_length; i++) {
278
383
    Local<String> specifier = module->GetModuleRequest(i);
279
766
    Utf8Value specifier_utf8(env->isolate(), specifier);
280
766
    std::string specifier_std(*specifier_utf8, specifier_utf8.length());
281
282
    Local<Value> argv[] = {
283
      specifier
284
766
    };
285
286
    MaybeLocal<Value> maybe_resolve_return_value =
287
766
        resolver_arg->Call(mod_context, that, arraysize(argv), argv);
288
383
    if (maybe_resolve_return_value.IsEmpty()) {
289
      return;
290
    }
291
    Local<Value> resolve_return_value =
292
383
        maybe_resolve_return_value.ToLocalChecked();
293
383
    if (!resolve_return_value->IsPromise()) {
294
      env->ThrowError("linking error, expected resolver to return a promise");
295
    }
296
383
    Local<Promise> resolve_promise = resolve_return_value.As<Promise>();
297
383
    obj->resolve_cache_[specifier_std].Reset(env->isolate(), resolve_promise);
298
299
766
    promises[i] = resolve_promise;
300
  }
301
302
1626
  args.GetReturnValue().Set(
303
      Array::New(isolate, promises.out(), promises.length()));
304
}
305
306
31847
void ModuleWrap::Instantiate(const FunctionCallbackInfo<Value>& args) {
307
31847
  Environment* env = Environment::GetCurrent(args);
308
31847
  Isolate* isolate = args.GetIsolate();
309
  ModuleWrap* obj;
310
31857
  ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
311
31847
  Local<Context> context = obj->context();
312
63694
  Local<Module> module = obj->module_.Get(isolate);
313
63684
  TryCatchScope try_catch(env);
314
31847
  USE(module->InstantiateModule(context, ResolveCallback));
315
316
  // clear resolve cache on instantiate
317
31847
  obj->resolve_cache_.clear();
318
319

31847
  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
31838
void ModuleWrap::Evaluate(const FunctionCallbackInfo<Value>& args) {
330
31838
  Environment* env = Environment::GetCurrent(args);
331
31838
  Isolate* isolate = env->isolate();
332
  ModuleWrap* obj;
333
31842
  ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
334
31838
  Local<Context> context = obj->context();
335
63676
  Local<Module> module = obj->module_.Get(isolate);
336
337
31838
  ContextifyContext* contextify_context = obj->contextify_context_;
338
63671
  std::shared_ptr<MicrotaskQueue> microtask_queue;
339
31838
  if (contextify_context != nullptr)
340
3
      microtask_queue = contextify_context->microtask_queue();
341
342
  // module.evaluate(timeout, breakOnSigint)
343
31838
  CHECK_EQ(args.Length(), 2);
344
345
63676
  CHECK(args[0]->IsNumber());
346
127352
  int64_t timeout = args[0]->IntegerValue(env->context()).FromJust();
347
348
63676
  CHECK(args[1]->IsBoolean());
349
63676
  bool break_on_sigint = args[1]->IsTrue();
350
351
63671
  ShouldNotAbortOnUncaughtScope no_abort_scope(env);
352
63671
  TryCatchScope try_catch(env);
353
354
31838
  bool timed_out = false;
355
31838
  bool received_signal = false;
356
  MaybeLocal<Value> result;
357
31838
  auto run = [&]() {
358
63676
    MaybeLocal<Value> result = module->Evaluate(context);
359

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

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

31837
  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
31837
  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
31833
  if (env->isolate_data()->options()->experimental_top_level_await) {
407
63648
    args.GetReturnValue().Set(result.ToLocalChecked());
408
  }
409
}
410
411
164
void ModuleWrap::GetNamespace(const FunctionCallbackInfo<Value>& args) {
412
164
  Environment* env = Environment::GetCurrent(args);
413
164
  Isolate* isolate = args.GetIsolate();
414
  ModuleWrap* obj;
415
164
  ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
416
417
328
  Local<Module> module = obj->module_.Get(isolate);
418
419
164
  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
164
      break;
429
    default:
430
      UNREACHABLE();
431
  }
432
433
164
  Local<Value> result = module->GetModuleNamespace();
434
328
  args.GetReturnValue().Set(result);
435
}
436
437
179
void ModuleWrap::GetStatus(const FunctionCallbackInfo<Value>& args) {
438
179
  Isolate* isolate = args.GetIsolate();
439
  ModuleWrap* obj;
440
179
  ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
441
442
358
  Local<Module> module = obj->module_.Get(isolate);
443
444
537
  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
364
MaybeLocal<Module> ModuleWrap::ResolveCallback(Local<Context> context,
476
                                               Local<String> specifier,
477
                                               Local<Module> referrer) {
478
364
  Environment* env = Environment::GetCurrent(context);
479
364
  if (env == nullptr) {
480
    Isolate* isolate = context->GetIsolate();
481
    THROW_ERR_EXECUTION_ENVIRONMENT_NOT_AVAILABLE(isolate);
482
    return MaybeLocal<Module>();
483
  }
484
485
364
  Isolate* isolate = env->isolate();
486
487
364
  ModuleWrap* dependent = GetFromModule(env, referrer);
488
364
  if (dependent == nullptr) {
489
    env->ThrowError("linking error, null dep");
490
    return MaybeLocal<Module>();
491
  }
492
493
728
  Utf8Value specifier_utf8(isolate, specifier);
494
728
  std::string specifier_std(*specifier_utf8, specifier_utf8.length());
495
496
364
  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
728
      dependent->resolve_cache_[specifier_std].Get(isolate);
503
504
364
  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
728
  Local<Object> module_object = resolve_promise->Result().As<Object>();
511

728
  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
364
  ASSIGN_OR_RETURN_UNWRAP(&module, module_object, MaybeLocal<Module>());
519
728
  return module->module_.Get(isolate);
520
}
521
522
133
static MaybeLocal<Promise> ImportModuleDynamically(
523
    Local<Context> context,
524
    Local<ScriptOrModule> referrer,
525
    Local<String> specifier) {
526
133
  Isolate* iso = context->GetIsolate();
527
133
  Environment* env = Environment::GetCurrent(context);
528
133
  if (env == nullptr) {
529
    THROW_ERR_EXECUTION_ENVIRONMENT_NOT_AVAILABLE(iso);
530
    return MaybeLocal<Promise>();
531
  }
532
533
133
  EscapableHandleScope handle_scope(iso);
534
535
  Local<Function> import_callback =
536
133
    env->host_import_module_dynamically_callback();
537
538
133
  Local<PrimitiveArray> options = referrer->GetHostDefinedOptions();
539
133
  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
266
  int type = options->Get(iso, HostDefinedOptions::kType)
553
266
                 .As<Number>()
554
266
                 ->Int32Value(context)
555
133
                 .ToChecked();
556
266
  uint32_t id = options->Get(iso, HostDefinedOptions::kID)
557
266
                    .As<Number>()
558
266
                    ->Uint32Value(context)
559
133
                    .ToChecked();
560
133
  if (type == ScriptType::kScript) {
561
7
    contextify::ContextifyScript* wrap = env->id_to_script_map.find(id)->second;
562
14
    object = wrap->object();
563
126
  } else if (type == ScriptType::kModule) {
564
74
    ModuleWrap* wrap = ModuleWrap::GetFromID(env, id);
565
148
    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
266
  };
578
579
  Local<Value> result;
580
399
  if (import_callback->Call(
581
        context,
582
        Undefined(iso),
583
133
        arraysize(import_args),
584
399
        import_args).ToLocal(&result)) {
585
133
    CHECK(result->IsPromise());
586
133
    return handle_scope.Escape(result.As<Promise>());
587
  }
588
589
  return MaybeLocal<Promise>();
590
}
591
592
4748
void ModuleWrap::SetImportModuleDynamicallyCallback(
593
    const FunctionCallbackInfo<Value>& args) {
594
4748
  Isolate* iso = args.GetIsolate();
595
4748
  Environment* env = Environment::GetCurrent(args);
596
9496
  HandleScope handle_scope(iso);
597
598
4748
  CHECK_EQ(args.Length(), 1);
599
9496
  CHECK(args[0]->IsFunction());
600
9496
  Local<Function> import_callback = args[0].As<Function>();
601
4748
  env->set_host_import_module_dynamically_callback(import_callback);
602
603
4748
  iso->SetHostImportModuleDynamicallyCallback(ImportModuleDynamically);
604
4748
}
605
606
80
void ModuleWrap::HostInitializeImportMetaObjectCallback(
607
    Local<Context> context, Local<Module> module, Local<Object> meta) {
608
80
  Environment* env = Environment::GetCurrent(context);
609
80
  if (env == nullptr)
610
    return;
611
80
  ModuleWrap* module_wrap = GetFromModule(env, module);
612
613
80
  if (module_wrap == nullptr) {
614
    return;
615
  }
616
617
80
  Local<Object> wrap = module_wrap->object();
618
  Local<Function> callback =
619
80
      env->host_initialize_import_meta_object_callback();
620
240
  Local<Value> args[] = { wrap, meta };
621
160
  TryCatchScope try_catch(env);
622
160
  USE(callback->Call(
623
320
        context, Undefined(env->isolate()), arraysize(args), args));
624

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

31694
  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
31694
  return Undefined(isolate);
668
}
669
670
2694541
void ModuleWrap::SetSyntheticExport(const FunctionCallbackInfo<Value>& args) {
671
2694541
  Isolate* isolate = args.GetIsolate();
672
2694541
  Local<Object> that = args.This();
673
674
  ModuleWrap* obj;
675
2694541
  ASSIGN_OR_RETURN_UNWRAP(&obj, that);
676
677
2694544
  CHECK(obj->synthetic_);
678
679
2694544
  CHECK_EQ(args.Length(), 2);
680
681
8083632
  CHECK(args[0]->IsString());
682
5389088
  Local<String> export_name = args[0].As<String>();
683
684
2694544
  Local<Value> export_value = args[1];
685
686
5389088
  Local<Module> module = obj->module_.Get(isolate);
687
2694544
  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
4749
void ModuleWrap::Initialize(Local<Object> target,
720
                            Local<Value> unused,
721
                            Local<Context> context,
722
                            void* priv) {
723
4749
  Environment* env = Environment::GetCurrent(context);
724
4749
  Isolate* isolate = env->isolate();
725
726
4749
  Local<FunctionTemplate> tpl = env->NewFunctionTemplate(New);
727
9498
  tpl->SetClassName(FIXED_ONE_BYTE_STRING(isolate, "ModuleWrap"));
728
14247
  tpl->InstanceTemplate()->SetInternalFieldCount(
729
4749
      ModuleWrap::kInternalFieldCount);
730
9498
  tpl->Inherit(BaseObject::GetConstructorTemplate(env));
731
732
4749
  env->SetProtoMethod(tpl, "link", Link);
733
4749
  env->SetProtoMethod(tpl, "instantiate", Instantiate);
734
4749
  env->SetProtoMethod(tpl, "evaluate", Evaluate);
735
4749
  env->SetProtoMethod(tpl, "setExport", SetSyntheticExport);
736
4749
  env->SetProtoMethodNoSideEffect(tpl, "createCachedData", CreateCachedData);
737
4749
  env->SetProtoMethodNoSideEffect(tpl, "getNamespace", GetNamespace);
738
4749
  env->SetProtoMethodNoSideEffect(tpl, "getStatus", GetStatus);
739
4749
  env->SetProtoMethodNoSideEffect(tpl, "getError", GetError);
740
  env->SetProtoMethodNoSideEffect(tpl, "getStaticDependencySpecifiers",
741
4749
                                  GetStaticDependencySpecifiers);
742
743
9498
  target->Set(env->context(), FIXED_ONE_BYTE_STRING(isolate, "ModuleWrap"),
744
23745
              tpl->GetFunction(context).ToLocalChecked()).Check();
745
  env->SetMethod(target,
746
                 "setImportModuleDynamicallyCallback",
747
4749
                 SetImportModuleDynamicallyCallback);
748
  env->SetMethod(target,
749
                 "setInitializeImportMetaObjectCallback",
750
4749
                 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
18996
    V(kUninstantiated);
758
18996
    V(kInstantiating);
759
18996
    V(kInstantiated);
760
18996
    V(kEvaluating);
761
18996
    V(kEvaluated);
762
18996
    V(kErrored);
763
#undef V
764
4749
}
765
766
}  // namespace loader
767
}  // namespace node
768
769

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