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: 375 417 89.9 %
Date: 2020-09-03 22:13:26 Branches: 159 261 60.9 %

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
31989
ModuleWrap::ModuleWrap(Environment* env,
53
                       Local<Object> object,
54
                       Local<Module> module,
55
31989
                       Local<String> url)
56
  : BaseObject(env, object),
57
    module_(env->isolate(), module),
58
63978
    id_(env->get_next_module_id()) {
59
31989
  env->id_to_module_map.emplace(id_, this);
60
61
31989
  Local<Value> undefined = Undefined(env->isolate());
62
31989
  object->SetInternalField(kURLSlot, url);
63
31989
  object->SetInternalField(kSyntheticEvaluationStepsSlot, undefined);
64
31989
  object->SetInternalField(kContextObjectSlot, undefined);
65
31989
}
66
67
119097
ModuleWrap::~ModuleWrap() {
68
59548
  HandleScope scope(env()->isolate());
69
59550
  Local<Module> module = module_.Get(env()->isolate());
70
29775
  env()->id_to_module_map.erase(id_);
71
29774
  auto range = env()->hash_to_module_map.equal_range(module->GetIdentityHash());
72
29774
  for (auto it = range.first; it != range.second; ++it) {
73
29774
    if (it->second == this) {
74
29774
      env()->hash_to_module_map.erase(it);
75
29774
      break;
76
    }
77
  }
78
59549
}
79
80
64093
Local<Context> ModuleWrap::context() const {
81
192279
  Local<Value> obj = object()->GetInternalField(kContextObjectSlot);
82
64093
  if (obj.IsEmpty()) return {};
83
128186
  return obj.As<Object>()->CreationContext();
84
}
85
86
32063
ModuleWrap* ModuleWrap::GetFromModule(Environment* env,
87
                                      Local<Module> module) {
88
32063
  auto range = env->hash_to_module_map.equal_range(module->GetIdentityHash());
89
32063
  for (auto it = range.first; it != range.second; ++it) {
90
64126
    if (it->second->module_ == module) {
91
32063
      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
31997
void ModuleWrap::New(const FunctionCallbackInfo<Value>& args) {
108
31997
  CHECK(args.IsConstructCall());
109
31997
  CHECK_GE(args.Length(), 3);
110
111
31997
  Environment* env = Environment::GetCurrent(args);
112
31997
  Isolate* isolate = env->isolate();
113
114
31997
  Local<Object> that = args.This();
115
116
95991
  CHECK(args[0]->IsString());
117
63994
  Local<String> url = args[0].As<String>();
118
119
  Local<Context> context;
120
31997
  ContextifyContext* contextify_context = nullptr;
121
95991
  if (args[1]->IsUndefined()) {
122
31988
    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
63994
  bool synthetic = args[2]->IsArray();
135
31997
  if (synthetic) {
136
    // new ModuleWrap(url, context, exportNames, syntheticExecutionFunction)
137
63254
    CHECK(args[3]->IsFunction());
138
  } else {
139
    // new ModuleWrap(url, context, source, lineOffset, columOffset, cachedData)
140
1110
    CHECK(args[2]->IsString());
141
740
    CHECK(args[3]->IsNumber());
142
740
    line_offset = args[3].As<Integer>();
143
740
    CHECK(args[4]->IsNumber());
144
740
    column_offset = args[4].As<Integer>();
145
  }
146
147
  Local<PrimitiveArray> host_defined_options =
148
31997
      PrimitiveArray::New(isolate, HostDefinedOptions::kLength);
149
95991
  host_defined_options->Set(isolate, HostDefinedOptions::kType,
150
31997
                            Number::New(isolate, ScriptType::kModule));
151
152
63986
  ShouldNotAbortOnUncaughtScope no_abort_scope(env);
153
63986
  TryCatchScope try_catch(env);
154
155
  Local<Module> module;
156
157
  {
158
31989
    Context::Scope context_scope(context);
159
31997
    if (synthetic) {
160
63254
      CHECK(args[2]->IsArray());
161
63254
      Local<Array> export_names_arr = args[2].As<Array>();
162
163
31627
      uint32_t len = export_names_arr->Length();
164
63254
      std::vector<Local<String>> export_names(len);
165
926837
      for (uint32_t i = 0; i < len; i++) {
166
        Local<Value> export_name_val =
167
1790420
            export_names_arr->Get(context, i).ToLocalChecked();
168
1790420
        CHECK(export_name_val->IsString());
169
1790420
        export_names[i] = export_name_val.As<String>();
170
      }
171
172
      module = Module::CreateSyntheticModule(isolate, url, export_names,
173
31627
        SyntheticModuleEvaluationStepsCallback);
174
    } else {
175
370
      ScriptCompiler::CachedData* cached_data = nullptr;
176
1110
      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
740
      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
370
                          host_defined_options);
197
362
      ScriptCompiler::Source source(source_text, origin, cached_data);
198
      ScriptCompiler::CompileOptions options;
199
370
      if (source.GetCachedData() == nullptr) {
200
368
        options = ScriptCompiler::kNoCompileOptions;
201
      } else {
202
2
        options = ScriptCompiler::kConsumeCodeCache;
203
      }
204
740
      if (!ScriptCompiler::CompileModule(isolate, &source, options)
205
370
               .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

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

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

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

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

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

740
  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
370
  ASSIGN_OR_RETURN_UNWRAP(&module, module_object, MaybeLocal<Module>());
519
740
  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
4825
void ModuleWrap::SetImportModuleDynamicallyCallback(
593
    const FunctionCallbackInfo<Value>& args) {
594
4825
  Isolate* iso = args.GetIsolate();
595
4825
  Environment* env = Environment::GetCurrent(args);
596
9650
  HandleScope handle_scope(iso);
597
598
4825
  CHECK_EQ(args.Length(), 1);
599
9650
  CHECK(args[0]->IsFunction());
600
9650
  Local<Function> import_callback = args[0].As<Function>();
601
4825
  env->set_host_import_module_dynamically_callback(import_callback);
602
603
4825
  iso->SetHostImportModuleDynamicallyCallback(ImportModuleDynamically);
604
4825
}
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
4825
void ModuleWrap::SetInitializeImportMetaObjectCallback(
630
    const FunctionCallbackInfo<Value>& args) {
631
4825
  Environment* env = Environment::GetCurrent(args);
632
4825
  Isolate* isolate = env->isolate();
633
634
4825
  CHECK_EQ(args.Length(), 1);
635
9650
  CHECK(args[0]->IsFunction());
636
9650
  Local<Function> import_meta_callback = args[0].As<Function>();
637
4825
  env->set_host_initialize_import_meta_object_callback(import_meta_callback);
638
639
  isolate->SetHostInitializeImportMetaObjectCallback(
640
4825
      HostInitializeImportMetaObjectCallback);
641
4825
}
642
643
31613
MaybeLocal<Value> ModuleWrap::SyntheticModuleEvaluationStepsCallback(
644
    Local<Context> context, Local<Module> module) {
645
31613
  Environment* env = Environment::GetCurrent(context);
646
31613
  Isolate* isolate = env->isolate();
647
648
31613
  ModuleWrap* obj = GetFromModule(env, module);
649
650
63226
  TryCatchScope try_catch(env);
651
  Local<Function> synthetic_evaluation_steps =
652
126452
      obj->object()->GetInternalField(kSyntheticEvaluationStepsSlot)
653
31613
          .As<Function>();
654
94839
  obj->object()->SetInternalField(
655
31613
      kSyntheticEvaluationStepsSlot, Undefined(isolate));
656
  MaybeLocal<Value> ret = synthetic_evaluation_steps->Call(context,
657
63226
      obj->object(), 0, nullptr);
658
31613
  if (ret.IsEmpty()) {
659
1
    CHECK(try_catch.HasCaught());
660
  }
661

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

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