Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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 CommandLineOptions* vm_options,
506 char** script_name,
507 CommandLineOptions* dart_options,
508 bool* print_flags_seen,
509 bool* verbose_debug_seen) {
510 // Store the executable name.
512
513 // Start the rest after the executable name.
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 // Parse out the vm options.
523 while (i < argc) {
524 bool skipVmOption = false;
525 if (!OptionProcessor::TryProcess(argv[i], &temp_vm_options)) {
526 // Check if this flag is a potentially valid VM flag.
528 break;
529 }
530 // The following flags are processed as DartDev flags and are not to
531 // be treated as if they are VM flags.
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 // Just add this option even if we don't go to dartdev.
547 // It is irrelevant for the vm.
548 dart_options->AddArgument("--no-analytics");
549 skipVmOption = true;
550 } else if (IsOption(argv[i], "dds")) {
551 // This flag is set by default in dartdev, so we ignore it. --no-dds is
552 // a VM flag as disabling DDS changes how we configure the VM service,
553 // so we don't need to handle that case here.
554 skipVmOption = true;
555 } else if (IsOption(argv[i], "serve-observatory")) {
556 // This flag is currently set by default in vmservice_io.dart, so we
557 // ignore it. --no-serve-observatory is a VM flag so we don't need to
558 // handle that case here.
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)
575#else
576 // DartDev is not supported in AOT.
577 Options::disable_dart_dev_ = true;
578#endif // !defined(DART_PRECOMPILED_RUNTIME)
579 if (Options::deterministic()) {
580 // Both an embedder and VM flag.
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());
590 Options::long_ssl_cert_evaluation());
592 Options::bypass_trusting_system_roots());
593#endif // !defined(DART_IO_SECURE_SOCKET_DISABLED)
594
596 Options::delayed_filewatch_callback());
597
598 // The arguments to the VM are at positions 1 through i-1 in argv.
600
601 bool implicitly_use_dart_dev = false;
602 bool run_script = false;
603 // Get the script name.
604 if (i < argc) {
605#if !defined(DART_PRECOMPILED_RUNTIME)
606 // If the script name is a valid file or a URL, we'll run the script
607 // directly. Otherwise, this might be a DartDev command and we need to try
608 // to find the DartDev snapshot so we can forward the command and its
609 // arguments.
610 bool is_potential_file_path = !DartDevIsolate::ShouldParseCommand(argv[i]);
611#else
612 bool is_potential_file_path = true;
613#endif // !defined(DART_PRECOMPILED_RUNTIME)
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 { // NOLINT
624 }
625 if (!Options::disable_dart_dev() && enable_vm_service_) {
626 // Handle the special case where the user is running a Dart program
627 // without using a DartDev command and wants to use the VM service. Here
628 // we'll run the program using DartDev as it's used to spawn a DDS
629 // instance.
630 if (is_potential_file_path) {
631 implicitly_use_dart_dev = true;
632 }
633 }
634#endif // !defined(DART_PRECOMPILED_RUNTIME)
635 }
636#if !defined(DART_PRECOMPILED_RUNTIME)
637 else if (!Options::disable_dart_dev()) { // NOLINT
638 // Handles following invocation arguments:
639 // - dart help
640 // - dart --help
641 // - dart
642 if (((Options::help_option() && !Options::verbose_option()) ||
643 (argc == 1))) {
645 // Let DartDev handle the default help message.
646 dart_options->AddArgument("help");
647 return true;
648 }
649 // Handles cases where only analytics flags are provided. We need to start
650 // the DartDev isolate to set this state.
651 else if (enable_dartdev_analytics || disable_dartdev_analytics) { // NOLINT
652 // The analytics flags are a special case as we don't have a target script
653 // or DartDev command but we still want to launch DartDev.
655 dart_options->AddArgument(enable_dartdev_analytics
656 ? "--enable-analytics"
657 : "--disable-analytics");
658 return true;
659 }
660 // Let the VM handle '--version' and '--help --disable-dart-dev'.
661 // Otherwise, we'll launch the DartDev isolate to print its help message
662 // and set an error exit code.
663 else if (!Options::help_option() && !Options::version_option()) { // NOLINT
665 return true;
666 }
667 return false;
668 }
669#endif // !defined(DART_PRECOMPILED_RUNTIME)
670 // Handle argument parsing errors.
671 else { // NOLINT
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 // If running with dartdev, attempt to parse VM flags which are part of the
684 // dartdev command (e.g., --enable-vm-service, --observe, etc).
685 if (!run_script) {
686 int tmp_i = i;
687 // We only run the CLI implicitly if the service is enabled and the user
688 // didn't run with the 'run' command. If they did provide a command, we need
689 // to skip it here to continue parsing VM flags.
690 if (!implicitly_use_dart_dev) {
691 tmp_i++;
692 }
693 while (tmp_i < argc) {
694 // Check if this flag is a potentially valid VM flag. If not, we've likely
695 // hit a script name and are done parsing VM flags.
696 if (!OptionProcessor::IsValidFlag(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 // Parse out options to be passed to dart main.
706 while (i < argc) {
707 if (implicitly_use_dart_dev && first_option) {
708 // Special case where user enables VM service without using a dartdev
709 // run command. If 'run' is provided, it will be the first argument
710 // processed in this loop.
711 dart_options->AddArgument("run");
712 } else {
713 // dart run isn't able to parse these options properly. Since it doesn't
714 // need to use the values from these options, just strip them from the
715 // argument list passed to dart run.
716 if (!IsOption(argv[i], "observe") &&
717 !IsOption(argv[i], "enable-vm-service")) {
718 dart_options->AddArgument(argv[i]);
719 }
720 i++;
721 }
722 // Add DDS specific flags immediately after the dartdev command.
723 if (first_option) {
724 // DDS is only enabled for the run command. Make sure we don't pass DDS
725 // specific flags along with other commands, otherwise argument parsing
726 // will fail unexpectedly.
727 bool run_command = implicitly_use_dart_dev;
728 if (!run_command && strcmp(argv[i - 1], "run") == 0) {
729 run_command = true;
730 }
731#if !defined(DART_PRECOMPILED_RUNTIME)
732 // Bring any --packages option into the dartdev command
734 packages_argument != nullptr) {
735 dart_options->AddArgument(packages_argument);
736 }
737#endif // !defined(DART_PRECOMPILED_RUNTIME)
738 first_option = false;
739 }
740 }
741
742 // Verify consistency of arguments.
743
744 // snapshot_depfile is an alias for depfile. Passing them both is an error.
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)) {
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)) {
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) {
773 "Specifying an option to generate a snapshot and"
774 " run using a snapshot is invalid.\n");
775 return false;
776 }
777
778 // If --snapshot is given without --snapshot-kind, default to script snapshot.
779 if ((snapshot_filename_ != nullptr) && (gen_snapshot_kind_ == kNone)) {
780 gen_snapshot_kind_ = kKernel;
781 }
782
783 return true;
784}
785
786} // namespace bin
787} // 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()
static void PrintUsage()
static bool ParseArguments(int argc, char **argv, bool vm_run_app_snapshot, 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_OPTION_DEFINITION(flag, variable)
#define BOOL_OPTION_DEFINITION(flag, variable)
#define STRING_OPTIONS_LIST(V)
char ** argv
Definition library.h:9
#define ENUM_OPTION_DEFINITION(name, type, variable)
#define HANDLE_DARTDEV_VM_DEBUG_OPTIONS(V, arg)
#define IS_DEBUG_OPTION(name, arg)
#define SHORT_BOOL_OPTION_DEFINITION(short_name, long_name, variable)
#define CB_OPTION_DEFINITION(callback)
#define DEBUG_BOOL_OPTIONS_LIST(V)
#define ENUM_OPTIONS_LIST(V)
#define SHORT_BOOL_OPTIONS_LIST(V)
#define CB_OPTIONS_LIST(V)
static bool IsOption(const char *arg, const char *option)
static const char *const kVerbosityLevelNames[]
DFE dfe
Definition dfe.cc:59
static bool vm_run_app_snapshot
Definition main_impl.cc:71
static void hot_reload_rollback_test_mode_callback(CommandLineOptions *vm_options)
static constexpr const char * DEFAULT_VM_SERVICE_SERVER_IP
static constexpr int DEFAULT_VM_SERVICE_SERVER_PORT
static void hot_reload_test_mode_callback(CommandLineOptions *vm_options)
static constexpr int INVALID_VM_SERVICE_SERVER_PORT
static const char *const kSnapshotKindNames[]
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
#define DEFINE_STRING_OPTION_CB(name, callback)
Definition options.h:63
#define DEFINE_BOOL_OPTION_CB(name, callback)
Definition options.h:102