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: 379 417 90.9 %
Date: 2020-11-21 04:10:54 Branches: 162 261 62.1 %

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

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

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

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

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

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

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

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

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

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