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 394 89.3 %
Date: 2020-05-27 22:15:15 Branches: 146 245 59.6 %

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

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

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

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

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

30576
  if (timed_out || received_signal) {
359

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

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

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

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