Where Online Learning is simpler!
The C and C++ Include Header Files
cat -n /usr/include/nodejs/src/node_options.h
1 #ifndef SRC_NODE_OPTIONS_H_ 2 #define SRC_NODE_OPTIONS_H_ 3 4 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 5 6 #include <memory> 7 #include <string> 8 #include <unordered_map> 9 #include <vector> 10 #include "node_constants.h" 11 #include "node_mutex.h" 12 #include "util.h" 13 14 #if HAVE_OPENSSL 15 #include "openssl/opensslv.h" 16 #endif 17 18 namespace node { 19 20 class HostPort { 21 public: 22 HostPort(const std::string& host_name, int port) 23 : host_name_(host_name), port_(port) {} 24 HostPort(const HostPort&) = default; 25 HostPort& operator=(const HostPort&) = default; 26 HostPort(HostPort&&) = default; 27 HostPort& operator=(HostPort&&) = default; 28 29 void set_host(const std::string& host) { host_name_ = host; } 30 31 void set_port(uint16_t port) { port_ = port; } 32 33 const std::string& host() const { return host_name_; } 34 35 uint16_t port() const { return port_; } 36 37 void Update(const HostPort& other) { 38 if (!other.host_name_.empty()) host_name_ = other.host_name_; 39 port_ = other.port_; 40 } 41 42 private: 43 std::string host_name_; 44 uint16_t port_; 45 }; 46 47 class Options { 48 public: 49 virtual void CheckOptions(std::vector<std::string>* errors, 50 std::vector<std::string>* argv) {} 51 virtual ~Options() = default; 52 }; 53 54 struct InspectPublishUid { 55 bool console; 56 bool http; 57 }; 58 59 // These options are currently essentially per-Environment, but it can be nice 60 // to keep them separate since they are a group of options applying to a very 61 // specific part of Node. It might also make more sense for them to be 62 // per-Isolate, rather than per-Environment. 63 class DebugOptions : public Options { 64 public: 65 DebugOptions() = default; 66 DebugOptions(const DebugOptions&) = default; 67 DebugOptions& operator=(const DebugOptions&) = default; 68 DebugOptions(DebugOptions&&) = default; 69 DebugOptions& operator=(DebugOptions&&) = default; 70 71 bool allow_attaching_debugger = true; 72 // --inspect 73 bool inspector_enabled = false; 74 // --inspect-wait 75 bool inspect_wait = false; 76 // --debug 77 bool deprecated_debug = false; 78 // --inspect-brk 79 bool break_first_line = false; 80 // --inspect-brk-node 81 bool break_node_first_line = false; 82 // --inspect-publish-uid 83 std::string inspect_publish_uid_string = "stderr,http"; 84 85 InspectPublishUid inspect_publish_uid; 86 87 enum { kDefaultInspectorPort = 9229 }; 88 89 HostPort host_port{"127.0.0.1", kDefaultInspectorPort}; 90 91 // Used to patch the options as if --inspect-brk is passed. 92 void EnableBreakFirstLine() { 93 inspector_enabled = true; 94 break_first_line = true; 95 } 96 97 void DisableWaitOrBreakFirstLine() { 98 inspect_wait = false; 99 break_first_line = false; 100 } 101 102 bool wait_for_connect() const { 103 return break_first_line || break_node_first_line || inspect_wait; 104 } 105 106 bool should_break_first_line() const { 107 return break_first_line || break_node_first_line; 108 } 109 110 void CheckOptions(std::vector<std::string>* errors, 111 std::vector<std::string>* argv) override; 112 }; 113 114 class EnvironmentOptions : public Options { 115 public: 116 bool abort_on_uncaught_exception = false; 117 std::vector<std::string> conditions; 118 bool detect_module = true; 119 bool disable_sigusr1 = false; 120 bool print_required_tla = false; 121 bool require_module = true; 122 std::string dns_result_order; 123 bool enable_source_maps = false; 124 bool experimental_addon_modules = false; 125 bool experimental_eventsource = false; 126 bool experimental_fetch = true; 127 bool experimental_websocket = true; 128 bool experimental_sqlite = true; 129 bool experimental_webstorage = false; 130 std::string localstorage_file; 131 bool experimental_global_customevent = true; 132 bool experimental_global_navigator = true; 133 bool experimental_global_web_crypto = true; 134 bool experimental_import_meta_resolve = false; 135 std::string input_type; // Value of --input-type 136 std::string type; // Value of --experimental-default-type 137 bool entry_is_url = false; 138 bool permission = false; 139 std::vector<std::string> allow_fs_read; 140 std::vector<std::string> allow_fs_write; 141 bool allow_addons = false; 142 bool allow_child_process = false; 143 bool allow_wasi = false; 144 bool allow_worker_threads = false; 145 bool experimental_repl_await = true; 146 bool experimental_vm_modules = false; 147 bool async_context_frame = false; 148 bool expose_internals = false; 149 bool force_node_api_uncaught_exceptions_policy = false; 150 bool frozen_intrinsics = false; 151 int64_t heap_snapshot_near_heap_limit = 0; 152 std::string heap_snapshot_signal; 153 bool network_family_autoselection = true; 154 uint64_t network_family_autoselection_attempt_timeout = 250; 155 uint64_t max_http_header_size = 16 * 1024; 156 bool deprecation = true; 157 bool force_async_hooks_checks = true; 158 bool allow_native_addons = true; 159 bool global_search_paths = true; 160 bool warnings = true; 161 std::vector<std::string> disable_warnings; 162 bool force_context_aware = false; 163 bool pending_deprecation = false; 164 bool preserve_symlinks = false; 165 bool preserve_symlinks_main = false; 166 bool prof_process = false; 167 #if HAVE_INSPECTOR 168 std::string cpu_prof_dir; 169 static const uint64_t kDefaultCpuProfInterval = 1000; 170 uint64_t cpu_prof_interval = kDefaultCpuProfInterval; 171 std::string cpu_prof_name; 172 bool cpu_prof = false; 173 bool experimental_network_inspection = false; 174 bool experimental_worker_inspection = false; 175 bool experimental_inspector_network_resource = false; 176 std::string heap_prof_dir; 177 std::string heap_prof_name; 178 static const uint64_t kDefaultHeapProfInterval = 512 * 1024; 179 uint64_t heap_prof_interval = kDefaultHeapProfInterval; 180 bool heap_prof = false; 181 #endif // HAVE_INSPECTOR 182 std::string redirect_warnings; 183 std::string diagnostic_dir; 184 std::string env_file; 185 std::string optional_env_file; 186 bool has_env_file_string = false; 187 bool test_runner = false; 188 uint64_t test_runner_concurrency = 0; 189 uint64_t test_runner_timeout = 0; 190 bool test_runner_coverage = false; 191 bool test_runner_force_exit = false; 192 uint64_t test_coverage_branches = 0; 193 uint64_t test_coverage_functions = 0; 194 uint64_t test_coverage_lines = 0; 195 bool test_runner_module_mocks = false; 196 bool test_runner_update_snapshots = false; 197 std::vector<std::string> test_name_pattern; 198 std::vector<std::string> test_reporter; 199 std::vector<std::string> test_reporter_destination; 200 bool test_only = false; 201 bool test_udp_no_try_send = false; 202 std::string test_isolation = "process"; 203 std::string test_shard; 204 std::vector<std::string> test_skip_pattern; 205 std::vector<std::string> coverage_include_pattern; 206 std::vector<std::string> coverage_exclude_pattern; 207 bool throw_deprecation = false; 208 bool trace_atomics_wait = false; 209 bool trace_deprecation = false; 210 bool trace_exit = false; 211 bool trace_sync_io = false; 212 bool trace_tls = false; 213 bool trace_uncaught = false; 214 bool trace_warnings = false; 215 bool trace_promises = false; 216 bool trace_env = false; 217 bool trace_env_js_stack = false; 218 bool trace_env_native_stack = false; 219 std::string trace_require_module; 220 bool extra_info_on_fatal_exception = true; 221 std::string unhandled_rejections; 222 std::vector<std::string> userland_loaders; 223 bool verify_base_objects = 224 #ifdef DEBUG 225 true; 226 #else 227 false; 228 #endif // DEBUG 229 230 bool watch_mode = false; 231 bool watch_mode_report_to_parent = false; 232 bool watch_mode_preserve_output = false; 233 std::string watch_mode_kill_signal = "SIGTERM"; 234 std::vector<std::string> watch_mode_paths; 235 236 bool syntax_check_only = false; 237 bool has_eval_string = false; 238 std::string eval_string; 239 bool print_eval = false; 240 bool force_repl = false; 241 242 bool insecure_http_parser = false; 243 bool use_env_proxy = false; 244 245 bool tls_min_v1_0 = false; 246 bool tls_min_v1_1 = false; 247 bool tls_min_v1_2 = false; 248 bool tls_min_v1_3 = false; 249 bool tls_max_v1_2 = false; 250 bool tls_max_v1_3 = false; 251 std::string tls_keylog; 252 253 std::vector<std::string> preload_cjs_modules; 254 255 std::vector<std::string> preload_esm_modules; 256 257 bool experimental_strip_types = HAVE_AMARO; 258 bool experimental_transform_types = false; 259 260 std::vector<std::string> user_argv; 261 262 bool report_exclude_env = false; 263 bool report_exclude_network = false; 264 std::string experimental_config_file_path; 265 bool experimental_default_config_file = false; 266 267 inline DebugOptions* get_debug_options() { return &debug_options_; } 268 inline const DebugOptions& debug_options() const { return debug_options_; } 269 270 void CheckOptions(std::vector<std::string>* errors, 271 std::vector<std::string>* argv) override; 272 273 private: 274 DebugOptions debug_options_; 275 }; 276 277 class PerIsolateOptions : public Options { 278 public: 279 PerIsolateOptions() = default; 280 PerIsolateOptions(PerIsolateOptions&&) = default; 281 282 std::shared_ptr<EnvironmentOptions> per_env { new EnvironmentOptions() }; 283 bool track_heap_objects = false; 284 bool report_uncaught_exception = false; 285 bool report_on_signal = false; 286 bool experimental_shadow_realm = false; 287 std::string max_old_space_size_percentage; 288 std::string max_old_space_size; 289 int64_t stack_trace_limit = 10; 290 std::string report_signal = "SIGUSR2"; 291 bool build_snapshot = false; 292 std::string build_snapshot_config; 293 inline EnvironmentOptions* get_per_env_options(); 294 void CheckOptions(std::vector<std::string>* errors, 295 std::vector<std::string>* argv) override; 296 void HandleMaxOldSpaceSizePercentage(std::vector<std::string>* errors, 297 std::string* max_old_space_size); 298 299 inline std::shared_ptr<PerIsolateOptions> Clone() const; 300 301 private: 302 PerIsolateOptions(const PerIsolateOptions&) = default; 303 }; 304 305 class PerProcessOptions : public Options { 306 public: 307 // Options shouldn't be here unless they affect the entire process scope, and 308 // that should avoided when possible. 309 // 310 // When an option is used during process initialization, it does not need 311 // protection, but any use after that will likely require synchronization 312 // using the node::per_process::cli_options_mutex, typically: 313 // 314 // Mutex::ScopedLock lock(node::per_process::cli_options_mutex); 315 std::shared_ptr<PerIsolateOptions> per_isolate { new PerIsolateOptions() }; 316 317 std::string title; 318 std::string trace_event_categories; 319 std::string trace_event_file_pattern = "node_trace.${rotation}.log"; 320 int64_t v8_thread_pool_size = 4; 321 bool zero_fill_all_buffers = false; 322 bool debug_arraybuffer_allocations = false; 323 std::string disable_proto; 324 // We enable the shared read-only heap which currently requires that the 325 // snapshot used in different isolates in the same process to be the same. 326 // Therefore --node-snapshot is a per-process option. 327 bool node_snapshot = true; 328 std::string snapshot_blob; 329 330 std::vector<std::string> security_reverts; 331 bool print_bash_completion = false; 332 bool print_help = false; 333 bool print_v8_help = false; 334 bool print_version = false; 335 std::string experimental_sea_config; 336 std::string run; 337 338 #ifdef NODE_HAVE_I18N_SUPPORT 339 std::string icu_data_dir; 340 #endif 341 342 // Per-process because they affect singleton OpenSSL shared library state, 343 // or are used once during process initialization. 344 #if HAVE_OPENSSL 345 std::string openssl_config; 346 std::string tls_cipher_list = DEFAULT_CIPHER_LIST_CORE; 347 int64_t secure_heap = 0; 348 int64_t secure_heap_min = 2; 349 #ifdef NODE_OPENSSL_CERT_STORE 350 bool ssl_openssl_cert_store = true; 351 #else 352 bool ssl_openssl_cert_store = false; 353 #endif 354 bool use_openssl_ca = false; 355 bool use_system_ca = false; 356 bool use_bundled_ca = false; 357 bool enable_fips_crypto = false; 358 bool force_fips_crypto = false; 359 #endif 360 #if OPENSSL_VERSION_MAJOR >= 3 361 bool openssl_legacy_provider = false; 362 bool openssl_shared_config = false; 363 #endif 364 365 bool disable_wasm_trap_handler = false; 366 367 // Per-process because reports can be triggered outside a known V8 context. 368 bool report_on_fatalerror = false; 369 bool report_compact = false; 370 std::string report_directory; 371 std::string report_filename; 372 373 // TODO(addaleax): Some of these could probably be per-Environment. 374 std::string use_largepages = "off"; 375 bool trace_sigint = false; 376 std::vector<std::string> cmdline; 377 378 inline PerIsolateOptions* get_per_isolate_options(); 379 void CheckOptions(std::vector<std::string>* errors, 380 std::vector<std::string>* argv) override; 381 }; 382 383 // The actual options parser, as opposed to the structs containing them: 384 385 namespace options_parser { 386 387 HostPort SplitHostPort(const std::string& arg, 388 std::vector<std::string>* errors); 389 void GetOptions(const v8::FunctionCallbackInfo<v8::Value>& args); 390 std::string GetBashCompletion(); 391 392 enum OptionType { 393 kNoOp, 394 kV8Option, 395 kBoolean, 396 kInteger, 397 kUInteger, 398 kString, 399 kHostPort, 400 kStringList, 401 }; 402 std::unordered_map<std::string, OptionType> MapEnvOptionsFlagInputType(); 403 404 template <typename Options> 405 class OptionsParser { 406 public: 407 virtual ~OptionsParser() = default; 408 409 typedef Options TargetType; 410 411 struct NoOp {}; 412 struct V8Option {}; 413 414 // These methods add a single option to the parser. Optionally, it can be 415 // specified whether the option should be allowed from environment variable 416 // sources (i.e. NODE_OPTIONS). 417 void AddOption(const char* name, 418 const char* help_text, 419 bool Options::*field, 420 OptionEnvvarSettings env_setting = kDisallowedInEnvvar, 421 bool default_is_true = false); 422 void AddOption(const char* name, 423 const char* help_text, 424 uint64_t Options::*field, 425 OptionEnvvarSettings env_setting = kDisallowedInEnvvar); 426 void AddOption(const char* name, 427 const char* help_text, 428 int64_t Options::*field, 429 OptionEnvvarSettings env_setting = kDisallowedInEnvvar); 430 void AddOption(const char* name, 431 const char* help_text, 432 std::string Options::*field, 433 OptionEnvvarSettings env_setting = kDisallowedInEnvvar); 434 void AddOption(const char* name, 435 const char* help_text, 436 std::vector<std::string> Options::*field, 437 OptionEnvvarSettings env_setting = kDisallowedInEnvvar); 438 void AddOption(const char* name, 439 const char* help_text, 440 HostPort Options::*field, 441 OptionEnvvarSettings env_setting = kDisallowedInEnvvar); 442 void AddOption(const char* name, 443 const char* help_text, 444 NoOp no_op_tag, 445 OptionEnvvarSettings env_setting = kDisallowedInEnvvar); 446 void AddOption(const char* name, 447 const char* help_text, 448 V8Option v8_option_tag, 449 OptionEnvvarSettings env_setting = kDisallowedInEnvvar); 450 451 // Adds aliases. An alias can be of the form "--option-a" -> "--option-b", 452 // or have a more complex group expansion, like 453 // "--option-a" -> { "--option-b", "--harmony-foobar", "--eval", "42" } 454 // If `from` has the form "--option-a=", the alias will only be expanded if 455 // the option is presented in that form (i.e. with a '='). 456 // If `from` has the form "--option-a <arg>", the alias will only be expanded 457 // if the option has a non-option argument (not starting with -) following it. 458 void AddAlias(const char* from, const char* to); 459 void AddAlias(const char* from, const std::vector<std::string>& to); 460 void AddAlias(const char* from, 461 const std::initializer_list<std::string>& to); 462 463 // Add implications from some arbitrary option to a boolean one, either 464 // in a way that makes `from` set `to` to true or to false. 465 void Implies(const char* from, const char* to); 466 void ImpliesNot(const char* from, const char* to); 467 468 // Insert options from another options parser into this one, along with 469 // a method that yields the target options type from this parser's options 470 // type. 471 template <typename ChildOptions> 472 void Insert(const OptionsParser<ChildOptions>& child_options_parser, 473 ChildOptions* (Options::* get_child)()); 474 475 // Parse a sequence of options into an options struct, a list of 476 // arguments that were parsed as options, a list of unknown/JS engine options, 477 // and leave the remainder in the input `args` vector. 478 // 479 // For example, an `args` input of 480 // 481 // node --foo --harmony-bar --fizzle=42 -- /path/to/cow moo 482 // 483 // expands as 484 // 485 // - `args` -> { "node", "/path/to/cow", "moo" } 486 // - `exec_args` -> { "--foo", "--harmony-bar", "--fizzle=42" } 487 // - `v8_args` -> `{ "node", "--harmony-bar" } 488 // - `options->foo == true`, `options->fizzle == 42`. 489 // 490 // If `*error` is set, the result of the parsing should be discarded and the 491 // contents of any of the argument vectors should be considered undefined. 492 void Parse(std::vector<std::string>* const args, 493 std::vector<std::string>* const exec_args, 494 std::vector<std::string>* const v8_args, 495 Options* const options, 496 OptionEnvvarSettings required_env_settings, 497 std::vector<std::string>* const errors) const; 498 499 private: 500 // We support the wide variety of different option types by remembering 501 // how to access them, given a certain `Options` struct. 502 503 // Represents a field within `Options`. 504 class BaseOptionField { 505 public: 506 virtual ~BaseOptionField() = default; 507 virtual void* LookupImpl(Options* options) const = 0; 508 509 template <typename T> 510 inline T* Lookup(Options* options) const { 511 return static_cast<T*>(LookupImpl(options)); 512 } 513 }; 514 515 // Represents a field of type T within `Options` that can be looked up 516 // as a C++ member field. 517 template <typename T> 518 class SimpleOptionField : public BaseOptionField { 519 public: 520 explicit SimpleOptionField(T Options::* field) : field_(field) {} 521 void* LookupImpl(Options* options) const override { 522 return static_cast<void*>(&(options->*field_)); 523 } 524 525 private: 526 T Options::* field_; 527 }; 528 529 template <typename T> 530 inline T* Lookup(std::shared_ptr<BaseOptionField> field, 531 Options* options) const { 532 return field->template Lookup<T>(options); 533 } 534 535 // An option consists of: 536 // - A type. 537 // - A way to store/access the property value. 538 // - The information of whether it may occur in an env var or not. 539 struct OptionInfo { 540 OptionType type; 541 std::shared_ptr<BaseOptionField> field; 542 OptionEnvvarSettings env_setting; 543 std::string help_text; 544 bool default_is_true = false; 545 }; 546 547 // An implied option is composed of the information on where to store a 548 // specific boolean value (if another specific option is encountered). 549 struct Implication { 550 OptionType type; 551 std::string name; 552 std::shared_ptr<BaseOptionField> target_field; 553 bool target_value; 554 }; 555 556 // These are helpers that make `Insert()` support properties of other 557 // options structs, if we know how to access them. 558 template <typename OriginalField, typename ChildOptions> 559 static auto Convert( 560 std::shared_ptr<OriginalField> original, 561 ChildOptions* (Options::* get_child)()); 562 template <typename ChildOptions> 563 static auto Convert( 564 typename OptionsParser<ChildOptions>::OptionInfo original, 565 ChildOptions* (Options::* get_child)()); 566 template <typename ChildOptions> 567 static auto Convert( 568 typename OptionsParser<ChildOptions>::Implication original, 569 ChildOptions* (Options::* get_child)()); 570 571 std::unordered_map<std::string, OptionInfo> options_; 572 std::unordered_map<std::string, std::vector<std::string>> aliases_; 573 std::unordered_multimap<std::string, Implication> implications_; 574 575 template <typename OtherOptions> 576 friend class OptionsParser; 577 578 friend void GetCLIOptionsValues( 579 const v8::FunctionCallbackInfo<v8::Value>& args); 580 friend void GetCLIOptionsInfo( 581 const v8::FunctionCallbackInfo<v8::Value>& args); 582 friend std::string GetBashCompletion(); 583 friend std::unordered_map<std::string, OptionType> 584 MapEnvOptionsFlagInputType(); 585 friend void GetEnvOptionsInputType( 586 const v8::FunctionCallbackInfo<v8::Value>& args); 587 }; 588 589 using StringVector = std::vector<std::string>; 590 template <class OptionsType, class = Options> 591 void Parse( 592 StringVector* const args, StringVector* const exec_args, 593 StringVector* const v8_args, OptionsType* const options, 594 OptionEnvvarSettings required_env_settings, StringVector* const errors); 595 596 } // namespace options_parser 597 598 namespace per_process { 599 600 extern Mutex cli_options_mutex; 601 extern NODE_EXTERN_PRIVATE std::shared_ptr<PerProcessOptions> cli_options; 602 603 } // namespace per_process 604 605 void HandleEnvOptions(std::shared_ptr<EnvironmentOptions> env_options); 606 void HandleEnvOptions(std::shared_ptr<EnvironmentOptions> env_options, 607 std::function<std::string(const char*)> opt_getter); 608 609 std::vector<std::string> ParseNodeOptionsEnvVar( 610 const std::string& node_options, std::vector<std::string>* errors); 611 } // namespace node 612 613 #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 614 615 #endif // SRC_NODE_OPTIONS_H_