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: 364 407 89.4 %
Date: 2020-07-19 22:14:24 Branches: 154 259 59.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::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
34077
ModuleWrap::ModuleWrap(Environment* env,
53
                       Local<Object> object,
54
                       Local<Module> module,
55
34077
                       Local<String> url)
56
  : BaseObject(env, object),
57
    module_(env->isolate(), module),
58
    url_(env->isolate(), url),
59
170385
    id_(env->get_next_module_id()) {
60
34077
  env->id_to_module_map.emplace(id_, this);
61
34077
}
62
63
222141
ModuleWrap::~ModuleWrap() {
64
63468
  HandleScope scope(env()->isolate());
65
63471
  Local<Module> module = module_.Get(env()->isolate());
66
31736
  env()->id_to_module_map.erase(id_);
67
31736
  auto range = env()->hash_to_module_map.equal_range(module->GetIdentityHash());
68
31733
  for (auto it = range.first; it != range.second; ++it) {
69
31735
    if (it->second == this) {
70
31734
      env()->hash_to_module_map.erase(it);
71
31734
      break;
72
    }
73
  }
74
63466
}
75
76
34156
ModuleWrap* ModuleWrap::GetFromModule(Environment* env,
77
                                      Local<Module> module) {
78
34156
  auto range = env->hash_to_module_map.equal_range(module->GetIdentityHash());
79
34156
  for (auto it = range.first; it != range.second; ++it) {
80
68312
    if (it->second->module_ == module) {
81
34156
      return it->second;
82
    }
83
  }
84
  return nullptr;
85
}
86
87
73
ModuleWrap* ModuleWrap::GetFromID(Environment* env, uint32_t id) {
88
73
  auto module_wrap_it = env->id_to_module_map.find(id);
89
73
  if (module_wrap_it == env->id_to_module_map.end()) {
90
    return nullptr;
91
  }
92
73
  return module_wrap_it->second;
93
}
94
95
// new ModuleWrap(url, context, source, lineOffset, columnOffset)
96
// new ModuleWrap(url, context, exportNames, syntheticExecutionFunction)
97
34085
void ModuleWrap::New(const FunctionCallbackInfo<Value>& args) {
98
34085
  CHECK(args.IsConstructCall());
99
34085
  CHECK_GE(args.Length(), 3);
100
101
34085
  Environment* env = Environment::GetCurrent(args);
102
34085
  Isolate* isolate = env->isolate();
103
104
34085
  Local<Object> that = args.This();
105
106
102255
  CHECK(args[0]->IsString());
107
68170
  Local<String> url = args[0].As<String>();
108
109
  Local<Context> context;
110
34085
  ContextifyContext* contextify_context = nullptr;
111
102255
  if (args[1]->IsUndefined()) {
112
34076
    context = that->CreationContext();
113
  } else {
114
18
    CHECK(args[1]->IsObject());
115
9
    contextify_context = ContextifyContext::ContextFromContextifiedSandbox(
116
27
        env, args[1].As<Object>());
117
9
    CHECK_NOT_NULL(contextify_context);
118
9
    context = contextify_context->context();
119
  }
120
121
  Local<Integer> line_offset;
122
  Local<Integer> column_offset;
123
124
68170
  bool synthetic = args[2]->IsArray();
125
34085
  if (synthetic) {
126
    // new ModuleWrap(url, context, exportNames, syntheticExecutionFunction)
127
67488
    CHECK(args[3]->IsFunction());
128
  } else {
129
    // new ModuleWrap(url, context, source, lineOffset, columOffset, cachedData)
130
1023
    CHECK(args[2]->IsString());
131
682
    CHECK(args[3]->IsNumber());
132
682
    line_offset = args[3].As<Integer>();
133
682
    CHECK(args[4]->IsNumber());
134
682
    column_offset = args[4].As<Integer>();
135
  }
136
137
  Local<PrimitiveArray> host_defined_options =
138
34085
      PrimitiveArray::New(isolate, HostDefinedOptions::kLength);
139
102255
  host_defined_options->Set(isolate, HostDefinedOptions::kType,
140
34085
                            Number::New(isolate, ScriptType::kModule));
141
142
68162
  ShouldNotAbortOnUncaughtScope no_abort_scope(env);
143
68162
  TryCatchScope try_catch(env);
144
145
  Local<Module> module;
146
147
  {
148
34077
    Context::Scope context_scope(context);
149
34085
    if (synthetic) {
150
67488
      CHECK(args[2]->IsArray());
151
67488
      Local<Array> export_names_arr = args[2].As<Array>();
152
153
33744
      uint32_t len = export_names_arr->Length();
154
67488
      std::vector<Local<String>> export_names(len);
155
986547
      for (uint32_t i = 0; i < len; i++) {
156
        Local<Value> export_name_val =
157
1905606
            export_names_arr->Get(context, i).ToLocalChecked();
158
1905606
        CHECK(export_name_val->IsString());
159
1905606
        export_names[i] = export_name_val.As<String>();
160
      }
161
162
      module = Module::CreateSyntheticModule(isolate, url, export_names,
163
33744
        SyntheticModuleEvaluationStepsCallback);
164
    } else {
165
341
      ScriptCompiler::CachedData* cached_data = nullptr;
166
1023
      if (!args[5]->IsUndefined()) {
167
4
        CHECK(args[5]->IsArrayBufferView());
168
4
        Local<ArrayBufferView> cached_data_buf = args[5].As<ArrayBufferView>();
169
        uint8_t* data = static_cast<uint8_t*>(
170
4
            cached_data_buf->Buffer()->GetBackingStore()->Data());
171
2
        cached_data =
172
2
            new ScriptCompiler::CachedData(data + cached_data_buf->ByteOffset(),
173
2
                                           cached_data_buf->ByteLength());
174
      }
175
176
682
      Local<String> source_text = args[2].As<String>();
177
      ScriptOrigin origin(url,
178
                          line_offset,                      // line offset
179
                          column_offset,                    // column offset
180
                          True(isolate),                    // is cross origin
181
                          Local<Integer>(),                 // script id
182
                          Local<Value>(),                   // source map URL
183
                          False(isolate),                   // is opaque (?)
184
                          False(isolate),                   // is WASM
185
                          True(isolate),                    // is ES Module
186
341
                          host_defined_options);
187
333
      ScriptCompiler::Source source(source_text, origin, cached_data);
188
      ScriptCompiler::CompileOptions options;
189
341
      if (source.GetCachedData() == nullptr) {
190
339
        options = ScriptCompiler::kNoCompileOptions;
191
      } else {
192
2
        options = ScriptCompiler::kConsumeCodeCache;
193
      }
194
682
      if (!ScriptCompiler::CompileModule(isolate, &source, options)
195
341
               .ToLocal(&module)) {
196

7
        if (try_catch.HasCaught() && !try_catch.HasTerminated()) {
197
14
          CHECK(!try_catch.Message().IsEmpty());
198
14
          CHECK(!try_catch.Exception().IsEmpty());
199
7
          AppendExceptionLine(env, try_catch.Exception(), try_catch.Message(),
200
7
                              ErrorHandlingMode::MODULE_ERROR);
201
7
          try_catch.ReThrow();
202
        }
203
7
        return;
204
      }
205

336
      if (options == ScriptCompiler::kConsumeCodeCache &&
206
2
          source.GetCachedData()->rejected) {
207
        THROW_ERR_VM_MODULE_CACHED_DATA_REJECTED(
208
1
            env, "cachedData buffer was rejected");
209
1
        try_catch.ReThrow();
210
1
        return;
211
      }
212
    }
213
  }
214
215
136308
  if (!that->Set(context, env->url_string(), url).FromMaybe(false)) {
216
    return;
217
  }
218
219
34077
  ModuleWrap* obj = new ModuleWrap(env, that, module, url);
220
221
34077
  if (synthetic) {
222
33744
    obj->synthetic_ = true;
223
33744
    obj->synthetic_evaluation_steps_.Reset(
224
101232
        env->isolate(), args[3].As<Function>());
225
  }
226
227
34077
  obj->context_.Reset(isolate, context);
228
34077
  obj->contextify_context_ = contextify_context;
229
230
34077
  env->hash_to_module_map.emplace(module->GetIdentityHash(), obj);
231
232
102231
  host_defined_options->Set(isolate, HostDefinedOptions::kID,
233
68154
                            Number::New(isolate, obj->id()));
234
235
34077
  that->SetIntegrityLevel(context, IntegrityLevel::kFrozen);
236
68154
  args.GetReturnValue().Set(that);
237
}
238
239
521
void ModuleWrap::Link(const FunctionCallbackInfo<Value>& args) {
240
521
  Environment* env = Environment::GetCurrent(args);
241
521
  Isolate* isolate = args.GetIsolate();
242
243
521
  CHECK_EQ(args.Length(), 1);
244
1042
  CHECK(args[0]->IsFunction());
245
246
521
  Local<Object> that = args.This();
247
248
  ModuleWrap* obj;
249
524
  ASSIGN_OR_RETURN_UNWRAP(&obj, that);
250
251
521
  if (obj->linked_)
252
3
    return;
253
518
  obj->linked_ = true;
254
255
1036
  Local<Function> resolver_arg = args[0].As<Function>();
256
257
1036
  Local<Context> mod_context = obj->context_.Get(isolate);
258
1036
  Local<Module> module = obj->module_.Get(isolate);
259
260
518
  const int module_requests_length = module->GetModuleRequestsLength();
261
1036
  MaybeStackBuffer<Local<Value>, 16> promises(module_requests_length);
262
263
  // call the dependency resolve callbacks
264
887
  for (int i = 0; i < module_requests_length; i++) {
265
369
    Local<String> specifier = module->GetModuleRequest(i);
266
738
    Utf8Value specifier_utf8(env->isolate(), specifier);
267
738
    std::string specifier_std(*specifier_utf8, specifier_utf8.length());
268
269
    Local<Value> argv[] = {
270
      specifier
271
738
    };
272
273
    MaybeLocal<Value> maybe_resolve_return_value =
274
738
        resolver_arg->Call(mod_context, that, arraysize(argv), argv);
275
369
    if (maybe_resolve_return_value.IsEmpty()) {
276
      return;
277
    }
278
    Local<Value> resolve_return_value =
279
369
        maybe_resolve_return_value.ToLocalChecked();
280
369
    if (!resolve_return_value->IsPromise()) {
281
      env->ThrowError("linking error, expected resolver to return a promise");
282
    }
283
369
    Local<Promise> resolve_promise = resolve_return_value.As<Promise>();
284
369
    obj->resolve_cache_[specifier_std].Reset(env->isolate(), resolve_promise);
285
286
738
    promises[i] = resolve_promise;
287
  }
288
289
1554
  args.GetReturnValue().Set(
290
      Array::New(isolate, promises.out(), promises.length()));
291
}
292
293
33873
void ModuleWrap::Instantiate(const FunctionCallbackInfo<Value>& args) {
294
33873
  Environment* env = Environment::GetCurrent(args);
295
33873
  Isolate* isolate = args.GetIsolate();
296
  ModuleWrap* obj;
297
33883
  ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
298
67746
  Local<Context> context = obj->context_.Get(isolate);
299
67746
  Local<Module> module = obj->module_.Get(isolate);
300
67736
  TryCatchScope try_catch(env);
301
33873
  USE(module->InstantiateModule(context, ResolveCallback));
302
303
  // clear resolve cache on instantiate
304
33873
  obj->resolve_cache_.clear();
305
306

33873
  if (try_catch.HasCaught() && !try_catch.HasTerminated()) {
307
20
    CHECK(!try_catch.Message().IsEmpty());
308
20
    CHECK(!try_catch.Exception().IsEmpty());
309
10
    AppendExceptionLine(env, try_catch.Exception(), try_catch.Message(),
310
10
                        ErrorHandlingMode::MODULE_ERROR);
311
10
    try_catch.ReThrow();
312
10
    return;
313
  }
314
}
315
316
33864
void ModuleWrap::Evaluate(const FunctionCallbackInfo<Value>& args) {
317
33864
  Environment* env = Environment::GetCurrent(args);
318
33864
  Isolate* isolate = env->isolate();
319
  ModuleWrap* obj;
320
33873
  ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
321
67728
  Local<Context> context = obj->context_.Get(isolate);
322
67728
  Local<Module> module = obj->module_.Get(isolate);
323
324
33864
  ContextifyContext* contextify_context = obj->contextify_context_;
325
67718
  std::shared_ptr<MicrotaskQueue> microtask_queue;
326
33864
  if (contextify_context != nullptr)
327
3
      microtask_queue = contextify_context->microtask_queue();
328
329
  // module.evaluate(timeout, breakOnSigint)
330
33864
  CHECK_EQ(args.Length(), 2);
331
332
67728
  CHECK(args[0]->IsNumber());
333
135456
  int64_t timeout = args[0]->IntegerValue(env->context()).FromJust();
334
335
67728
  CHECK(args[1]->IsBoolean());
336
67728
  bool break_on_sigint = args[1]->IsTrue();
337
338
67718
  ShouldNotAbortOnUncaughtScope no_abort_scope(env);
339
67718
  TryCatchScope try_catch(env);
340
341
33864
  bool timed_out = false;
342
33864
  bool received_signal = false;
343
  MaybeLocal<Value> result;
344
33864
  auto run = [&]() {
345
67728
    MaybeLocal<Value> result = module->Evaluate(context);
346

33863
    if (!result.IsEmpty() && microtask_queue)
347
1
      microtask_queue->PerformCheckpoint(isolate);
348
33863
    return result;
349
33864
  };
350

33864
  if (break_on_sigint && timeout != -1) {
351
    Watchdog wd(isolate, timeout, &timed_out);
352
    SigintWatchdog swd(isolate, &received_signal);
353
    result = run();
354
33864
  } else if (break_on_sigint) {
355
    SigintWatchdog swd(isolate, &received_signal);
356
    result = run();
357
33864
  } else if (timeout != -1) {
358
6
    Watchdog wd(isolate, timeout, &timed_out);
359
3
    result = run();
360
  } else {
361
33861
    result = run();
362
  }
363
364
33863
  if (result.IsEmpty()) {
365
8
    CHECK(try_catch.HasCaught());
366
  }
367
368
  // Convert the termination exception into a regular exception.
369

33863
  if (timed_out || received_signal) {
370

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

700
  if (module_object.IsEmpty() || !module_object->IsObject()) {
499
    env->ThrowError("linking error, expected a valid module object from "
500
                    "resolver");
501
    return MaybeLocal<Module>();
502
  }
503
504
  ModuleWrap* module;
505
350
  ASSIGN_OR_RETURN_UNWRAP(&module, module_object, MaybeLocal<Module>());
506
700
  return module->module_.Get(isolate);
507
}
508
509
130
static MaybeLocal<Promise> ImportModuleDynamically(
510
    Local<Context> context,
511
    Local<ScriptOrModule> referrer,
512
    Local<String> specifier) {
513
130
  Isolate* iso = context->GetIsolate();
514
130
  Environment* env = Environment::GetCurrent(context);
515
130
  if (env == nullptr) {
516
    THROW_ERR_EXECUTION_ENVIRONMENT_NOT_AVAILABLE(iso);
517
    return MaybeLocal<Promise>();
518
  }
519
520
130
  EscapableHandleScope handle_scope(iso);
521
522
  Local<Function> import_callback =
523
130
    env->host_import_module_dynamically_callback();
524
525
130
  Local<PrimitiveArray> options = referrer->GetHostDefinedOptions();
526
130
  if (options->Length() != HostDefinedOptions::kLength) {
527
    Local<Promise::Resolver> resolver;
528
    if (!Promise::Resolver::New(context).ToLocal(&resolver)) return {};
529
    resolver
530
        ->Reject(context,
531
                 v8::Exception::TypeError(FIXED_ONE_BYTE_STRING(
532
                     context->GetIsolate(), "Invalid host defined options")))
533
        .ToChecked();
534
    return handle_scope.Escape(resolver->GetPromise());
535
  }
536
537
  Local<Value> object;
538
539
260
  int type = options->Get(iso, HostDefinedOptions::kType)
540
260
                 .As<Number>()
541
260
                 ->Int32Value(context)
542
130
                 .ToChecked();
543
260
  uint32_t id = options->Get(iso, HostDefinedOptions::kID)
544
260
                    .As<Number>()
545
260
                    ->Uint32Value(context)
546
130
                    .ToChecked();
547
130
  if (type == ScriptType::kScript) {
548
5
    contextify::ContextifyScript* wrap = env->id_to_script_map.find(id)->second;
549
10
    object = wrap->object();
550
125
  } else if (type == ScriptType::kModule) {
551
73
    ModuleWrap* wrap = ModuleWrap::GetFromID(env, id);
552
146
    object = wrap->object();
553
52
  } else if (type == ScriptType::kFunction) {
554
52
    auto it = env->id_to_function_map.find(id);
555
52
    CHECK_NE(it, env->id_to_function_map.end());
556
104
    object = it->second->object();
557
  } else {
558
    UNREACHABLE();
559
  }
560
561
  Local<Value> import_args[] = {
562
    object,
563
    Local<Value>(specifier),
564
260
  };
565
566
  Local<Value> result;
567
390
  if (import_callback->Call(
568
        context,
569
        Undefined(iso),
570
130
        arraysize(import_args),
571
390
        import_args).ToLocal(&result)) {
572
130
    CHECK(result->IsPromise());
573
130
    return handle_scope.Escape(result.As<Promise>());
574
  }
575
576
  return MaybeLocal<Promise>();
577
}
578
579
5272
void ModuleWrap::SetImportModuleDynamicallyCallback(
580
    const FunctionCallbackInfo<Value>& args) {
581
5272
  Isolate* iso = args.GetIsolate();
582
5272
  Environment* env = Environment::GetCurrent(args);
583
10544
  HandleScope handle_scope(iso);
584
585
5272
  CHECK_EQ(args.Length(), 1);
586
10544
  CHECK(args[0]->IsFunction());
587
10544
  Local<Function> import_callback = args[0].As<Function>();
588
5272
  env->set_host_import_module_dynamically_callback(import_callback);
589
590
5272
  iso->SetHostImportModuleDynamicallyCallback(ImportModuleDynamically);
591
5272
}
592
593
76
void ModuleWrap::HostInitializeImportMetaObjectCallback(
594
    Local<Context> context, Local<Module> module, Local<Object> meta) {
595
76
  Environment* env = Environment::GetCurrent(context);
596
76
  if (env == nullptr)
597
    return;
598
76
  ModuleWrap* module_wrap = GetFromModule(env, module);
599
600
76
  if (module_wrap == nullptr) {
601
    return;
602
  }
603
604
76
  Local<Object> wrap = module_wrap->object();
605
  Local<Function> callback =
606
76
      env->host_initialize_import_meta_object_callback();
607
228
  Local<Value> args[] = { wrap, meta };
608
152
  TryCatchScope try_catch(env);
609
152
  USE(callback->Call(
610
304
        context, Undefined(env->isolate()), arraysize(args), args));
611

76
  if (try_catch.HasCaught() && !try_catch.HasTerminated()) {
612
    try_catch.ReThrow();
613
  }
614
}
615
616
5272
void ModuleWrap::SetInitializeImportMetaObjectCallback(
617
    const FunctionCallbackInfo<Value>& args) {
618
5272
  Environment* env = Environment::GetCurrent(args);
619
5272
  Isolate* isolate = env->isolate();
620
621
5272
  CHECK_EQ(args.Length(), 1);
622
10544
  CHECK(args[0]->IsFunction());
623
10544
  Local<Function> import_meta_callback = args[0].As<Function>();
624
5272
  env->set_host_initialize_import_meta_object_callback(import_meta_callback);
625
626
  isolate->SetHostInitializeImportMetaObjectCallback(
627
5272
      HostInitializeImportMetaObjectCallback);
628
5272
}
629
630
33730
MaybeLocal<Value> ModuleWrap::SyntheticModuleEvaluationStepsCallback(
631
    Local<Context> context, Local<Module> module) {
632
33730
  Environment* env = Environment::GetCurrent(context);
633
33730
  Isolate* isolate = env->isolate();
634
635
33730
  ModuleWrap* obj = GetFromModule(env, module);
636
637
67460
  TryCatchScope try_catch(env);
638
  Local<Function> synthetic_evaluation_steps =
639
67460
      obj->synthetic_evaluation_steps_.Get(isolate);
640
33730
  obj->synthetic_evaluation_steps_.Reset();
641
  MaybeLocal<Value> ret = synthetic_evaluation_steps->Call(context,
642
67460
      obj->object(), 0, nullptr);
643
33730
  if (ret.IsEmpty()) {
644
    CHECK(try_catch.HasCaught());
645
  }
646

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

19959
NODE_MODULE_CONTEXT_AWARE_INTERNAL(module_wrap,
755
                                   node::loader::ModuleWrap::Initialize)