76 { \
77 return Options::callback(arg, o); \
78 } \
81#undef CB_OPTION_DEFINITION
82
83#if !defined(DART_PRECOMPILED_RUNTIME)
84DFE* Options::dfe_ = nullptr;
85
87#endif
88
90
91 vm_options->AddArgument("--identity_reload");
92
93 vm_options->AddArgument("--reload_every=4");
94
95 vm_options->AddArgument("--reload_every_optimized=false");
96
97 vm_options->AddArgument("--reload_every_back_off");
98
99 vm_options->AddArgument("--check_reloaded");
100#if !defined(DART_PRECOMPILED_RUNTIME)
101 Options::dfe()->set_use_incremental_compiler(true);
102#endif
103}
104
106
108 CommandLineOptions* vm_options) {
109
110 vm_options->AddArgument("--identity_reload");
111
112 vm_options->AddArgument("--reload_every=4");
113
114 vm_options->AddArgument("--reload_every_optimized=false");
115
116 vm_options->AddArgument("--reload_every_back_off");
117
118 vm_options->AddArgument("--check_reloaded");
119
120 vm_options->AddArgument("--reload_force_rollback");
121#if !defined(DART_PRECOMPILED_RUNTIME)
122 Options::dfe()->set_use_incremental_compiler(true);
123#endif
124}
125
127 hot_reload_rollback_test_mode_callback);
128
129void Options::PrintVersion() {
131}
132
133
134void Options::PrintUsage() {
135 Syslog::Print(
136 "Usage: dart [<vm-flags>] <dart-script-file> [<script-arguments>]\n"
137 "\n"
138 "Executes the Dart script <dart-script-file> with "
139 "the given list of <script-arguments>.\n"
140 "\n");
141 if (!Options::verbose_option()) {
142 Syslog::Print(
143"Common VM flags:\n"
144#if !defined(PRODUCT)
145"--enable-asserts\n"
146" Enable assert statements.\n"
147#endif
148"--help or -h\n"
149" Display this message (add -v or --verbose for information about\n"
150" all VM options).\n"
151"--packages=<path>\n"
152" Where to find a package spec file.\n"
153"--define=<key>=<value> or -D<key>=<value>\n"
154" Define an environment declaration. To specify multiple declarations,\n"
155" use multiple instances of this option.\n"
156#if !defined(PRODUCT)
157"--observe[=<port>[/<bind-address>]]\n"
158" The observe flag is a convenience flag used to run a program with a\n"
159" set of options which are often useful for debugging under Observatory.\n"
160" These options are currently:\n"
161" --enable-vm-service[=<port>[/<bind-address>]]\n"
162" --serve-devtools\n"
163" --pause-isolates-on-exit\n"
164" --pause-isolates-on-unhandled-exceptions\n"
165" --warn-on-pause-with-no-debugger\n"
166" --timeline-streams=\"Compiler, Dart, GC\"\n"
167" This set is subject to change.\n"
168" Please see these options (--help --verbose) for further documentation.\n"
169"--write-service-info=<file_uri>\n"
170" Outputs information necessary to connect to the VM service to the\n"
171" specified file in JSON format. Useful for clients which are unable to\n"
172" listen to stdout for the Dart VM service listening message.\n"
173#endif
174"--snapshot-kind=<snapshot_kind>\n"
175"--snapshot=<file_name>\n"
176" These snapshot options are used to generate a snapshot of the loaded\n"
177" Dart script:\n"
178" <snapshot-kind> controls the kind of snapshot, it could be\n"
179" kernel(default) or app-jit\n"
180" <file_name> specifies the file into which the snapshot is written\n"
181"--version\n"
182" Print the SDK version.\n");
183 } else {
184 Syslog::Print(
185"Supported options:\n"
186#if !defined(PRODUCT)
187"--enable-asserts\n"
188" Enable assert statements.\n"
189#endif
190"--help or -h\n"
191" Display this message (add -v or --verbose for information about\n"
192" all VM options).\n"
193"--packages=<path>\n"
194" Where to find a package spec file.\n"
195"--define=<key>=<value> or -D<key>=<value>\n"
196" Define an environment declaration. To specify multiple declarations,\n"
197" use multiple instances of this option.\n"
198#if !defined(PRODUCT)
199"--observe[=<port>[/<bind-address>]]\n"
200" The observe flag is a convenience flag used to run a program with a\n"
201" set of options which are often useful for debugging under Observatory.\n"
202" These options are currently:\n"
203" --enable-vm-service[=<port>[/<bind-address>]]\n"
204" --serve-devtools\n"
205" --pause-isolates-on-exit\n"
206" --pause-isolates-on-unhandled-exceptions\n"
207" --warn-on-pause-with-no-debugger\n"
208" --timeline-streams=\"Compiler, Dart, GC\"\n"
209" This set is subject to change.\n"
210" Please see these options for further documentation.\n"
211#endif
212"--version\n"
213" Print the VM version.\n"
214"\n"
215"--trace-loading\n"
216" enables tracing of library and script loading\n"
217"\n"
218#if !defined(PRODUCT)
219"--enable-vm-service[=<port>[/<bind-address>]]\n"
220" Enables the VM service and listens on specified port for connections\n"
221" (default port number is 8181, default bind address is localhost).\n"
222"\n"
223"--disable-service-auth-codes\n"
224" Disables the requirement for an authentication code to communicate with\n"
225" the VM service. Authentication codes help protect against CSRF attacks,\n"
226" so it is not recommended to disable them unless behind a firewall on a\n"
227" secure device.\n"
228"\n"
229"--enable-service-port-fallback\n"
230" When the VM service is told to bind to a particular port, fallback to 0 if\n"
231" it fails to bind instead of failing to start.\n"
232"\n"
233#endif
234"--root-certs-file=<path>\n"
235" The path to a file containing the trusted root certificates to use for\n"
236" secure socket connections.\n"
237"--root-certs-cache=<path>\n"
238" The path to a cache directory containing the trusted root certificates to\n"
239" use for secure socket connections.\n"
240#if defined(DART_HOST_OS_LINUX) || \
241 defined(DART_HOST_OS_ANDROID) || \
242 defined(DART_HOST_OS_FUCHSIA)
243"--namespace=<path>\n"
244" The path to a directory that dart:io calls will treat as the root of the\n"
245" filesystem.\n"
246#endif
247"\n"
248"The following options are only used for VM development and may\n"
249"be changed in any future version:\n");
250 const char* print_flags = "--print_flags";
253 }
254}
255
256
258bool Options::ProcessEnvironmentOption(const char* arg,
259 CommandLineOptions* vm_options) {
260 return OptionProcessor::ProcessEnvironmentOption(arg, vm_options,
261 &Options::environment_);
262}
263
264void Options::Cleanup() {
265#if defined(DART_PRECOMPILED_RUNTIME)
266 DestroyEnvArgv();
267#endif
268 DestroyEnvironment();
269}
270
271void Options::DestroyEnvironment() {
272 if (environment_ != nullptr) {
273 for (SimpleHashMap::Entry* p = environment_->Start();
p !=
nullptr;
274 p = environment_->Next(p)) {
277 }
278 delete environment_;
279 environment_ = nullptr;
280 }
281}
282
283#if defined(DART_PRECOMPILED_RUNTIME)
284
285
286
287
288
289
290
291char** Options::GetEnvArguments(int* argc) {
293 const char* env_args_str = std::getenv("DART_VM_OPTIONS");
294 if (env_args_str == nullptr) {
295 *argc = 0;
296 return nullptr;
297 }
298
299 intptr_t n = strlen(env_args_str);
300 if (n == 0) {
301 return nullptr;
302 }
303
304
305
306
307
308
309
310 int arg_count = 1;
311 for (int i = 0; i < n; ++i) {
312
313 if (env_args_str[i] == ',' && i + 1 != n) {
314 arg_count++;
315 }
316 }
317
318 env_argv_ = new char*[arg_count];
319 env_argc_ = arg_count;
320 *argc = arg_count;
321
322 int current_arg = 0;
323 char* token;
324 char* rest = const_cast<char*>(env_args_str);
325
326
327 while ((token = strtok_r(rest, ",", &rest)) != nullptr) {
328
329
330 env_argv_[current_arg++] = Utils::StrNDup(token, rest - token);
331 }
332
333 return env_argv_;
334}
335
336char** Options::env_argv_ = nullptr;
337int Options::env_argc_ = 0;
338
339void Options::DestroyEnvArgv() {
340 for (int i = 0; i < env_argc_; ++i) {
341 free(env_argv_[i]);
342 }
343 delete[] env_argv_;
344 env_argv_ = nullptr;
345}
346#endif
347
348bool Options::ExtractPortAndAddress(const char* option_value,
349 int* out_port,
350 const char** out_ip,
351 int default_port,
352 const char* default_ip) {
353
354
355
356
357
358
359
360
361 if (*option_value == '\0') {
362 *out_ip = default_ip;
363 *out_port = default_port;
364 return true;
365 }
366
367 if ((*option_value != '=') && (*option_value != ':')) {
368 return false;
369 }
370
371 int port = atoi(option_value + 1);
372 const char* slash = strstr(option_value, "/");
373 if (slash == nullptr) {
374 *out_ip = default_ip;
376 return true;
377 }
378
379 *out_ip = slash + 1;
381 return true;
382}
383
384
385
386static bool IsOption(
const char* arg,
const char* option) {
387 if (arg[0] != '-' || arg[1] != '-') {
388
389 return false;
390 }
391 for (int i = 0; option[i] != '\0'; i++) {
392 auto c = arg[i + 2];
393 if (c == '\0') {
394
395 return false;
396 }
397 if ((c == '_' ? '-' : c) != option[i]) {
398 return false;
399 }
400 }
401 return true;
402}
403
404const char* Options::vm_service_server_ip_ = DEFAULT_VM_SERVICE_SERVER_IP;
405int Options::vm_service_server_port_ = INVALID_VM_SERVICE_SERVER_PORT;
406bool Options::ProcessEnableVmServiceOption(const char* arg,
407 CommandLineOptions* vm_options) {
408#if !defined(PRODUCT)
410 OptionProcessor::ProcessOption(arg, "--enable-vm-service");
411 if (value == nullptr) {
412 return false;
413 }
414 if (!ExtractPortAndAddress(
415 value, &vm_service_server_port_, &vm_service_server_ip_,
416 DEFAULT_VM_SERVICE_SERVER_PORT, DEFAULT_VM_SERVICE_SERVER_IP)) {
417 Syslog::PrintErr(
418 "unrecognized --enable-vm-service option syntax. "
419 "Use --enable-vm-service[=<port number>[/<bind address>]]\n");
420 return false;
421 }
422#if !defined(DART_PRECOMPILED_RUNTIME)
424#endif
425 enable_vm_service_ = true;
426 return true;
427#else
428
429 return false;
430#endif
431}
432
433bool Options::ProcessObserveOption(const char* arg,
434 CommandLineOptions* vm_options) {
435#if !defined(PRODUCT)
436 const char*
value = OptionProcessor::ProcessOption(arg,
"--observe");
437 if (value == nullptr) {
438 return false;
439 }
440 if (!ExtractPortAndAddress(
441 value, &vm_service_server_port_, &vm_service_server_ip_,
442 DEFAULT_VM_SERVICE_SERVER_PORT, DEFAULT_VM_SERVICE_SERVER_IP)) {
443 Syslog::PrintErr(
444 "unrecognized --observe option syntax. "
445 "Use --observe[=<port number>[/<bind address>]]\n");
446 return false;
447 }
448
449
450 vm_options->AddArgument("--pause-isolates-on-exit");
451 vm_options->AddArgument("--pause-isolates-on-unhandled-exceptions");
452 vm_options->AddArgument("--profiler");
453 vm_options->AddArgument("--warn-on-pause-with-no-debugger");
454 vm_options->AddArgument("--timeline-streams=\"Compiler,Dart,GC\"");
455#if !defined(DART_PRECOMPILED_RUNTIME)
457#endif
458 enable_vm_service_ = true;
459 return true;
460#else
461
462 return false;
463#endif
464}
465
466
467bool Options::ProcessVMDebuggingOptions(const char* arg,
468 CommandLineOptions* vm_options) {
469#define IS_DEBUG_OPTION(name, arg) \
470 if (strncmp(name, arg, strlen(name)) == 0) { \
471 vm_options->AddArgument(arg); \
472 return true; \
473 }
474
475
476
477
478
479
480
481#define HANDLE_DARTDEV_VM_DEBUG_OPTIONS(V, arg) \
482 V("--enable-asserts", arg) \
483 V("--pause-isolates-on-exit", arg) \
484 V("--no-pause-isolates-on-exit", arg) \
485 V("--pause-isolates-on-start", arg) \
486 V("--no-pause-isolates-on-start", arg) \
487 V("--pause-isolates-on-unhandled-exception", arg) \
488 V("--no-pause-isolates-on-unhandled-exception", arg) \
489 V("--warn-on-pause-with-no-debugger", arg) \
490 V("--no-warn-on-pause-with-no-debugger", arg) \
491 V("--timeline-streams", arg) \
492 V("--timeline-recorder", arg) \
493 V("--enable-experiment", arg)
495
496#undef IS_DEBUG_OPTION
497#undef HANDLE_DARTDEV_VM_DEBUG_OPTIONS
498
499 return false;
500}
501
502bool Options::ParseArguments(int argc,
503 char** argv,
504 bool vm_run_app_snapshot,
505 CommandLineOptions* vm_options,
506 char** script_name,
507 CommandLineOptions* dart_options,
508 bool* print_flags_seen,
509 bool* verbose_debug_seen) {
510
511 Platform::SetExecutableName(argv[0]);
512
513
514 int i = 1;
515
516 CommandLineOptions temp_vm_options(vm_options->max_count());
517
518 bool enable_dartdev_analytics = false;
519 bool disable_dartdev_analytics = false;
520 char* packages_argument = nullptr;
521
522
523 while (i < argc) {
524 bool skipVmOption = false;
525 if (!OptionProcessor::TryProcess(argv[i], &temp_vm_options)) {
526
527 if (!OptionProcessor::IsValidFlag(argv[i])) {
528 break;
529 }
530
531
532 if (
IsOption(argv[i],
"print-flags")) {
533 *print_flags_seen = true;
534 }
else if (
IsOption(argv[i],
"verbose-debug")) {
535 *verbose_debug_seen = true;
536 }
else if (
IsOption(argv[i],
"enable-analytics")) {
537 enable_dartdev_analytics = true;
538 skipVmOption = true;
539 }
else if (
IsOption(argv[i],
"disable-analytics")) {
540 disable_dartdev_analytics = true;
541 skipVmOption = true;
542 }
else if (
IsOption(argv[i],
"disable-telemetry")) {
543 disable_dartdev_analytics = true;
544 skipVmOption = true;
545 }
else if (
IsOption(argv[i],
"no-analytics")) {
546
547
548 dart_options->AddArgument("--no-analytics");
549 skipVmOption = true;
550 }
else if (
IsOption(argv[i],
"dds")) {
551
552
553
554 skipVmOption = true;
555 }
else if (
IsOption(argv[i],
"serve-observatory")) {
556
557
558
559 skipVmOption = true;
560 }
else if (
IsOption(argv[i],
"print-dtd-uri")) {
561 skipVmOption = true;
562 }
563 if (!skipVmOption) {
564 temp_vm_options.AddArgument(argv[i]);
565 }
566 }
567 if (
IsOption(argv[i],
"packages")) {
568 packages_argument =
argv[i];
569 }
570 i++;
571 }
572
573#if !defined(DART_PRECOMPILED_RUNTIME)
574 Options::dfe()->set_use_dfe();
575#else
576
577 Options::disable_dart_dev_ = true;
578#endif
579 if (Options::deterministic()) {
580
581 temp_vm_options.AddArgument("--deterministic");
582 }
583
584 Socket::set_short_socket_read(Options::short_socket_read());
585 Socket::set_short_socket_write(Options::short_socket_write());
586#if !defined(DART_IO_SECURE_SOCKET_DISABLED)
587 SSLCertContext::set_root_certs_file(Options::root_certs_file());
588 SSLCertContext::set_root_certs_cache(Options::root_certs_cache());
589 SSLCertContext::set_long_ssl_cert_evaluation(
590 Options::long_ssl_cert_evaluation());
591 SSLCertContext::set_bypass_trusting_system_roots(
592 Options::bypass_trusting_system_roots());
593#endif
594
595 FileSystemWatcher::set_delayed_filewatch_callback(
596 Options::delayed_filewatch_callback());
597
598
599 Platform::SetExecutableArguments(i, argv);
600
601 bool implicitly_use_dart_dev = false;
602 bool run_script = false;
603
604 if (i < argc) {
605#if !defined(DART_PRECOMPILED_RUNTIME)
606
607
608
609
610 bool is_potential_file_path = !DartDevIsolate::ShouldParseCommand(argv[i]);
611#else
612 bool is_potential_file_path = true;
613#endif
614 if (Options::disable_dart_dev() ||
615 (Options::snapshot_filename() != nullptr) ||
616 (is_potential_file_path && !enable_vm_service_)) {
617 *script_name = Utils::StrDup(argv[i]);
618 run_script = true;
619 i++;
620 }
621#if !defined(DART_PRECOMPILED_RUNTIME)
622 else {
623 DartDevIsolate::set_should_run_dart_dev(true);
624 }
625 if (!Options::disable_dart_dev() && enable_vm_service_) {
626
627
628
629
630 if (is_potential_file_path) {
631 implicitly_use_dart_dev = true;
632 }
633 }
634#endif
635 }
636#if !defined(DART_PRECOMPILED_RUNTIME)
637 else if (!Options::disable_dart_dev()) {
638
639
640
641
642 if (((Options::help_option() && !Options::verbose_option()) ||
643 (argc == 1))) {
644 DartDevIsolate::set_should_run_dart_dev(true);
645
646 dart_options->AddArgument("help");
647 return true;
648 }
649
650
651 else if (enable_dartdev_analytics || disable_dartdev_analytics) {
652
653
654 DartDevIsolate::set_should_run_dart_dev(true);
655 dart_options->AddArgument(enable_dartdev_analytics
656 ? "--enable-analytics"
657 : "--disable-analytics");
658 return true;
659 }
660
661
662
663 else if (!Options::help_option() && !Options::version_option()) {
664 DartDevIsolate::PrintUsageErrorOnRun();
665 return true;
666 }
667 return false;
668 }
669#endif
670
671 else {
672 return false;
673 }
674 USE(enable_dartdev_analytics);
675 USE(disable_dartdev_analytics);
676 USE(packages_argument);
677
678 const char** vm_argv = temp_vm_options.arguments();
679 int vm_argc = temp_vm_options.count();
680
681 vm_options->AddArguments(vm_argv, vm_argc);
682
683
684
685 if (!run_script) {
686 int tmp_i = i;
687
688
689
690 if (!implicitly_use_dart_dev) {
691 tmp_i++;
692 }
693 while (tmp_i < argc) {
694
695
696 if (!OptionProcessor::IsValidFlag(argv[tmp_i]) &&
697 !OptionProcessor::IsValidShortFlag(argv[tmp_i])) {
698 break;
699 }
700 OptionProcessor::TryProcess(argv[tmp_i], vm_options);
701 tmp_i++;
702 }
703 }
704 bool first_option = true;
705
706 while (i < argc) {
707 if (implicitly_use_dart_dev && first_option) {
708
709
710
711 dart_options->AddArgument("run");
712 } else {
713
714
715
716 if (!
IsOption(argv[i],
"observe") &&
717 !
IsOption(argv[i],
"enable-vm-service")) {
718 dart_options->AddArgument(argv[i]);
719 }
720 i++;
721 }
722
723 if (first_option) {
724
725
726
728 if (!run_command && strcmp(argv[i - 1], "run") == 0) {
730 }
731#if !defined(DART_PRECOMPILED_RUNTIME)
732
733 if (DartDevIsolate::should_run_dart_dev() &&
734 packages_argument != nullptr) {
735 dart_options->AddArgument(packages_argument);
736 }
737#endif
738 first_option = false;
739 }
740 }
741
742
743
744
745 if ((snapshot_deps_filename_ != nullptr) && (depfile_ != nullptr)) {
746 Syslog::PrintErr("Specify only one of --depfile and --snapshot_depfile\n");
747 return false;
748 }
749 if (snapshot_deps_filename_ != nullptr) {
750 depfile_ = snapshot_deps_filename_;
751 snapshot_deps_filename_ = nullptr;
752 }
753
754 if ((packages_file_ != nullptr) && (strlen(packages_file_) == 0)) {
755 Syslog::PrintErr("Empty package file name specified.\n");
756 return false;
757 }
758 if ((gen_snapshot_kind_ !=
kNone) && (snapshot_filename_ ==
nullptr)) {
759 Syslog::PrintErr(
760 "Generating a snapshot requires a filename (--snapshot).\n");
761 return false;
762 }
763 if ((gen_snapshot_kind_ ==
kNone) && (depfile_ !=
nullptr) &&
764 (snapshot_filename_ == nullptr) &&
765 (depfile_output_filename_ == nullptr)) {
766 Syslog::PrintErr(
767 "Generating a depfile requires an output filename"
768 " (--depfile-output-filename or --snapshot).\n");
769 return false;
770 }
771 if ((gen_snapshot_kind_ !=
kNone) && vm_run_app_snapshot) {
772 Syslog::PrintErr(
773 "Specifying an option to generate a snapshot and"
774 " run using a snapshot is invalid.\n");
775 return false;
776 }
777
778
779 if ((snapshot_filename_ !=
nullptr) && (gen_snapshot_kind_ ==
kNone)) {
781 }
782
783 return true;
784}
785
786}
787}
void set_use_incremental_compiler(bool value)
DART_EXPORT const char * Dart_VersionString(void)
DART_EXPORT DART_WARN_UNUSED_RESULT char * Dart_SetVMFlags(int argc, const char **argv)
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
const uint8_t uint32_t uint32_t GError ** error
#define HANDLE_DARTDEV_VM_DEBUG_OPTIONS(V, arg)
#define IS_DEBUG_OPTION(name, arg)
#define CB_OPTION_DEFINITION(callback)
#define CB_OPTIONS_LIST(V)
static bool IsOption(const char *arg, const char *option)
static void hot_reload_rollback_test_mode_callback(CommandLineOptions *vm_options)
static void hot_reload_test_mode_callback(CommandLineOptions *vm_options)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service port
#define DEFINE_STRING_OPTION_CB(name, callback)
#define DEFINE_BOOL_OPTION_CB(name, callback)