Flutter Engine
The Flutter Engine
main_options.cc
Go to the documentation of this file.
1// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#include "bin/main_options.h"
6
7#include <stdio.h>
8#include <stdlib.h>
9#include <string.h>
10
11#include "bin/dartdev_isolate.h"
12#include "bin/error_exit.h"
14#include "bin/options.h"
15#include "bin/platform.h"
16#include "bin/utils.h"
17#include "platform/syslog.h"
18#if !defined(DART_IO_SECURE_SOCKET_DISABLED)
20#endif // !defined(DART_IO_SECURE_SOCKET_DISABLED)
21#include "bin/socket.h"
22#include "include/dart_api.h"
23#include "platform/assert.h"
24#include "platform/globals.h"
25#include "platform/hashmap.h"
26
27namespace dart {
28namespace bin {
29
30// These strings must match the enum SnapshotKind in main_options.h.
31static const char* const kSnapshotKindNames[] = {
32 "none",
33 "kernel",
34 "app-jit",
35 nullptr,
36};
37
38// These strings must match the enum VerbosityLevel in main_options.h.
39static const char* const kVerbosityLevelNames[] = {
40 "error", "warning", "info", "all", nullptr,
41};
42
43SnapshotKind Options::gen_snapshot_kind_ = kNone;
44VerbosityLevel Options::verbosity_ = kAll;
45bool Options::enable_vm_service_ = false;
46
47#define OPTION_FIELD(variable) Options::variable##_
48
49#define STRING_OPTION_DEFINITION(name, variable) \
50 const char* OPTION_FIELD(variable) = nullptr; \
51 DEFINE_STRING_OPTION(name, OPTION_FIELD(variable))
53#undef STRING_OPTION_DEFINITION
54
55#define BOOL_OPTION_DEFINITION(name, variable) \
56 bool OPTION_FIELD(variable) = false; \
57 DEFINE_BOOL_OPTION(name, OPTION_FIELD(variable))
59#if defined(DEBUG)
61#endif
62#undef BOOL_OPTION_DEFINITION
63
64#define SHORT_BOOL_OPTION_DEFINITION(short_name, long_name, variable) \
65 bool OPTION_FIELD(variable) = false; \
66 DEFINE_BOOL_OPTION_SHORT(short_name, long_name, OPTION_FIELD(variable))
68#undef SHORT_BOOL_OPTION_DEFINITION
69
70#define ENUM_OPTION_DEFINITION(name, type, variable) \
71 DEFINE_ENUM_OPTION(name, type, OPTION_FIELD(variable))
73#undef ENUM_OPTION_DEFINITION
74
75#define CB_OPTION_DEFINITION(callback) \
76 static bool callback##Helper(const char* arg, CommandLineOptions* o) { \
77 return Options::callback(arg, o); \
78 } \
79 DEFINE_CB_OPTION(callback##Helper)
81#undef CB_OPTION_DEFINITION
82
83#if !defined(DART_PRECOMPILED_RUNTIME)
84DFE* Options::dfe_ = nullptr;
85
87#endif // !defined(DART_PRECOMPILED_RUNTIME)
88
90 // Identity reload.
91 vm_options->AddArgument("--identity_reload");
92 // Start reloading quickly.
93 vm_options->AddArgument("--reload_every=4");
94 // Reload from optimized and unoptimized code.
95 vm_options->AddArgument("--reload_every_optimized=false");
96 // Reload less frequently as time goes on.
97 vm_options->AddArgument("--reload_every_back_off");
98 // Ensure that every isolate has reloaded once before exiting.
99 vm_options->AddArgument("--check_reloaded");
100#if !defined(DART_PRECOMPILED_RUNTIME)
102#endif // !defined(DART_PRECOMPILED_RUNTIME)
103}
104
106
108 CommandLineOptions* vm_options) {
109 // Identity reload.
110 vm_options->AddArgument("--identity_reload");
111 // Start reloading quickly.
112 vm_options->AddArgument("--reload_every=4");
113 // Reload from optimized and unoptimized code.
114 vm_options->AddArgument("--reload_every_optimized=false");
115 // Reload less frequently as time goes on.
116 vm_options->AddArgument("--reload_every_back_off");
117 // Ensure that every isolate has reloaded once before exiting.
118 vm_options->AddArgument("--check_reloaded");
119 // Force all reloads to fail and execute the rollback code.
120 vm_options->AddArgument("--reload_force_rollback");
121#if !defined(DART_PRECOMPILED_RUNTIME)
123#endif // !defined(DART_PRECOMPILED_RUNTIME)
124}
125
126DEFINE_BOOL_OPTION_CB(hot_reload_rollback_test_mode,
128
130 Syslog::Print("Dart SDK version: %s\n", Dart_VersionString());
131}
132
133// clang-format off
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()) {
143"Common VM flags:\n"
144#if !defined(PRODUCT)
145"--enable-asserts\n"
146" Enable assert statements.\n"
147#endif // !defined(PRODUCT)
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 // !defined(PRODUCT)
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 {
185"Supported options:\n"
186#if !defined(PRODUCT)
187"--enable-asserts\n"
188" Enable assert statements.\n"
189#endif // !defined(PRODUCT)
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 // !defined(PRODUCT)
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 // !defined(PRODUCT)
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 // defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_ANDROID)
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";
251 char* error = Dart_SetVMFlags(1, &print_flags);
252 ASSERT(error == nullptr);
253 }
254}
255// clang-format on
256
257dart::SimpleHashMap* Options::environment_ = nullptr;
258bool Options::ProcessEnvironmentOption(const char* arg,
259 CommandLineOptions* vm_options) {
260 return OptionProcessor::ProcessEnvironmentOption(arg, vm_options,
261 &Options::environment_);
262}
263
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)) {
275 free(p->key);
276 free(p->value);
277 }
278 delete environment_;
279 environment_ = nullptr;
280 }
281}
282
283#if defined(DART_PRECOMPILED_RUNTIME)
284// Retrieves the set of arguments stored in the DART_VM_OPTIONS environment
285// variable.
286//
287// DART_VM_OPTIONS should contain a list of comma-separated options and flags
288// with no spaces. Options that support providing multiple values as
289// comma-separated lists (e.g., --timeline-streams=Dart,GC,Compiler) are not
290// supported and will cause argument parsing to fail.
291char** Options::GetEnvArguments(int* argc) {
292 ASSERT(argc != nullptr);
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 // Find the number of arguments based on the number of ','s.
305 //
306 // WARNING: this won't work for arguments that support CSVs. There's less
307 // than a handful of options that support multiple values. If we want to
308 // support this case, we need to determine a way to specify groupings of CSVs
309 // in environment variables.
310 int arg_count = 1;
311 for (int i = 0; i < n; ++i) {
312 // Ignore the last comma if it's the last character in the string.
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 // Split out the individual arguments.
327 while ((token = strtok_r(rest, ",", &rest)) != nullptr) {
328 // TODO(bkonyi): consider stripping leading/trailing whitespace from
329 // arguments.
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 // defined(DART_PRECOMPILED_RUNTIME)
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 // [option_value] has to be one of the following formats:
354 // - ""
355 // - ":8181"
356 // - "=8181"
357 // - ":8181/192.168.0.1"
358 // - "=8181/192.168.0.1"
359 // - "=8181/::1"
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;
375 *out_port = port;
376 return true;
377 }
378
379 *out_ip = slash + 1;
380 *out_port = port;
381 return true;
382}
383
384// Returns true if arg starts with the characters "--" followed by option, but
385// all '_' in the option name are treated as '-'.
386static bool IsOption(const char* arg, const char* option) {
387 if (arg[0] != '-' || arg[1] != '-') {
388 // Special case first two characters to avoid recognizing __flag.
389 return false;
390 }
391 for (int i = 0; option[i] != '\0'; i++) {
392 auto c = arg[i + 2];
393 if (c == '\0') {
394 // Not long enough.
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)
409 const char* value =
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_,
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 // !defined(DART_PRECOMPILED_RUNTIME)
425 enable_vm_service_ = true;
426 return true;
427#else
428 // VM service not available in product mode.
429 return false;
430#endif // !defined(PRODUCT)
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_,
444 "unrecognized --observe option syntax. "
445 "Use --observe[=<port number>[/<bind address>]]\n");
446 return false;
447 }
448
449 // These options should also be documented in the help message.
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 // !defined(DART_PRECOMPILED_RUNTIME)
458 enable_vm_service_ = true;
459 return true;
460#else
461 // VM service not available in product mode.
462 return false;
463#endif // !defined(PRODUCT)
464}
465
466// Explicitly handle VM flags that can be parsed by DartDev's run command.
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// This is an exhaustive set of VM flags that are accepted by 'dart run'. Flags
476// defined in main_options.h do not need to be handled here as they already
477// have handlers generated.
478//
479// NOTE: When updating this list of VM flags, be sure to make the corresponding
480// changes in pkg/dartdev/lib/src/commands/run.dart.
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
503 char** argv,
505 bool parsing_dart_vm_options,
506 CommandLineOptions* vm_options,
507 char** script_name,
508 CommandLineOptions* dart_options,
509 bool* print_flags_seen,
510 bool* verbose_debug_seen) {
511 int i = 0;
512#if !defined(DART_PRECOMPILED_RUNTIME)
513 // DART_VM_OPTIONS is only implemented for compiled executables.
514 ASSERT(!parsing_dart_vm_options);
515#endif // !defined(DART_PRECOMPILED_RUNTIME)
516 if (!parsing_dart_vm_options) {
517 // Store the executable name.
519
520 // Start the rest after the executable name.
521 i = 1;
522 }
523
524 CommandLineOptions temp_vm_options(vm_options->max_count());
525
526 bool enable_dartdev_analytics = false;
527 bool disable_dartdev_analytics = false;
528 char* packages_argument = nullptr;
529
530 // Parse out the vm options.
531 while (i < argc) {
532 bool skipVmOption = false;
533 if (!OptionProcessor::TryProcess(argv[i], &temp_vm_options)) {
534 // Check if this flag is a potentially valid VM flag.
536 break;
537 }
538 // The following flags are processed as DartDev flags and are not to
539 // be treated as if they are VM flags.
540 if (IsOption(argv[i], "print-flags")) {
541 *print_flags_seen = true;
542 } else if (IsOption(argv[i], "verbose-debug")) {
543 *verbose_debug_seen = true;
544 } else if (IsOption(argv[i], "enable-analytics")) {
545 enable_dartdev_analytics = true;
546 skipVmOption = true;
547 } else if (IsOption(argv[i], "disable-analytics")) {
548 disable_dartdev_analytics = true;
549 skipVmOption = true;
550 } else if (IsOption(argv[i], "disable-telemetry")) {
551 disable_dartdev_analytics = true;
552 skipVmOption = true;
553 } else if (IsOption(argv[i], "no-analytics")) {
554 // Just add this option even if we don't go to dartdev.
555 // It is irrelevant for the vm.
556 dart_options->AddArgument("--no-analytics");
557 skipVmOption = true;
558 } else if (IsOption(argv[i], "dds")) {
559 // This flag is set by default in dartdev, so we ignore it. --no-dds is
560 // a VM flag as disabling DDS changes how we configure the VM service,
561 // so we don't need to handle that case here.
562 skipVmOption = true;
563 } else if (IsOption(argv[i], "serve-observatory")) {
564 // This flag is currently set by default in vmservice_io.dart, so we
565 // ignore it. --no-serve-observatory is a VM flag so we don't need to
566 // handle that case here.
567 skipVmOption = true;
568 } else if (IsOption(argv[i], "print-dtd-uri")) {
569 skipVmOption = true;
570 }
571 if (!skipVmOption) {
572 temp_vm_options.AddArgument(argv[i]);
573 }
574 }
575 if (IsOption(argv[i], "packages")) {
576 packages_argument = argv[i];
577 }
578 i++;
579 }
580
581#if !defined(DART_PRECOMPILED_RUNTIME)
583#else
584 // DartDev is not supported in AOT.
585 Options::disable_dart_dev_ = true;
586#endif // !defined(DART_PRECOMPILED_RUNTIME)
587 if (Options::deterministic()) {
588 // Both an embedder and VM flag.
589 temp_vm_options.AddArgument("--deterministic");
590 }
591
592 Socket::set_short_socket_read(Options::short_socket_read());
593 Socket::set_short_socket_write(Options::short_socket_write());
594#if !defined(DART_IO_SECURE_SOCKET_DISABLED)
595 SSLCertContext::set_root_certs_file(Options::root_certs_file());
596 SSLCertContext::set_root_certs_cache(Options::root_certs_cache());
598 Options::long_ssl_cert_evaluation());
600 Options::bypass_trusting_system_roots());
601#endif // !defined(DART_IO_SECURE_SOCKET_DISABLED)
602
604 Options::delayed_filewatch_callback());
605
606 // The arguments to the VM are at positions 1 through i-1 in argv.
608
609 bool implicitly_use_dart_dev = false;
610 bool run_script = false;
611 // Get the script name.
612 if (i < argc) {
613#if !defined(DART_PRECOMPILED_RUNTIME)
614 // If the script name is a valid file or a URL, we'll run the script
615 // directly. Otherwise, this might be a DartDev command and we need to try
616 // to find the DartDev snapshot so we can forward the command and its
617 // arguments.
618 bool is_potential_file_path = !DartDevIsolate::ShouldParseCommand(argv[i]);
619#else
620 bool is_potential_file_path = true;
621#endif // !defined(DART_PRECOMPILED_RUNTIME)
622 if (Options::disable_dart_dev() ||
623 (Options::snapshot_filename() != nullptr) ||
624 (is_potential_file_path && !enable_vm_service_)) {
625 *script_name = Utils::StrDup(argv[i]);
626 run_script = true;
627 i++;
628 }
629#if !defined(DART_PRECOMPILED_RUNTIME)
630 else { // NOLINT
632 }
633 if (!Options::disable_dart_dev() && enable_vm_service_) {
634 // Handle the special case where the user is running a Dart program
635 // without using a DartDev command and wants to use the VM service. Here
636 // we'll run the program using DartDev as it's used to spawn a DDS
637 // instance.
638 if (is_potential_file_path) {
639 implicitly_use_dart_dev = true;
640 }
641 }
642#endif // !defined(DART_PRECOMPILED_RUNTIME)
643 }
644#if !defined(DART_PRECOMPILED_RUNTIME)
645 else if (!Options::disable_dart_dev()) { // NOLINT
646 // Handles following invocation arguments:
647 // - dart help
648 // - dart --help
649 // - dart
650 if (((Options::help_option() && !Options::verbose_option()) ||
651 (argc == 1))) {
653 // Let DartDev handle the default help message.
654 dart_options->AddArgument("help");
655 return true;
656 }
657 // Handles cases where only analytics flags are provided. We need to start
658 // the DartDev isolate to set this state.
659 else if (enable_dartdev_analytics || disable_dartdev_analytics) { // NOLINT
660 // The analytics flags are a special case as we don't have a target script
661 // or DartDev command but we still want to launch DartDev.
663 dart_options->AddArgument(enable_dartdev_analytics
664 ? "--enable-analytics"
665 : "--disable-analytics");
666 return true;
667 }
668 // Let the VM handle '--version' and '--help --disable-dart-dev'.
669 // Otherwise, we'll launch the DartDev isolate to print its help message
670 // and set an error exit code.
671 else if (!Options::help_option() && !Options::version_option()) { // NOLINT
673 return true;
674 }
675 return false;
676 }
677#endif // !defined(DART_PRECOMPILED_RUNTIME)
678 // Handle argument parsing errors and missing script / command name when not
679 // processing options set via DART_VM_OPTIONS.
680 else if (!parsing_dart_vm_options || Options::help_option() || // NOLINT
681 Options::version_option()) { // NOLINT
682 return false;
683 }
684 USE(enable_dartdev_analytics);
685 USE(disable_dartdev_analytics);
686 USE(packages_argument);
687
688 const char** vm_argv = temp_vm_options.arguments();
689 int vm_argc = temp_vm_options.count();
690
691 vm_options->AddArguments(vm_argv, vm_argc);
692
693#if !defined(DART_PRECOMPILED_RUNTIME)
694 // If we're parsing DART_VM_OPTIONS, there shouldn't be any script set or
695 // Dart arguments left to parse.
696 if (parsing_dart_vm_options) {
697 ASSERT(i == argc);
698 return true;
699 }
700#endif // !defined(DART_PRECOMPILED_RUNTIME)
701
702 // If running with dartdev, attempt to parse VM flags which are part of the
703 // dartdev command (e.g., --enable-vm-service, --observe, etc).
704 if (!run_script) {
705 int tmp_i = i;
706 // We only run the CLI implicitly if the service is enabled and the user
707 // didn't run with the 'run' command. If they did provide a command, we need
708 // to skip it here to continue parsing VM flags.
709 if (!implicitly_use_dart_dev) {
710 tmp_i++;
711 }
712 while (tmp_i < argc) {
713 // Check if this flag is a potentially valid VM flag. If not, we've likely
714 // hit a script name and are done parsing VM flags.
715 if (!OptionProcessor::IsValidFlag(argv[tmp_i]) &&
717 break;
718 }
719 OptionProcessor::TryProcess(argv[tmp_i], vm_options);
720 tmp_i++;
721 }
722 }
723 bool first_option = true;
724 // Parse out options to be passed to dart main.
725 while (i < argc) {
726 if (implicitly_use_dart_dev && first_option) {
727 // Special case where user enables VM service without using a dartdev
728 // run command. If 'run' is provided, it will be the first argument
729 // processed in this loop.
730 dart_options->AddArgument("run");
731 } else {
732 // dart run isn't able to parse these options properly. Since it doesn't
733 // need to use the values from these options, just strip them from the
734 // argument list passed to dart run.
735 if (!IsOption(argv[i], "observe") &&
736 !IsOption(argv[i], "enable-vm-service")) {
737 dart_options->AddArgument(argv[i]);
738 }
739 i++;
740 }
741 // Add DDS specific flags immediately after the dartdev command.
742 if (first_option) {
743 // DDS is only enabled for the run command. Make sure we don't pass DDS
744 // specific flags along with other commands, otherwise argument parsing
745 // will fail unexpectedly.
746 bool run_command = implicitly_use_dart_dev;
747 if (!run_command && strcmp(argv[i - 1], "run") == 0) {
748 run_command = true;
749 }
750#if !defined(DART_PRECOMPILED_RUNTIME)
751 // Bring any --packages option into the dartdev command
753 packages_argument != nullptr) {
754 dart_options->AddArgument(packages_argument);
755 }
756#endif // !defined(DART_PRECOMPILED_RUNTIME)
757 first_option = false;
758 }
759 }
760
761 // Verify consistency of arguments.
762
763 // snapshot_depfile is an alias for depfile. Passing them both is an error.
764 if ((snapshot_deps_filename_ != nullptr) && (depfile_ != nullptr)) {
765 Syslog::PrintErr("Specify only one of --depfile and --snapshot_depfile\n");
766 return false;
767 }
768 if (snapshot_deps_filename_ != nullptr) {
769 depfile_ = snapshot_deps_filename_;
770 snapshot_deps_filename_ = nullptr;
771 }
772
773 if ((packages_file_ != nullptr) && (strlen(packages_file_) == 0)) {
774 Syslog::PrintErr("Empty package file name specified.\n");
775 return false;
776 }
777 if ((gen_snapshot_kind_ != kNone) && (snapshot_filename_ == nullptr)) {
779 "Generating a snapshot requires a filename (--snapshot).\n");
780 return false;
781 }
782 if ((gen_snapshot_kind_ == kNone) && (depfile_ != nullptr) &&
783 (snapshot_filename_ == nullptr) &&
784 (depfile_output_filename_ == nullptr)) {
786 "Generating a depfile requires an output filename"
787 " (--depfile-output-filename or --snapshot).\n");
788 return false;
789 }
790 if ((gen_snapshot_kind_ != kNone) && vm_run_app_snapshot) {
792 "Specifying an option to generate a snapshot and"
793 " run using a snapshot is invalid.\n");
794 return false;
795 }
796
797 // If --snapshot is given without --snapshot-kind, default to script snapshot.
798 if ((snapshot_filename_ != nullptr) && (gen_snapshot_kind_ == kNone)) {
799 gen_snapshot_kind_ = kKernel;
800 }
801
802 return true;
803}
804
805} // namespace bin
806} // namespace dart
Entry * Start() const
Definition: hashmap.cc:123
Entry * Next(Entry *p) const
Definition: hashmap.cc:127
static void PrintErr(const char *format,...) PRINTF_ATTRIBUTE(1
static void Print(const char *format,...) PRINTF_ATTRIBUTE(1
static char * StrDup(const char *s)
static char * StrNDup(const char *s, intptr_t n)
const char ** arguments() const
Definition: dartutils.h:63
void AddArguments(const char **argv, int argc)
Definition: dartutils.h:77
void AddArgument(const char *argument)
Definition: dartutils.h:68
void set_use_dfe(bool value=true)
Definition: dfe.h:41
void set_frontend_filename(const char *name)
Definition: dfe.h:34
void set_use_incremental_compiler(bool value)
Definition: dfe.h:44
static bool should_run_dart_dev()
static void PrintUsageErrorOnRun()
static void set_should_run_dart_dev(bool enable)
static bool ShouldParseCommand(const char *script_uri)
static void set_delayed_filewatch_callback(bool value)
static bool TryProcess(const char *option, CommandLineOptions *options)
Definition: options.cc:34
static bool IsValidShortFlag(const char *name)
Definition: options.cc:16
static const char * ProcessOption(const char *option, const char *name)
Definition: options.cc:20
static bool ProcessEnvironmentOption(const char *arg, CommandLineOptions *vm_options, dart::SimpleHashMap **environment)
Definition: options.cc:54
static bool IsValidFlag(const char *name)
Definition: options.cc:12
static void Cleanup()
static void PrintVersion()
static DFE * dfe()
Definition: main_options.h:163
static void PrintUsage()
static bool ParseArguments(int argc, char **argv, bool vm_run_app_snapshot, bool parsing_dart_vm_options, CommandLineOptions *vm_options, char **script_name, CommandLineOptions *dart_options, bool *print_flags_seen, bool *verbose_debug_seen)
static void SetExecutableName(const char *executable_name)
Definition: platform.h:71
static void SetExecutableArguments(int script_index, char **argv)
Definition: platform.h:92
static void set_long_ssl_cert_evaluation(bool long_ssl_cert_evaluation)
static void set_bypass_trusting_system_roots(bool bypass_trusting_system_roots)
static void set_root_certs_file(const char *root_certs_file)
static void set_root_certs_cache(const char *root_certs_cache)
static void set_short_socket_read(bool short_socket_read)
Definition: socket.h:103
static void set_short_socket_write(bool short_socket_write)
Definition: socket.h:107
#define ASSERT(E)
const uint8_t uint32_t uint32_t GError ** error
uint8_t value
#define BOOL_OPTIONS_LIST(V)
#define STRING_OPTIONS_LIST(V)
Definition: gen_snapshot.cc:98
char ** argv
Definition: library.h:9
#define ENUM_OPTION_DEFINITION(name, type, variable)
Definition: main_options.cc:70
#define HANDLE_DARTDEV_VM_DEBUG_OPTIONS(V, arg)
#define IS_DEBUG_OPTION(name, arg)
#define SHORT_BOOL_OPTION_DEFINITION(short_name, long_name, variable)
Definition: main_options.cc:64
#define STRING_OPTION_DEFINITION(name, variable)
Definition: main_options.cc:49
#define BOOL_OPTION_DEFINITION(name, variable)
Definition: main_options.cc:55
#define CB_OPTION_DEFINITION(callback)
Definition: main_options.cc:75
#define DEBUG_BOOL_OPTIONS_LIST(V)
Definition: main_options.h:63
#define ENUM_OPTIONS_LIST(V)
Definition: main_options.h:71
#define SHORT_BOOL_OPTIONS_LIST(V)
Definition: main_options.h:59
#define CB_OPTIONS_LIST(V)
Definition: main_options.h:76
static bool IsOption(const char *arg, const char *option)
static const char *const kVerbosityLevelNames[]
Definition: main_options.cc:39
DEFINE_BOOL_OPTION_CB(hot_reload_test_mode, hot_reload_test_mode_callback)
DEFINE_STRING_OPTION_CB(dfe, { Options::dfe() ->set_frontend_filename(value);})
static bool ProcessEnvironmentOption(const char *arg, CommandLineOptions *vm_options)
Definition: gen_snapshot.cc:61
DFE dfe
Definition: dfe.cc:59
static bool vm_run_app_snapshot
Definition: main_impl.cc:67
static void hot_reload_rollback_test_mode_callback(CommandLineOptions *vm_options)
static constexpr const char * DEFAULT_VM_SERVICE_SERVER_IP
Definition: main_options.h:97
static constexpr int DEFAULT_VM_SERVICE_SERVER_PORT
Definition: main_options.h:98
static void hot_reload_test_mode_callback(CommandLineOptions *vm_options)
Definition: main_options.cc:89
static constexpr int INVALID_VM_SERVICE_SERVER_PORT
Definition: main_options.h:99
static const char *const kSnapshotKindNames[]
Definition: gen_snapshot.cc:86
Definition: dart_vm.cc:33
DART_EXPORT const char * Dart_VersionString()
static void USE(T &&)
Definition: globals.h:618
DART_EXPORT char * Dart_SetVMFlags(int argc, const char **argv)
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
Definition: switches.h:87