GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage-daily/nodes/benchmark/out/../src/node_options.cc Lines: 241 258 93.4 %
Date: 2019-03-02 22:23:06 Branches: 132 204 64.7 %

Line Branch Exec Source
1
#include <cerrno>
2
#include "env-inl.h"
3
#include "node_binding.h"
4
#include "node_options-inl.h"
5
6
using v8::Boolean;
7
using v8::Context;
8
using v8::FunctionCallbackInfo;
9
using v8::Integer;
10
using v8::Isolate;
11
using v8::Local;
12
using v8::Map;
13
using v8::Number;
14
using v8::Object;
15
using v8::String;
16
using v8::Undefined;
17
using v8::Value;
18
19
namespace node {
20
21
namespace per_process {
22
4292
Mutex cli_options_mutex;
23
4292
std::shared_ptr<PerProcessOptions> cli_options{new PerProcessOptions()};
24
}  // namespace per_process
25
26
8431
void DebugOptions::CheckOptions(std::vector<std::string>* errors) {
27
#if !NODE_USE_V8_PLATFORM
28
  if (inspector_enabled) {
29
    errors->push_back("Inspector is not available when Node is compiled "
30
                      "--without-v8-platform");
31
  }
32
#endif
33
34

8431
  if (deprecated_debug && !inspector_enabled) {
35
    errors->push_back("[DEP0062]: `node --debug` and `node --debug-brk` "
36
                      "are invalid. Please use `node --inspect` or "
37
2
                      "`node --inspect-brk` instead.");
38
  }
39
40

8431
  if (deprecated_debug && inspector_enabled && break_first_line) {
41
    errors->push_back("[DEP0062]: `node --inspect --debug-brk` is deprecated. "
42
3
                      "Please use `node --inspect-brk` instead.");
43
  }
44
8431
}
45
46
8422
void PerProcessOptions::CheckOptions(std::vector<std::string>* errors) {
47
#if HAVE_OPENSSL
48

8422
  if (use_openssl_ca && use_bundled_ca) {
49
    errors->push_back("either --use-openssl-ca or --use-bundled-ca can be "
50
1
                      "used, not both");
51
  }
52
#endif
53
8422
  per_isolate->CheckOptions(errors);
54
8422
}
55
56
8431
void PerIsolateOptions::CheckOptions(std::vector<std::string>* errors) {
57
8431
  per_env->CheckOptions(errors);
58
#ifdef NODE_REPORT
59
8431
  if (per_env->experimental_report)
60
8436
    return;
61
62
8426
  if (!report_directory.empty()) {
63
    errors->push_back("--diagnostic-report-directory option is valid only when "
64
                      "--experimental-report is set");
65
  }
66
67
8426
  if (!report_filename.empty()) {
68
    errors->push_back("--diagnostic-report-filename option is valid only when "
69
                      "--experimental-report is set");
70
  }
71
72
8426
  if (!report_signal.empty()) {
73
    errors->push_back("--diagnostic-report-signal option is valid only when "
74
                      "--experimental-report is set");
75
  }
76
77
8426
  if (report_on_fatalerror) {
78
    errors->push_back(
79
        "--diagnostic-report-on-fatalerror option is valid only when "
80
        "--experimental-report is set");
81
  }
82
83
8426
  if (report_on_signal) {
84
    errors->push_back("--diagnostic-report-on-signal option is valid only when "
85
                      "--experimental-report is set");
86
  }
87
88
8426
  if (report_uncaught_exception) {
89
    errors->push_back(
90
        "--diagnostic-report-uncaught-exception option is valid only when "
91
        "--experimental-report is set");
92
  }
93
#endif  // NODE_REPORT
94
}
95
96
8431
void EnvironmentOptions::CheckOptions(std::vector<std::string>* errors) {
97

8431
  if (!userland_loader.empty() && !experimental_modules) {
98
    errors->push_back("--loader requires --experimental-modules be enabled");
99
  }
100
101

8431
  if (syntax_check_only && has_eval_string) {
102
4
    errors->push_back("either --check or --eval can be used, not both");
103
  }
104
105

8431
  if (http_parser != "legacy" && http_parser != "llhttp") {
106
    errors->push_back("invalid value for --http-parser");
107
  }
108
109
#if HAVE_INSPECTOR
110
8431
  debug_options_.CheckOptions(errors);
111
#endif  // HAVE_INSPECTOR
112
8431
}
113
114
namespace options_parser {
115
116
// Explicitly access the singelton instances in their dependancy order.
117
// This was moved here to workaround a compiler bug.
118
// Refs: https://github.com/nodejs/node/issues/25593
119
120
#if HAVE_INSPECTOR
121
4292
const DebugOptionsParser DebugOptionsParser::instance;
122
#endif  // HAVE_INSPECTOR
123
124
4292
const EnvironmentOptionsParser EnvironmentOptionsParser::instance;
125
126
4292
const PerIsolateOptionsParser PerIsolateOptionsParser::instance;
127
128
4292
const PerProcessOptionsParser PerProcessOptionsParser::instance;
129
130
// XXX: If you add an option here, please also add it to doc/node.1 and
131
// doc/api/cli.md
132
// TODO(addaleax): Make that unnecessary.
133
134
4292
DebugOptionsParser::DebugOptionsParser() {
135
  AddOption("--inspect-port",
136
            "set host:port for inspector",
137
            &DebugOptions::host_port,
138
4292
            kAllowedInEnvironment);
139
4292
  AddAlias("--debug-port", "--inspect-port");
140
141
  AddOption("--inspect",
142
            "activate inspector on host:port (default: 127.0.0.1:9229)",
143
            &DebugOptions::inspector_enabled,
144
4292
            kAllowedInEnvironment);
145
4292
  AddAlias("--inspect=", { "--inspect-port", "--inspect" });
146
147
4292
  AddOption("--debug", "", &DebugOptions::deprecated_debug);
148
4292
  AddAlias("--debug=", { "--inspect-port", "--debug" });
149
150
  AddOption("--inspect-brk",
151
            "activate inspector on host:port and break at start of user script",
152
            &DebugOptions::break_first_line,
153
4292
            kAllowedInEnvironment);
154
4292
  Implies("--inspect-brk", "--inspect");
155
4292
  AddAlias("--inspect-brk=", { "--inspect-port", "--inspect-brk" });
156
157
4292
  AddOption("--inspect-brk-node", "", &DebugOptions::break_node_first_line);
158
4292
  Implies("--inspect-brk-node", "--inspect");
159
4292
  AddAlias("--inspect-brk-node=", { "--inspect-port", "--inspect-brk-node" });
160
161
4292
  AddOption("--debug-brk", "", &DebugOptions::break_first_line);
162
4292
  Implies("--debug-brk", "--debug");
163
4292
  AddAlias("--debug-brk=", { "--inspect-port", "--debug-brk" });
164
4292
}
165
166
4292
EnvironmentOptionsParser::EnvironmentOptionsParser() {
167
  AddOption("--experimental-modules",
168
            "experimental ES Module support and caching modules",
169
            &EnvironmentOptions::experimental_modules,
170
4292
            kAllowedInEnvironment);
171
  AddOption("--experimental-policy",
172
            "use the specified file as a "
173
            "security policy",
174
            &EnvironmentOptions::experimental_policy,
175
4292
            kAllowedInEnvironment);
176
  AddOption("--experimental-repl-await",
177
            "experimental await keyword support in REPL",
178
            &EnvironmentOptions::experimental_repl_await,
179
4292
            kAllowedInEnvironment);
180
  AddOption("--experimental-vm-modules",
181
            "experimental ES Module support in vm module",
182
            &EnvironmentOptions::experimental_vm_modules,
183
4292
            kAllowedInEnvironment);
184
4292
  AddOption("--experimental-worker", "", NoOp{}, kAllowedInEnvironment);
185
#ifdef NODE_REPORT
186
  AddOption("--experimental-report",
187
            "enable report generation",
188
            &EnvironmentOptions::experimental_report,
189
4292
            kAllowedInEnvironment);
190
#endif  // NODE_REPORT
191
4292
  AddOption("--expose-internals", "", &EnvironmentOptions::expose_internals);
192
  AddOption("--http-parser",
193
            "Select which HTTP parser to use; either 'legacy' or 'llhttp' "
194
            "(default: llhttp).",
195
            &EnvironmentOptions::http_parser,
196
4292
            kAllowedInEnvironment);
197
  AddOption("--loader",
198
            "(with --experimental-modules) use the specified file as a "
199
            "custom loader",
200
            &EnvironmentOptions::userland_loader,
201
4292
            kAllowedInEnvironment);
202
  AddOption("--no-deprecation",
203
            "silence deprecation warnings",
204
            &EnvironmentOptions::no_deprecation,
205
4292
            kAllowedInEnvironment);
206
  AddOption("--no-force-async-hooks-checks",
207
            "disable checks for async_hooks",
208
            &EnvironmentOptions::no_force_async_hooks_checks,
209
4292
            kAllowedInEnvironment);
210
  AddOption("--no-warnings",
211
            "silence all process warnings",
212
            &EnvironmentOptions::no_warnings,
213
4292
            kAllowedInEnvironment);
214
  AddOption("--pending-deprecation",
215
            "emit pending deprecation warnings",
216
            &EnvironmentOptions::pending_deprecation,
217
4292
            kAllowedInEnvironment);
218
  AddOption("--preserve-symlinks",
219
            "preserve symbolic links when resolving",
220
4292
            &EnvironmentOptions::preserve_symlinks);
221
  AddOption("--preserve-symlinks-main",
222
            "preserve symbolic links when resolving the main module",
223
4292
            &EnvironmentOptions::preserve_symlinks_main);
224
  AddOption("--prof-process",
225
            "process V8 profiler output generated using --prof",
226
4292
            &EnvironmentOptions::prof_process);
227
  // Options after --prof-process are passed through to the prof processor.
228
4292
  AddAlias("--prof-process", { "--prof-process", "--" });
229
  AddOption("--redirect-warnings",
230
            "write warnings to file instead of stderr",
231
            &EnvironmentOptions::redirect_warnings,
232
4292
            kAllowedInEnvironment);
233
  AddOption("--throw-deprecation",
234
            "throw an exception on deprecations",
235
            &EnvironmentOptions::throw_deprecation,
236
4292
            kAllowedInEnvironment);
237
  AddOption("--trace-deprecation",
238
            "show stack traces on deprecations",
239
            &EnvironmentOptions::trace_deprecation,
240
4292
            kAllowedInEnvironment);
241
  AddOption("--trace-sync-io",
242
            "show stack trace when use of sync IO is detected after the "
243
            "first tick",
244
            &EnvironmentOptions::trace_sync_io,
245
4292
            kAllowedInEnvironment);
246
  AddOption("--trace-warnings",
247
            "show stack traces on process warnings",
248
            &EnvironmentOptions::trace_warnings,
249
4292
            kAllowedInEnvironment);
250
251
  AddOption("--check",
252
            "syntax check script without executing",
253
4292
            &EnvironmentOptions::syntax_check_only);
254
4292
  AddAlias("-c", "--check");
255
  // This option is only so that we can tell --eval with an empty string from
256
  // no eval at all. Having it not start with a dash makes it inaccessible
257
  // from the parser itself, but available for using Implies().
258
  // TODO(addaleax): When moving --help over to something generated from the
259
  // programmatic descriptions, this will need some special care.
260
  // (See also [ssl_openssl_cert_store] below.)
261
4292
  AddOption("[has_eval_string]", "", &EnvironmentOptions::has_eval_string);
262
4292
  AddOption("--eval", "evaluate script", &EnvironmentOptions::eval_string);
263
4292
  Implies("--eval", "[has_eval_string]");
264
  AddOption("--print",
265
            "evaluate script and print result",
266
4292
            &EnvironmentOptions::print_eval);
267
4292
  AddAlias("-e", "--eval");
268
4292
  AddAlias("--print <arg>", "-pe");
269
4292
  AddAlias("-pe", { "--print", "--eval" });
270
4292
  AddAlias("-p", "--print");
271
  AddOption("--require",
272
            "module to preload (option can be repeated)",
273
            &EnvironmentOptions::preload_modules,
274
4292
            kAllowedInEnvironment);
275
4292
  AddAlias("-r", "--require");
276
  AddOption("--interactive",
277
            "always enter the REPL even if stdin does not appear "
278
            "to be a terminal",
279
4292
            &EnvironmentOptions::force_repl);
280
4292
  AddAlias("-i", "--interactive");
281
282
4292
  AddOption("--napi-modules", "", NoOp{}, kAllowedInEnvironment);
283
284
#if HAVE_OPENSSL
285
  AddOption("--tls-v1.0",
286
            "enable TLSv1.0 and greater by default",
287
            &EnvironmentOptions::tls_v1_0,
288
4292
            kAllowedInEnvironment);
289
  AddOption("--tls-v1.1",
290
            "enable TLSv1.1 and greater by default",
291
            &EnvironmentOptions::tls_v1_1,
292
4292
            kAllowedInEnvironment);
293
#endif
294
295
#if HAVE_INSPECTOR
296
  Insert(&DebugOptionsParser::instance,
297
4292
         &EnvironmentOptions::get_debug_options);
298
#endif  // HAVE_INSPECTOR
299
4292
}
300
301
4292
PerIsolateOptionsParser::PerIsolateOptionsParser() {
302
  AddOption("--track-heap-objects",
303
            "track heap object allocations for heap snapshots",
304
            &PerIsolateOptions::track_heap_objects,
305
4292
            kAllowedInEnvironment);
306
307
  // Explicitly add some V8 flags to mark them as allowed in NODE_OPTIONS.
308
  AddOption("--abort-on-uncaught-exception",
309
            "aborting instead of exiting causes a core file to be generated "
310
            "for analysis",
311
            V8Option{},
312
4292
            kAllowedInEnvironment);
313
4292
  AddOption("--max-old-space-size", "", V8Option{}, kAllowedInEnvironment);
314
4292
  AddOption("--perf-basic-prof", "", V8Option{}, kAllowedInEnvironment);
315
  AddOption("--perf-basic-prof-only-functions",
316
            "",
317
            V8Option{},
318
4292
            kAllowedInEnvironment);
319
4292
  AddOption("--perf-prof", "", V8Option{}, kAllowedInEnvironment);
320
  AddOption("--perf-prof-unwinding-info",
321
            "",
322
            V8Option{},
323
4292
            kAllowedInEnvironment);
324
4292
  AddOption("--stack-trace-limit", "", V8Option{}, kAllowedInEnvironment);
325
326
#ifdef NODE_REPORT
327
  AddOption("--diagnostic-report-uncaught-exception",
328
            "generate diagnostic report on uncaught exceptions",
329
            &PerIsolateOptions::report_uncaught_exception,
330
4292
            kAllowedInEnvironment);
331
  AddOption("--diagnostic-report-on-signal",
332
            "generate diagnostic report upon receiving signals",
333
            &PerIsolateOptions::report_on_signal,
334
4292
            kAllowedInEnvironment);
335
  AddOption("--diagnostic-report-on-fatalerror",
336
            "generate diagnostic report on fatal (internal) errors",
337
            &PerIsolateOptions::report_on_fatalerror,
338
4292
            kAllowedInEnvironment);
339
  AddOption("--diagnostic-report-signal",
340
            "causes diagnostic report to be produced on provided signal,"
341
            " unsupported in Windows. (default: SIGUSR2)",
342
            &PerIsolateOptions::report_signal,
343
4292
            kAllowedInEnvironment);
344
4292
  Implies("--diagnostic-report-signal", "--diagnostic-report-on-signal");
345
  AddOption("--diagnostic-report-filename",
346
            "define custom report file name."
347
            " (default: YYYYMMDD.HHMMSS.PID.SEQUENCE#.txt)",
348
            &PerIsolateOptions::report_filename,
349
4292
            kAllowedInEnvironment);
350
  AddOption("--diagnostic-report-directory",
351
            "define custom report pathname."
352
            " (default: current working directory of Node.js process)",
353
            &PerIsolateOptions::report_directory,
354
4292
            kAllowedInEnvironment);
355
#endif  // NODE_REPORT
356
357
  Insert(&EnvironmentOptionsParser::instance,
358
4292
         &PerIsolateOptions::get_per_env_options);
359
4292
}
360
361
4292
PerProcessOptionsParser::PerProcessOptionsParser() {
362
  AddOption("--title",
363
            "the process title to use on startup",
364
            &PerProcessOptions::title,
365
4292
            kAllowedInEnvironment);
366
  AddOption("--trace-event-categories",
367
            "comma separated list of trace event categories to record",
368
            &PerProcessOptions::trace_event_categories,
369
4292
            kAllowedInEnvironment);
370
  AddOption("--trace-event-file-pattern",
371
            "Template string specifying the filepath for the trace-events "
372
            "data, it supports ${rotation} and ${pid}.",
373
            &PerProcessOptions::trace_event_file_pattern,
374
4292
            kAllowedInEnvironment);
375
  AddAlias("--trace-events-enabled", {
376
4292
    "--trace-event-categories", "v8,node,node.async_hooks" });
377
  AddOption("--max-http-header-size",
378
            "set the maximum size of HTTP headers (default: 8KB)",
379
            &PerProcessOptions::max_http_header_size,
380
4292
            kAllowedInEnvironment);
381
  AddOption("--v8-pool-size",
382
            "set V8's thread pool size",
383
            &PerProcessOptions::v8_thread_pool_size,
384
4292
            kAllowedInEnvironment);
385
  AddOption("--zero-fill-buffers",
386
            "automatically zero-fill all newly allocated Buffer and "
387
            "SlowBuffer instances",
388
            &PerProcessOptions::zero_fill_all_buffers,
389
4292
            kAllowedInEnvironment);
390
  AddOption("--debug-arraybuffer-allocations",
391
            "", /* undocumented, only for debugging */
392
            &PerProcessOptions::debug_arraybuffer_allocations,
393
4292
            kAllowedInEnvironment);
394
395
4292
  AddOption("--security-reverts", "", &PerProcessOptions::security_reverts);
396
  AddOption("--completion-bash",
397
            "print source-able bash completion script",
398
4292
            &PerProcessOptions::print_bash_completion);
399
  AddOption("--help",
400
            "print node command line options",
401
4292
            &PerProcessOptions::print_help);
402
4292
  AddAlias("-h", "--help");
403
  AddOption(
404
4292
      "--version", "print Node.js version", &PerProcessOptions::print_version);
405
4292
  AddAlias("-v", "--version");
406
  AddOption("--v8-options",
407
            "print V8 command line options",
408
4292
            &PerProcessOptions::print_v8_help);
409
410
#ifdef NODE_HAVE_I18N_SUPPORT
411
  AddOption("--icu-data-dir",
412
            "set ICU data load path to dir (overrides NODE_ICU_DATA)"
413
#ifndef NODE_HAVE_SMALL_ICU
414
            " (note: linked-in ICU data is present)\n"
415
#endif
416
            ,
417
            &PerProcessOptions::icu_data_dir,
418
4292
            kAllowedInEnvironment);
419
#endif
420
421
#if HAVE_OPENSSL
422
  AddOption("--openssl-config",
423
            "load OpenSSL configuration from the specified file "
424
            "(overrides OPENSSL_CONF)",
425
            &PerProcessOptions::openssl_config,
426
4292
            kAllowedInEnvironment);
427
  AddOption("--tls-cipher-list",
428
            "use an alternative default TLS cipher list",
429
            &PerProcessOptions::tls_cipher_list,
430
4292
            kAllowedInEnvironment);
431
  AddOption("--use-openssl-ca",
432
            "use OpenSSL's default CA store"
433
#if defined(NODE_OPENSSL_CERT_STORE)
434
            " (default)"
435
#endif
436
            ,
437
            &PerProcessOptions::use_openssl_ca,
438
4292
            kAllowedInEnvironment);
439
  AddOption("--use-bundled-ca",
440
            "use bundled CA store"
441
#if !defined(NODE_OPENSSL_CERT_STORE)
442
            " (default)"
443
#endif
444
            ,
445
            &PerProcessOptions::use_bundled_ca,
446
4292
            kAllowedInEnvironment);
447
  // Similar to [has_eval_string] above, except that the separation between
448
  // this and use_openssl_ca only exists for option validation after parsing.
449
  // This is not ideal.
450
  AddOption("[ssl_openssl_cert_store]",
451
            "",
452
4292
            &PerProcessOptions::ssl_openssl_cert_store);
453
4292
  Implies("--use-openssl-ca", "[ssl_openssl_cert_store]");
454
4292
  ImpliesNot("--use-bundled-ca", "[ssl_openssl_cert_store]");
455
#if NODE_FIPS_MODE
456
  AddOption("--enable-fips",
457
            "enable FIPS crypto at startup",
458
            &PerProcessOptions::enable_fips_crypto,
459
            kAllowedInEnvironment);
460
  AddOption("--force-fips",
461
            "force FIPS crypto (cannot be disabled)",
462
            &PerProcessOptions::force_fips_crypto,
463
            kAllowedInEnvironment);
464
#endif
465
#endif
466
467
  Insert(&PerIsolateOptionsParser::instance,
468
4292
         &PerProcessOptions::get_per_isolate_options);
469
4292
}
470
471
107
inline std::string RemoveBrackets(const std::string& host) {
472


107
  if (!host.empty() && host.front() == '[' && host.back() == ']')
473
4
    return host.substr(1, host.size() - 2);
474
  else
475
103
    return host;
476
}
477
478
95
inline int ParseAndValidatePort(const std::string& port,
479
                                std::vector<std::string>* errors) {
480
  char* endptr;
481
95
  errno = 0;
482
95
  const long result = strtol(port.c_str(), &endptr, 10);  // NOLINT(runtime/int)
483

95
  if (errno != 0 || *endptr != '\0'||
484

64
      (result != 0 && result < 1024) || result > 65535) {
485
    errors->push_back(" must be 0 or in range 1024 to 65535.");
486
  }
487
95
  return static_cast<int>(result);
488
}
489
490
95
HostPort SplitHostPort(const std::string& arg,
491
                      std::vector<std::string>* errors) {
492
  // remove_brackets only works if no port is specified
493
  // so if it has an effect only an IPv6 address was specified.
494
95
  std::string host = RemoveBrackets(arg);
495
95
  if (host.length() < arg.length())
496
    return HostPort{host, DebugOptions::kDefaultInspectorPort};
497
498
95
  size_t colon = arg.rfind(':');
499
95
  if (colon == std::string::npos) {
500
    // Either a port number or a host name.  Assume that
501
    // if it's not all decimal digits, it's a host name.
502
383
    for (char c : arg) {
503

300
      if (c < '0' || c > '9') {
504
        return HostPort{arg, DebugOptions::kDefaultInspectorPort};
505
      }
506
    }
507
83
    return HostPort { "", ParseAndValidatePort(arg, errors) };
508
  }
509
  // Host and port found:
510
  return HostPort { RemoveBrackets(arg.substr(0, colon)),
511
12
                    ParseAndValidatePort(arg.substr(colon + 1), errors) };
512
}
513
514
// Return a map containing all the options and their metadata as well
515
// as the aliases
516
4408
void GetOptions(const FunctionCallbackInfo<Value>& args) {
517
4408
  Mutex::ScopedLock lock(per_process::cli_options_mutex);
518
4408
  Environment* env = Environment::GetCurrent(args);
519
4408
  Isolate* isolate = env->isolate();
520
4408
  Local<Context> context = env->context();
521
522
  // Temporarily act as if the current Environment's/IsolateData's options were
523
  // the default options, i.e. like they are the ones we'd access for global
524
  // options parsing, so that all options are available from the main parser.
525
8816
  auto original_per_isolate = per_process::cli_options->per_isolate;
526
4408
  per_process::cli_options->per_isolate = env->isolate_data()->options();
527
8816
  auto original_per_env = per_process::cli_options->per_isolate->per_env;
528
4408
  per_process::cli_options->per_isolate->per_env = env->options();
529
4408
  OnScopeLeave on_scope_leave([&]() {
530
4408
    per_process::cli_options->per_isolate->per_env = original_per_env;
531
4408
    per_process::cli_options->per_isolate = original_per_isolate;
532
13224
  });
533
534
4408
  const auto& parser = PerProcessOptionsParser::instance;
535
536
4408
  Local<Map> options = Map::New(isolate);
537
304152
  for (const auto& item : parser.options_) {
538
    Local<Value> value;
539
299744
    const auto& option_info = item.second;
540
299744
    auto field = option_info.field;
541
299744
    PerProcessOptions* opts = per_process::cli_options.get();
542


299744
    switch (option_info.type) {
543
      case kNoOp:
544
      case kV8Option:
545
        // Special case for --abort-on-uncaught-exception which is also
546
        // respected by Node.js internals
547
39672
        if (item.first == "--abort-on-uncaught-exception") {
548
          value = Boolean::New(
549
8816
            isolate, original_per_env->abort_on_uncaught_exception);
550
        } else {
551
35264
          value = Undefined(isolate);
552
        }
553
39672
        break;
554
      case kBoolean:
555
352640
        value = Boolean::New(isolate, *parser.Lookup<bool>(field, opts));
556
176320
        break;
557
      case kInteger:
558
8816
        value = Number::New(isolate, *parser.Lookup<int64_t>(field, opts));
559
4408
        break;
560
      case kUInteger:
561
8816
        value = Number::New(isolate, *parser.Lookup<uint64_t>(field, opts));
562
4408
        break;
563
      case kString:
564
185136
        if (!ToV8Value(context, *parser.Lookup<std::string>(field, opts))
565
185136
                 .ToLocal(&value)) {
566
          return;
567
        }
568
61712
        break;
569
      case kStringList:
570
17632
        if (!ToV8Value(context,
571
17632
                       *parser.Lookup<std::vector<std::string>>(field, opts))
572
26448
                 .ToLocal(&value)) {
573
          return;
574
        }
575
8816
        break;
576
      case kHostPort: {
577
4408
        const HostPort& host_port = *parser.Lookup<HostPort>(field, opts);
578
4408
        Local<Object> obj = Object::New(isolate);
579
        Local<Value> host;
580

26448
        if (!ToV8Value(context, host_port.host()).ToLocal(&host) ||
581


39672
            obj->Set(context, env->host_string(), host).IsNothing() ||
582
            obj->Set(context,
583
                     env->port_string(),
584

17632
                     Integer::New(isolate, host_port.port()))
585
22040
                .IsNothing()) {
586
          return;
587
        }
588
4408
        value = obj;
589
4408
        break;
590
      }
591
      default:
592
        UNREACHABLE();
593
    }
594
299744
    CHECK(!value.IsEmpty());
595
596
599488
    Local<Value> name = ToV8Value(context, item.first).ToLocalChecked();
597
299744
    Local<Object> info = Object::New(isolate);
598
    Local<Value> help_text;
599

2098208
    if (!ToV8Value(context, option_info.help_text).ToLocal(&help_text) ||
600
899232
        !info->Set(context, env->help_text_string(), help_text)
601

2697696
             .FromMaybe(false) ||
602
        !info->Set(context,
603
                   env->env_var_settings_string(),
604
                   Integer::New(isolate,
605

1198976
                                static_cast<int>(option_info.env_setting)))
606

2997440
             .FromMaybe(false) ||
607
        !info->Set(context,
608
                   env->type_string(),
609

1198976
                   Integer::New(isolate, static_cast<int>(option_info.type)))
610

2697696
             .FromMaybe(false) ||
611


2997440
        info->Set(context, env->value_string(), value).IsNothing() ||
612

1198976
        options->Set(context, name, info).IsEmpty()) {
613
      return;
614
    }
615
299744
  }
616
617
  Local<Value> aliases;
618
8816
  if (!ToV8Value(context, parser.aliases_).ToLocal(&aliases)) return;
619
620
4408
  Local<Object> ret = Object::New(isolate);
621



35264
  if (ret->Set(context, env->options_string(), options).IsNothing() ||
622

22040
      ret->Set(context, env->aliases_string(), aliases).IsNothing()) {
623
    return;
624
  }
625
626
13224
  args.GetReturnValue().Set(ret);
627
}
628
629
4408
void Initialize(Local<Object> target,
630
                Local<Value> unused,
631
                Local<Context> context,
632
                void* priv) {
633
4408
  Environment* env = Environment::GetCurrent(context);
634
4408
  Isolate* isolate = env->isolate();
635
4408
  env->SetMethodNoSideEffect(target, "getOptions", GetOptions);
636
637
4408
  Local<Object> env_settings = Object::New(isolate);
638
17632
  NODE_DEFINE_CONSTANT(env_settings, kAllowedInEnvironment);
639
17632
  NODE_DEFINE_CONSTANT(env_settings, kDisallowedInEnvironment);
640
  target
641
      ->Set(
642
13224
          context, FIXED_ONE_BYTE_STRING(isolate, "envSettings"), env_settings)
643
8816
      .FromJust();
644
645
4408
  Local<Object> types = Object::New(isolate);
646
17632
  NODE_DEFINE_CONSTANT(types, kNoOp);
647
17632
  NODE_DEFINE_CONSTANT(types, kV8Option);
648
17632
  NODE_DEFINE_CONSTANT(types, kBoolean);
649
17632
  NODE_DEFINE_CONSTANT(types, kInteger);
650
17632
  NODE_DEFINE_CONSTANT(types, kUInteger);
651
17632
  NODE_DEFINE_CONSTANT(types, kString);
652
17632
  NODE_DEFINE_CONSTANT(types, kHostPort);
653
17632
  NODE_DEFINE_CONSTANT(types, kStringList);
654
13224
  target->Set(context, FIXED_ONE_BYTE_STRING(isolate, "types"), types)
655
8816
      .FromJust();
656
4408
}
657
658
}  // namespace options_parser
659
}  // namespace node
660
661

17168
NODE_MODULE_CONTEXT_AWARE_INTERNAL(options, node::options_parser::Initialize)