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: 377 415 90.8 %
Date: 2021-02-11 04:11:15 Branches: 164 263 62.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
33720
ModuleWrap::ModuleWrap(Environment* env,
53
                       Local<Object> object,
54
                       Local<Module> module,
55
33720
                       Local<String> url)
56
  : BaseObject(env, object),
57
    module_(env->isolate(), module),
58
67440
    id_(env->get_next_module_id()) {
59
33719
  env->id_to_module_map.emplace(id_, this);
60
61
33720
  Local<Value> undefined = Undefined(env->isolate());
62
33720
  object->SetInternalField(kURLSlot, url);
63
33720
  object->SetInternalField(kSyntheticEvaluationStepsSlot, undefined);
64
33720
  object->SetInternalField(kContextObjectSlot, undefined);
65
33720
}
66
67
127372
ModuleWrap::~ModuleWrap() {
68
63684
  HandleScope scope(env()->isolate());
69
63689
  Local<Module> module = module_.Get(env()->isolate());
70
31846
  env()->id_to_module_map.erase(id_);
71
31842
  auto range = env()->hash_to_module_map.equal_range(module->GetIdentityHash());
72
31846
  for (auto it = range.first; it != range.second; ++it) {
73
31846
    if (it->second == this) {
74
31845
      env()->hash_to_module_map.erase(it);
75
31844
      break;
76
    }
77
  }
78
63690
}
79
80
67583
Local<Context> ModuleWrap::context() const {
81
202749
  Local<Value> obj = object()->GetInternalField(kContextObjectSlot);
82
67583
  if (obj.IsEmpty()) return {};
83
135166
  return obj.As<Object>()->CreationContext();
84
}
85
86
33818
ModuleWrap* ModuleWrap::GetFromModule(Environment* env,
87
                                      Local<Module> module) {
88
33818
  auto range = env->hash_to_module_map.equal_range(module->GetIdentityHash());
89
33818
  for (auto it = range.first; it != range.second; ++it) {
90
67636
    if (it->second->module_ == module) {
91
33818
      return it->second;
92
    }
93
  }
94
  return nullptr;
95
}
96
97
122
ModuleWrap* ModuleWrap::GetFromID(Environment* env, uint32_t id) {
98
122
  auto module_wrap_it = env->id_to_module_map.find(id);
99
122
  if (module_wrap_it == env->id_to_module_map.end()) {
100
    return nullptr;
101
  }
102
122
  return module_wrap_it->second;
103
}
104
105
// new ModuleWrap(url, context, source, lineOffset, columnOffset)
106
// new ModuleWrap(url, context, exportNames, syntheticExecutionFunction)
107
33728
void ModuleWrap::New(const FunctionCallbackInfo<Value>& args) {
108
33728
  CHECK(args.IsConstructCall());
109
33728
  CHECK_GE(args.Length(), 3);
110
111
33728
  Environment* env = Environment::GetCurrent(args);
112
33728
  Isolate* isolate = env->isolate();
113
114
33728
  Local<Object> that = args.This();
115
116
101184
  CHECK(args[0]->IsString());
117
67456
  Local<String> url = args[0].As<String>();
118
119
  Local<Context> context;
120
33728
  ContextifyContext* contextify_context = nullptr;
121
101184
  if (args[1]->IsUndefined()) {
122
33719
    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
67456
  bool synthetic = args[2]->IsArray();
135
33728
  if (synthetic) {
136
    // new ModuleWrap(url, context, exportNames, syntheticExecutionFunction)
137
66636
    CHECK(args[3]->IsFunction());
138
  } else {
139
    // new ModuleWrap(url, context, source, lineOffset, columOffset, cachedData)
140
1230
    CHECK(args[2]->IsString());
141
820
    CHECK(args[3]->IsNumber());
142
820
    line_offset = args[3].As<Integer>();
143
820
    CHECK(args[4]->IsNumber());
144
820
    column_offset = args[4].As<Integer>();
145
  }
146
147
  Local<PrimitiveArray> host_defined_options =
148
33728
      PrimitiveArray::New(isolate, HostDefinedOptions::kLength);
149
101184
  host_defined_options->Set(isolate, HostDefinedOptions::kType,
150
33728
                            Number::New(isolate, ScriptType::kModule));
151
152
67448
  ShouldNotAbortOnUncaughtScope no_abort_scope(env);
153
67448
  TryCatchScope try_catch(env);
154
155
  Local<Module> module;
156
157
  {
158
33720
    Context::Scope context_scope(context);
159
33728
    if (synthetic) {
160
66636
      CHECK(args[2]->IsArray());
161
66636
      Local<Array> export_names_arr = args[2].As<Array>();
162
163
33318
      uint32_t len = export_names_arr->Length();
164
66636
      std::vector<Local<String>> export_names(len);
165
999202
      for (uint32_t i = 0; i < len; i++) {
166
        Local<Value> export_name_val =
167
1931775
            export_names_arr->Get(context, i).ToLocalChecked();
168
1931782
        CHECK(export_name_val->IsString());
169
1931780
        export_names[i] = export_name_val.As<String>();
170
      }
171
172
      module = Module::CreateSyntheticModule(isolate, url, export_names,
173
33318
        SyntheticModuleEvaluationStepsCallback);
174
    } else {
175
410
      ScriptCompiler::CachedData* cached_data = nullptr;
176
1230
      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
820
      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
410
                          host_defined_options);
197
402
      ScriptCompiler::Source source(source_text, origin, cached_data);
198
      ScriptCompiler::CompileOptions options;
199
410
      if (source.GetCachedData() == nullptr) {
200
408
        options = ScriptCompiler::kNoCompileOptions;
201
      } else {
202
2
        options = ScriptCompiler::kConsumeCodeCache;
203
      }
204
820
      if (!ScriptCompiler::CompileModule(isolate, &source, options)
205
410
               .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

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

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

33467
    if (!result.IsEmpty() && microtask_queue)
361
1
      microtask_queue->PerformCheckpoint(isolate);
362
33467
    return result;
363
33468
  };
364

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

33467
  if (timed_out || received_signal) {
384

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

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

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

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

18788
NODE_MODULE_CONTEXT_AWARE_INTERNAL(module_wrap,
769
                                   node::loader::ModuleWrap::Initialize)