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: 352 395 89.1 %
Date: 2020-06-24 22:13:30 Branches: 142 245 58.0 %

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::Module;
39
using v8::Number;
40
using v8::Object;
41
using v8::PrimitiveArray;
42
using v8::Promise;
43
using v8::ScriptCompiler;
44
using v8::ScriptOrigin;
45
using v8::ScriptOrModule;
46
using v8::String;
47
using v8::UnboundModuleScript;
48
using v8::Undefined;
49
using v8::Value;
50
51
31470
ModuleWrap::ModuleWrap(Environment* env,
52
                       Local<Object> object,
53
                       Local<Module> module,
54
31470
                       Local<String> url)
55
  : BaseObject(env, object),
56
    module_(env->isolate(), module),
57
    url_(env->isolate(), url),
58
157349
    id_(env->get_next_module_id()) {
59
31470
  env->id_to_module_map.emplace(id_, this);
60
31470
}
61
62
204647
ModuleWrap::~ModuleWrap() {
63
58471
  HandleScope scope(env()->isolate());
64
58471
  Local<Module> module = module_.Get(env()->isolate());
65
29235
  env()->id_to_module_map.erase(id_);
66
29236
  auto range = env()->hash_to_module_map.equal_range(module->GetIdentityHash());
67
29235
  for (auto it = range.first; it != range.second; ++it) {
68
29235
    if (it->second == this) {
69
29236
      env()->hash_to_module_map.erase(it);
70
29236
      break;
71
    }
72
  }
73
58471
}
74
75
31545
ModuleWrap* ModuleWrap::GetFromModule(Environment* env,
76
                                      Local<Module> module) {
77
31545
  auto range = env->hash_to_module_map.equal_range(module->GetIdentityHash());
78
31545
  for (auto it = range.first; it != range.second; ++it) {
79
63090
    if (it->second->module_ == module) {
80
31545
      return it->second;
81
    }
82
  }
83
  return nullptr;
84
}
85
86
72
ModuleWrap* ModuleWrap::GetFromID(Environment* env, uint32_t id) {
87
72
  auto module_wrap_it = env->id_to_module_map.find(id);
88
72
  if (module_wrap_it == env->id_to_module_map.end()) {
89
    return nullptr;
90
  }
91
72
  return module_wrap_it->second;
92
}
93
94
// new ModuleWrap(url, context, source, lineOffset, columnOffset)
95
// new ModuleWrap(url, context, exportNames, syntheticExecutionFunction)
96
31477
void ModuleWrap::New(const FunctionCallbackInfo<Value>& args) {
97
31477
  CHECK(args.IsConstructCall());
98
31477
  CHECK_GE(args.Length(), 3);
99
100
31477
  Environment* env = Environment::GetCurrent(args);
101
31478
  Isolate* isolate = env->isolate();
102
103
31478
  Local<Object> that = args.This();
104
105
94434
  CHECK(args[0]->IsString());
106
62956
  Local<String> url = args[0].As<String>();
107
108
  Local<Context> context;
109
94434
  if (args[1]->IsUndefined()) {
110
31471
    context = that->CreationContext();
111
  } else {
112
14
    CHECK(args[1]->IsObject());
113
    ContextifyContext* sandbox =
114
7
        ContextifyContext::ContextFromContextifiedSandbox(
115
21
            env, args[1].As<Object>());
116
7
    CHECK_NOT_NULL(sandbox);
117
7
    context = sandbox->context();
118
  }
119
120
  Local<Integer> line_offset;
121
  Local<Integer> column_offset;
122
123
62956
  bool synthetic = args[2]->IsArray();
124
31478
  if (synthetic) {
125
    // new ModuleWrap(url, context, exportNames, syntheticExecutionFunction)
126
62294
    CHECK(args[3]->IsFunction());
127
  } else {
128
    // new ModuleWrap(url, context, source, lineOffset, columOffset, cachedData)
129
993
    CHECK(args[2]->IsString());
130
662
    CHECK(args[3]->IsNumber());
131
662
    line_offset = args[3].As<Integer>();
132
662
    CHECK(args[4]->IsNumber());
133
662
    column_offset = args[4].As<Integer>();
134
  }
135
136
  Local<PrimitiveArray> host_defined_options =
137
31478
      PrimitiveArray::New(isolate, HostDefinedOptions::kLength);
138
94434
  host_defined_options->Set(isolate, HostDefinedOptions::kType,
139
31478
                            Number::New(isolate, ScriptType::kModule));
140
141
62948
  ShouldNotAbortOnUncaughtScope no_abort_scope(env);
142
62948
  TryCatchScope try_catch(env);
143
144
  Local<Module> module;
145
146
  {
147
31470
    Context::Scope context_scope(context);
148
31477
    if (synthetic) {
149
62292
      CHECK(args[2]->IsArray());
150
62292
      Local<Array> export_names_arr = args[2].As<Array>();
151
152
31146
      uint32_t len = export_names_arr->Length();
153
62293
      std::vector<Local<String>> export_names(len);
154
892904
      for (uint32_t i = 0; i < len; i++) {
155
        Local<Value> export_name_val =
156
1723515
            export_names_arr->Get(context, i).ToLocalChecked();
157
1723516
        CHECK(export_name_val->IsString());
158
1723516
        export_names[i] = export_name_val.As<String>();
159
      }
160
161
      module = Module::CreateSyntheticModule(isolate, url, export_names,
162
31147
        SyntheticModuleEvaluationStepsCallback);
163
    } else {
164
331
      ScriptCompiler::CachedData* cached_data = nullptr;
165
993
      if (!args[5]->IsUndefined()) {
166
4
        CHECK(args[5]->IsArrayBufferView());
167
4
        Local<ArrayBufferView> cached_data_buf = args[5].As<ArrayBufferView>();
168
        uint8_t* data = static_cast<uint8_t*>(
169
4
            cached_data_buf->Buffer()->GetBackingStore()->Data());
170
2
        cached_data =
171
2
            new ScriptCompiler::CachedData(data + cached_data_buf->ByteOffset(),
172
2
                                           cached_data_buf->ByteLength());
173
      }
174
175
662
      Local<String> source_text = args[2].As<String>();
176
      ScriptOrigin origin(url,
177
                          line_offset,                      // line offset
178
                          column_offset,                    // column offset
179
                          True(isolate),                    // is cross origin
180
                          Local<Integer>(),                 // script id
181
                          Local<Value>(),                   // source map URL
182
                          False(isolate),                   // is opaque (?)
183
                          False(isolate),                   // is WASM
184
                          True(isolate),                    // is ES Module
185
331
                          host_defined_options);
186
323
      ScriptCompiler::Source source(source_text, origin, cached_data);
187
      ScriptCompiler::CompileOptions options;
188
331
      if (source.GetCachedData() == nullptr) {
189
329
        options = ScriptCompiler::kNoCompileOptions;
190
      } else {
191
2
        options = ScriptCompiler::kConsumeCodeCache;
192
      }
193
662
      if (!ScriptCompiler::CompileModule(isolate, &source, options)
194
331
               .ToLocal(&module)) {
195

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

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

31271
  if (try_catch.HasCaught() && !try_catch.HasTerminated()) {
305
20
    CHECK(!try_catch.Message().IsEmpty());
306
20
    CHECK(!try_catch.Exception().IsEmpty());
307
10
    AppendExceptionLine(env, try_catch.Exception(), try_catch.Message(),
308
10
                        ErrorHandlingMode::MODULE_ERROR);
309
10
    try_catch.ReThrow();
310
10
    return;
311
  }
312
}
313
314
31261
void ModuleWrap::Evaluate(const FunctionCallbackInfo<Value>& args) {
315
31261
  Environment* env = Environment::GetCurrent(args);
316
31261
  Isolate* isolate = env->isolate();
317
  ModuleWrap* obj;
318
31268
  ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
319
62522
  Local<Context> context = obj->context_.Get(isolate);
320
62522
  Local<Module> module = obj->module_.Get(isolate);
321
322
  // module.evaluate(timeout, breakOnSigint)
323
31261
  CHECK_EQ(args.Length(), 2);
324
325
62522
  CHECK(args[0]->IsNumber());
326
125040
  int64_t timeout = args[0]->IntegerValue(env->context()).FromJust();
327
328
62520
  CHECK(args[1]->IsBoolean());
329
62520
  bool break_on_sigint = args[1]->IsTrue();
330
331
62514
  ShouldNotAbortOnUncaughtScope no_abort_scope(env);
332
62514
  TryCatchScope try_catch(env);
333
334
31261
  bool timed_out = false;
335
31261
  bool received_signal = false;
336
  MaybeLocal<Value> result;
337

31261
  if (break_on_sigint && timeout != -1) {
338
    Watchdog wd(isolate, timeout, &timed_out);
339
    SigintWatchdog swd(isolate, &received_signal);
340
    result = module->Evaluate(context);
341
31261
  } else if (break_on_sigint) {
342
    SigintWatchdog swd(isolate, &received_signal);
343
    result = module->Evaluate(context);
344
31261
  } else if (timeout != -1) {
345
2
    Watchdog wd(isolate, timeout, &timed_out);
346
1
    result = module->Evaluate(context);
347
  } else {
348
31260
    result = module->Evaluate(context);
349
  }
350
351
31260
  if (result.IsEmpty()) {
352
7
    CHECK(try_catch.HasCaught());
353
  }
354
355
  // Convert the termination exception into a regular exception.
356

31260
  if (timed_out || received_signal) {
357

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

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

73
  if (try_catch.HasCaught() && !try_catch.HasTerminated()) {
599
    try_catch.ReThrow();
600
  }
601
}
602
603
4670
void ModuleWrap::SetInitializeImportMetaObjectCallback(
604
    const FunctionCallbackInfo<Value>& args) {
605
4670
  Environment* env = Environment::GetCurrent(args);
606
4670
  Isolate* isolate = env->isolate();
607
608
4670
  CHECK_EQ(args.Length(), 1);
609
9340
  CHECK(args[0]->IsFunction());
610
9340
  Local<Function> import_meta_callback = args[0].As<Function>();
611
4670
  env->set_host_initialize_import_meta_object_callback(import_meta_callback);
612
613
  isolate->SetHostInitializeImportMetaObjectCallback(
614
4670
      HostInitializeImportMetaObjectCallback);
615
4670
}
616
617
31133
MaybeLocal<Value> ModuleWrap::SyntheticModuleEvaluationStepsCallback(
618
    Local<Context> context, Local<Module> module) {
619
31133
  Environment* env = Environment::GetCurrent(context);
620
31133
  Isolate* isolate = env->isolate();
621
622
31133
  ModuleWrap* obj = GetFromModule(env, module);
623
624
62266
  TryCatchScope try_catch(env);
625
  Local<Function> synthetic_evaluation_steps =
626
62266
      obj->synthetic_evaluation_steps_.Get(isolate);
627
31133
  obj->synthetic_evaluation_steps_.Reset();
628
  MaybeLocal<Value> ret = synthetic_evaluation_steps->Call(context,
629
62266
      obj->object(), 0, nullptr);
630
31133
  if (ret.IsEmpty()) {
631
    CHECK(try_catch.HasCaught());
632
  }
633

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