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: 553 622 88.9 %
Date: 2019-07-28 22:34:34 Branches: 286 440 65.0 %

Line Branch Exec Source
1
#include "module_wrap.h"
2
3
#include "env.h"
4
#include "memory_tracker-inl.h"
5
#include "node_errors.h"
6
#include "node_url.h"
7
#include "util-inl.h"
8
#include "node_contextify.h"
9
#include "node_watchdog.h"
10
11
#include <sys/stat.h>  // S_IFDIR
12
13
#include <algorithm>
14
#include <climits>  // PATH_MAX
15
16
namespace node {
17
namespace loader {
18
19
using errors::TryCatchScope;
20
21
using node::contextify::ContextifyContext;
22
using node::url::URL;
23
using node::url::URL_FLAGS_FAILED;
24
using v8::Array;
25
using v8::Context;
26
using v8::Function;
27
using v8::FunctionCallbackInfo;
28
using v8::FunctionTemplate;
29
using v8::Global;
30
using v8::HandleScope;
31
using v8::Integer;
32
using v8::IntegrityLevel;
33
using v8::Isolate;
34
using v8::Just;
35
using v8::Local;
36
using v8::Maybe;
37
using v8::MaybeLocal;
38
using v8::Module;
39
using v8::Nothing;
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::String;
47
using v8::Undefined;
48
using v8::Value;
49
50
static const char* const EXTENSIONS[] = {
51
  ".mjs",
52
  ".cjs",
53
  ".js",
54
  ".json",
55
  ".node"
56
};
57
58
381
ModuleWrap::ModuleWrap(Environment* env,
59
                       Local<Object> object,
60
                       Local<Module> module,
61
                       Local<String> url) :
62
  BaseObject(env, object),
63
1524
  id_(env->get_next_module_id()) {
64
381
  module_.Reset(env->isolate(), module);
65
381
  url_.Reset(env->isolate(), url);
66
381
  env->id_to_module_map.emplace(id_, this);
67
381
}
68
69
2184
ModuleWrap::~ModuleWrap() {
70
364
  HandleScope scope(env()->isolate());
71
728
  Local<Module> module = module_.Get(env()->isolate());
72
364
  env()->id_to_module_map.erase(id_);
73
364
  auto range = env()->hash_to_module_map.equal_range(module->GetIdentityHash());
74
364
  for (auto it = range.first; it != range.second; ++it) {
75
364
    if (it->second == this) {
76
364
      env()->hash_to_module_map.erase(it);
77
364
      break;
78
    }
79
364
  }
80
728
}
81
82
323
ModuleWrap* ModuleWrap::GetFromModule(Environment* env,
83
                                      Local<Module> module) {
84
323
  auto range = env->hash_to_module_map.equal_range(module->GetIdentityHash());
85
323
  for (auto it = range.first; it != range.second; ++it) {
86
646
    if (it->second->module_ == module) {
87
323
      return it->second;
88
    }
89
  }
90
  return nullptr;
91
}
92
93
16
ModuleWrap* ModuleWrap::GetFromID(Environment* env, uint32_t id) {
94
16
  auto module_wrap_it = env->id_to_module_map.find(id);
95
16
  if (module_wrap_it == env->id_to_module_map.end()) {
96
    return nullptr;
97
  }
98
16
  return module_wrap_it->second;
99
}
100
101
387
void ModuleWrap::New(const FunctionCallbackInfo<Value>& args) {
102
387
  Environment* env = Environment::GetCurrent(args);
103
387
  Isolate* isolate = env->isolate();
104
105
387
  CHECK(args.IsConstructCall());
106
387
  Local<Object> that = args.This();
107
108
387
  const int argc = args.Length();
109
387
  CHECK_GE(argc, 2);
110
111
1161
  CHECK(args[0]->IsString());
112
774
  Local<String> source_text = args[0].As<String>();
113
114
1161
  CHECK(args[1]->IsString());
115
774
  Local<String> url = args[1].As<String>();
116
117
  Local<Context> context;
118
  Local<Integer> line_offset;
119
  Local<Integer> column_offset;
120
121
387
  if (argc == 5) {
122
    // new ModuleWrap(source, url, context?, lineOffset, columnOffset)
123
174
    if (args[2]->IsUndefined()) {
124
51
      context = that->CreationContext();
125
    } else {
126
14
      CHECK(args[2]->IsObject());
127
      ContextifyContext* sandbox =
128
          ContextifyContext::ContextFromContextifiedSandbox(
129
14
              env, args[2].As<Object>());
130
7
      CHECK_NOT_NULL(sandbox);
131
7
      context = sandbox->context();
132
    }
133
134
116
    CHECK(args[3]->IsNumber());
135
116
    line_offset = args[3].As<Integer>();
136
137
116
    CHECK(args[4]->IsNumber());
138
116
    column_offset = args[4].As<Integer>();
139
  } else {
140
    // new ModuleWrap(source, url)
141
329
    context = that->CreationContext();
142
329
    line_offset = Integer::New(isolate, 0);
143
329
    column_offset = Integer::New(isolate, 0);
144
  }
145
146
387
  ShouldNotAbortOnUncaughtScope no_abort_scope(env);
147
768
  TryCatchScope try_catch(env);
148
  Local<Module> module;
149
150
  Local<PrimitiveArray> host_defined_options =
151
387
      PrimitiveArray::New(isolate, HostDefinedOptions::kLength);
152
  host_defined_options->Set(isolate, HostDefinedOptions::kType,
153
774
                            Number::New(isolate, ScriptType::kModule));
154
155
  // compile
156
  {
157
    ScriptOrigin origin(url,
158
                        line_offset,                          // line offset
159
                        column_offset,                        // column offset
160
                        True(isolate),                        // is cross origin
161
                        Local<Integer>(),                     // script id
162
                        Local<Value>(),                       // source map URL
163
                        False(isolate),                       // is opaque (?)
164
                        False(isolate),                       // is WASM
165
                        True(isolate),                        // is ES Module
166
387
                        host_defined_options);
167
    Context::Scope context_scope(context);
168
381
    ScriptCompiler::Source source(source_text, origin);
169
774
    if (!ScriptCompiler::CompileModule(isolate, &source).ToLocal(&module)) {
170

6
      if (try_catch.HasCaught() && !try_catch.HasTerminated()) {
171
12
        CHECK(!try_catch.Message().IsEmpty());
172
12
        CHECK(!try_catch.Exception().IsEmpty());
173
        AppendExceptionLine(env, try_catch.Exception(), try_catch.Message(),
174
6
                            ErrorHandlingMode::MODULE_ERROR);
175
6
        try_catch.ReThrow();
176
      }
177
6
      return;
178
381
    }
179
  }
180
181
1524
  if (!that->Set(context, env->url_string(), url).FromMaybe(false)) {
182
    return;
183
  }
184
185
381
  ModuleWrap* obj = new ModuleWrap(env, that, module, url);
186
381
  obj->context_.Reset(isolate, context);
187
188
381
  env->hash_to_module_map.emplace(module->GetIdentityHash(), obj);
189
190
  host_defined_options->Set(isolate, HostDefinedOptions::kID,
191
762
                            Number::New(isolate, obj->id()));
192
193
381
  that->SetIntegrityLevel(context, IntegrityLevel::kFrozen);
194
1143
  args.GetReturnValue().Set(that);
195
}
196
197
358
void ModuleWrap::Link(const FunctionCallbackInfo<Value>& args) {
198
358
  Environment* env = Environment::GetCurrent(args);
199
358
  Isolate* isolate = args.GetIsolate();
200
201
358
  CHECK_EQ(args.Length(), 1);
202
716
  CHECK(args[0]->IsFunction());
203
204
358
  Local<Object> that = args.This();
205
206
  ModuleWrap* obj;
207
358
  ASSIGN_OR_RETURN_UNWRAP(&obj, that);
208
209
358
  if (obj->linked_)
210
    return;
211
358
  obj->linked_ = true;
212
213
716
  Local<Function> resolver_arg = args[0].As<Function>();
214
215
716
  Local<Context> mod_context = obj->context_.Get(isolate);
216
716
  Local<Module> module = obj->module_.Get(isolate);
217
218
  Local<Array> promises = Array::New(isolate,
219
358
                                     module->GetModuleRequestsLength());
220
221
  // call the dependency resolve callbacks
222
1090
  for (int i = 0; i < module->GetModuleRequestsLength(); i++) {
223
187
    Local<String> specifier = module->GetModuleRequest(i);
224
187
    Utf8Value specifier_utf8(env->isolate(), specifier);
225
374
    std::string specifier_std(*specifier_utf8, specifier_utf8.length());
226
227
    Local<Value> argv[] = {
228
      specifier
229
374
    };
230
231
    MaybeLocal<Value> maybe_resolve_return_value =
232
187
        resolver_arg->Call(mod_context, that, 1, argv);
233
187
    if (maybe_resolve_return_value.IsEmpty()) {
234
      return;
235
    }
236
    Local<Value> resolve_return_value =
237
187
        maybe_resolve_return_value.ToLocalChecked();
238
187
    if (!resolve_return_value->IsPromise()) {
239
      env->ThrowError("linking error, expected resolver to return a promise");
240
    }
241
187
    Local<Promise> resolve_promise = resolve_return_value.As<Promise>();
242
187
    obj->resolve_cache_[specifier_std].Reset(env->isolate(), resolve_promise);
243
244
561
    promises->Set(mod_context, i, resolve_promise).Check();
245
187
  }
246
247
716
  args.GetReturnValue().Set(promises);
248
}
249
250
109
void ModuleWrap::Instantiate(const FunctionCallbackInfo<Value>& args) {
251
109
  Environment* env = Environment::GetCurrent(args);
252
109
  Isolate* isolate = args.GetIsolate();
253
  ModuleWrap* obj;
254
112
  ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
255
218
  Local<Context> context = obj->context_.Get(isolate);
256
218
  Local<Module> module = obj->module_.Get(isolate);
257
109
  TryCatchScope try_catch(env);
258
109
  USE(module->InstantiateModule(context, ResolveCallback));
259
260
  // clear resolve cache on instantiate
261
109
  obj->resolve_cache_.clear();
262
263

109
  if (try_catch.HasCaught() && !try_catch.HasTerminated()) {
264
6
    CHECK(!try_catch.Message().IsEmpty());
265
6
    CHECK(!try_catch.Exception().IsEmpty());
266
    AppendExceptionLine(env, try_catch.Exception(), try_catch.Message(),
267
3
                        ErrorHandlingMode::MODULE_ERROR);
268
3
    try_catch.ReThrow();
269
3
    return;
270
106
  }
271
}
272
273
114
void ModuleWrap::Evaluate(const FunctionCallbackInfo<Value>& args) {
274
114
  Environment* env = Environment::GetCurrent(args);
275
114
  Isolate* isolate = env->isolate();
276
  ModuleWrap* obj;
277
121
  ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
278
228
  Local<Context> context = obj->context_.Get(isolate);
279
228
  Local<Module> module = obj->module_.Get(isolate);
280
281
  // module.evaluate(timeout, breakOnSigint)
282
114
  CHECK_EQ(args.Length(), 2);
283
284
228
  CHECK(args[0]->IsNumber());
285
456
  int64_t timeout = args[0]->IntegerValue(env->context()).FromJust();
286
287
228
  CHECK(args[1]->IsBoolean());
288
228
  bool break_on_sigint = args[1]->IsTrue();
289
290
114
  ShouldNotAbortOnUncaughtScope no_abort_scope(env);
291
220
  TryCatchScope try_catch(env);
292
293
114
  bool timed_out = false;
294
114
  bool received_signal = false;
295
  MaybeLocal<Value> result;
296

114
  if (break_on_sigint && timeout != -1) {
297
    Watchdog wd(isolate, timeout, &timed_out);
298
    SigintWatchdog swd(isolate, &received_signal);
299
    result = module->Evaluate(context);
300
114
  } else if (break_on_sigint) {
301
    SigintWatchdog swd(isolate, &received_signal);
302
    result = module->Evaluate(context);
303
114
  } else if (timeout != -1) {
304
1
    Watchdog wd(isolate, timeout, &timed_out);
305
1
    result = module->Evaluate(context);
306
  } else {
307
113
    result = module->Evaluate(context);
308
  }
309
310
  // Convert the termination exception into a regular exception.
311

113
  if (timed_out || received_signal) {
312

1
    if (!env->is_main_thread() && env->is_stopping())
313
      return;
314
1
    env->isolate()->CancelTerminateExecution();
315
    // It is possible that execution was terminated by another timeout in
316
    // which this timeout is nested, so check whether one of the watchdogs
317
    // from this invocation is responsible for termination.
318
1
    if (timed_out) {
319
1
      THROW_ERR_SCRIPT_EXECUTION_TIMEOUT(env, timeout);
320
    } else if (received_signal) {
321
      THROW_ERR_SCRIPT_EXECUTION_INTERRUPTED(env);
322
    }
323
  }
324
325
113
  if (try_catch.HasCaught()) {
326
7
    if (!try_catch.HasTerminated())
327
6
      try_catch.ReThrow();
328
7
    return;
329
  }
330
331
318
  args.GetReturnValue().Set(result.ToLocalChecked());
332
}
333
334
97
void ModuleWrap::Namespace(const FunctionCallbackInfo<Value>& args) {
335
97
  Environment* env = Environment::GetCurrent(args);
336
97
  Isolate* isolate = args.GetIsolate();
337
  ModuleWrap* obj;
338
97
  ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
339
340
194
  Local<Module> module = obj->module_.Get(isolate);
341
342
97
  switch (module->GetStatus()) {
343
    default:
344
      return env->ThrowError(
345
          "cannot get namespace, Module has not been instantiated");
346
    case v8::Module::Status::kInstantiated:
347
    case v8::Module::Status::kEvaluating:
348
    case v8::Module::Status::kEvaluated:
349
97
      break;
350
  }
351
352
97
  Local<Value> result = module->GetModuleNamespace();
353
194
  args.GetReturnValue().Set(result);
354
}
355
356
105
void ModuleWrap::GetStatus(const FunctionCallbackInfo<Value>& args) {
357
105
  Isolate* isolate = args.GetIsolate();
358
  ModuleWrap* obj;
359
210
  ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
360
361
210
  Local<Module> module = obj->module_.Get(isolate);
362
363
315
  args.GetReturnValue().Set(module->GetStatus());
364
}
365
366
2
void ModuleWrap::GetStaticDependencySpecifiers(
367
    const FunctionCallbackInfo<Value>& args) {
368
2
  Environment* env = Environment::GetCurrent(args);
369
  ModuleWrap* obj;
370
4
  ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
371
372
4
  Local<Module> module = obj->module_.Get(env->isolate());
373
374
2
  int count = module->GetModuleRequestsLength();
375
376
2
  Local<Array> specifiers = Array::New(env->isolate(), count);
377
378
3
  for (int i = 0; i < count; i++)
379
4
    specifiers->Set(env->context(), i, module->GetModuleRequest(i)).Check();
380
381
4
  args.GetReturnValue().Set(specifiers);
382
}
383
384
1
void ModuleWrap::GetError(const FunctionCallbackInfo<Value>& args) {
385
1
  Isolate* isolate = args.GetIsolate();
386
  ModuleWrap* obj;
387
2
  ASSIGN_OR_RETURN_UNWRAP(&obj, args.This());
388
389
2
  Local<Module> module = obj->module_.Get(isolate);
390
3
  args.GetReturnValue().Set(module->GetException());
391
}
392
393
177
MaybeLocal<Module> ModuleWrap::ResolveCallback(Local<Context> context,
394
                                               Local<String> specifier,
395
                                               Local<Module> referrer) {
396
177
  Environment* env = Environment::GetCurrent(context);
397
177
  CHECK_NOT_NULL(env);  // TODO(addaleax): Handle nullptr here.
398
177
  Isolate* isolate = env->isolate();
399
400
177
  ModuleWrap* dependent = GetFromModule(env, referrer);
401
177
  if (dependent == nullptr) {
402
    env->ThrowError("linking error, null dep");
403
    return MaybeLocal<Module>();
404
  }
405
406
177
  Utf8Value specifier_utf8(isolate, specifier);
407
354
  std::string specifier_std(*specifier_utf8, specifier_utf8.length());
408
409
177
  if (dependent->resolve_cache_.count(specifier_std) != 1) {
410
    env->ThrowError("linking error, not in local cache");
411
    return MaybeLocal<Module>();
412
  }
413
414
  Local<Promise> resolve_promise =
415
354
      dependent->resolve_cache_[specifier_std].Get(isolate);
416
417
177
  if (resolve_promise->State() != Promise::kFulfilled) {
418
    env->ThrowError("linking error, dependency promises must be resolved on "
419
                    "instantiate");
420
    return MaybeLocal<Module>();
421
  }
422
423
354
  Local<Object> module_object = resolve_promise->Result().As<Object>();
424

354
  if (module_object.IsEmpty() || !module_object->IsObject()) {
425
    env->ThrowError("linking error, expected a valid module object from "
426
                    "resolver");
427
    return MaybeLocal<Module>();
428
  }
429
430
  ModuleWrap* module;
431
177
  ASSIGN_OR_RETURN_UNWRAP(&module, module_object, MaybeLocal<Module>());
432
531
  return module->module_.Get(isolate);
433
}
434
435
namespace {
436
437
// Tests whether a path starts with /, ./ or ../
438
// In WhatWG terminology, the alternative case is called a "bare" specifier
439
// (e.g. in `import "jquery"`).
440
191
inline bool ShouldBeTreatedAsRelativeOrAbsolutePath(
441
    const std::string& specifier) {
442
191
  size_t len = specifier.length();
443
191
  if (len == 0)
444
    return false;
445
191
  if (specifier[0] == '/') {
446
76
    return true;
447
115
  } else if (specifier[0] == '.') {
448

100
    if (len == 1 || specifier[1] == '/')
449
32
      return true;
450
68
    if (specifier[1] == '.') {
451

68
      if (len == 2 || specifier[2] == '/')
452
68
        return true;
453
    }
454
  }
455
15
  return false;
456
}
457
458
18
std::string ReadFile(uv_file file) {
459
18
  std::string contents;
460
  uv_fs_t req;
461
  char buffer_memory[4096];
462
18
  uv_buf_t buf = uv_buf_init(buffer_memory, sizeof(buffer_memory));
463
464
  do {
465
    const int r = uv_fs_read(uv_default_loop(),
466
                             &req,
467
                             file,
468
                             &buf,
469
                             1,
470
36
                             contents.length(),  // offset
471
36
                             nullptr);
472
36
    uv_fs_req_cleanup(&req);
473
474
36
    if (r <= 0)
475
18
      break;
476
18
    contents.append(buf.base, r);
477
  } while (true);
478
18
  return contents;
479
}
480
481
enum DescriptorType {
482
  FILE,
483
  DIRECTORY,
484
  NONE
485
};
486
487
// When DescriptorType cache is added, this can also return
488
// Nothing for the "null" cache entries.
489
975
inline Maybe<uv_file> OpenDescriptor(const std::string& path) {
490
  uv_fs_t fs_req;
491
975
  uv_file fd = uv_fs_open(nullptr, &fs_req, path.c_str(), O_RDONLY, 0, nullptr);
492
975
  uv_fs_req_cleanup(&fs_req);
493
975
  if (fd < 0) return Nothing<uv_file>();
494
205
  return Just(fd);
495
}
496
497
205
inline void CloseDescriptor(uv_file fd) {
498
  uv_fs_t fs_req;
499
205
  CHECK_EQ(0, uv_fs_close(nullptr, &fs_req, fd, nullptr));
500
205
  uv_fs_req_cleanup(&fs_req);
501
205
}
502
503
205
inline DescriptorType CheckDescriptorAtFile(uv_file fd) {
504
  uv_fs_t fs_req;
505
205
  int rc = uv_fs_fstat(nullptr, &fs_req, fd, nullptr);
506
205
  if (rc == 0) {
507
205
    uint64_t is_directory = fs_req.statbuf.st_mode & S_IFDIR;
508
205
    uv_fs_req_cleanup(&fs_req);
509
205
    return is_directory ? DIRECTORY : FILE;
510
  }
511
  uv_fs_req_cleanup(&fs_req);
512
  return NONE;
513
}
514
515
// TODO(@guybedford): Add a DescriptorType cache layer here.
516
// Should be directory based -> if path/to/dir doesn't exist
517
// then the cache should early-fail any path/to/dir/file check.
518
260
DescriptorType CheckDescriptorAtPath(const std::string& path) {
519
260
  Maybe<uv_file> fd = OpenDescriptor(path);
520
260
  if (fd.IsNothing()) return NONE;
521
187
  DescriptorType type = CheckDescriptorAtFile(fd.FromJust());
522
187
  CloseDescriptor(fd.FromJust());
523
187
  return type;
524
}
525
526
715
Maybe<std::string> ReadIfFile(const std::string& path) {
527
715
  Maybe<uv_file> fd = OpenDescriptor(path);
528
715
  if (fd.IsNothing()) return Nothing<std::string>();
529
18
  DescriptorType type = CheckDescriptorAtFile(fd.FromJust());
530
18
  if (type != FILE) return Nothing<std::string>();
531
18
  std::string source = ReadFile(fd.FromJust());
532
18
  CloseDescriptor(fd.FromJust());
533
18
  return Just(source);
534
}
535
536
using Exists = PackageConfig::Exists;
537
using IsValid = PackageConfig::IsValid;
538
using HasMain = PackageConfig::HasMain;
539
using PackageType = PackageConfig::PackageType;
540
541
1482
Maybe<const PackageConfig*> GetPackageConfig(Environment* env,
542
                                             const std::string& path,
543
                                             const URL& base) {
544
1482
  auto existing = env->package_json_cache.find(path);
545
1482
  if (existing != env->package_json_cache.end()) {
546
767
    const PackageConfig* pcfg = &existing->second;
547
767
    if (pcfg->is_valid == IsValid::No) {
548
      std::string msg = "Invalid JSON in '" + path +
549
        "' imported from " + base.ToFilePath();
550
      node::THROW_ERR_INVALID_PACKAGE_CONFIG(env, msg.c_str());
551
      return Nothing<const PackageConfig*>();
552
    }
553
767
    return Just(pcfg);
554
  }
555
556
715
  Maybe<std::string> source = ReadIfFile(path);
557
558
715
  if (source.IsNothing()) {
559
    auto entry = env->package_json_cache.emplace(path,
560
        PackageConfig { Exists::No, IsValid::Yes, HasMain::No, "",
561
1394
                        PackageType::None, Global<Value>() });
562
697
    return Just(&entry.first->second);
563
  }
564
565
18
  std::string pkg_src = source.FromJust();
566
567
18
  Isolate* isolate = env->isolate();
568
36
  v8::HandleScope handle_scope(isolate);
569
570
  Local<Object> pkg_json;
571
  {
572
    Local<Value> src;
573
    Local<Value> pkg_json_v;
574
18
    Local<Context> context = env->context();
575
576

108
    if (!ToV8Value(context, pkg_src).ToLocal(&src) ||
577

144
        !v8::JSON::Parse(context, src.As<String>()).ToLocal(&pkg_json_v) ||
578
54
        !pkg_json_v->ToObject(context).ToLocal(&pkg_json)) {
579
      env->package_json_cache.emplace(path,
580
          PackageConfig { Exists::Yes, IsValid::No, HasMain::No, "",
581
                          PackageType::None, Global<Value>() });
582
      std::string msg = "Invalid JSON in '" + path +
583
          "' imported from " + base.ToFilePath();
584
      node::THROW_ERR_INVALID_PACKAGE_CONFIG(env, msg.c_str());
585
      return Nothing<const PackageConfig*>();
586
    }
587
  }
588
589
  Local<Value> pkg_main;
590
18
  HasMain has_main = HasMain::No;
591
36
  std::string main_std;
592
72
  if (pkg_json->Get(env->context(), env->main_string()).ToLocal(&pkg_main)) {
593
36
    if (pkg_main->IsString()) {
594
13
      has_main = HasMain::Yes;
595
    }
596
18
    Utf8Value main_utf8(isolate, pkg_main);
597
18
    main_std.assign(std::string(*main_utf8, main_utf8.length()));
598
  }
599
600
18
  PackageType pkg_type = PackageType::None;
601
  Local<Value> type_v;
602
72
  if (pkg_json->Get(env->context(), env->type_string()).ToLocal(&type_v)) {
603
36
    if (type_v->StrictEquals(env->module_string())) {
604
6
      pkg_type = PackageType::Module;
605
24
    } else if (type_v->StrictEquals(env->commonjs_string())) {
606
4
      pkg_type = PackageType::CommonJS;
607
    }
608
    // ignore unknown types for forwards compatibility
609
  }
610
611
  Local<Value> exports_v;
612

108
  if (env->options()->experimental_exports &&
613
      pkg_json->Get(env->context(),
614


144
      env->exports_string()).ToLocal(&exports_v) &&
615
36
      !exports_v->IsNullOrUndefined()) {
616
    Global<Value> exports;
617
2
    exports.Reset(env->isolate(), exports_v);
618
619
    auto entry = env->package_json_cache.emplace(path,
620
        PackageConfig { Exists::Yes, IsValid::Yes, has_main, main_std,
621
4
                        pkg_type, std::move(exports) });
622
2
    return Just(&entry.first->second);
623
  }
624
625
  auto entry = env->package_json_cache.emplace(path,
626
      PackageConfig { Exists::Yes, IsValid::Yes, has_main, main_std,
627
32
                      pkg_type, Global<Value>() });
628
731
  return Just(&entry.first->second);
629
}
630
631
172
Maybe<const PackageConfig*> GetPackageScopeConfig(Environment* env,
632
                                                  const URL& resolved,
633
                                                  const URL& base) {
634
172
  URL pjson_url("./package.json", &resolved);
635
  while (true) {
636
    Maybe<const PackageConfig*> pkg_cfg =
637
1472
        GetPackageConfig(env, pjson_url.ToFilePath(), base);
638
1644
    if (pkg_cfg.IsNothing()) return pkg_cfg;
639
1472
    if (pkg_cfg.FromJust()->exists == Exists::Yes) return pkg_cfg;
640
641
1445
    URL last_pjson_url = pjson_url;
642
1445
    pjson_url = URL("../package.json", pjson_url);
643
644
    // Terminates at root where ../package.json equals ../../package.json
645
    // (can't just check "/package.json" for Windows support).
646
1445
    if (pjson_url.path() == last_pjson_url.path()) {
647
      auto entry = env->package_json_cache.emplace(pjson_url.ToFilePath(),
648
          PackageConfig { Exists::No, IsValid::Yes, HasMain::No, "",
649
290
                          PackageType::None, Global<Value>() });
650
145
      const PackageConfig* pcfg = &entry.first->second;
651
145
      return Just(pcfg);
652
    }
653
1472
  }
654
}
655
656
/*
657
 * Legacy CommonJS main resolution:
658
 * 1. let M = pkg_url + (json main field)
659
 * 2. TRY(M, M.js, M.json, M.node)
660
 * 3. TRY(M/index.js, M/index.json, M/index.node)
661
 * 4. TRY(pkg_url/index.js, pkg_url/index.json, pkg_url/index.node)
662
 * 5. NOT_FOUND
663
 */
664
59
inline bool FileExists(const URL& url) {
665
59
  return CheckDescriptorAtPath(url.ToFilePath()) == FILE;
666
}
667
1
Maybe<URL> LegacyMainResolve(const URL& pjson_url,
668
                             const PackageConfig& pcfg) {
669
1
  URL guess;
670
1
  if (pcfg.has_main == HasMain::Yes) {
671
    // Note: fs check redundances will be handled by Descriptor cache here.
672
    if (FileExists(guess = URL("./" + pcfg.main, pjson_url))) {
673
      return Just(guess);
674
    }
675
    if (FileExists(guess = URL("./" + pcfg.main + ".js", pjson_url))) {
676
      return Just(guess);
677
    }
678
    if (FileExists(guess = URL("./" + pcfg.main + ".json", pjson_url))) {
679
      return Just(guess);
680
    }
681
    if (FileExists(guess = URL("./" + pcfg.main + ".node", pjson_url))) {
682
      return Just(guess);
683
    }
684
    if (FileExists(guess = URL("./" + pcfg.main + "/index.js", pjson_url))) {
685
      return Just(guess);
686
    }
687
    // Such stat.
688
    if (FileExists(guess = URL("./" + pcfg.main + "/index.json", pjson_url))) {
689
      return Just(guess);
690
    }
691
    if (FileExists(guess = URL("./" + pcfg.main + "/index.node", pjson_url))) {
692
      return Just(guess);
693
    }
694
    // Fallthrough.
695
  }
696
1
  if (FileExists(guess = URL("./index.js", pjson_url))) {
697
    return Just(guess);
698
  }
699
  // So fs.
700
1
  if (FileExists(guess = URL("./index.json", pjson_url))) {
701
    return Just(guess);
702
  }
703
1
  if (FileExists(guess = URL("./index.node", pjson_url))) {
704
    return Just(guess);
705
  }
706
  // Not found.
707
1
  return Nothing<URL>();
708
}
709
710
enum ResolveExtensionsOptions {
711
  TRY_EXACT_NAME,
712
  ONLY_VIA_EXTENSIONS
713
};
714
715
template <ResolveExtensionsOptions options>
716
22
Maybe<URL> ResolveExtensions(const URL& search) {
717
  if (options == TRY_EXACT_NAME) {
718
17
    if (FileExists(search)) {
719
9
      return Just(search);
720
    }
721
  }
722
723

45
  for (const char* extension : EXTENSIONS) {
724
39
    URL guess(search.path() + extension, &search);
725

39
    if (FileExists(guess)) {
726

7
      return Just(guess);
727
    }
728
  }
729
730
6
  return Nothing<URL>();
731
}
732
733
5
inline Maybe<URL> ResolveIndex(const URL& search) {
734
5
  return ResolveExtensions<ONLY_VIA_EXTENSIONS>(URL("index", search));
735
}
736
737
185
Maybe<URL> FinalizeResolution(Environment* env,
738
                              const URL& resolved,
739
                              const URL& base) {
740
185
  if (env->options()->es_module_specifier_resolution == "node") {
741
17
    Maybe<URL> file = ResolveExtensions<TRY_EXACT_NAME>(resolved);
742
17
    if (!file.IsNothing()) {
743
12
      return file;
744
    }
745
5
    if (resolved.path().back() != '/') {
746
4
      file = ResolveIndex(URL(resolved.path() + "/", &base));
747
    } else {
748
1
      file = ResolveIndex(resolved);
749
    }
750
5
    if (!file.IsNothing()) {
751
4
      return file;
752
    }
753
2
    std::string msg = "Cannot find module '" + resolved.path() +
754
4
        "' imported from " + base.ToFilePath();
755
1
    node::THROW_ERR_MODULE_NOT_FOUND(env, msg.c_str());
756
18
    return Nothing<URL>();
757
  }
758
759
168
  const std::string& path = resolved.ToFilePath();
760
168
  if (CheckDescriptorAtPath(path) != FILE) {
761
26
    std::string msg = "Cannot find module '" + path +
762
39
        "' imported from " + base.ToFilePath();
763
13
    node::THROW_ERR_MODULE_NOT_FOUND(env, msg.c_str());
764
13
    return Nothing<URL>();
765
  }
766
767
155
  return Just(resolved);
768
}
769
770
5
Maybe<URL> PackageMainResolve(Environment* env,
771
                              const URL& pjson_url,
772
                              const PackageConfig& pcfg,
773
                              const URL& base) {
774
5
  if (pcfg.exists == Exists::Yes) {
775
5
    if (pcfg.has_main == HasMain::Yes) {
776
4
      URL resolved(pcfg.main, pjson_url);
777
7
      const std::string& path = resolved.ToFilePath();
778
4
      if (CheckDescriptorAtPath(path) == FILE) {
779
1
        return Just(resolved);
780
3
      }
781
    }
782
4
    if (env->options()->es_module_specifier_resolution == "node") {
783
3
      if (pcfg.has_main == HasMain::Yes) {
784
3
        return FinalizeResolution(env, URL(pcfg.main, pjson_url), base);
785
      } else {
786
        return FinalizeResolution(env, URL("index", pjson_url), base);
787
      }
788
    }
789
1
    if (pcfg.type != PackageType::Module) {
790
1
      Maybe<URL> resolved = LegacyMainResolve(pjson_url, pcfg);
791
1
      if (!resolved.IsNothing()) {
792
        return resolved;
793
1
      }
794
    }
795
  }
796
2
  std::string msg = "Cannot find main entry point for '" +
797
2
      URL(".", pjson_url).ToFilePath() + "' imported from " +
798
3
      base.ToFilePath();
799
1
  node::THROW_ERR_MODULE_NOT_FOUND(env, msg.c_str());
800
1
  return Nothing<URL>();
801
}
802
803
5
Maybe<URL> PackageExportsResolve(Environment* env,
804
                                 const URL& pjson_url,
805
                                 const std::string& pkg_subpath,
806
                                 const PackageConfig& pcfg,
807
                                 const URL& base) {
808
5
  CHECK(env->options()->experimental_exports);
809
5
  Isolate* isolate = env->isolate();
810
5
  Local<Context> context = env->context();
811
10
  Local<Value> exports = pcfg.exports.Get(isolate);
812
5
  if (exports->IsObject()) {
813
4
    Local<Object> exports_obj = exports.As<Object>();
814
    Local<String> subpath = String::NewFromUtf8(isolate,
815
8
        pkg_subpath.c_str(), v8::NewStringType::kNormal).ToLocalChecked();
816
817
8
    auto target = exports_obj->Get(context, subpath).ToLocalChecked();
818
8
    if (target->IsString()) {
819
2
      Utf8Value target_utf8(isolate, target.As<v8::String>());
820
2
      std::string target(*target_utf8, target_utf8.length());
821
2
      if (target.substr(0, 2) == "./") {
822
2
        URL target_url(target, pjson_url);
823
2
        return FinalizeResolution(env, target_url, base);
824
      }
825
    }
826
827
    Local<String> best_match;
828
2
    std::string best_match_str = "";
829
    Local<Array> keys =
830
4
        exports_obj->GetOwnPropertyNames(context).ToLocalChecked();
831
24
    for (uint32_t i = 0; i < keys->Length(); ++i) {
832
30
      Local<String> key = keys->Get(context, i).ToLocalChecked().As<String>();
833
10
      Utf8Value key_utf8(isolate, key);
834
12
      std::string key_str(*key_utf8, key_utf8.length());
835
10
      if (key_str.back() != '/') continue;
836


3
      if (pkg_subpath.substr(0, key_str.length()) == key_str &&
837
1
          key_str.length() > best_match_str.length()) {
838
1
        best_match = key;
839
1
        best_match_str = key_str;
840
      }
841
2
    }
842
843
2
    if (best_match_str.length() > 0) {
844
2
      auto target = exports_obj->Get(context, best_match).ToLocalChecked();
845
2
      if (target->IsString()) {
846
1
        Utf8Value target_utf8(isolate, target.As<v8::String>());
847
1
        std::string target(*target_utf8, target_utf8.length());
848


1
        if (target.back() == '/' && target.substr(0, 2) == "./") {
849
1
          std::string subpath = pkg_subpath.substr(best_match_str.length());
850
2
          URL target_url(target + subpath, pjson_url);
851
2
          return FinalizeResolution(env, target_url, base);
852
        }
853
      }
854
1
    }
855
  }
856
4
  std::string msg = "Package exports for '" +
857
4
      URL(".", pjson_url).ToFilePath() + "' do not define a '" + pkg_subpath +
858
6
      "' subpath, imported from " + base.ToFilePath();
859
2
  node::THROW_ERR_PATH_NOT_EXPORTED(env, msg.c_str());
860
2
  return Nothing<URL>();
861
}
862
863
12
Maybe<URL> PackageResolve(Environment* env,
864
                          const std::string& specifier,
865
                          const URL& base) {
866
12
  size_t sep_index = specifier.find('/');
867


12
  if (specifier[0] == '@' && (sep_index == std::string::npos ||
868
      specifier.length() == 0)) {
869
    std::string msg = "Invalid package name '" + specifier +
870
      "' imported from " + base.ToFilePath();
871
    node::THROW_ERR_INVALID_MODULE_SPECIFIER(env, msg.c_str());
872
    return Nothing<URL>();
873
  }
874
12
  bool scope = false;
875
12
  if (specifier[0] == '@') {
876
    scope = true;
877
    sep_index = specifier.find('/', sep_index + 1);
878
  }
879
  std::string pkg_name = specifier.substr(0,
880
12
      sep_index == std::string::npos ? std::string::npos : sep_index);
881
24
  std::string pkg_subpath;
882

17
  if ((sep_index == std::string::npos ||
883
5
      sep_index == specifier.length() - 1)) {
884
7
    pkg_subpath = "";
885
  } else {
886
5
    pkg_subpath = "." + specifier.substr(sep_index);
887
  }
888
24
  URL pjson_url("./node_modules/" + pkg_name + "/package.json", &base);
889
24
  std::string pjson_path = pjson_url.ToFilePath();
890
24
  std::string last_path;
891
19
  do {
892
    DescriptorType check =
893
29
        CheckDescriptorAtPath(pjson_path.substr(0, pjson_path.length() - 13));
894
29
    if (check != DIRECTORY) {
895
19
      last_path = pjson_path;
896
38
      pjson_url = URL((scope ?
897
38
          "../../../../node_modules/" : "../../../node_modules/") +
898
57
          pkg_name + "/package.json", &pjson_url);
899
19
      pjson_path = pjson_url.ToFilePath();
900
19
      continue;
901
    }
902
903
    // Package match.
904
10
    Maybe<const PackageConfig*> pcfg = GetPackageConfig(env, pjson_path, base);
905
    // Invalid package configuration error.
906
20
    if (pcfg.IsNothing()) return Nothing<URL>();
907
10
    if (!pkg_subpath.length()) {
908
5
      return PackageMainResolve(env, pjson_url, *pcfg.FromJust(), base);
909
    } else {
910
10
      if (!pcfg.FromJust()->exports.IsEmpty()) {
911
        return PackageExportsResolve(env, pjson_url, pkg_subpath,
912
5
                                     *pcfg.FromJust(), base);
913
      } else {
914
        return FinalizeResolution(env, URL(pkg_subpath, pjson_url), base);
915
      }
916
    }
917
    CHECK(false);
918
    // Cross-platform root check.
919
19
  } while (pjson_path.length() != last_path.length());
920
921
4
  std::string msg = "Cannot find package '" + pkg_name +
922
8
      "' imported from " + base.ToFilePath();
923
2
  node::THROW_ERR_MODULE_NOT_FOUND(env, msg.c_str());
924
14
  return Nothing<URL>();
925
}
926
927
}  // anonymous namespace
928
929
191
Maybe<URL> Resolve(Environment* env,
930
                   const std::string& specifier,
931
                   const URL& base) {
932
  // Order swapped from spec for minor perf gain.
933
  // Ok since relative URLs cannot parse as URLs.
934
191
  URL resolved;
935
191
  if (ShouldBeTreatedAsRelativeOrAbsolutePath(specifier)) {
936
176
    resolved = URL(specifier, base);
937
  } else {
938
15
    URL pure_url(specifier);
939
15
    if (!(pure_url.flags() & URL_FLAGS_FAILED)) {
940
3
      resolved = pure_url;
941
    } else {
942
12
      return PackageResolve(env, specifier, base);
943
3
    }
944
  }
945
179
  return FinalizeResolution(env, resolved, base);
946
}
947
948
191
void ModuleWrap::Resolve(const FunctionCallbackInfo<Value>& args) {
949
191
  Environment* env = Environment::GetCurrent(args);
950
951
  // module.resolve(specifier, url)
952
191
  CHECK_EQ(args.Length(), 2);
953
954
573
  CHECK(args[0]->IsString());
955
191
  Utf8Value specifier_utf8(env->isolate(), args[0]);
956
363
  std::string specifier_std(*specifier_utf8, specifier_utf8.length());
957
958
573
  CHECK(args[1]->IsString());
959
363
  Utf8Value url_utf8(env->isolate(), args[1]);
960
363
  URL url(*url_utf8, url_utf8.length());
961
962
191
  if (url.flags() & URL_FLAGS_FAILED) {
963
    return node::THROW_ERR_INVALID_ARG_TYPE(
964
        env, "second argument is not a URL string");
965
  }
966
967
  Maybe<URL> result =
968
      node::loader::Resolve(env,
969
                            specifier_std,
970
363
                            url);
971
191
  if (result.IsNothing()) {
972
19
    return;
973
  }
974
975
172
  URL resolution = result.FromJust();
976
172
  CHECK(!(resolution.flags() & URL_FLAGS_FAILED));
977
978
  Local<Value> resolution_obj;
979
344
  if (resolution.ToObject(env).ToLocal(&resolution_obj))
980
516
    args.GetReturnValue().Set(resolution_obj);
981
}
982
983
172
void ModuleWrap::GetPackageType(const FunctionCallbackInfo<Value>& args) {
984
172
  Environment* env = Environment::GetCurrent(args);
985
986
  // module.getPackageType(url)
987
172
  CHECK_EQ(args.Length(), 1);
988
989
516
  CHECK(args[0]->IsString());
990
172
  Utf8Value url_utf8(env->isolate(), args[0]);
991
344
  URL url(*url_utf8, url_utf8.length());
992
993
172
  PackageType pkg_type = PackageType::None;
994
  Maybe<const PackageConfig*> pcfg =
995
172
      GetPackageScopeConfig(env, url, url);
996
172
  if (!pcfg.IsNothing()) {
997
172
    pkg_type = pcfg.FromJust()->type;
998
  }
999
1000
688
  args.GetReturnValue().Set(Integer::New(env->isolate(), pkg_type));
1001
172
}
1002
1003
29
static MaybeLocal<Promise> ImportModuleDynamically(
1004
    Local<Context> context,
1005
    Local<v8::ScriptOrModule> referrer,
1006
    Local<String> specifier) {
1007
29
  Isolate* iso = context->GetIsolate();
1008
29
  Environment* env = Environment::GetCurrent(context);
1009
29
  CHECK_NOT_NULL(env);  // TODO(addaleax): Handle nullptr here.
1010
29
  v8::EscapableHandleScope handle_scope(iso);
1011
1012
  Local<Function> import_callback =
1013
29
    env->host_import_module_dynamically_callback();
1014
1015
29
  Local<PrimitiveArray> options = referrer->GetHostDefinedOptions();
1016
29
  if (options->Length() != HostDefinedOptions::kLength) {
1017
    Local<Promise::Resolver> resolver =
1018
        Promise::Resolver::New(context).ToLocalChecked();
1019
    resolver
1020
        ->Reject(context,
1021
                 v8::Exception::TypeError(FIXED_ONE_BYTE_STRING(
1022
                     context->GetIsolate(), "Invalid host defined options")))
1023
        .ToChecked();
1024
    return handle_scope.Escape(resolver->GetPromise());
1025
  }
1026
1027
  Local<Value> object;
1028
1029
29
  int type = options->Get(iso, HostDefinedOptions::kType)
1030
58
                 .As<Number>()
1031
87
                 ->Int32Value(context)
1032
58
                 .ToChecked();
1033
29
  uint32_t id = options->Get(iso, HostDefinedOptions::kID)
1034
58
                    .As<Number>()
1035
87
                    ->Uint32Value(context)
1036
58
                    .ToChecked();
1037
29
  if (type == ScriptType::kScript) {
1038
2
    contextify::ContextifyScript* wrap = env->id_to_script_map.find(id)->second;
1039
4
    object = wrap->object();
1040
27
  } else if (type == ScriptType::kModule) {
1041
16
    ModuleWrap* wrap = ModuleWrap::GetFromID(env, id);
1042
32
    object = wrap->object();
1043
11
  } else if (type == ScriptType::kFunction) {
1044
11
    auto it = env->id_to_function_map.find(id);
1045
11
    CHECK_NE(it, env->id_to_function_map.end());
1046
22
    object = it->second->object();
1047
  } else {
1048
    UNREACHABLE();
1049
  }
1050
1051
  Local<Value> import_args[] = {
1052
    object,
1053
    Local<Value>(specifier),
1054
58
  };
1055
1056
  Local<Value> result;
1057
58
  if (import_callback->Call(
1058
        context,
1059
        v8::Undefined(iso),
1060
29
        arraysize(import_args),
1061
87
        import_args).ToLocal(&result)) {
1062
29
    CHECK(result->IsPromise());
1063
29
    return handle_scope.Escape(result.As<Promise>());
1064
  }
1065
1066
  return MaybeLocal<Promise>();
1067
}
1068
1069
96
void ModuleWrap::SetImportModuleDynamicallyCallback(
1070
    const FunctionCallbackInfo<Value>& args) {
1071
96
  Isolate* iso = args.GetIsolate();
1072
96
  Environment* env = Environment::GetCurrent(args);
1073
96
  HandleScope handle_scope(iso);
1074
1075
96
  CHECK_EQ(args.Length(), 1);
1076
192
  CHECK(args[0]->IsFunction());
1077
192
  Local<Function> import_callback = args[0].As<Function>();
1078
96
  env->set_host_import_module_dynamically_callback(import_callback);
1079
1080
96
  iso->SetHostImportModuleDynamicallyCallback(ImportModuleDynamically);
1081
96
}
1082
1083
146
void ModuleWrap::HostInitializeImportMetaObjectCallback(
1084
    Local<Context> context, Local<Module> module, Local<Object> meta) {
1085
146
  Environment* env = Environment::GetCurrent(context);
1086
146
  CHECK_NOT_NULL(env);  // TODO(addaleax): Handle nullptr here.
1087
146
  ModuleWrap* module_wrap = GetFromModule(env, module);
1088
1089
146
  if (module_wrap == nullptr) {
1090
146
    return;
1091
  }
1092
1093
146
  Local<Object> wrap = module_wrap->object();
1094
  Local<Function> callback =
1095
146
      env->host_initialize_import_meta_object_callback();
1096
438
  Local<Value> args[] = { wrap, meta };
1097
438
  callback->Call(context, Undefined(env->isolate()), arraysize(args), args)
1098
292
      .ToLocalChecked();
1099
}
1100
1101
96
void ModuleWrap::SetInitializeImportMetaObjectCallback(
1102
    const FunctionCallbackInfo<Value>& args) {
1103
96
  Environment* env = Environment::GetCurrent(args);
1104
96
  Isolate* isolate = env->isolate();
1105
1106
96
  CHECK_EQ(args.Length(), 1);
1107
192
  CHECK(args[0]->IsFunction());
1108
192
  Local<Function> import_meta_callback = args[0].As<Function>();
1109
96
  env->set_host_initialize_import_meta_object_callback(import_meta_callback);
1110
1111
  isolate->SetHostInitializeImportMetaObjectCallback(
1112
96
      HostInitializeImportMetaObjectCallback);
1113
96
}
1114
1115
4951
void ModuleWrap::Initialize(Local<Object> target,
1116
                            Local<Value> unused,
1117
                            Local<Context> context,
1118
                            void* priv) {
1119
4951
  Environment* env = Environment::GetCurrent(context);
1120
4951
  Isolate* isolate = env->isolate();
1121
1122
4951
  Local<FunctionTemplate> tpl = env->NewFunctionTemplate(New);
1123
9902
  tpl->SetClassName(FIXED_ONE_BYTE_STRING(isolate, "ModuleWrap"));
1124
9902
  tpl->InstanceTemplate()->SetInternalFieldCount(1);
1125
1126
4951
  env->SetProtoMethod(tpl, "link", Link);
1127
4951
  env->SetProtoMethod(tpl, "instantiate", Instantiate);
1128
4951
  env->SetProtoMethod(tpl, "evaluate", Evaluate);
1129
4951
  env->SetProtoMethodNoSideEffect(tpl, "namespace", Namespace);
1130
4951
  env->SetProtoMethodNoSideEffect(tpl, "getStatus", GetStatus);
1131
4951
  env->SetProtoMethodNoSideEffect(tpl, "getError", GetError);
1132
  env->SetProtoMethodNoSideEffect(tpl, "getStaticDependencySpecifiers",
1133
4951
                                  GetStaticDependencySpecifiers);
1134
1135
  target->Set(env->context(), FIXED_ONE_BYTE_STRING(isolate, "ModuleWrap"),
1136
24755
              tpl->GetFunction(context).ToLocalChecked()).Check();
1137
4951
  env->SetMethod(target, "resolve", Resolve);
1138
4951
  env->SetMethod(target, "getPackageType", GetPackageType);
1139
  env->SetMethod(target,
1140
                 "setImportModuleDynamicallyCallback",
1141
4951
                 SetImportModuleDynamicallyCallback);
1142
  env->SetMethod(target,
1143
                 "setInitializeImportMetaObjectCallback",
1144
4951
                 SetInitializeImportMetaObjectCallback);
1145
1146
#define V(name)                                                                \
1147
    target->Set(context,                                                       \
1148
      FIXED_ONE_BYTE_STRING(env->isolate(), #name),                            \
1149
      Integer::New(env->isolate(), Module::Status::name))                      \
1150
        .FromJust()
1151
19804
    V(kUninstantiated);
1152
19804
    V(kInstantiating);
1153
19804
    V(kInstantiated);
1154
19804
    V(kEvaluating);
1155
19804
    V(kEvaluated);
1156
19804
    V(kErrored);
1157
#undef V
1158
4951
}
1159
1160
}  // namespace loader
1161
}  // namespace node
1162
1163
4827
NODE_MODULE_CONTEXT_AWARE_INTERNAL(module_wrap,
1164
                                   node::loader::ModuleWrap::Initialize)