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: 390 430 90.7 %
Date: 2021-04-26 04:12:24 Branches: 167 267 62.5 %

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

7
        if (try_catch.HasCaught() && !try_catch.HasTerminated()) {
211
14
          CHECK(!try_catch.Message().IsEmpty());
212
14
          CHECK(!try_catch.Exception().IsEmpty());
213
7
          AppendExceptionLine(env, try_catch.Exception(), try_catch.Message(),
214
7
                              ErrorHandlingMode::MODULE_ERROR);
215
7
          try_catch.ReThrow();
216
        }
217
7
        return;
218
      }
219

429
      if (options == ScriptCompiler::kConsumeCodeCache &&
220
2
          source.GetCachedData()->rejected) {
221
        THROW_ERR_VM_MODULE_CACHED_DATA_REJECTED(
222
1
            env, "cachedData buffer was rejected");
223
1
        try_catch.ReThrow();
224
1
        return;
225
      }
226
    }
227
  }
228
229
170410
  if (!that->Set(context, env->url_string(), url).FromMaybe(false)) {
230
    return;
231
  }
232
233
42601
  ModuleWrap* obj = new ModuleWrap(env, that, module, url);
234
235
42601
  if (synthetic) {
236
42175
    obj->synthetic_ = true;
237
84352
    obj->object()->SetInternalField(kSyntheticEvaluationStepsSlot, args[3]);
238
  }
239
240
  // Use the extras object as an object whose GetCreationContext() will be the
241
  // original `context`, since the `Context` itself strictly speaking cannot
242
  // be stored in an internal field.
243
170412
  obj->object()->SetInternalField(kContextObjectSlot,
244
42603
      context->GetExtrasBindingObject());
245
42603
  obj->contextify_context_ = contextify_context;
246
247
42603
  env->hash_to_module_map.emplace(module->GetIdentityHash(), obj);
248
249
127804
  host_defined_options->Set(isolate, HostDefinedOptions::kID,
250
85203
                            Number::New(isolate, obj->id()));
251
252
42602
  that->SetIntegrityLevel(context, IntegrityLevel::kFrozen);
253
85206
  args.GetReturnValue().Set(that);
254
}
255
256
670
void ModuleWrap::Link(const FunctionCallbackInfo<Value>& args) {
257
670
  Environment* env = Environment::GetCurrent(args);
258
670
  Isolate* isolate = args.GetIsolate();
259
260
670
  CHECK_EQ(args.Length(), 1);
261
1340
  CHECK(args[0]->IsFunction());
262
263
670
  Local<Object> that = args.This();
264
265
  ModuleWrap* obj;
266
673
  ASSIGN_OR_RETURN_UNWRAP(&obj, that);
267
268
670
  if (obj->linked_)
269
3
    return;
270
667
  obj->linked_ = true;
271
272
1334
  Local<Function> resolver_arg = args[0].As<Function>();
273
274
667
  Local<Context> mod_context = obj->context();
275
1334
  Local<Module> module = obj->module_.Get(isolate);
276
277
667
  Local<FixedArray> module_requests = module->GetModuleRequests();
278
667
  const int module_requests_length = module_requests->Length();
279
1334
  MaybeStackBuffer<Local<Value>, 16> promises(module_requests_length);
280
281
  // call the dependency resolve callbacks
282
1130
  for (int i = 0; i < module_requests_length; i++) {
283
    Local<ModuleRequest> module_request =
284
1389
      module_requests->Get(env->context(), i).As<ModuleRequest>();
285
463
    Local<String> specifier = module_request->GetSpecifier();
286
926
    Utf8Value specifier_utf8(env->isolate(), specifier);
287
926
    std::string specifier_std(*specifier_utf8, specifier_utf8.length());
288
289
463
    Local<FixedArray> raw_assertions = module_request->GetImportAssertions();
290
    Local<Object> assertions =
291
926
        Object::New(isolate, v8::Null(env->isolate()), nullptr, nullptr, 0);
292
930
    for (int i = 0; i < raw_assertions->Length(); i += 3) {
293
      assertions
294
4
          ->Set(env->context(),
295
                Local<String>::Cast(raw_assertions->Get(env->context(), i)),
296
14
                Local<Value>::Cast(raw_assertions->Get(env->context(), i + 1)))
297
          .ToChecked();
298
    }
299
300
    Local<Value> argv[] = {
301
        specifier,
302
        assertions,
303
1389
    };
304
305
    MaybeLocal<Value> maybe_resolve_return_value =
306
926
        resolver_arg->Call(mod_context, that, arraysize(argv), argv);
307
463
    if (maybe_resolve_return_value.IsEmpty()) {
308
      return;
309
    }
310
    Local<Value> resolve_return_value =
311
463
        maybe_resolve_return_value.ToLocalChecked();
312
463
    if (!resolve_return_value->IsPromise()) {
313
      THROW_ERR_VM_MODULE_LINK_FAILURE(
314
          env, "request for '%s' did not return promise", specifier_std);
315
      return;
316
    }
317
463
    Local<Promise> resolve_promise = resolve_return_value.As<Promise>();
318
463
    obj->resolve_cache_[specifier_std].Reset(env->isolate(), resolve_promise);
319
320
926
    promises[i] = resolve_promise;
321
  }
322
323
2001
  args.GetReturnValue().Set(
324
      Array::New(isolate, promises.out(), promises.length()));
325
}
326
327
42340
void ModuleWrap::Instantiate(const FunctionCallbackInfo<Value>& args) {
328
42340
  Environment* env = Environment::GetCurrent(args);
329
42341
  Isolate* isolate = args.GetIsolate();
330
  ModuleWrap* obj;
331
42353
  ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
332
42341
  Local<Context> context = obj->context();
333
84682
  Local<Module> module = obj->module_.Get(isolate);
334
84670
  TryCatchScope try_catch(env);
335
42342
  USE(module->InstantiateModule(context, ResolveModuleCallback));
336
337
  // clear resolve cache on instantiate
338
42342
  obj->resolve_cache_.clear();
339
340

42341
  if (try_catch.HasCaught() && !try_catch.HasTerminated()) {
341
24
    CHECK(!try_catch.Message().IsEmpty());
342
24
    CHECK(!try_catch.Exception().IsEmpty());
343
12
    AppendExceptionLine(env, try_catch.Exception(), try_catch.Message(),
344
12
                        ErrorHandlingMode::MODULE_ERROR);
345
12
    try_catch.ReThrow();
346
12
    return;
347
  }
348
}
349
350
42336
void ModuleWrap::Evaluate(const FunctionCallbackInfo<Value>& args) {
351
42336
  Environment* env = Environment::GetCurrent(args);
352
42336
  Isolate* isolate = env->isolate();
353
  ModuleWrap* obj;
354
42345
  ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
355
42336
  Local<Context> context = obj->context();
356
84670
  Local<Module> module = obj->module_.Get(isolate);
357
358
42335
  ContextifyContext* contextify_context = obj->contextify_context_;
359
84661
  std::shared_ptr<MicrotaskQueue> microtask_queue;
360
42335
  if (contextify_context != nullptr)
361
4
      microtask_queue = contextify_context->microtask_queue();
362
363
  // module.evaluate(timeout, breakOnSigint)
364
42335
  CHECK_EQ(args.Length(), 2);
365
366
84670
  CHECK(args[0]->IsNumber());
367
169342
  int64_t timeout = args[0]->IntegerValue(env->context()).FromJust();
368
369
84670
  CHECK(args[1]->IsBoolean());
370
84672
  bool break_on_sigint = args[1]->IsTrue();
371
372
84661
  ShouldNotAbortOnUncaughtScope no_abort_scope(env);
373
84662
  TryCatchScope try_catch(env);
374
84662
  Isolate::SafeForTerminationScope safe_for_termination(env->isolate());
375
376
42335
  bool timed_out = false;
377
42335
  bool received_signal = false;
378
  MaybeLocal<Value> result;
379
42335
  auto run = [&]() {
380
84670
    MaybeLocal<Value> result = module->Evaluate(context);
381

42333
    if (!result.IsEmpty() && microtask_queue)
382
1
      microtask_queue->PerformCheckpoint(isolate);
383
42334
    return result;
384
42335
  };
385

42335
  if (break_on_sigint && timeout != -1) {
386
    Watchdog wd(isolate, timeout, &timed_out);
387
    SigintWatchdog swd(isolate, &received_signal);
388
    result = run();
389
42335
  } else if (break_on_sigint) {
390
    SigintWatchdog swd(isolate, &received_signal);
391
    result = run();
392
42335
  } else if (timeout != -1) {
393
6
    Watchdog wd(isolate, timeout, &timed_out);
394
3
    result = run();
395
  } else {
396
42332
    result = run();
397
  }
398
399
42334
  if (result.IsEmpty()) {
400
3
    CHECK(try_catch.HasCaught());
401
  }
402
403
  // Convert the termination exception into a regular exception.
404

42334
  if (timed_out || received_signal) {
405

3
    if (!env->is_main_thread() && env->is_stopping())
406
      return;
407
3
    env->isolate()->CancelTerminateExecution();
408
    // It is possible that execution was terminated by another timeout in
409
    // which this timeout is nested, so check whether one of the watchdogs
410
    // from this invocation is responsible for termination.
411
3
    if (timed_out) {
412
3
      THROW_ERR_SCRIPT_EXECUTION_TIMEOUT(env, timeout);
413
    } else if (received_signal) {
414
      THROW_ERR_SCRIPT_EXECUTION_INTERRUPTED(env);
415
    }
416
  }
417
418
42334
  if (try_catch.HasCaught()) {
419
9
    if (!try_catch.HasTerminated())
420
8
      try_catch.ReThrow();
421
9
    return;
422
  }
423
424
  // If TLA is enabled, `result` is the evaluation's promise.
425
  // Otherwise, `result` is the last evaluated value of the module,
426
  // which could be a promise, which would result in it being incorrectly
427
  // unwrapped when the higher level code awaits the evaluation.
428
42325
  if (env->isolate_data()->options()->experimental_top_level_await) {
429
84630
    args.GetReturnValue().Set(result.ToLocalChecked());
430
  }
431
}
432
433
205
void ModuleWrap::GetNamespace(const FunctionCallbackInfo<Value>& args) {
434
205
  Environment* env = Environment::GetCurrent(args);
435
205
  Isolate* isolate = args.GetIsolate();
436
  ModuleWrap* obj;
437
205
  ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
438
439
410
  Local<Module> module = obj->module_.Get(isolate);
440
441
205
  switch (module->GetStatus()) {
442
    case v8::Module::Status::kUninstantiated:
443
    case v8::Module::Status::kInstantiating:
444
      return env->ThrowError(
445
          "cannot get namespace, module has not been instantiated");
446
    case v8::Module::Status::kInstantiated:
447
    case v8::Module::Status::kEvaluating:
448
    case v8::Module::Status::kEvaluated:
449
    case v8::Module::Status::kErrored:
450
205
      break;
451
    default:
452
      UNREACHABLE();
453
  }
454
455
205
  Local<Value> result = module->GetModuleNamespace();
456
410
  args.GetReturnValue().Set(result);
457
}
458
459
213
void ModuleWrap::GetStatus(const FunctionCallbackInfo<Value>& args) {
460
213
  Isolate* isolate = args.GetIsolate();
461
  ModuleWrap* obj;
462
213
  ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
463
464
426
  Local<Module> module = obj->module_.Get(isolate);
465
466
639
  args.GetReturnValue().Set(module->GetStatus());
467
}
468
469
2
void ModuleWrap::GetStaticDependencySpecifiers(
470
    const FunctionCallbackInfo<Value>& args) {
471
2
  Environment* env = Environment::GetCurrent(args);
472
  ModuleWrap* obj;
473
2
  ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
474
475
4
  Local<Module> module = obj->module_.Get(env->isolate());
476
477
2
  Local<FixedArray> module_requests = module->GetModuleRequests();
478
2
  int count = module_requests->Length();
479
480
4
  MaybeStackBuffer<Local<Value>, 16> specifiers(count);
481
482
3
  for (int i = 0; i < count; i++) {
483
    Local<ModuleRequest> module_request =
484
3
      module_requests->Get(env->context(), i).As<ModuleRequest>();
485
3
    specifiers[i] = module_request->GetSpecifier();
486
  }
487
488
6
  args.GetReturnValue().Set(
489
      Array::New(env->isolate(), specifiers.out(), count));
490
}
491
492
1
void ModuleWrap::GetError(const FunctionCallbackInfo<Value>& args) {
493
1
  Isolate* isolate = args.GetIsolate();
494
  ModuleWrap* obj;
495
1
  ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
496
497
2
  Local<Module> module = obj->module_.Get(isolate);
498
3
  args.GetReturnValue().Set(module->GetException());
499
}
500
501
442
MaybeLocal<Module> ModuleWrap::ResolveModuleCallback(
502
    Local<Context> context,
503
    Local<String> specifier,
504
    Local<FixedArray> import_assertions,
505
    Local<Module> referrer) {
506
442
  Environment* env = Environment::GetCurrent(context);
507
442
  if (env == nullptr) {
508
    Isolate* isolate = context->GetIsolate();
509
    THROW_ERR_EXECUTION_ENVIRONMENT_NOT_AVAILABLE(isolate);
510
    return MaybeLocal<Module>();
511
  }
512
513
442
  Isolate* isolate = env->isolate();
514
515
884
  Utf8Value specifier_utf8(isolate, specifier);
516
884
  std::string specifier_std(*specifier_utf8, specifier_utf8.length());
517
518
442
  ModuleWrap* dependent = GetFromModule(env, referrer);
519
442
  if (dependent == nullptr) {
520
    THROW_ERR_VM_MODULE_LINK_FAILURE(
521
        env, "request for '%s' is from invalid module", specifier_std);
522
    return MaybeLocal<Module>();
523
  }
524
525
442
  if (dependent->resolve_cache_.count(specifier_std) != 1) {
526
    THROW_ERR_VM_MODULE_LINK_FAILURE(
527
        env, "request for '%s' is not in cache", specifier_std);
528
    return MaybeLocal<Module>();
529
  }
530
531
  Local<Promise> resolve_promise =
532
884
      dependent->resolve_cache_[specifier_std].Get(isolate);
533
534
442
  if (resolve_promise->State() != Promise::kFulfilled) {
535
    THROW_ERR_VM_MODULE_LINK_FAILURE(
536
        env, "request for '%s' is not yet fulfilled", specifier_std);
537
    return MaybeLocal<Module>();
538
  }
539
540
884
  Local<Object> module_object = resolve_promise->Result().As<Object>();
541

884
  if (module_object.IsEmpty() || !module_object->IsObject()) {
542
    THROW_ERR_VM_MODULE_LINK_FAILURE(
543
        env, "request for '%s' did not return an object", specifier_std);
544
    return MaybeLocal<Module>();
545
  }
546
547
  ModuleWrap* module;
548
442
  ASSIGN_OR_RETURN_UNWRAP(&module, module_object, MaybeLocal<Module>());
549
884
  return module->module_.Get(isolate);
550
}
551
552
199
static MaybeLocal<Promise> ImportModuleDynamically(
553
    Local<Context> context,
554
    Local<ScriptOrModule> referrer,
555
    Local<String> specifier,
556
    Local<FixedArray> import_assertions) {
557
199
  Isolate* isolate = context->GetIsolate();
558
199
  Environment* env = Environment::GetCurrent(context);
559
199
  if (env == nullptr) {
560
    THROW_ERR_EXECUTION_ENVIRONMENT_NOT_AVAILABLE(isolate);
561
    return MaybeLocal<Promise>();
562
  }
563
564
199
  EscapableHandleScope handle_scope(isolate);
565
566
  Local<Function> import_callback =
567
199
    env->host_import_module_dynamically_callback();
568
569
199
  Local<PrimitiveArray> options = referrer->GetHostDefinedOptions();
570
199
  if (options->Length() != HostDefinedOptions::kLength) {
571
    Local<Promise::Resolver> resolver;
572
    if (!Promise::Resolver::New(context).ToLocal(&resolver)) return {};
573
    resolver
574
        ->Reject(context,
575
                 v8::Exception::TypeError(FIXED_ONE_BYTE_STRING(
576
                     context->GetIsolate(), "Invalid host defined options")))
577
        .ToChecked();
578
    return handle_scope.Escape(resolver->GetPromise());
579
  }
580
581
  Local<Value> object;
582
583
398
  int type = options->Get(isolate, HostDefinedOptions::kType)
584
398
                 .As<Number>()
585
398
                 ->Int32Value(context)
586
199
                 .ToChecked();
587
398
  uint32_t id = options->Get(isolate, HostDefinedOptions::kID)
588
398
                    .As<Number>()
589
398
                    ->Uint32Value(context)
590
199
                    .ToChecked();
591
199
  if (type == ScriptType::kScript) {
592
7
    contextify::ContextifyScript* wrap = env->id_to_script_map.find(id)->second;
593
14
    object = wrap->object();
594
192
  } else if (type == ScriptType::kModule) {
595
122
    ModuleWrap* wrap = ModuleWrap::GetFromID(env, id);
596
244
    object = wrap->object();
597
70
  } else if (type == ScriptType::kFunction) {
598
70
    auto it = env->id_to_function_map.find(id);
599
70
    CHECK_NE(it, env->id_to_function_map.end());
600
140
    object = it->second->object();
601
  } else {
602
    UNREACHABLE();
603
  }
604
605
  Local<Value> import_args[] = {
606
    object,
607
    Local<Value>(specifier),
608
398
  };
609
610
  Local<Value> result;
611
597
  if (import_callback->Call(
612
        context,
613
        Undefined(isolate),
614
199
        arraysize(import_args),
615
597
        import_args).ToLocal(&result)) {
616
199
    CHECK(result->IsPromise());
617
199
    return handle_scope.Escape(result.As<Promise>());
618
  }
619
620
  return MaybeLocal<Promise>();
621
}
622
623
5183
void ModuleWrap::SetImportModuleDynamicallyCallback(
624
    const FunctionCallbackInfo<Value>& args) {
625
5183
  Isolate* isolate = args.GetIsolate();
626
5183
  Environment* env = Environment::GetCurrent(args);
627
10366
  HandleScope handle_scope(isolate);
628
629
5183
  CHECK_EQ(args.Length(), 1);
630
10366
  CHECK(args[0]->IsFunction());
631
10366
  Local<Function> import_callback = args[0].As<Function>();
632
5183
  env->set_host_import_module_dynamically_callback(import_callback);
633
634
5183
  isolate->SetHostImportModuleDynamicallyCallback(ImportModuleDynamically);
635
5183
}
636
637
85
void ModuleWrap::HostInitializeImportMetaObjectCallback(
638
    Local<Context> context, Local<Module> module, Local<Object> meta) {
639
85
  Environment* env = Environment::GetCurrent(context);
640
85
  if (env == nullptr)
641
    return;
642
85
  ModuleWrap* module_wrap = GetFromModule(env, module);
643
644
85
  if (module_wrap == nullptr) {
645
    return;
646
  }
647
648
85
  Local<Object> wrap = module_wrap->object();
649
  Local<Function> callback =
650
85
      env->host_initialize_import_meta_object_callback();
651
255
  Local<Value> args[] = { wrap, meta };
652
170
  TryCatchScope try_catch(env);
653
170
  USE(callback->Call(
654
340
        context, Undefined(env->isolate()), arraysize(args), args));
655

85
  if (try_catch.HasCaught() && !try_catch.HasTerminated()) {
656
    try_catch.ReThrow();
657
  }
658
}
659
660
5183
void ModuleWrap::SetInitializeImportMetaObjectCallback(
661
    const FunctionCallbackInfo<Value>& args) {
662
5183
  Environment* env = Environment::GetCurrent(args);
663
5183
  Isolate* isolate = env->isolate();
664
665
5183
  CHECK_EQ(args.Length(), 1);
666
10366
  CHECK(args[0]->IsFunction());
667
10366
  Local<Function> import_meta_callback = args[0].As<Function>();
668
5183
  env->set_host_initialize_import_meta_object_callback(import_meta_callback);
669
670
  isolate->SetHostInitializeImportMetaObjectCallback(
671
5183
      HostInitializeImportMetaObjectCallback);
672
5183
}
673
674
42160
MaybeLocal<Value> ModuleWrap::SyntheticModuleEvaluationStepsCallback(
675
    Local<Context> context, Local<Module> module) {
676
42160
  Environment* env = Environment::GetCurrent(context);
677
42161
  Isolate* isolate = env->isolate();
678
679
42161
  ModuleWrap* obj = GetFromModule(env, module);
680
681
84322
  TryCatchScope try_catch(env);
682
  Local<Function> synthetic_evaluation_steps =
683
168644
      obj->object()->GetInternalField(kSyntheticEvaluationStepsSlot)
684
42161
          .As<Function>();
685
126483
  obj->object()->SetInternalField(
686
42161
      kSyntheticEvaluationStepsSlot, Undefined(isolate));
687
  MaybeLocal<Value> ret = synthetic_evaluation_steps->Call(context,
688
84322
      obj->object(), 0, nullptr);
689
42159
  if (ret.IsEmpty()) {
690
5
    CHECK(try_catch.HasCaught());
691
  }
692

42159
  if (try_catch.HasCaught() && !try_catch.HasTerminated()) {
693
10
    CHECK(!try_catch.Message().IsEmpty());
694
10
    CHECK(!try_catch.Exception().IsEmpty());
695
5
    try_catch.ReThrow();
696
5
    return MaybeLocal<Value>();
697
  }
698
699
  Local<Promise::Resolver> resolver;
700
84309
  if (!Promise::Resolver::New(context).ToLocal(&resolver)) {
701
    return MaybeLocal<Value>();
702
  }
703
704
84310
  resolver->Resolve(context, Undefined(isolate)).ToChecked();
705
84311
  return resolver->GetPromise();
706
}
707
708
3640009
void ModuleWrap::SetSyntheticExport(const FunctionCallbackInfo<Value>& args) {
709
3640009
  Isolate* isolate = args.GetIsolate();
710
3640009
  Local<Object> that = args.This();
711
712
  ModuleWrap* obj;
713
3640009
  ASSIGN_OR_RETURN_UNWRAP(&obj, that);
714
715
3640070
  CHECK(obj->synthetic_);
716
717
3640070
  CHECK_EQ(args.Length(), 2);
718
719
10920210
  CHECK(args[0]->IsString());
720
7280140
  Local<String> export_name = args[0].As<String>();
721
722
3640070
  Local<Value> export_value = args[1];
723
724
7280157
  Local<Module> module = obj->module_.Get(isolate);
725
3640087
  USE(module->SetSyntheticModuleExport(isolate, export_name, export_value));
726
}
727
728
1
void ModuleWrap::CreateCachedData(const FunctionCallbackInfo<Value>& args) {
729
1
  Isolate* isolate = args.GetIsolate();
730
1
  Local<Object> that = args.This();
731
732
  ModuleWrap* obj;
733
1
  ASSIGN_OR_RETURN_UNWRAP(&obj, that);
734
735
1
  CHECK(!obj->synthetic_);
736
737
2
  Local<Module> module = obj->module_.Get(isolate);
738
739
1
  CHECK_LT(module->GetStatus(), v8::Module::Status::kEvaluating);
740
741
  Local<UnboundModuleScript> unbound_module_script =
742
1
      module->GetUnboundModuleScript();
743
  std::unique_ptr<ScriptCompiler::CachedData> cached_data(
744
2
      ScriptCompiler::CreateCodeCache(unbound_module_script));
745
1
  Environment* env = Environment::GetCurrent(args);
746
1
  if (!cached_data) {
747
    args.GetReturnValue().Set(Buffer::New(env, 0).ToLocalChecked());
748
  } else {
749
    MaybeLocal<Object> buf =
750
        Buffer::Copy(env,
751
1
                     reinterpret_cast<const char*>(cached_data->data),
752
2
                     cached_data->length);
753
2
    args.GetReturnValue().Set(buf.ToLocalChecked());
754
  }
755
}
756
757
5184
void ModuleWrap::Initialize(Local<Object> target,
758
                            Local<Value> unused,
759
                            Local<Context> context,
760
                            void* priv) {
761
5184
  Environment* env = Environment::GetCurrent(context);
762
763
5184
  Local<FunctionTemplate> tpl = env->NewFunctionTemplate(New);
764
15552
  tpl->InstanceTemplate()->SetInternalFieldCount(
765
5184
      ModuleWrap::kInternalFieldCount);
766
10368
  tpl->Inherit(BaseObject::GetConstructorTemplate(env));
767
768
5184
  env->SetProtoMethod(tpl, "link", Link);
769
5184
  env->SetProtoMethod(tpl, "instantiate", Instantiate);
770
5184
  env->SetProtoMethod(tpl, "evaluate", Evaluate);
771
5184
  env->SetProtoMethod(tpl, "setExport", SetSyntheticExport);
772
5184
  env->SetProtoMethodNoSideEffect(tpl, "createCachedData", CreateCachedData);
773
5184
  env->SetProtoMethodNoSideEffect(tpl, "getNamespace", GetNamespace);
774
5184
  env->SetProtoMethodNoSideEffect(tpl, "getStatus", GetStatus);
775
5184
  env->SetProtoMethodNoSideEffect(tpl, "getError", GetError);
776
  env->SetProtoMethodNoSideEffect(tpl, "getStaticDependencySpecifiers",
777
5184
                                  GetStaticDependencySpecifiers);
778
779
5184
  env->SetConstructorFunction(target, "ModuleWrap", tpl);
780
781
  env->SetMethod(target,
782
                 "setImportModuleDynamicallyCallback",
783
5184
                 SetImportModuleDynamicallyCallback);
784
  env->SetMethod(target,
785
                 "setInitializeImportMetaObjectCallback",
786
5184
                 SetInitializeImportMetaObjectCallback);
787
788
#define V(name)                                                                \
789
    target->Set(context,                                                       \
790
      FIXED_ONE_BYTE_STRING(env->isolate(), #name),                            \
791
      Integer::New(env->isolate(), Module::Status::name))                      \
792
        .FromJust()
793
20736
    V(kUninstantiated);
794
20736
    V(kInstantiating);
795
20736
    V(kInstantiated);
796
20736
    V(kEvaluating);
797
20736
    V(kEvaluated);
798
20736
    V(kErrored);
799
#undef V
800
5184
}
801
802
}  // namespace loader
803
}  // namespace node
804
805

19292
NODE_MODULE_CONTEXT_AWARE_INTERNAL(module_wrap,
806
                                   node::loader::ModuleWrap::Initialize)