Revert "[VM/dartdev] Switch dartdev to use an AOT runtime."
This reverts commit 5399dbf6f6ed5210ed3e6474f877cf9153362f92.
Reason for revert : Flutter rolls are failing
TEST=ci
Change-Id: I76fede849705514496adbc2ab7f6c262de4103ca
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/439661
Reviewed-by: Jason Simmons <jsimmons@google.com>
Commit-Queue: Siva Annamalai <asiva@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index 25f4b6a..56c1c6a 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -42,7 +42,6 @@
deps = [
"runtime/bin:dart",
- "runtime/bin:dartvm",
"runtime/bin:ffi_test_dynamic_library",
"runtime/bin:ffi_test_functions",
"runtime/bin:process_test",
@@ -61,15 +60,12 @@
deps += [
"runtime/bin:dartaotruntime",
"runtime/bin:dartaotruntime_product",
- "utils/dartdev:dartdev_aot_snapshot",
"utils/dds:dds_aot",
- "utils/dtd:dtd_aot",
"utils/kernel-service:frontend_server_aot_product",
]
} else {
deps += [
"utils/dds:dds",
- "utils/dtd:dtd",
"utils/kernel-service:frontend_server",
]
}
@@ -424,7 +420,7 @@
}
test_binaries = [
- "dartvm",
+ "dart",
"dartaotruntime",
"run_vm_tests",
]
diff --git a/CHANGELOG.md b/CHANGELOG.md
index de6d293..9317c2a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -83,25 +83,6 @@
[cross-compilation]: https://dart.dev/tools/dart-compile#cross-compilation-exe
-#### Dart CLI and Dart VM
-
-- The Dart CLI and Dart VM have been split into two seperate executables.
-
- The Dart CLI tool has been split out of the VM into it's own embedder which
- runs in AOT mode. The pure Dart VM executable is called `dartvm` and
- has no Dart CLI functionality in it
-
- The Dart CLI executable parses the CLI commands and invokes the rest
- of the AOT tools in the same process, for the 'run' and 'test'
- commands it execs a process which runs `dartvm`
-
- `dart hello.dart` execs the `dartvm` process and runs 'hello.dart'
-
- The Dart CLI is not generated for ia32 as we are not shipping a
- Dart SDK for ia32 anymore (support to execute the `dartvm` for ia32
- architecture is retained)
-
-
#### Pub
- Git dependencies can now be version-solved based on git tags.
diff --git a/build/dart/dart_action.gni b/build/dart/dart_action.gni
index 8f75a32..7b5d40c 100644
--- a/build/dart/dart_action.gni
+++ b/build/dart/dart_action.gni
@@ -10,7 +10,7 @@
# - prebuilt_dart_action()
# Runs Dart scripts using the downloaded prebuilt Dart SDK. This is the
# preferred method of running Dart code during the build as it is much
-# faster than using dartvm_action() in debug and cross builds.
+# faster than using dart_action() in debug and cross builds.
# However, prebuilt_dart_action() should *not* be used to generate snapshots.
#
# - prebuilt_dartaotruntime_action()
@@ -18,7 +18,7 @@
# preferred method of running Dart AOT code during the build as it avoids
# the multiple layers of code that prebuilt_dart_action goes through.
#
-# - dartvm_action()
+# - dart_action()
# Runs Dart scripts using the binary built for runtime/bin:dart using the
# host toolchain. It should only be used when an artifact agreeing exactly
# with the version of the Dart VM being built must be produced, for example
@@ -350,10 +350,10 @@
# outputs
# testonly
# visibility
-template("dartvm_action") {
+template("dart_action") {
assert(defined(invoker.script), "script must be defined for $target_name")
_built_tool_action(target_name) {
- tool = "$_dart_root/runtime/bin:dartvm"
+ tool = "$_dart_root/runtime/bin:dart"
forward_variables_from(invoker,
[
"args",
diff --git a/build/rbe/rewrapper_dart.py b/build/rbe/rewrapper_dart.py
index e81969d..11dfbd6 100644
--- a/build/rbe/rewrapper_dart.py
+++ b/build/rbe/rewrapper_dart.py
@@ -269,9 +269,6 @@
elif arg.endswith('/dart'):
self.dart_subdir = os.path.dirname(arg)
return self.parse_dart()
- elif arg.endswith('/dartvm'):
- self.dart_subdir = os.path.dirname(arg)
- return self.parse_dart()
elif arg.endswith('/dartaotruntime'):
self.dart_subdir = os.path.dirname(arg)
return self.parse_dartaotruntime()
diff --git a/pkg/analysis_server/integration_test/analysis/get_errors_non_standard_sdk_test.dart b/pkg/analysis_server/integration_test/analysis/get_errors_non_standard_sdk_test.dart
index 4903ad8..d57a211 100644
--- a/pkg/analysis_server/integration_test/analysis/get_errors_non_standard_sdk_test.dart
+++ b/pkg/analysis_server/integration_test/analysis/get_errors_non_standard_sdk_test.dart
@@ -27,11 +27,6 @@
return path.join(sdkPath, 'bin', name);
}
- String executableVmFilePathIn(String sdkPath) {
- var name = Platform.isWindows ? 'dartvm.exe' : 'dartvm';
- return path.join(sdkPath, 'bin', name);
- }
-
String serverSnapshotPathIn(String sdkPath) {
return path.join(
sdkPath,
@@ -56,10 +51,6 @@
).copySync(executableFilePathIn(sdkPath));
File(
- executableVmFilePathIn(standardSdkPath),
- ).copySync(executableVmFilePathIn(sdkPath));
-
- File(
serverSnapshotPathIn(standardSdkPath),
).copySync(serverSnapshotPathIn(sdkPath));
diff --git a/pkg/dartdev/lib/src/commands/compile.dart b/pkg/dartdev/lib/src/commands/compile.dart
index 7a55052..ab36839 100644
--- a/pkg/dartdev/lib/src/commands/compile.dart
+++ b/pkg/dartdev/lib/src/commands/compile.dart
@@ -98,12 +98,19 @@
}
final args = argResults!;
var snapshot = sdk.dart2jsAotSnapshot;
+ var script = sdk.dartAotRuntime;
+ var useExecProcess = true;
if (!Sdk.checkArtifactExists(snapshot, logError: false)) {
- log.stderr('Error: JS compilation failed');
- log.stderr('Unable to find $snapshot');
- return compileErrorExitCode;
+ // AOT snapshots cannot be generated on IA32, so we need this fallback
+ // branch until support for IA32 is dropped (https://dartbug.com/49969).
+ script = sdk.dart2jsSnapshot;
+ if (!Sdk.checkArtifactExists(script)) {
+ return genericErrorExitCode;
+ }
+ useExecProcess = false;
}
final dart2jsCommand = [
+ if (useExecProcess) snapshot,
'--libraries-spec=${sdk.librariesJson}',
'--cfe-invocation-modes=compile',
'--invoker=dart_cli',
@@ -112,10 +119,10 @@
];
try {
VmInteropHandler.run(
- snapshot,
+ script,
dart2jsCommand,
packageConfigOverride: null,
- useExecProcess: false,
+ useExecProcess: useExecProcess,
);
return 0;
} catch (e, st) {
@@ -156,21 +163,28 @@
}
final args = argResults!;
var snapshot = sdk.ddcAotSnapshot;
+ var script = sdk.dartAotRuntime;
+ var useExecProcess = true;
if (!Sdk.checkArtifactExists(snapshot, logError: false)) {
- log.stderr('Error: JS compilation failed');
- log.stderr('Unable to find $snapshot');
- return compileErrorExitCode;
+ // AOT snapshots cannot be generated on IA32, so we need this fallback
+ // branch until support for IA32 is dropped (https://dartbug.com/49969).
+ script = sdk.ddcSnapshot;
+ if (!Sdk.checkArtifactExists(script)) {
+ return genericErrorExitCode;
+ }
+ useExecProcess = false;
}
final ddcCommand = <String>[
+ if (useExecProcess) snapshot,
// Add the remaining arguments.
if (args.rest.isNotEmpty) ...args.rest.sublist(0),
];
try {
VmInteropHandler.run(
- snapshot,
+ script,
ddcCommand,
packageConfigOverride: null,
- useExecProcess: false,
+ useExecProcess: useExecProcess,
);
return 0;
} catch (e, st) {
@@ -445,7 +459,7 @@
log.stdout('Compiling $sourcePath to jit-snapshot file $outputFile.');
// TODO(bkonyi): perform compilation in same process.
- return await runProcess([sdk.dartvm, ...buildArgs]);
+ return await runProcess([sdk.dart, ...buildArgs]);
}
}
diff --git a/pkg/dartdev/lib/src/commands/dart_mcp_server.dart b/pkg/dartdev/lib/src/commands/dart_mcp_server.dart
index 8d6f6ca..142c375 100644
--- a/pkg/dartdev/lib/src/commands/dart_mcp_server.dart
+++ b/pkg/dartdev/lib/src/commands/dart_mcp_server.dart
@@ -51,11 +51,12 @@
}
try {
VmInteropHandler.run(
- sdk.dartMCPServerAotSnapshot,
+ sdk.dartAotRuntime,
[
+ sdk.dartMCPServerAotSnapshot,
...forwardedArgs,
],
- useExecProcess: false,
+ useExecProcess: true,
);
return 0;
} catch (e, st) {
diff --git a/pkg/dartdev/lib/src/commands/development_service.dart b/pkg/dartdev/lib/src/commands/development_service.dart
index bf80eba..f640da4 100644
--- a/pkg/dartdev/lib/src/commands/development_service.dart
+++ b/pkg/dartdev/lib/src/commands/development_service.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
+import 'dart:io';
import 'package:dds/src/arg_parser.dart';
import 'package:path/path.dart';
@@ -36,22 +37,38 @@
Future<int> run() async {
final sdkDir = dirname(sdk.dart);
final fullSdk = sdkDir.endsWith('bin');
+ var script = fullSdk
+ ? sdk.dartAotRuntime
+ : absolute(sdkDir, 'dartaotruntime${Platform.isWindows ? '.exe' : ''}');
var snapshot = fullSdk
? sdk.ddsAotSnapshot
: absolute(sdkDir, 'dds_aot.dart.snapshot');
+ var useExecProcess = true;
final args = argResults!.arguments;
if (!Sdk.checkArtifactExists(snapshot, logError: false)) {
- log.stderr('Error: launching development server failed : '
- 'Unable to find snapshot for the development server');
- return 255;
+ // On ia32 platforms we do not have an AOT snapshot and so we need
+ // to run the JIT snapshot.
+ useExecProcess = false;
+ script =
+ fullSdk ? sdk.ddsSnapshot : absolute(sdkDir, 'dds.dart.snapshot');
+ if (!Sdk.checkArtifactExists(script, logError: false)) {
+ log.stderr('Error: launching development server failed : '
+ 'Unable to find snapshot for the development server');
+ return 255;
+ }
}
+ final ddsCommand = [
+ if (useExecProcess) snapshot,
+ // Add the remaining args.
+ if (args.isNotEmpty) ...args,
+ ];
try {
VmInteropHandler.run(
- snapshot,
- args,
+ script,
+ ddsCommand,
packageConfigOverride: null,
- useExecProcess: false,
+ useExecProcess: useExecProcess,
);
return 0;
} catch (e, st) {
diff --git a/pkg/dartdev/lib/src/commands/language_server.dart b/pkg/dartdev/lib/src/commands/language_server.dart
index f4d95d2..9c446db 100644
--- a/pkg/dartdev/lib/src/commands/language_server.dart
+++ b/pkg/dartdev/lib/src/commands/language_server.dart
@@ -54,27 +54,26 @@
args = [...args, '--$protocol=$lsp'];
}
try {
- var script = sdk.analysisServerAotSnapshot;
- var useExec = false;
if (argResults!.flag(useAotSnapshotFlag)) {
- if (!Sdk.checkArtifactExists(sdk.analysisServerAotSnapshot)) {
- log.stderr('Error: launching language analysis server failed');
- log.stderr('${sdk.analysisServerAotSnapshot} not found');
+ if (!Sdk.checkArtifactExists(sdk.dartAotRuntime)) {
return _genericErrorExitCode;
}
args = [...args];
args.remove('--$useAotSnapshotFlag');
+ VmInteropHandler.run(
+ sdk.dartAotRuntime,
+ [sdk.analysisServerAotSnapshot, ...args],
+ useExecProcess: true,
+ );
} else {
args = [...args];
args.remove('--no-$useAotSnapshotFlag');
- script = sdk.analysisServerSnapshot;
- useExec = true;
+ VmInteropHandler.run(
+ sdk.analysisServerSnapshot,
+ args,
+ useExecProcess: false,
+ );
}
- VmInteropHandler.run(
- script,
- args,
- useExecProcess: useExec,
- );
return 0;
} catch (e, st) {
log.stderr('Error: launching language analysis server failed');
@@ -82,7 +81,7 @@
if (verbose) {
log.stderr(st.toString());
}
- return _genericErrorExitCode;
+ return 255;
}
}
diff --git a/pkg/dartdev/lib/src/commands/run.dart b/pkg/dartdev/lib/src/commands/run.dart
index b897714..1035d4b 100644
--- a/pkg/dartdev/lib/src/commands/run.dart
+++ b/pkg/dartdev/lib/src/commands/run.dart
@@ -25,6 +25,7 @@
import 'compilation_server.dart';
class RunCommand extends DartdevCommand {
+ static const bool isProductMode = bool.fromEnvironment('dart.vm.product');
static const String cmdName = 'run';
// kErrorExitCode, as defined in runtime/bin/error_exit.h
@@ -91,101 +92,109 @@
argParser.addSeparator(
'Debugging options:',
);
- argParser
- ..addOption(
- 'observe',
- help: 'The observe flag is a convenience flag used to run a program '
- 'with a set of common options useful for debugging. '
- 'Run `dart help -v run` for details.',
- valueHelp: '[<port>[/<bind-address>]]',
- )
- ..addFlag(
- 'enable-asserts',
- help: 'Enable assert statements.',
- )
- ..addOption(
- 'launch-dds',
- hide: true,
- help: 'Launch DDS.',
- );
+ if (!isProductMode) {
+ argParser
+ ..addOption(
+ 'observe',
+ help: 'The observe flag is a convenience flag used to run a program '
+ 'with a set of common options useful for debugging. '
+ 'Run `dart help -v run` for details.',
+ valueHelp: '[<port>[/<bind-address>]]',
+ )
+ ..addFlag(
+ 'enable-asserts',
+ help: 'Enable assert statements.',
+ )
+ ..addOption(
+ 'launch-dds',
+ hide: true,
+ help: 'Launch DDS.',
+ );
- if (verbose) {
- argParser.addSeparator(
- verbose ? 'Options implied by --observe are currently:' : '');
- }
- argParser
- ..addOption(
- 'enable-vm-service',
- help: 'Enables the VM service and listens on the specified port for '
- 'connections (default port number is 8181, default bind address '
- 'is localhost).',
- valueHelp: '[<port>[/<bind-address>]]',
- hide: !verbose,
- )
- ..addFlag(
- 'serve-devtools',
- help: 'Serves an instance of the Dart DevTools debugger and profiler '
- 'via the VM service at <vm-service-uri>/devtools.',
- defaultsTo: true,
- hide: !verbose,
- )
- ..addFlag(
- 'pause-isolates-on-exit',
- help: 'Pause isolates on exit when '
- 'running with --enable-vm-service.',
- hide: !verbose,
- )
- ..addFlag(
- 'pause-isolates-on-unhandled-exceptions',
- help: 'Pause isolates when an unhandled exception is encountered '
- 'when running with --enable-vm-service.',
- hide: !verbose,
- )
- ..addFlag(
- 'warn-on-pause-with-no-debugger',
- help:
- 'Print a warning when an isolate pauses with no attached debugger'
- ' when running with --enable-vm-service.',
- hide: !verbose,
- )
- ..addOption(
- 'timeline-streams',
- help: 'Enables recording for specific timeline streams.\n'
- 'Valid streams include: all, API, Compiler, CompilerVerbose, Dart, '
- 'Debugger, Embedder, GC, Isolate, Microtask, VM.\n'
- 'Defaults to "Compiler, Dart, GC, Microtask" when --observe is '
- 'provided.',
- valueHelp: 'str1, str2, ...',
- hide: !verbose,
- );
+ if (verbose) {
+ argParser.addSeparator(
+ verbose ? 'Options implied by --observe are currently:' : '');
+ }
+ argParser
+ ..addOption(
+ 'enable-vm-service',
+ help: 'Enables the VM service and listens on the specified port for '
+ 'connections (default port number is 8181, default bind address '
+ 'is localhost).',
+ valueHelp: '[<port>[/<bind-address>]]',
+ hide: !verbose,
+ )
+ ..addFlag(
+ 'serve-devtools',
+ help: 'Serves an instance of the Dart DevTools debugger and profiler '
+ 'via the VM service at <vm-service-uri>/devtools.',
+ defaultsTo: true,
+ hide: !verbose,
+ )
+ ..addFlag(
+ 'pause-isolates-on-exit',
+ help: 'Pause isolates on exit when '
+ 'running with --enable-vm-service.',
+ hide: !verbose,
+ )
+ ..addFlag(
+ 'pause-isolates-on-unhandled-exceptions',
+ help: 'Pause isolates when an unhandled exception is encountered '
+ 'when running with --enable-vm-service.',
+ hide: !verbose,
+ )
+ ..addFlag(
+ 'warn-on-pause-with-no-debugger',
+ help:
+ 'Print a warning when an isolate pauses with no attached debugger'
+ ' when running with --enable-vm-service.',
+ hide: !verbose,
+ )
+ ..addOption(
+ 'timeline-streams',
+ help: 'Enables recording for specific timeline streams.\n'
+ 'Valid streams include: all, API, Compiler, CompilerVerbose, Dart, '
+ 'Debugger, Embedder, GC, Isolate, Microtask, VM.\n'
+ 'Defaults to "Compiler, Dart, GC, Microtask" when --observe is '
+ 'provided.',
+ valueHelp: 'str1, str2, ...',
+ hide: !verbose,
+ );
- if (verbose) {
- argParser.addSeparator('Other debugging options:');
+ if (verbose) {
+ argParser.addSeparator('Other debugging options:');
+ }
+ argParser
+ ..addFlag(
+ 'pause-isolates-on-start',
+ help: 'Pause isolates on start when '
+ 'running with --enable-vm-service.',
+ hide: !verbose,
+ )
+ ..addOption(
+ 'timeline-recorder',
+ help: 'Selects the timeline recorder to use.\n'
+ 'Valid recorders include: none, ring, endless, startup, '
+ 'systrace, file, callback, perfettofile.\n'
+ 'Defaults to ring.',
+ valueHelp: 'recorder',
+ hide: !verbose,
+ )
+ ..addFlag(
+ 'profile-microtasks',
+ hide: !verbose,
+ negatable: false,
+ help: 'Record information about each microtask. Information about '
+ 'completed microtasks will be written to the "Microtask" '
+ 'timeline stream.',
+ );
+ } else {
+ argParser.addOption('timeline-recorder',
+ help: 'Selects the timeline recorder to use.\n'
+ 'Valid recorders include: none, systrace, file, callback.\n'
+ 'Defaults to none.',
+ valueHelp: 'recorder');
}
- argParser
- ..addFlag(
- 'pause-isolates-on-start',
- help: 'Pause isolates on start when '
- 'running with --enable-vm-service.',
- hide: !verbose,
- )
- ..addOption(
- 'timeline-recorder',
- help: 'Selects the timeline recorder to use.\n'
- 'Valid recorders include: none, ring, endless, startup, '
- 'systrace, file, callback, perfettofile.\n'
- 'Defaults to ring.',
- valueHelp: 'recorder',
- hide: !verbose,
- )
- ..addFlag(
- 'profile-microtasks',
- hide: !verbose,
- negatable: false,
- help: 'Record information about each microtask. Information about '
- 'completed microtasks will be written to the "Microtask" '
- 'timeline stream.',
- );
argParser.addSeparator('Logging options:');
argParser.addOption(
@@ -206,24 +215,26 @@
help: 'Define an environment declaration.',
hide: !verbose,
);
- argParser
- ..addFlag(
- 'disable-service-auth-codes',
- hide: !verbose,
- negatable: false,
- help: 'Disables the requirement for an authentication code to '
- 'communicate with the VM service. Authentication codes help '
- 'protect against CSRF attacks, so it is not recommended to '
- 'disable them unless behind a firewall on a secure device.',
- )
- ..addFlag(
- 'enable-service-port-fallback',
- hide: !verbose,
- negatable: false,
- help: 'When the VM service is told to bind to a particular port, '
- 'fallback to 0 if it fails to bind instead of failing to '
- 'start.',
- );
+ if (!isProductMode) {
+ argParser
+ ..addFlag(
+ 'disable-service-auth-codes',
+ hide: !verbose,
+ negatable: false,
+ help: 'Disables the requirement for an authentication code to '
+ 'communicate with the VM service. Authentication codes help '
+ 'protect against CSRF attacks, so it is not recommended to '
+ 'disable them unless behind a firewall on a secure device.',
+ )
+ ..addFlag(
+ 'enable-service-port-fallback',
+ hide: !verbose,
+ negatable: false,
+ help: 'When the VM service is told to bind to a particular port, '
+ 'fallback to 0 if it fails to bind instead of failing to '
+ 'start.',
+ );
+ }
argParser
..addOption(
'namespace',
@@ -260,38 +271,40 @@
'supplies a mapping of package names\ninto paths.',
);
- argParser
- ..addOption(
- 'write-service-info',
- help: 'Outputs information necessary to connect to the VM service to '
- 'specified file in JSON format. Useful for clients which are '
- 'unable to listen to stdout for the Dart VM service listening '
- 'message.',
- valueHelp: 'file',
- hide: !verbose,
- )
- ..addFlag('dds',
+ if (!isProductMode) {
+ argParser
+ ..addOption(
+ 'write-service-info',
+ help: 'Outputs information necessary to connect to the VM service to '
+ 'specified file in JSON format. Useful for clients which are '
+ 'unable to listen to stdout for the Dart VM service listening '
+ 'message.',
+ valueHelp: 'file',
hide: !verbose,
- help:
- 'Use the Dart Development Service (DDS) for enhanced debugging '
- 'functionality. Note: Disabling DDS may break some '
- 'functionality in IDEs and other tooling.',
- defaultsTo: true)
- ..addFlag('serve-observatory',
+ )
+ ..addFlag('dds',
+ hide: !verbose,
+ help:
+ 'Use the Dart Development Service (DDS) for enhanced debugging '
+ 'functionality. Note: Disabling DDS may break some '
+ 'functionality in IDEs and other tooling.',
+ defaultsTo: true)
+ ..addFlag('serve-observatory',
+ hide: !verbose,
+ help: 'Enable hosting Observatory through the VM Service.',
+ defaultsTo: true)
+ ..addFlag(
+ 'print-dtd',
hide: !verbose,
- help: 'Enable hosting Observatory through the VM Service.',
- defaultsTo: true)
- ..addFlag(
- 'print-dtd',
- hide: !verbose,
- help: 'Prints connection details for the Dart Tooling Daemon (DTD).'
- 'Useful for Dart DevTools extension authors working with DTD in the '
- 'extension development environment.',
- )
- ..addFlag(
- 'debug-dds',
- hide: true,
- );
+ help: 'Prints connection details for the Dart Tooling Daemon (DTD).'
+ 'Useful for Dart DevTools extension authors working with DTD in the '
+ 'extension development environment.',
+ )
+ ..addFlag(
+ 'debug-dds',
+ hide: true,
+ );
+ }
argParser.addExperimentalFlags(verbose: verbose);
}
@@ -515,7 +528,6 @@
runArgs,
packageConfigOverride:
args.option('packages') ?? executable.packageConfig,
- useExecProcess: true,
);
return 0;
}
diff --git a/pkg/dartdev/lib/src/commands/test.dart b/pkg/dartdev/lib/src/commands/test.dart
index 3698559..d08a492 100644
--- a/pkg/dartdev/lib/src/commands/test.dart
+++ b/pkg/dartdev/lib/src/commands/test.dart
@@ -112,7 +112,6 @@
testExecutable.executable,
argsRestNoExperimentOrSuppressAnalytics,
packageConfigOverride: testExecutable.packageConfig!,
- useExecProcess: true,
// TODO(bkonyi): remove once DartDev moves to AOT and this flag can be
// provided directly to the process spawned by `dart run` and
// `dart test`.
diff --git a/pkg/dartdev/lib/src/commands/tooling_daemon.dart b/pkg/dartdev/lib/src/commands/tooling_daemon.dart
index 0c09d06..59a1419 100644
--- a/pkg/dartdev/lib/src/commands/tooling_daemon.dart
+++ b/pkg/dartdev/lib/src/commands/tooling_daemon.dart
@@ -33,19 +33,28 @@
@override
Future<int> run() async {
+ var script = sdk.dartAotRuntime;
var snapshot = sdk.dtdAotSnapshot;
+ var useExecProcess = true;
final args = argResults!.arguments;
+
if (!Sdk.checkArtifactExists(sdk.dtdAotSnapshot, logError: false)) {
- log.stderr('Error: launching dart tooling daemon failed : '
- 'Unable to find snapshot for the tooling daemon');
- return 255;
+ // On ia32 platforms we do not have an AOT snapshot and so we need
+ // to run the JIT snapshot.
+ useExecProcess = false;
+ script = sdk.dtdSnapshot;
}
+ final dtdCommand = [
+ if (useExecProcess) snapshot,
+ // Add the remaining args.
+ if (args.isNotEmpty) ...args,
+ ];
try {
VmInteropHandler.run(
- snapshot,
- args,
+ script,
+ dtdCommand,
packageConfigOverride: null,
- useExecProcess : false,
+ useExecProcess: useExecProcess,
);
return 0;
} catch (e, st) {
diff --git a/pkg/dartdev/lib/src/dds_runner.dart b/pkg/dartdev/lib/src/dds_runner.dart
index b1cd2e6..f387d33 100644
--- a/pkg/dartdev/lib/src/dds_runner.dart
+++ b/pkg/dartdev/lib/src/dds_runner.dart
@@ -22,10 +22,6 @@
required bool debugDds,
required bool enableServicePortFallback,
}) async {
- void printError(String details) => stderr.writeln(
- 'Could not start the VM service:\n$details',
- );
-
final sdkDir = dirname(sdk.dart);
final fullSdk = sdkDir.endsWith('bin');
var execName = fullSdk
@@ -36,8 +32,14 @@
: absolute(sdkDir, 'dds_aot.dart.snapshot');
final isAot = Sdk.checkArtifactExists(snapshotName) ? true : false;
if (!isAot) {
- printError('Unable to find snapshot for the development server');
- return false;
+ // On ia32 sdks we do not have an AOT runtime and so we would be
+ // using the regular executable.
+ snapshotName =
+ fullSdk ? sdk.ddsSnapshot : absolute(sdkDir, 'dds.dart.snapshot');
+ if (!Sdk.checkArtifactExists(snapshotName)) {
+ return false;
+ }
+ execName = sdk.dart;
}
final process = await Process.start(
@@ -79,6 +81,10 @@
// DDS will close stderr once it's finished launching.
final launchResult = await process.stderr.transform(utf8.decoder).join();
+ void printError(String details) => stderr.writeln(
+ 'Could not start the VM service:\n$details',
+ );
+
try {
final result = json.decode(launchResult) as Map<String, dynamic>;
if (result
diff --git a/pkg/dartdev/lib/src/generate_kernel.dart b/pkg/dartdev/lib/src/generate_kernel.dart
index 6241512..b84cd60 100644
--- a/pkg/dartdev/lib/src/generate_kernel.dart
+++ b/pkg/dartdev/lib/src/generate_kernel.dart
@@ -142,7 +142,17 @@
mode: ProcessStartMode.detachedWithStdio,
);
} else {
- throw StateError('Unable to find snapshot for frontend server');
+ // AOT snapshots cannot be generated on IA32, so we need this fallback
+ // branch until support for IA32 is dropped (https://dartbug.com/49969).
+ frontendServerProcess = await Process.start(
+ sdk.dart,
+ [
+ sdk.frontendServerSnapshot,
+ '--resident-info-file-name=${serverInfoFile.absolute.path}'
+ ],
+ workingDirectory: homeDir?.path,
+ mode: ProcessStartMode.detachedWithStdio,
+ );
}
final serverOutput =
diff --git a/pkg/dartdev/lib/src/processes.dart b/pkg/dartdev/lib/src/processes.dart
index 64c3a44..3223161 100644
--- a/pkg/dartdev/lib/src/processes.dart
+++ b/pkg/dartdev/lib/src/processes.dart
@@ -289,8 +289,7 @@
}
bool _isProcessDartRelated(ProcessInfo process) {
- return process.command == 'dart' || process.command == 'dart.exe' ||
- process.command == 'dartvm' || process.command == 'dartvm.exe';
+ return process.command == 'dart' || process.command == 'dart.exe';
}
String _getCommandFrom(String commandLine) {
diff --git a/pkg/dartdev/lib/src/sdk.dart b/pkg/dartdev/lib/src/sdk.dart
index dfd73ae..845c38d 100644
--- a/pkg/dartdev/lib/src/sdk.dart
+++ b/pkg/dartdev/lib/src/sdk.dart
@@ -53,19 +53,6 @@
);
}
- String get dartvm {
- final basename = Platform.isWindows? 'dartvm.exe' : 'dartvm';
- return path.absolute(
- _runFromBuildRoot
- ? sdkPath
- : path.absolute(
- sdkPath,
- 'bin',
- ),
- basename,
- );
- }
-
String get dartAotRuntime => _runFromBuildRoot
? path.absolute(
sdkPath,
@@ -87,6 +74,10 @@
'analysis_server.dart.snapshot',
);
+ String get ddcSnapshot => _snapshotPathFor(
+ 'dartdevc.dart.snapshot',
+ );
+
String get ddcAotSnapshot => _runFromBuildRoot
? _snapshotPathFor(
'dartdevc_aot_product.dart.snapshot',
@@ -95,6 +86,10 @@
'dartdevc_aot.dart.snapshot',
);
+ String get dart2jsSnapshot => _snapshotPathFor(
+ 'dart2js.dart.snapshot',
+ );
+
String get dart2jsAotSnapshot => _runFromBuildRoot
? _snapshotPathFor(
'dart2js_aot_product.dart.snapshot',
@@ -111,10 +106,18 @@
'dart_mcp_server_aot.dart.snapshot',
);
+ String get ddsSnapshot => _snapshotPathFor(
+ 'dds.dart.snapshot',
+ );
+
String get ddsAotSnapshot => _snapshotPathFor(
'dds_aot.dart.snapshot',
);
+ String get frontendServerSnapshot => _snapshotPathFor(
+ 'frontend_server.dart.snapshot',
+ );
+
String get frontendServerAotSnapshot => _runFromBuildRoot
? _snapshotPathFor(
'frontend_server_aot_product.dart.snapshot',
@@ -123,6 +126,10 @@
'frontend_server_aot.dart.snapshot',
);
+ String get dtdSnapshot => _snapshotPathFor(
+ 'dart_tooling_daemon.dart.snapshot',
+ );
+
String get dtdAotSnapshot => _snapshotPathFor(
'dart_tooling_daemon_aot.dart.snapshot',
);
@@ -222,7 +229,7 @@
// non-standard SDK layouts that can involve symlinks (e.g., Brew
// installations, google3 tests, etc).
if (!checkArtifactExists(
- path.join(snapshotsDir, 'dartdev_aot.dart.snapshot'),
+ path.join(snapshotsDir, 'dartdev.dart.snapshot'),
logError: false,
)) {
return null;
diff --git a/pkg/dartdev/test/commands/flag_test.dart b/pkg/dartdev/test/commands/flag_test.dart
index c2814f5..42b1c87 100644
--- a/pkg/dartdev/test/commands/flag_test.dart
+++ b/pkg/dartdev/test/commands/flag_test.dart
@@ -100,10 +100,18 @@
test('print Dart CLI help on usage error', () async {
p = project();
var result = await p.run(['---help']);
- expect(result.exitCode, 64);
- expect(result.stderr, contains('Could not find an option named "---help"'));
- expectUsage(result.stderr);
- expect(result.stdout, isEmpty);
+ expect(result.exitCode, 255);
+ expect(result.stdout, contains(DartdevRunner.dartdevDescription));
+ expect(result.stderr, isEmpty);
+ });
+
+ test('print VM help on usage error when --disable-dart-dev is provided',
+ () async {
+ p = project();
+ var result = await p.run(['---help', '--disable-dart-dev']);
+ expect(result.exitCode, 255);
+ expect(result.stdout, isNot(contains(DartdevRunner.dartdevDescription)));
+ expect(result.stderr, isEmpty);
});
test('help', () async {
diff --git a/pkg/dartdev/test/commands/info_linux_test.dart b/pkg/dartdev/test/commands/info_linux_test.dart
index 2425140..dac77ad 100644
--- a/pkg/dartdev/test/commands/info_linux_test.dart
+++ b/pkg/dartdev/test/commands/info_linux_test.dart
@@ -47,7 +47,7 @@
expect(output, contains('providing this information'));
expect(output, contains('## Process info'));
expect(output, contains('Memory |'));
- expect(output, contains(RegExp('| dart(vm)? ')));
+ expect(output, contains('| dart '));
});
}, timeout: longTimeout);
}
diff --git a/pkg/dartdev/test/commands/info_macos_test.dart b/pkg/dartdev/test/commands/info_macos_test.dart
index 78695eb..8b5a2ab 100644
--- a/pkg/dartdev/test/commands/info_macos_test.dart
+++ b/pkg/dartdev/test/commands/info_macos_test.dart
@@ -59,7 +59,7 @@
expect(output, contains('providing this information'));
expect(output, contains('## Process info'));
expect(output, contains('Memory |')); // Header is aligned right.
- expect(output, contains(RegExp('| dart(vm)? ')));
+ expect(output, contains('| dart '));
});
}, timeout: longTimeout);
}
diff --git a/pkg/dartdev/test/commands/info_windows_test.dart b/pkg/dartdev/test/commands/info_windows_test.dart
index ba4b29c..79815962 100644
--- a/pkg/dartdev/test/commands/info_windows_test.dart
+++ b/pkg/dartdev/test/commands/info_windows_test.dart
@@ -24,7 +24,7 @@
expect(process.memoryMb, greaterThan(0));
expect(process.cpuPercent, null);
expect(process.elapsedTime, null);
- expect(process.commandLine, startsWith('dart'));
+ expect(process.commandLine, startsWith('dart.exe'));
}
});
diff --git a/pkg/dartdev/test/commands/run_test.dart b/pkg/dartdev/test/commands/run_test.dart
index ae1d9b7..ba860408 100644
--- a/pkg/dartdev/test/commands/run_test.dart
+++ b/pkg/dartdev/test/commands/run_test.dart
@@ -838,8 +838,7 @@
sub = process.stdout.transform(utf8.decoder).listen((event) async {
if (event.contains('ready')) {
readyCompleter.complete();
- }
- if (event.contains(devToolsMessagePrefix)) {
+ } else if (event.contains(devToolsMessagePrefix)) {
await sub.cancel();
completer.complete();
}
@@ -929,6 +928,20 @@
});
});
+ test('running dartdev is a prerequisite for passing --resident', () async {
+ p = project(mainSrc: 'void main() {}');
+ final result = await p.run(['--resident', p.relativeFilePath]);
+
+ expect(result.exitCode, 255);
+ expect(
+ result.stderr,
+ contains(
+ 'Passing the `--resident` flag to `dart` is invalid. It must be passed '
+ 'to `dart run`.',
+ ),
+ );
+ });
+
test(
'passing --resident is a prerequisite for passing --resident-compiler-info-file',
() async {
@@ -1090,7 +1103,8 @@
final result = await p.run([
'run',
'--resident',
- '--$residentCompilerInfoFileOption=${path.relative(serverInfoFile, from: p.dirPath)}',
+ '--$residentCompilerInfoFileOption',
+ path.relative(serverInfoFile, from: p.dirPath),
p.relativeFilePath,
]);
diff --git a/pkg/dartdev/test/sdk_test.dart b/pkg/dartdev/test/sdk_test.dart
index a39439d..9ef7801 100644
--- a/pkg/dartdev/test/sdk_test.dart
+++ b/pkg/dartdev/test/sdk_test.dart
@@ -26,11 +26,11 @@
});
test('dds snapshot', () {
- expectFileExists(Sdk().ddsAotSnapshot);
+ expectSnapshotExists(Sdk().ddsAotSnapshot, Sdk().ddsSnapshot);
});
test('dart2js snapshot', () {
- expectFileExists(Sdk().dart2jsAotSnapshot);
+ expectSnapshotExists(Sdk().dart2jsAotSnapshot, Sdk().dart2jsSnapshot);
});
}
@@ -45,6 +45,10 @@
expect(File(path).existsSync(), isTrue);
}
+void expectSnapshotExists(String aotpath, String jitpath) {
+ expect(File(aotpath).existsSync() || File(jitpath).existsSync(), isTrue);
+}
+
void expectDirectoryExists(String path) {
expect(Directory(path).existsSync(), isTrue);
}
diff --git a/pkg/dartdev/test/smoke/implicit_smoke_test.dart b/pkg/dartdev/test/smoke/implicit_smoke_test.dart
index 21094c4..a9dc7ad 100644
--- a/pkg/dartdev/test/smoke/implicit_smoke_test.dart
+++ b/pkg/dartdev/test/smoke/implicit_smoke_test.dart
@@ -73,8 +73,7 @@
void onData(event) {
if (event.contains(dartVMServiceMsg)) {
sawServiceMsg = true;
- }
- if (event.contains('Observe smoke test!')) {
+ } else if (event.contains('Observe smoke test!')) {
sawProgramMsg = true;
}
if (sawServiceMsg && sawProgramMsg) {
diff --git a/pkg/dartdev/test/smoke/smoke_test.dart b/pkg/dartdev/test/smoke/smoke_test.dart
index 95e3684..ea7a101 100644
--- a/pkg/dartdev/test/smoke/smoke_test.dart
+++ b/pkg/dartdev/test/smoke/smoke_test.dart
@@ -61,9 +61,9 @@
script,
],
);
- expect(result.exitCode, 0);
expect(result.stderr, isEmpty);
expect(result.stdout, contains('Smoke test!'));
+ expect(result.exitCode, 0);
}
});
@@ -78,8 +78,7 @@
void onData(event) {
if (event.contains(dartVMServiceMsg)) {
sawServiceMsg = true;
- }
- if (event.contains('Observe smoke test!')) {
+ } else if (event.contains('Observe smoke test!')) {
sawProgramMsg = true;
}
if (sawServiceMsg && sawProgramMsg) {
@@ -154,9 +153,9 @@
script,
],
);
- expect(result.exitCode, 0);
expect(result.stderr, isEmpty);
expect(result.stdout, contains('Smoke test!'));
+ expect(result.exitCode, 0);
});
// This test verifies that an error is thrown when an invalid experiment
@@ -172,9 +171,9 @@
script,
],
);
- expect(result.exitCode, 254);
expect(result.stderr, isNotEmpty);
expect(result.stdout, isEmpty);
+ expect(result.exitCode, 254);
});
},
timeout: Timeout.none,
diff --git a/pkg/dds/lib/src/devtools/dtd.dart b/pkg/dds/lib/src/devtools/dtd.dart
index 29417e8..72b06ed 100644
--- a/pkg/dds/lib/src/devtools/dtd.dart
+++ b/pkg/dds/lib/src/devtools/dtd.dart
@@ -34,19 +34,14 @@
runFromBuildRoot = true;
}
- // Try to locate the DDS snapshot to determine if we're able to find
+ // Try to locate the DartDev snapshot to determine if we're able to find
// the SDK snapshots with this SDK path. This is meant to handle
// non-standard SDK layouts that can involve symlinks (e.g., Brew
// installations, google3 tests, etc).
if (!File(
- path.join(snapshotsDir, 'dds_aot.dart.snapshot'),
+ path.join(snapshotsDir, 'dartdev.dart.snapshot'),
).existsSync()) {
- // We do not have an AOT snpashot and hence look for the JIT snapshot.
- if (!File(
- path.join(snapshotsDir, 'dds.dart.snapshot'),
- ).existsSync()) {
- return null;
- }
+ return null;
}
return (sdkPath, runFromBuildRoot);
}
@@ -73,6 +68,11 @@
snapshotDir,
'dart_tooling_daemon_aot.dart.snapshot',
);
+ final dtdSnapshot = path.absolute(
+ snapshotDir,
+ 'dart_tooling_daemon.dart.snapshot',
+ );
+
final completer = Completer<DtdInfo?>();
void completeForError() => completer.complete(null);
@@ -124,11 +124,8 @@
);
} catch (_, __) {
// Spawning an isolate using the AOT snapshot of the tooling daemon failed,
- // try again using the JIT snapshot of the tooling daemon.
- final dtdSnapshot = path.absolute(
- snapshotDir,
- 'dart_tooling_daemon.dart.snapshot',
- );
+ // we are probably in a JIT VM, try again using the JIT snapshot of the
+ // tooling daemon.
try {
await Isolate.spawnUri(
Uri.file(dtdSnapshot),
diff --git a/pkg/dds/test/devtools_server/utils/server_driver.dart b/pkg/dds/test/devtools_server/utils/server_driver.dart
index b48e0b6..d2ad505 100644
--- a/pkg/dds/test/devtools_server/utils/server_driver.dart
+++ b/pkg/dds/test/devtools_server/utils/server_driver.dart
@@ -78,8 +78,10 @@
int? tryPorts,
List<String> additionalArgs = const [],
}) async {
+ final script =
+ resolveTestRelativePath('devtools_server/utils/serve_devtools.dart');
final args = [
- 'devtools',
+ script.toFilePath(),
'--machine',
'--port',
'$port',
diff --git a/pkg/test_runner/lib/src/process_queue.dart b/pkg/test_runner/lib/src/process_queue.dart
index a426b75..62b670d 100644
--- a/pkg/test_runner/lib/src/process_queue.dart
+++ b/pkg/test_runner/lib/src/process_queue.dart
@@ -715,8 +715,6 @@
steps
.add(() => device.pushCachedData("$buildPath/dart", '$devicedir/dart'));
steps.add(() => device
- .pushCachedData("$buildPath/dartvm", '$devicedir/dartvm'));
- steps.add(() => device
.runAdbCommand(['push', hostKernelFile, '$deviceTestDir/out.dill']));
steps.addAll(_pushLibraries(command, device, devicedir, deviceTestDir));
diff --git a/pkg/test_runner/lib/src/runtime_configuration.dart b/pkg/test_runner/lib/src/runtime_configuration.dart
index b2050ad..a2f2727 100644
--- a/pkg/test_runner/lib/src/runtime_configuration.dart
+++ b/pkg/test_runner/lib/src/runtime_configuration.dart
@@ -547,7 +547,7 @@
argument.replaceAll(Directory.current.path, "pkg/data"))
.toList();
- var component = "dartvm_test_component.cm";
+ var component = "dart_test_component.cm";
if (aot) {
component = "dartaotruntime_test_component.cm";
arguments[arguments.length - 1] =
diff --git a/runtime/BUILD.gn b/runtime/BUILD.gn
index dfa1dbc..6e3a35a 100644
--- a/runtime/BUILD.gn
+++ b/runtime/BUILD.gn
@@ -59,25 +59,6 @@
]
}
-config("dartdev_config") {
- defines = []
- cflags = []
- defines += [
- "DART_PRECOMPILED_RUNTIME",
- "EXCLUDE_CFE_AND_KERNEL_PLATFORM",
- ]
- if (!dart_debug) {
- defines += [ "PRODUCT" ]
- if (is_posix) {
- cflags = [
- # This is the equivalent from `build/config/BUILDCONFIG.gn` which includes
- # `build/config/gcc:symbol_visibility_hidden` in product mode.
- "-fvisibility=hidden",
- ]
- }
- }
-}
-
config("add_empty_macho_section_config") {
if (is_mac || is_ios) {
# We create an empty __space_for_note section in a __CUSTOM segment to
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index b3b71b3..63a919c 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -916,6 +916,8 @@
"error_exit.cc",
"error_exit.h",
"icu.cc",
+ "main_options.cc",
+ "main_options.h",
"options.cc",
"options.h",
"snapshot_utils.cc",
@@ -964,7 +966,7 @@
}
}
-dart_executable("dartvm") {
+dart_executable("dart") {
extra_deps = [
":dart_snapshot_cc",
"..:libdart_jit",
@@ -972,7 +974,8 @@
]
extra_sources = [
"builtin.cc",
- "common_options.h",
+ "dartdev_isolate.cc",
+ "dartdev_isolate.h",
"dfe.cc",
"dfe.h",
"gzip.cc",
@@ -981,8 +984,6 @@
"loader.h",
"main.cc",
"main_impl.cc",
- "main_options.cc",
- "main_options.h",
]
if (!exclude_kernel_service) {
extra_deps += [ ":dart_kernel_platform_cc" ]
@@ -1006,15 +1007,12 @@
]
extra_sources = [
"builtin.cc",
- "common_options.h",
"gzip.cc",
"gzip.h",
"loader.cc",
"loader.h",
"main.cc",
"main_impl.cc",
- "main_options.cc",
- "main_options.h",
"snapshot_empty.cc",
]
@@ -1043,15 +1041,12 @@
]
extra_sources = [
"builtin.cc",
- "common_options.h",
"gzip.cc",
"gzip.h",
"loader.cc",
"loader.h",
"main.cc",
"main_impl.cc",
- "main_options.cc",
- "main_options.h",
"snapshot_empty.cc",
]
@@ -1061,40 +1056,6 @@
]
}
-if (dart_target_arch != "ia32" && dart_target_arch != "x86") {
- dart_executable("dart") {
- use_product_mode = true
- extra_configs = [
- "..:dartdev_config",
- "..:add_empty_macho_section_config",
- ]
- extra_deps = [
- ":shared_object_loaders_product",
- "..:libdart_aotruntime_product",
- "../platform:libdart_platform_aotruntime_product",
- ]
- extra_sources = [
- "builtin.cc",
- "common_options.h",
- "dartdev.cc",
- "dartdev.h",
- "dartdev_options.cc",
- "dartdev_options.h",
- "gzip.cc",
- "gzip.h",
- "loader.cc",
- "loader.h",
- "snapshot_empty.cc",
- ]
- }
-} else {
- copy("dart") {
- deps = [ ":dartvm" ]
- sources = [ "$root_build_dir/dartvm${executable_suffix}" ]
- outputs = [ "$root_build_dir/dart${executable_suffix}" ]
- }
-}
-
# This flag is set in runtime/runtime_args.gni
# The analyze_snapshot tool is only supported on 64 bit AOT builds running under
# linux and android platforms
@@ -1118,11 +1079,8 @@
extra_sources = [
"analyze_snapshot.cc",
"builtin.cc",
- "common_options.h",
"loader.cc",
"loader.h",
- "main_options.cc",
- "main_options.h",
]
if (use_product_mode) {
@@ -1248,7 +1206,7 @@
}
shared_library("entrypoints_verification_test") {
- deps = [ ":dartvm" ]
+ deps = [ ":dart" ]
sources = [ "entrypoints_verification_test.cc" ]
if (is_win) {
sources += [ "dart_api_win.c" ]
@@ -1257,13 +1215,13 @@
}
shared_library("ffi_test_dynamic_library") {
- deps = [ ":dartvm" ]
+ deps = [ ":dart" ]
sources = [ "ffi_test/ffi_test_dynamic_library.cc" ]
include_dirs = [ ".." ]
}
shared_library("ffi_test_functions") {
- deps = [ ":dartvm" ]
+ deps = [ ":dart" ]
sources = [
# This file must be compiled in for dynamic linking.
@@ -1301,11 +1259,8 @@
extra_sources = [
"../vm/libfuzzer/dart_libfuzzer.cc",
"builtin.cc",
- "common_options.h",
"dfe.cc",
"dfe.h",
- "main_options.cc",
- "main_options.h",
]
if (!exclude_kernel_service) {
extra_deps += [ ":dart_kernel_platform_cc" ]
diff --git a/runtime/bin/common_options.h b/runtime/bin/common_options.h
deleted file mode 100644
index d375685..0000000
--- a/runtime/bin/common_options.h
+++ /dev/null
@@ -1,173 +0,0 @@
-// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef RUNTIME_BIN_COMMON_OPTIONS_H_
-#define RUNTIME_BIN_COMMON_OPTIONS_H_
-
-#include "include/dart_api.h"
-#include "platform/assert.h"
-#include "platform/globals.h"
-#include "platform/syslog.h"
-
-namespace dart {
-namespace bin {
-
-static void _PrintVersion() {
- Syslog::Print("Dart SDK version: %s\n", Dart_VersionString());
-}
-
-// clang-format off
-static void _PrintUsage() {
- Syslog::Print(
- "Usage: dart [<vm-flags>] <dart-script-file> [<script-arguments>]\n"
- "\n"
- "Executes the Dart script <dart-script-file> with "
- "the given list of <script-arguments>.\n"
- "\n");
-}
-
-static void _PrintNonVerboseUsage() {
- Syslog::Print(
-"Common VM flags:\n"
-#if !defined(PRODUCT)
-"--enable-asserts\n"
-" Enable assert statements.\n"
-#endif // !defined(PRODUCT)
-"--help or -h\n"
-" Display this message (add -v or --verbose for information about\n"
-" all VM options).\n"
-"--packages=<path>\n"
-" Where to find a package spec file.\n"
-"--define=<key>=<value> or -D<key>=<value>\n"
-" Define an environment declaration. To specify multiple declarations,\n"
-" use multiple instances of this option.\n"
-#if !defined(PRODUCT)
-"--observe[=<port>[/<bind-address>]]\n"
-" The observe flag is a convenience flag used to run a program with a\n"
-" set of options which are often useful for debugging under Dart DevTools.\n"
-" These options are currently:\n"
-" --enable-vm-service[=<port>[/<bind-address>]]\n"
-" --serve-devtools\n"
-" --pause-isolates-on-exit\n"
-" --pause-isolates-on-unhandled-exceptions\n"
-" --warn-on-pause-with-no-debugger\n"
-" --timeline-streams=\"Compiler, Dart, GC, Microtask\"\n"
-" This set is subject to change.\n"
-" Please see these options (--help --verbose) for further documentation.\n"
-"--write-service-info=<file_uri>\n"
-" Outputs information necessary to connect to the VM service to the\n"
-" specified file in JSON format. Useful for clients which are unable to\n"
-" listen to stdout for the Dart VM service listening message.\n"
-#endif // !defined(PRODUCT)
-"--snapshot-kind=<snapshot_kind>\n"
-"--snapshot=<file_name>\n"
-" These snapshot options are used to generate a snapshot of the loaded\n"
-" Dart script:\n"
-" <snapshot-kind> controls the kind of snapshot, it could be\n"
-" kernel(default) or app-jit\n"
-" <file_name> specifies the file into which the snapshot is written\n"
-"--version\n"
-" Print the SDK version.\n");
-}
-
-static void _PrintVerboseUsage() {
- Syslog::Print(
-"Supported options:\n"
-#if !defined(PRODUCT)
-"--enable-asserts\n"
-" Enable assert statements.\n"
-#endif // !defined(PRODUCT)
-"--help or -h\n"
-" Display this message (add -v or --verbose for information about\n"
-" all VM options).\n"
-"--packages=<path>\n"
-" Where to find a package spec file.\n"
-"--define=<key>=<value> or -D<key>=<value>\n"
-" Define an environment declaration. To specify multiple declarations,\n"
-" use multiple instances of this option.\n"
-#if !defined(PRODUCT)
-"--observe[=<port>[/<bind-address>]]\n"
-" The observe flag is a convenience flag used to run a program with a\n"
-" set of options which are often useful for debugging under Dart DevTools.\n"
-" These options are currently:\n"
-" --enable-vm-service[=<port>[/<bind-address>]]\n"
-" --serve-devtools\n"
-" --pause-isolates-on-exit\n"
-" --pause-isolates-on-unhandled-exceptions\n"
-" --warn-on-pause-with-no-debugger\n"
-" --timeline-streams=\"Compiler, Dart, GC, Microtask\"\n"
-" This set is subject to change.\n"
-" Please see these options for further documentation.\n"
-"--profile-microtasks\n"
-" Record information about each microtask. Information about completed\n"
-" microtasks will be written to the \"Microtask\" timeline stream.\n"
-#endif // !defined(PRODUCT)
-"--version\n"
-" Print the VM version.\n"
-"\n"
-"--trace-loading\n"
-" enables tracing of library and script loading\n"
-"\n"
-#if !defined(PRODUCT)
-"--enable-vm-service[=<port>[/<bind-address>]]\n"
-" Enables the VM service and listens on specified port for connections\n"
-" (default port number is 8181, default bind address is localhost).\n"
-"\n"
-"--disable-service-auth-codes\n"
-" Disables the requirement for an authentication code to communicate with\n"
-" the VM service. Authentication codes help protect against CSRF attacks,\n"
-" so it is not recommended to disable them unless behind a firewall on a\n"
-" secure device.\n"
-"\n"
-"--enable-service-port-fallback\n"
-" When the VM service is told to bind to a particular port, fallback to 0 if\n"
-" it fails to bind instead of failing to start.\n"
-"\n"
-#endif // !defined(PRODUCT)
-"--root-certs-file=<path>\n"
-" The path to a file containing the trusted root certificates to use for\n"
-" secure socket connections.\n"
-"--root-certs-cache=<path>\n"
-" The path to a cache directory containing the trusted root certificates to\n"
-" use for secure socket connections.\n"
-#if defined(DART_HOST_OS_LINUX) || \
- defined(DART_HOST_OS_ANDROID) || \
- defined(DART_HOST_OS_FUCHSIA)
-"--namespace=<path>\n"
-" The path to a directory that dart:io calls will treat as the root of the\n"
-" filesystem.\n"
-#endif // defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_ANDROID)
-"\n"
-"The following options are only used for VM development and may\n"
-"be changed in any future version:\n");
- const char* print_flags = "--print_flags";
- char* error = Dart_SetVMFlags(1, &print_flags);
- ASSERT(error == nullptr);
-}
-// clang-format on
-
-// Returns true if arg starts with the characters "--" followed by option, but
-// all '_' in the option name are treated as '-'.
-static bool IsOption(const char* arg, const char* option) {
- if (arg[0] != '-' || arg[1] != '-') {
- // Special case first two characters to avoid recognizing __flag.
- return false;
- }
- for (int i = 0; option[i] != '\0'; i++) {
- auto c = arg[i + 2];
- if (c == '\0') {
- // Not long enough.
- return false;
- }
- if ((c == '_' ? '-' : c) != option[i]) {
- return false;
- }
- }
- return true;
-}
-
-} // namespace bin
-} // namespace dart
-
-#endif // RUNTIME_BIN_COMMON_OPTIONS_H_
diff --git a/runtime/bin/dartvm_test_component.cml b/runtime/bin/dart_test_component.cml
similarity index 93%
rename from runtime/bin/dartvm_test_component.cml
rename to runtime/bin/dart_test_component.cml
index 463d84e..3bff2c9 100644
--- a/runtime/bin/dartvm_test_component.cml
+++ b/runtime/bin/dart_test_component.cml
@@ -7,7 +7,7 @@
"//runtime/vm-jit.shard.cml",
],
program: {
- binary: "exe.stripped/dartvm",
+ binary: "exe.stripped/dart",
runner: "elf_test_runner",
},
capabilities: [
diff --git a/runtime/bin/dartdev.cc b/runtime/bin/dartdev.cc
deleted file mode 100644
index aa94be8..0000000
--- a/runtime/bin/dartdev.cc
+++ /dev/null
@@ -1,1137 +0,0 @@
-// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <memory>
-#include <utility>
-
-#include "bin/builtin.h"
-#include "bin/console.h"
-#include "bin/crashpad.h"
-#include "bin/dartdev_options.h"
-#include "bin/dartutils.h"
-#include "bin/error_exit.h"
-#include "bin/eventhandler.h"
-#include "bin/exe_utils.h"
-#include "bin/file.h"
-#include "bin/gzip.h"
-#include "bin/isolate_data.h"
-#include "bin/loader.h"
-#include "bin/lockers.h"
-#include "bin/platform.h"
-#include "bin/process.h"
-#include "bin/snapshot_utils.h"
-#include "bin/thread.h"
-#include "bin/utils.h"
-#if defined(DART_HOST_OS_WINDOWS)
-#include "bin/utils_win.h"
-#endif
-#include "bin/vmservice_impl.h"
-#include "include/bin/dart_io_api.h"
-#include "include/dart_api.h"
-#include "include/dart_embedder_api.h"
-#include "include/dart_native_api.h"
-#include "include/dart_tools_api.h"
-#include "platform/assert.h"
-#include "platform/globals.h"
-#include "platform/growable_array.h"
-#include "platform/hashmap.h"
-#include "platform/syslog.h"
-#include "platform/text_buffer.h"
-#include "platform/utils.h"
-
-namespace dart {
-namespace bin {
-
-#if defined(DART_PRECOMPILED_RUNTIME)
-/**
- * Global state used to control and store generation of application snapshots.
- */
-static const uint8_t* ignore_vm_snapshot_data = nullptr;
-static const uint8_t* ignore_vm_snapshot_instructions = nullptr;
-static const uint8_t* app_isolate_snapshot_data = nullptr;
-static const uint8_t* app_isolate_snapshot_instructions = nullptr;
-
-#define SAVE_ERROR_AND_RETURN(result) \
- if (Dart_IsError(result)) { \
- *error = Utils::StrDup(Dart_GetError(result)); \
- return false; \
- }
-
-#define SAVE_ERROR_AND_EXIT(result) \
- *error = Utils::StrDup(Dart_GetError(result)); \
- if (Dart_IsCompilationError(result)) { \
- *exit_code = kCompilationErrorExitCode; \
- } else if (Dart_IsApiError(result)) { \
- *exit_code = kApiErrorExitCode; \
- } else { \
- *exit_code = kErrorExitCode; \
- } \
- Dart_ExitScope(); \
- Dart_ShutdownIsolate(); \
- return nullptr;
-
-#define CHECK_RESULT(result) \
- if (Dart_IsError(result)) { \
- SAVE_ERROR_AND_EXIT(result); \
- }
-
-#define CHECK_RESULT_CLEANUP(result, cleanup) \
- if (Dart_IsError(result)) { \
- delete (cleanup); \
- SAVE_ERROR_AND_EXIT(result); \
- }
-
-#define DART_DEV_ISOLATE_NAME "dartdev"
-
-// Helper class to ensure we enter a new Dart Scope and exit it.
-class DartScope {
- public:
- DartScope() { Dart_EnterScope(); }
- ~DartScope() { Dart_ExitScope(); }
-};
-
-static Dart_Handle SetupCoreLibraries(Dart_Isolate isolate,
- IsolateData* isolate_data,
- bool is_isolate_group_start,
- const char** resolved_packages_config) {
- auto isolate_group_data = isolate_data->isolate_group_data();
- const auto packages_file = isolate_data->packages_file();
- const auto script_uri = isolate_group_data->script_url;
-
- Dart_Handle result;
-
- // Prepare builtin and other core libraries for use to resolve URIs.
- // Set up various closures, e.g: printing, timers etc.
- // Set up package configuration for URI resolution.
- result = DartUtils::PrepareForScriptLoading(false, false, false);
- if (Dart_IsError(result)) return result;
-
- // Setup packages config if specified.
- result = DartUtils::SetupPackageConfig(packages_file);
- if (Dart_IsError(result)) return result;
- if (!Dart_IsNull(result) && resolved_packages_config != nullptr) {
- result = Dart_StringToCString(result, resolved_packages_config);
- if (Dart_IsError(result)) return result;
- ASSERT(*resolved_packages_config != nullptr);
- }
-
- result = Dart_SetEnvironmentCallback(DartUtils::EnvironmentCallback);
- if (Dart_IsError(result)) return result;
-
- // Setup the native resolver as the snapshot does not carry it.
- Builtin::SetNativeResolver(Builtin::kBuiltinLibrary);
- Builtin::SetNativeResolver(Builtin::kIOLibrary);
- Builtin::SetNativeResolver(Builtin::kCLILibrary);
- VmService::SetNativeResolver();
-
- const char* namespc = Options::namespc();
- result =
- DartUtils::SetupIOLibrary(namespc, script_uri, Options::exit_disabled());
- if (Dart_IsError(result)) return result;
-
- return Dart_Null();
-}
-
-static bool OnIsolateInitialize(void** child_callback_data, char** error) {
- Dart_Isolate isolate = Dart_CurrentIsolate();
- ASSERT(isolate != nullptr);
-
- auto isolate_group_data =
- reinterpret_cast<IsolateGroupData*>(Dart_CurrentIsolateGroupData());
-
- auto isolate_data = new IsolateData(isolate_group_data);
- *child_callback_data = isolate_data;
-
- DartScope scope; // Enter a new scope.
- const auto script_uri = isolate_group_data->script_url;
- const bool isolate_run_app_snapshot =
- isolate_group_data->RunFromAppSnapshot();
- Dart_Handle result = SetupCoreLibraries(isolate, isolate_data,
- /*group_start=*/false,
- /*resolved_packages_config=*/nullptr);
- SAVE_ERROR_AND_RETURN(result);
- if (isolate_run_app_snapshot) {
- result = Loader::InitForSnapshot(script_uri, isolate_data);
- SAVE_ERROR_AND_RETURN(result);
- } else {
- result = DartUtils::ResolveScript(Dart_NewStringFromCString(script_uri));
- SAVE_ERROR_AND_RETURN(result);
-
- if (isolate_group_data->kernel_buffer() != nullptr) {
- // Various core-library parts will send requests to the Loader to resolve
- // relative URIs and perform other related tasks. We need Loader to be
- // initialized for this to work because loading from Kernel binary
- // bypasses normal source code loading paths that initialize it.
- const char* resolved_script_uri = nullptr;
- result = Dart_StringToCString(result, &resolved_script_uri);
- SAVE_ERROR_AND_RETURN(result);
- result = Loader::InitForSnapshot(resolved_script_uri, isolate_data);
- SAVE_ERROR_AND_RETURN(result);
- }
- }
-
- return true;
-}
-
-static Dart_Isolate IsolateSetupHelper(Dart_Isolate isolate,
- bool is_dartdev_isolate,
- const char* script_uri,
- const char* packages_config,
- bool isolate_run_app_snapshot,
- Dart_IsolateFlags* flags,
- char** error,
- int* exit_code) {
- Dart_EnterScope();
-
- // Set up the library tag handler for the isolate group shared by all
- // isolates in the group.
- Dart_Handle result = Dart_SetLibraryTagHandler(Loader::LibraryTagHandler);
- CHECK_RESULT(result);
- result = Dart_SetDeferredLoadHandler(Loader::DeferredLoadHandler);
- CHECK_RESULT(result);
-
- auto isolate_data = reinterpret_cast<IsolateData*>(Dart_IsolateData(isolate));
-
- const char* resolved_packages_config = nullptr;
- result = SetupCoreLibraries(isolate, isolate_data,
- /*is_isolate_group_start=*/true,
- &resolved_packages_config);
- CHECK_RESULT(result);
-
- if (isolate_run_app_snapshot) {
- Dart_Handle result = Loader::InitForSnapshot(script_uri, isolate_data);
- CHECK_RESULT(result);
- } else {
- UNREACHABLE();
- }
-
- // Make the isolate runnable so that it is ready to handle messages.
- Dart_ExitScope();
- Dart_ExitIsolate();
- *error = Dart_IsolateMakeRunnable(isolate);
- if (*error != nullptr) {
- Dart_EnterIsolate(isolate);
- Dart_ShutdownIsolate();
- return nullptr;
- }
-
- return isolate;
-}
-
-// Returns newly created Isolate on success, nullptr on failure.
-static Dart_Isolate CreateIsolateGroupAndSetupHelper(
- bool is_dartdev_isolate,
- const char* script_uri,
- const char* name,
- const char* packages_config,
- Dart_IsolateFlags* flags,
- void* callback_data,
- char** error,
- int* exit_code) {
- int64_t start = Dart_TimelineGetMicros();
- ASSERT(script_uri != nullptr);
- uint8_t* kernel_buffer = nullptr;
- intptr_t kernel_buffer_size = 0;
- AppSnapshot* app_snapshot = nullptr;
-
- const uint8_t* isolate_snapshot_data = nullptr;
- const uint8_t* isolate_snapshot_instructions = nullptr;
- if (is_dartdev_isolate) {
- isolate_snapshot_data = app_isolate_snapshot_data;
- isolate_snapshot_instructions = app_isolate_snapshot_instructions;
- } else {
- // AOT: All isolates need to be run from AOT compiled snapshots.
- app_snapshot = Snapshot::TryReadAppSnapshot(
- script_uri, /*force_load_from_memory*/ false, /*decode_uri*/ true);
- if (app_snapshot == nullptr || !app_snapshot->IsAOT()) {
- *error = Utils::SCreate(
- "The uri(%s) provided to `Isolate.spawnUri()` does not "
- "contain a valid AOT snapshot.",
- script_uri);
- return nullptr;
- }
-
- app_snapshot->SetBuffers(
- &ignore_vm_snapshot_data, &ignore_vm_snapshot_instructions,
- &isolate_snapshot_data, &isolate_snapshot_instructions);
- }
-
- bool isolate_run_app_snapshot = true;
-
- auto isolate_group_data = new IsolateGroupData(
- script_uri, /*asset_resolution_base=*/nullptr, packages_config,
- app_snapshot, isolate_run_app_snapshot);
- if (kernel_buffer != nullptr) {
- isolate_group_data->SetKernelBufferNewlyOwned(kernel_buffer,
- kernel_buffer_size);
- }
-
- Dart_Isolate isolate = nullptr;
-
- IsolateData* isolate_data = nullptr;
- isolate_data = new IsolateData(isolate_group_data);
- isolate = Dart_CreateIsolateGroup(script_uri, name, isolate_snapshot_data,
- isolate_snapshot_instructions, flags,
- isolate_group_data, isolate_data, error);
- Dart_Isolate created_isolate = nullptr;
- if (isolate == nullptr) {
- delete isolate_data;
- delete isolate_group_data;
- } else {
- created_isolate = IsolateSetupHelper(
- isolate, is_dartdev_isolate, script_uri, packages_config,
- isolate_run_app_snapshot, flags, error, exit_code);
- }
- int64_t end = Dart_TimelineGetMicros();
- Dart_RecordTimelineEvent("CreateIsolateGroupAndSetupHelper", start, end,
- /*flow_id_count=*/0, nullptr,
- Dart_Timeline_Event_Duration,
- /*argument_count=*/0, nullptr, nullptr);
- return created_isolate;
-}
-
-#undef CHECK_RESULT
-
-static Dart_Isolate CreateIsolateGroupAndSetup(const char* script_uri,
- const char* main,
- const char* package_root,
- const char* package_config,
- Dart_IsolateFlags* flags,
- void* callback_data,
- char** error) {
- // The VM should never call the isolate helper with a nullptr flags.
- ASSERT(flags != nullptr);
- ASSERT(flags->version == DART_FLAGS_CURRENT_VERSION);
- ASSERT(package_root == nullptr);
-
- if (error != nullptr) {
- *error = nullptr;
- }
-
-#if defined(DART_HOST_OS_LINUX)
- // This would also be true in Linux, except that Google3 overrides the default
- // ELF interpreter to one that apparently doesn't create proper mappings.
- flags->snapshot_is_dontneed_safe = false;
-#else
- flags->snapshot_is_dontneed_safe = true;
-#endif
-
- int exit_code = 0;
-
- if (strcmp(script_uri, DART_VM_SERVICE_ISOLATE_NAME) == 0) {
- // We do not start the service isolate in the Dart CLI mode of execution.
- // If profiling or debugging of the individual tools is desired it is
- // possible to do that using the 'dartaotruntime' or 'dartvm' executables.
- return nullptr;
- }
-
- bool is_dartdev_isolate = false;
- return CreateIsolateGroupAndSetupHelper(is_dartdev_isolate, script_uri, main,
- package_config, flags, callback_data,
- error, &exit_code);
-}
-
-static void OnIsolateShutdown(void* isolate_group_data, void* isolate_data) {
- Dart_EnterScope();
- Dart_Handle sticky_error = Dart_GetStickyError();
- if (!Dart_IsNull(sticky_error) && !Dart_IsFatalError(sticky_error)) {
- Syslog::PrintErr("%s\n", Dart_GetError(sticky_error));
- }
- Dart_ExitScope();
-}
-
-static void DeleteIsolateData(void* isolate_group_data, void* callback_data) {
- auto isolate_data = reinterpret_cast<IsolateData*>(callback_data);
- delete isolate_data;
-}
-
-static void DeleteIsolateGroupData(void* callback_data) {
- auto isolate_group_data = reinterpret_cast<IsolateGroupData*>(callback_data);
- delete isolate_group_data;
-}
-
-static constexpr const char* kStdoutStreamId = "Stdout";
-static constexpr const char* kStderrStreamId = "Stderr";
-
-static bool ServiceStreamListenCallback(const char* stream_id) {
- if (strcmp(stream_id, kStdoutStreamId) == 0) {
- SetCaptureStdout(true);
- return true;
- } else if (strcmp(stream_id, kStderrStreamId) == 0) {
- SetCaptureStderr(true);
- return true;
- }
- return false;
-}
-
-static void ServiceStreamCancelCallback(const char* stream_id) {
- if (strcmp(stream_id, kStdoutStreamId) == 0) {
- SetCaptureStdout(false);
- } else if (strcmp(stream_id, kStderrStreamId) == 0) {
- SetCaptureStderr(false);
- } else {
- UNREACHABLE();
- }
-}
-
-static bool FileModifiedCallback(const char* url, int64_t since) {
- auto path = File::UriToPath(url);
- if (path == nullptr) {
- // If it isn't a file on local disk, we don't know if it has been
- // modified.
- return true;
- }
- int64_t data[File::kStatSize];
- File::Stat(nullptr, path.get(), data);
- if (data[File::kType] == File::kDoesNotExist) {
- return true;
- }
- return data[File::kModifiedTime] > since;
-}
-
-static void EmbedderInformationCallback(Dart_EmbedderInformation* info) {
- info->version = DART_EMBEDDER_INFORMATION_CURRENT_VERSION;
- info->name = "Dart VM";
- Process::GetRSSInformation(&(info->max_rss), &(info->current_rss));
-}
-
-#define CHECK_RESULT(result) \
- if (Dart_IsError(result)) { \
- const int exit_code = Dart_IsCompilationError(result) \
- ? kCompilationErrorExitCode \
- : kErrorExitCode; \
- ErrorExit(exit_code, "%s\n", Dart_GetError(result)); \
- }
-
-static bool CheckForInvalidPath(const char* path) {
- // TODO(zichangguo): "\\?\" is a prefix for paths on Windows.
- // Arguments passed are parsed as an URI. "\\?\" causes problems as a part
- // of URIs. This is a temporary workaround to prevent VM from crashing.
- // Issue: https://github.com/dart-lang/sdk/issues/42779
- if (strncmp(path, R"(\\?\)", 4) == 0) {
- Syslog::PrintErr(R"(\\?\ prefix is not supported)");
- return false;
- }
- return true;
-}
-
-class DartDev {
- public:
- // Return codes from dartdev.
- // Note: keep in sync with pkg/dartdev/lib/vm_interop_handler.dart
- typedef enum {
- DartDev_Result_Unknown = -1,
- DartDev_Result_Run = 1,
- DartDev_Result_RunExec = 2,
- DartDev_Result_Exit = 3,
- } DartDev_Result;
-
- static CStringUniquePtr ResolvedDartVmPath() {
-#if defined(DART_HOST_OS_WINDOWS)
- const char* filename = "dartvm.exe";
-#else
- const char* filename = "dartvm";
-#endif // defined(DART_HOST_OS_WINDOWS)
- auto try_resolve_path = [&](CStringUniquePtr dir_prefix) {
- // |dir_prefix| includes the last path separator.
- // Assume 'dartvm' and 'dart' executables are in the same directory.
- char* dartvm_path = Utils::SCreate("%s%s", dir_prefix.get(), filename);
- if (File::Exists(nullptr, dartvm_path)) {
- return CStringUniquePtr(dartvm_path);
- }
- free(dartvm_path);
- return CStringUniquePtr(nullptr);
- };
-
- auto result =
- try_resolve_path(EXEUtils::GetDirectoryPrefixFromResolvedExeName());
- if (result == nullptr) {
- result =
- try_resolve_path(EXEUtils::GetDirectoryPrefixFromUnresolvedExeName());
- }
- return result;
- }
-
- static CStringUniquePtr ResolvedSnapshotPath() {
- const char* filename = "dartdev_aot.dart.snapshot";
-
- auto try_resolve_path = [&](CStringUniquePtr dir_prefix) {
- // |dir_prefix| includes the last path separator.
- // First assume we're in dart-sdk/bin.
- char* snapshot_path =
- Utils::SCreate("%ssnapshots/%s", dir_prefix.get(), filename);
- if (File::Exists(nullptr, snapshot_path)) {
- return CStringUniquePtr(snapshot_path);
- }
- free(snapshot_path);
-
- // If we're not in dart-sdk/bin, we might be in one of the $SDK/out*/
- // directories, Try to use a snapshot from that directory.
- snapshot_path = Utils::SCreate("%s%s", dir_prefix.get(), filename);
- if (File::Exists(nullptr, snapshot_path)) {
- return CStringUniquePtr(snapshot_path);
- }
- free(snapshot_path);
- return CStringUniquePtr(nullptr);
- };
-
- auto result =
- try_resolve_path(EXEUtils::GetDirectoryPrefixFromResolvedExeName());
- if (result == nullptr) {
- result =
- try_resolve_path(EXEUtils::GetDirectoryPrefixFromUnresolvedExeName());
- }
- return result;
- }
-
- // Invoke the Dart VM directly bypassing dartdev.
- static void InvokeDartVM(int argc, char** argv, bool argv_converted) {
- auto dartvm_path = DartDev::ResolvedDartVmPath();
- char* exec_name = dartvm_path.get();
- if (exec_name == nullptr || !CheckForInvalidPath(exec_name)) {
- // Free environment if any.
- Syslog::PrintErr("Unable to locate the Dart VM executable");
- Options::Cleanup();
- Platform::Exit(kErrorExitCode);
- }
- int idx = 0;
- char err_msg[256];
- err_msg[0] = '\0';
- intptr_t num_args = argc + 2;
- char** exec_argv = new char*[num_args];
- exec_argv[idx] = Utils::StrDup(exec_name);
- const size_t kPathBufSize = PATH_MAX + 1;
- char dart_path[kPathBufSize];
- Platform::ResolveExecutablePathInto(dart_path, kPathBufSize);
- idx += 1;
- exec_argv[idx] = Utils::SCreate("--executable_name=%s", dart_path);
- for (intptr_t i = 1; i < argc; ++i) {
-#if defined(DART_HOST_OS_WINDOWS)
- exec_argv[i + idx] = StringUtilsWin::ArgumentEscape(argv[i]);
-#else
- exec_argv[i + idx] = Utils::StrDup(argv[i]);
-#endif // defined(DART_HOST_OS_WINDOWS)
- }
- // Null terminate the exec_argv array.
- exec_argv[num_args - 1] = nullptr;
-
- // Exec the script to be run and pass the arguments.
- int ret =
- Process::Exec(nullptr, exec_name, const_cast<const char**>(exec_argv),
- (num_args - 1), nullptr, err_msg, sizeof(err_msg));
- // Exec process done.
- if (ret != 0) {
- Syslog::PrintErr("%s\n", err_msg);
- }
- // Free copied argument strings if converted.
- if (argv_converted) {
- for (int i = 0; i < argc; i++) {
- free(argv[i]);
- }
- }
- for (int i = 0; i < argc; i++) {
- free(exec_argv[i]);
- }
- delete[] exec_argv;
-
- // Free environment if any.
- Options::Cleanup();
- Platform::Exit(ret);
- }
-
- // Process the DartDev_Result_Run result message produced by
- // VmInteropHandler in pkg/dartdev/lib/src/vm_interop_handler.dart
- static void RunResultCallback(Dart_CObject* message) {
- result_ = DartDev_Result_Run;
- ASSERT(GetArrayItem(message, 1)->type == Dart_CObject_kString);
- auto item2 = GetArrayItem(message, 2);
-
- ASSERT(item2->type == Dart_CObject_kString ||
- item2->type == Dart_CObject_kNull);
-
- auto item3 = GetArrayItem(message, 3);
-
- // ignoring mark_main_isolate_as_system_isolate
- ASSERT(item3->type == Dart_CObject_kBool);
-
- script_name_ = Utils::StrDup(GetArrayItem(message, 1)->value.as_string);
-
- ASSERT(GetArrayItem(message, 4)->type == Dart_CObject_kArray);
- Dart_CObject* args = GetArrayItem(message, 4);
- argc_ = args->value.as_array.length;
- Dart_CObject** dart_args = args->value.as_array.values;
-
- auto deleter = [](char** args) {
- for (intptr_t i = 0; i < argc_; ++i) {
- free(args[i]);
- }
- delete[] args;
- };
- argv_ =
- std::unique_ptr<char*[], void (*)(char**)>(new char*[argc_], deleter);
- for (intptr_t i = 0; i < argc_; ++i) {
- argv_[i] = Utils::StrDup(dart_args[i]->value.as_string);
- }
- }
-
- // Process the DartDev_Result_RunExec result message produced by
- // VmInteropHandler in pkg/dartdev/lib/src/vm_interop_handler.dart
- static void RunExecResultCallback(Dart_CObject* message) {
- result_ = DartDev_Result_RunExec;
- auto dartvm_path = DartDev::ResolvedDartVmPath();
- char* exec_name = dartvm_path.get();
- if (exec_name == nullptr || !CheckForInvalidPath(exec_name)) {
- Syslog::PrintErr("Unable to locate the Dart VM executable");
- Platform::Exit(kErrorExitCode);
- }
- ASSERT(GetArrayItem(message, 1)->type == Dart_CObject_kString);
- auto item2 = GetArrayItem(message, 2);
-
- ASSERT(item2->type == Dart_CObject_kString ||
- item2->type == Dart_CObject_kNull);
-
- package_config_override_ = nullptr;
-
- if (item2->type == Dart_CObject_kString) {
- package_config_override_ = Utils::StrDup(item2->value.as_string);
- }
-
- intptr_t num_vm_options = dart_vm_options_->count();
- const char** vm_options = dart_vm_options_->arguments();
- ASSERT(GetArrayItem(message, 4)->type == Dart_CObject_kArray);
- Dart_CObject* args = GetArrayItem(message, 4);
- intptr_t argc = args->value.as_array.length;
- Dart_CObject** dart_args = args->value.as_array.values;
- auto item3 = GetArrayItem(message, 3);
- ASSERT(item3->type == Dart_CObject_kBool);
- const bool mark_main_isolate_as_system_isolate = item3->value.as_bool;
- auto deleter = [](char** args) {
- for (intptr_t i = 0; i < argc_; ++i) {
- free(args[i]);
- }
- delete[] args;
- };
- // Total count of arguments to be passed to the script being execed.
- if (mark_main_isolate_as_system_isolate) {
- argc_ = argc + num_vm_options + 4;
- } else {
- argc_ = argc + num_vm_options + 3;
- }
-
- // Array of arguments to be passed to the script being execed.
- argv_ = std::unique_ptr<char*[], void (*)(char**)>(new char*[argc_ + 1],
- deleter);
-
- intptr_t idx = 0;
- // Copy in name of the executable to run (should be the dart vm).
- script_name_ = Utils::StrDup(exec_name);
- argv_[idx++] = script_name_;
- // Copy in VM options if any.
- // Copy in any vm options that need to be passed to the execed process.
- for (intptr_t i = 0; i < num_vm_options; ++i) {
- argv_[i + idx] = Utils::StrDup(vm_options[i]);
- }
- idx += num_vm_options;
- {
- const size_t kPathBufSize = PATH_MAX + 1;
- char dart_path[kPathBufSize];
- Platform::ResolveExecutablePathInto(dart_path, kPathBufSize);
- argv_[idx++] = Utils::SCreate("--executable_name=%s", dart_path);
- }
- if (mark_main_isolate_as_system_isolate) {
- argv_[idx++] = Utils::StrDup("--mark_main_isolate_as_system_isolate");
- }
- // Copy in name of the script to run.
- argv_[idx++] = Utils::StrDup(GetArrayItem(message, 1)->value.as_string);
- // Copy in the dart options that need to be passed to the script.
- for (intptr_t i = 0; i < argc; ++i) {
- argv_[i + idx] = Utils::StrDup(dart_args[i]->value.as_string);
- }
- // Null terminate the argv array.
- argv_[argc + idx] = nullptr;
- }
-
- // Process the DartDev_Result_Exit result message produced by
- // VmInteropHandler in pkg/dartdev/lib/src/vm_interop_handler.dart
- static void ExitResultCallback(Dart_CObject* message) {
- ASSERT(GetArrayItem(message, 1)->type == Dart_CObject_kInt32);
- int32_t dartdev_exit_code = GetArrayItem(message, 1)->value.as_int32;
-
- // If we're given a non-zero exit code, DartDev is signaling for us to
- // shutdown.
- Process::SetGlobalExitCode(dartdev_exit_code);
-
- // If DartDev hasn't signaled for us to do anything else, we can assume
- // there's nothing else for the VM to run and that we can exit.
- if (result_ == DartDev_Result_Unknown || dartdev_exit_code != 0) {
- result_ = DartDev_Result_Exit;
- }
- // Notify the dartdev runner that it can proceed with processing
- // the result from execution of dartdev.
- {
- MonitorLocker locker(monitor_);
- locker.Notify();
- }
- }
-
- // Callback that processes the result from execution of dartdev
- //
- static void ResultCallback(Dart_Port dest_port_id, Dart_CObject* message) {
- // These messages are produced in
- // pkg/dartdev/lib/src/vm_interop_handler.dart.
- ASSERT(message->type == Dart_CObject_kArray);
- int32_t type = GetArrayItem(message, 0)->value.as_int32;
- switch (type) {
- case DartDev_Result_Run: {
- RunResultCallback(message);
- break;
- }
- case DartDev_Result_RunExec: {
- RunExecResultCallback(message);
- break;
- }
- case DartDev_Result_Exit: {
- ExitResultCallback(message);
- break;
- }
- default:
- UNREACHABLE();
- }
- }
-
- static void RunDartDev(const char* script_name,
- CommandLineOptions* dart_vm_options,
- CommandLineOptions* dart_options) {
- ASSERT(script_name != nullptr);
- const char* base_name = strrchr(script_name, '/');
- if (base_name == nullptr) {
- base_name = script_name;
- } else {
- base_name++; // Skip '/'.
- }
- const intptr_t kMaxNameLength = 64;
- char name[kMaxNameLength];
- Utils::SNPrint(name, kMaxNameLength, "dart:%s", base_name);
- Platform::SetProcessName(name);
-
- dart_vm_options_ = dart_vm_options;
-
- // Call CreateIsolateGroupAndSetup which creates an isolate and loads up
- // the specified application script.
- Dart_IsolateFlags flags;
- Dart_IsolateFlagsInitialize(&flags);
-#if defined(DART_HOST_OS_LINUX)
- // This would also be true in Linux, except that Google3 overrides the
- // default ELF interpreter to one that apparently doesn't create proper
- // mappings.
- flags.snapshot_is_dontneed_safe = false;
-#else
- flags.snapshot_is_dontneed_safe = true;
-#endif
- flags.is_system_isolate = true;
- SpawnIsolate(script_name, "_startIsolate",
- /*is_dartdev_isolate*/ true,
- /*package_config_override*/ nullptr, &flags, dart_options);
-
- // Wait for the callbacks on the native port to be done before we
- // proceed.
- {
- MonitorLocker locker(monitor_);
- while (result_ == DartDev_Result_Unknown) {
- locker.Wait();
- }
- }
-
- /* Process the result returned by the dartdev isolate. */
- switch (result_) {
- case DartDev_Result_Run: {
- flags.is_system_isolate = false;
- SpawnIsolate(script_name_, "_startMainIsolate",
- /*is_dartdev_isolate*/ false, package_config_override_,
- &flags, dart_options);
- free(script_name_);
- free(package_config_override_);
- break;
- }
- case DartDev_Result_RunExec: {
- RunExec(script_name_);
- break;
- }
- case DartDev_Result_Exit: {
- // Nothing to do here, the process will terminate with the exit code
- // set earlier.
- break;
- }
- default:
- UNREACHABLE();
- }
- }
-
- private:
- static void SpawnIsolate(const char* script_name,
- const char* entry_point,
- bool is_dartdev_isolate,
- const char* package_config_override,
- Dart_IsolateFlags* flags,
- CommandLineOptions* dart_options) {
- // Start a new Isolate with the specified AOT snapshot.
- int exit_code = 0;
- char* error = nullptr;
-
- Dart_Isolate isolate = CreateIsolateGroupAndSetupHelper(
- is_dartdev_isolate, script_name, "main",
- Options::packages_file() == nullptr ? package_config_override
- : Options::packages_file(),
- flags, nullptr /* callback_data */, &error, &exit_code);
-
- if (isolate == nullptr) {
- if (error != nullptr) {
- Syslog::PrintErr("Isolate spawning failed: %s\n", error);
- free(error);
- }
- error = nullptr;
- Process::TerminateExitCodeHandler();
- error = Dart_Cleanup();
- if (error != nullptr) {
- Syslog::PrintErr("Dart_Cleanup failed: %s\n", error);
- free(error);
- }
- dart::embedder::Cleanup();
- Platform::Exit((exit_code != 0) ? exit_code : kErrorExitCode);
- }
-
- Dart_EnterIsolate(isolate);
- ASSERT(isolate == Dart_CurrentIsolate());
- ASSERT(isolate != nullptr);
- Dart_Handle result;
-
- Dart_EnterScope();
-
- Dart_Handle send_port = Dart_Null();
- Dart_Port send_port_id = ILLEGAL_PORT;
- if (is_dartdev_isolate) {
- // Create a SendPort that DartDev can use to communicate its results over.
- send_port_id =
- Dart_NewNativePort(DART_DEV_ISOLATE_NAME, ResultCallback, false);
- ASSERT(send_port_id != ILLEGAL_PORT);
- send_port = Dart_NewSendPort(send_port_id);
- CHECK_RESULT(send_port);
- }
-
- // Lookup the library of the root script.
- Dart_Handle root_lib = Dart_RootLibrary();
-
- if (Dart_IsNull(root_lib)) {
- ErrorExit(kErrorExitCode, "Unable to find root library for '%s'\n",
- script_name);
- }
-
- // Create a closure for the main entry point which is in the exported
- // namespace of the root library or invoke a getter of the same name
- // in the exported namespace and return the resulting closure.
- Dart_Handle main_closure =
- Dart_GetField(root_lib, Dart_NewStringFromCString("main"));
- CHECK_RESULT(main_closure);
- if (!Dart_IsClosure(main_closure)) {
- ErrorExit(kErrorExitCode, "Unable to find 'main' in root library '%s'\n",
- script_name);
- }
-
- Dart_Handle isolate_lib =
- Dart_LookupLibrary(Dart_NewStringFromCString("dart:isolate"));
- if (is_dartdev_isolate) {
- const intptr_t kNumIsolateArgs = 4;
- Dart_Handle isolate_args[kNumIsolateArgs];
- isolate_args[0] = main_closure; // entryPoint
- isolate_args[1] = dart_options->CreateRuntimeOptions(); // args
- isolate_args[2] = send_port;
- isolate_args[3] = Dart_True(); // isSpawnUri
- result = Dart_Invoke(isolate_lib, Dart_NewStringFromCString(entry_point),
- kNumIsolateArgs, isolate_args);
- } else {
- // Call _startIsolate in the isolate library to enable dispatching the
- // initial startup message.
- dart_options->Reset();
- dart_options->AddArguments(const_cast<const char**>(argv_.get()), argc_);
- const intptr_t kNumIsolateArgs = 2;
- Dart_Handle isolate_args[kNumIsolateArgs];
- isolate_args[0] = main_closure; // entryPoint
- isolate_args[1] = dart_options->CreateRuntimeOptions(); // args
- result = Dart_Invoke(isolate_lib, Dart_NewStringFromCString(entry_point),
- kNumIsolateArgs, isolate_args);
- }
- CHECK_RESULT(result);
-
- // Keep handling messages until the last active receive port is closed.
- result = Dart_RunLoop();
- CHECK_RESULT(result);
-
- if (is_dartdev_isolate) {
- // DartDev is done processing the command. Close the native port, this
- // will ensure we exit from the event handler loop and exit dartdev
- // isolate.
- Dart_CloseNativePort(send_port_id);
- }
- Dart_ExitScope();
-
- // Shutdown the isolate.
- Dart_ShutdownIsolate();
- }
-
- static void RunExec(const char* script_name) {
- // Exec the JIT Dart VM with the specified script file.
- char err_msg[256];
- err_msg[0] = '\0';
- int ret = Process::Exec(nullptr, script_name,
- const_cast<const char**>(argv_.get()), argc_,
- nullptr, err_msg, sizeof(err_msg));
- if (ret != 0) {
- Syslog::PrintErr("%s.\n", err_msg);
- Process::SetGlobalExitCode(ret);
- } else {
- Process::SetGlobalExitCode(ret);
- }
- }
-
- static Dart_CObject* GetArrayItem(Dart_CObject* message, intptr_t index) {
- return message->value.as_array.values[index];
- }
-
- static Monitor* monitor_;
- static DartDev_Result result_;
- static char* script_name_;
- static char* package_config_override_;
- static CommandLineOptions* dart_vm_options_;
- static std::unique_ptr<char*[], void (*)(char**)> argv_;
- static intptr_t argc_;
-};
-
-Monitor* DartDev::monitor_ = new Monitor();
-DartDev::DartDev_Result DartDev::result_ = DartDev::DartDev_Result_Unknown;
-char* DartDev::script_name_ = nullptr;
-char* DartDev::package_config_override_ = nullptr;
-CommandLineOptions* DartDev::dart_vm_options_ = nullptr;
-std::unique_ptr<char*[], void (*)(char**)> DartDev::argv_ =
- std::unique_ptr<char*[], void (*)(char**)>(nullptr, [](char**) {});
-intptr_t DartDev::argc_ = 0;
-
-#undef CHECK_RESULT
-
-static void FreeConvertedArgs(int argc, char** argv, bool argv_converted) {
- // Free copied argument strings if converted.
- if (argv_converted) {
- for (int i = 0; i < argc; i++) {
- free(argv[i]);
- }
- }
-}
-
-void main(int argc, char** argv) {
-#if !defined(DART_HOST_OS_WINDOWS)
- // Very early so any crashes during startup can also be symbolized.
- EXEUtils::LoadDartProfilerSymbols(argv[0]);
-#endif
-
- const int EXTRA_VM_ARGUMENTS = 10;
- // An invocation line is as follows
- // dart <vm_opts> <cmd-name> <vm-opts-to-cmd> <script_name> <dart-options>
-
- // vm-opts : Set of VM options that need to be passed to the AOT runtime
- // running in this dartdev process.
- CommandLineOptions vm_options(argc + EXTRA_VM_ARGUMENTS);
-
- // vm-opts-to-cmd : Set of VM options that need to be passed to the runtime
- // that executes the dartdev command.
- CommandLineOptions dart_vm_options(argc + EXTRA_VM_ARGUMENTS);
-
- // dart-options : Set of options to be passed to the Dart program
- CommandLineOptions dart_options(argc + EXTRA_VM_ARGUMENTS);
-
- // Perform platform specific initialization.
- if (!Platform::Initialize()) {
- Syslog::PrintErr("Initialization failed\n");
- Platform::Exit(kErrorExitCode);
- }
-
- // Save the console state so we can restore it at shutdown.
- Console::SaveConfig();
-
- // On Windows, the argv strings are code page encoded and not
- // utf8. We need to convert them to utf8.
- bool argv_converted = ShellUtils::GetUtf8Argv(argc, argv);
-
- // When running from the command line we assume that we are optimizing for
- // throughput, and therefore use a larger new gen semi space size and a faster
- // new gen growth factor unless others have been specified.
- if (kWordSize <= 4) {
- vm_options.AddArgument("--new_gen_semi_max_size=16");
- } else {
- vm_options.AddArgument("--new_gen_semi_max_size=32");
- }
- vm_options.AddArgument("--new_gen_growth_factor=4");
-
- // Parse command line arguments.
- bool skip_dartdev;
- bool success = Options::ParseDartDevArguments(
- argc, argv, &vm_options, &dart_vm_options, &dart_options, &skip_dartdev);
- if (!success) {
- FreeConvertedArgs(argc, argv, argv_converted);
- if (Options::help_option()) {
- Options::PrintUsage();
- Platform::Exit(0);
- } else if (Options::version_option()) {
- Options::PrintVersion();
- Platform::Exit(0);
- } else {
- Options::PrintUsage();
- Platform::Exit(kErrorExitCode);
- }
- }
- if (skip_dartdev) {
- // We are skipping execution of dartdev as no Dart command line has
- // been specified, in this case we directly exec the Dart JIT VM to
- // run the specified script and pass in the original command line
- // arguments.
- DartDev::InvokeDartVM(argc, argv, argv_converted);
- }
-
- DartUtils::SetEnvironment(Options::environment());
-
- if (Options::suppress_core_dump()) {
- Platform::SetCoreDumpResourceLimit(0);
- }
-
- Loader::InitOnce();
-
- // Setup script_name to point to the dartdev AOT snapshot.
- auto dartdev_path = DartDev::ResolvedSnapshotPath();
- char* script_name = dartdev_path.get();
- if (script_name == nullptr || !CheckForInvalidPath(script_name)) {
- Syslog::PrintErr("Unable to find AOT snapshot for dartdev\n");
- FreeConvertedArgs(argc, argv, argv_converted);
- Platform::Exit(kErrorExitCode);
- }
- AppSnapshot* app_snapshot = Snapshot::TryReadAppSnapshot(
- script_name, /*force_load_from_memory*/ false, /*decode_uri*/ false);
- if (app_snapshot == nullptr || !app_snapshot->IsAOT()) {
- Syslog::PrintErr("%s is not an AOT snapshot\n", script_name);
- FreeConvertedArgs(argc, argv, argv_converted);
- if (app_snapshot != nullptr) {
- delete app_snapshot;
- }
- Platform::Exit(kErrorExitCode);
- }
- app_snapshot->SetBuffers(
- &ignore_vm_snapshot_data, &ignore_vm_snapshot_instructions,
- &app_isolate_snapshot_data, &app_isolate_snapshot_instructions);
-
- vm_options.AddArgument("--precompilation");
-
- char* error = nullptr;
- if (!dart::embedder::InitOnce(&error)) {
- Syslog::PrintErr("dartdev embedder initialization failed: %s\n", error);
- free(error);
- FreeConvertedArgs(argc, argv, argv_converted);
- delete app_snapshot;
- Platform::Exit(kErrorExitCode);
- }
-
- error = Dart_SetVMFlags(vm_options.count(), vm_options.arguments());
- if (error != nullptr) {
- for (int i = 0; i < argc; i++) {
- Syslog::PrintErr("argv[%d]: %s\n", i, argv[i]);
- }
- Syslog::PrintErr("Setting VM flags failed: %s\n", error);
- free(error);
- FreeConvertedArgs(argc, argv, argv_converted);
- delete app_snapshot;
- Platform::Exit(kErrorExitCode);
- }
-
- // Initialize the Dart VM.
- Dart_InitializeParams init_params;
- memset(&init_params, 0, sizeof(init_params));
- init_params.version = DART_INITIALIZE_PARAMS_CURRENT_VERSION;
- init_params.vm_snapshot_data = ignore_vm_snapshot_data;
- init_params.vm_snapshot_instructions = ignore_vm_snapshot_instructions;
- init_params.create_group = CreateIsolateGroupAndSetup;
- init_params.initialize_isolate = OnIsolateInitialize;
- init_params.shutdown_isolate = OnIsolateShutdown;
- init_params.cleanup_isolate = DeleteIsolateData;
- init_params.cleanup_group = DeleteIsolateGroupData;
- init_params.file_open = DartUtils::OpenFile;
- init_params.file_read = DartUtils::ReadFile;
- init_params.file_write = DartUtils::WriteFile;
- init_params.file_close = DartUtils::CloseFile;
- init_params.entropy_source = DartUtils::EntropySource;
- init_params.start_kernel_isolate = false;
-#if defined(DART_HOST_OS_FUCHSIA)
- init_params.vmex_resource = ZX_HANDLE_INVALID;
-#endif
-
- error = Dart_Initialize(&init_params);
- if (error != nullptr) {
- dart::embedder::Cleanup();
- Syslog::PrintErr("VM initialization failed: %s\n", error);
- free(error);
- FreeConvertedArgs(argc, argv, argv_converted);
- delete app_snapshot;
- Platform::Exit(kErrorExitCode);
- }
-
- Dart_SetServiceStreamCallbacks(&ServiceStreamListenCallback,
- &ServiceStreamCancelCallback);
- Dart_SetFileModifiedCallback(&FileModifiedCallback);
- Dart_SetEmbedderInformationCallback(&EmbedderInformationCallback);
-
- // Run dartdev as the main isolate.
- // The result from the running the dartdev isolate could result in one of
- // these options
- // - Exit the process due to some command parsing errors
- // - Run the Dart script in a JIT mode by execing the JIT runtime
- // - Run the Dart AOT snapshot by creating a new Isolate
- DartDev::RunDartDev(script_name, &dart_vm_options, &dart_options);
-
- // Terminate process exit-code handler.
- Process::TerminateExitCodeHandler();
-
- error = Dart_Cleanup();
- if (error != nullptr) {
- Syslog::PrintErr("VM cleanup failed: %s\n", error);
- free(error);
- }
- const intptr_t global_exit_code = Process::GlobalExitCode();
- dart::embedder::Cleanup();
-
- delete app_snapshot;
-
- // Free copied argument strings if converted.
- if (argv_converted) {
- for (int i = 0; i < argc; i++) {
- free(argv[i]);
- }
- }
-
- // Free environment if any.
- Options::Cleanup();
-
- Platform::Exit(global_exit_code);
-}
-#else
-void main(int argc, char** argv) {
- Platform::Exit(kErrorExitCode);
-}
-#endif // defined(DART_PRECOMPILED_RUNTIME)
-
-} // namespace bin
-} // namespace dart
-
-int main(int argc, char** argv) {
- dart::bin::main(argc, argv);
- UNREACHABLE();
-}
diff --git a/runtime/bin/dartdev_isolate.cc b/runtime/bin/dartdev_isolate.cc
new file mode 100644
index 0000000..7287db7
--- /dev/null
+++ b/runtime/bin/dartdev_isolate.cc
@@ -0,0 +1,415 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "bin/dartdev_isolate.h"
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
+
+#include <functional>
+#include <memory>
+
+#include "bin/directory.h"
+#include "bin/error_exit.h"
+#include "bin/exe_utils.h"
+#include "bin/file.h"
+#include "bin/lockers.h"
+#include "bin/main_options.h"
+#include "bin/platform.h"
+#include "bin/process.h"
+#include "include/dart_embedder_api.h"
+#include "platform/utils.h"
+
+#define CHECK_RESULT(result) \
+ if (Dart_IsError(result)) { \
+ ProcessError(Dart_GetError(result), kErrorExitCode); \
+ if (send_port_id != ILLEGAL_PORT) { \
+ Dart_CloseNativePort(send_port_id); \
+ } \
+ Dart_ExitScope(); \
+ Dart_ShutdownIsolate(); \
+ return; \
+ }
+
+namespace dart {
+namespace bin {
+
+DartDevIsolate::DartDevRunner DartDevIsolate::runner_ =
+ DartDevIsolate::DartDevRunner();
+bool DartDevIsolate::should_run_dart_dev_ = false;
+bool DartDevIsolate::print_usage_error_ = false;
+CommandLineOptions* DartDevIsolate::vm_options_ = nullptr;
+Monitor* DartDevIsolate::DartDevRunner::monitor_ = new Monitor();
+DartDevIsolate::DartDev_Result DartDevIsolate::DartDevRunner::result_ =
+ DartDevIsolate::DartDev_Result_Unknown;
+char** DartDevIsolate::DartDevRunner::script_ = nullptr;
+char** DartDevIsolate::DartDevRunner::package_config_override_ = nullptr;
+std::unique_ptr<char*[], void (*)(char*[])>
+ DartDevIsolate::DartDevRunner::argv_ =
+ std::unique_ptr<char*[], void (*)(char**)>(nullptr, [](char**) {});
+intptr_t DartDevIsolate::DartDevRunner::argc_ = 0;
+
+bool DartDevIsolate::ShouldParseCommand(const char* script_uri) {
+ // If script_uri is a known DartDev command, we should not try to run it.
+ //
+ // Otherwise if script_uri is not a file path or of a known URI scheme, we
+ // assume this is a mistyped DartDev command.
+ //
+ // This should be kept in sync with the commands in
+ // `pkg/dartdev/lib/dartdev.dart`.
+ return (
+ (strcmp(script_uri, "analyze") == 0) ||
+ (strcmp(script_uri, "compilation-server") == 0) ||
+ (strcmp(script_uri, "build") == 0) ||
+ (strcmp(script_uri, "compile") == 0) ||
+ (strcmp(script_uri, "create") == 0) ||
+ (strcmp(script_uri, "development-service") == 0) ||
+ (strcmp(script_uri, "devtools") == 0) ||
+ (strcmp(script_uri, "doc") == 0) || (strcmp(script_uri, "fix") == 0) ||
+ (strcmp(script_uri, "format") == 0) ||
+ (strcmp(script_uri, "info") == 0) ||
+ (strcmp(script_uri, "mcp-server") == 0) ||
+ (strcmp(script_uri, "pub") == 0) || (strcmp(script_uri, "run") == 0) ||
+ (strcmp(script_uri, "test") == 0) || (strcmp(script_uri, "info") == 0) ||
+ (strcmp(script_uri, "language-server") == 0) ||
+ (strcmp(script_uri, "tooling-daemon") == 0) ||
+ (!File::ExistsUri(nullptr, script_uri) &&
+ (strncmp(script_uri, "http://", 7) != 0) &&
+ (strncmp(script_uri, "https://", 8) != 0) &&
+ (strncmp(script_uri, "file://", 7) != 0) &&
+ (strncmp(script_uri, "package:", 8) != 0) &&
+ (strncmp(script_uri, "google3://", 10) != 0)));
+}
+
+bool DartDevIsolate::ShouldParseVMOptions(const char* command) {
+ // If command is 'run' or 'test' parse the VM options as we need to pass
+ // it down to the VM that executes these commands.
+ return (strcmp(command, "run") == 0) || (strcmp(command, "test") == 0);
+}
+
+CStringUniquePtr DartDevIsolate::TryResolveArtifactPath(const char* filename) {
+ auto try_resolve_path = [&](CStringUniquePtr dir_prefix) {
+ // First assume we're in dart-sdk/bin.
+ char* snapshot_path =
+ Utils::SCreate("%ssnapshots/%s", dir_prefix.get(), filename);
+ if (File::Exists(nullptr, snapshot_path)) {
+ return CStringUniquePtr(snapshot_path);
+ }
+ free(snapshot_path);
+
+ // If we're not in dart-sdk/bin, we might be in one of the $SDK/out/*
+ // directories. Try to use a snapshot from a previously built SDK.
+ snapshot_path = Utils::SCreate("%s%s", dir_prefix.get(), filename);
+ if (File::Exists(nullptr, snapshot_path)) {
+ return CStringUniquePtr(snapshot_path);
+ }
+ free(snapshot_path);
+ return CStringUniquePtr(nullptr);
+ };
+
+ // Try to find the artifact using the resolved EXE path first. This can fail
+ // if the Dart SDK file structure is faked using symlinks and the actual
+ // artifacts are spread across directories on the file system (e.g., some
+ // google3 execution environments).
+ auto result =
+ try_resolve_path(EXEUtils::GetDirectoryPrefixFromResolvedExeName());
+ if (result == nullptr) {
+ result =
+ try_resolve_path(EXEUtils::GetDirectoryPrefixFromUnresolvedExeName());
+ }
+
+ return result;
+}
+
+CStringUniquePtr DartDevIsolate::TryResolveDartDevSnapshotPath() {
+ return TryResolveArtifactPath("dartdev.dart.snapshot");
+}
+
+void DartDevIsolate::DartDevRunner::Run(
+ Dart_IsolateGroupCreateCallback create_isolate,
+ char** packages_file,
+ char** script,
+ CommandLineOptions* dart_options) {
+ create_isolate_ = create_isolate;
+ dart_options_ = dart_options;
+ package_config_override_ = packages_file;
+ script_ = script;
+
+ // We've encountered an error during preliminary argument parsing so we'll
+ // output the standard help message and exit with an error code.
+ if (print_usage_error_) {
+ dart_options_->Reset();
+ dart_options_->AddArgument("--help");
+ }
+
+ MonitorLocker locker(monitor_);
+ Thread::Start("DartDev Runner", RunCallback, reinterpret_cast<uword>(this));
+ monitor_->WaitMicros(Monitor::kNoTimeout);
+
+ if (result_ == DartDevIsolate::DartDev_Result_Run) {
+ // Clear the DartDev dart_options and replace them with the processed
+ // options provided by DartDev.
+ dart_options_->Reset();
+ dart_options_->AddArguments(const_cast<const char**>(argv_.get()), argc_);
+ }
+}
+
+static Dart_CObject* GetArrayItem(Dart_CObject* message, intptr_t index) {
+ return message->value.as_array.values[index];
+}
+
+void DartDevIsolate::DartDevRunner::DartDevResultCallback(
+ Dart_Port dest_port_id,
+ Dart_CObject* message) {
+ // These messages are produced in pkg/dartdev/lib/src/vm_interop_handler.dart.
+ ASSERT(message->type == Dart_CObject_kArray);
+ int32_t type = GetArrayItem(message, 0)->value.as_int32;
+ switch (type) {
+ case DartDevIsolate::DartDev_Result_Run: {
+ result_ = DartDevIsolate::DartDev_Result_Run;
+ ASSERT(GetArrayItem(message, 1)->type == Dart_CObject_kString);
+ auto item2 = GetArrayItem(message, 2);
+
+ ASSERT(item2->type == Dart_CObject_kString ||
+ item2->type == Dart_CObject_kNull);
+
+ auto item3 = GetArrayItem(message, 3);
+
+ ASSERT(item3->type == Dart_CObject_kBool);
+ const bool mark_main_isolate_as_system_isolate = item3->value.as_bool;
+ if (mark_main_isolate_as_system_isolate) {
+ Options::set_mark_main_isolate_as_system_isolate(true);
+ }
+
+ if (*script_ != nullptr) {
+ free(*script_);
+ }
+ if (*package_config_override_ != nullptr) {
+ free(*package_config_override_);
+ *package_config_override_ = nullptr;
+ }
+ *script_ = Utils::StrDup(GetArrayItem(message, 1)->value.as_string);
+
+ if (item2->type == Dart_CObject_kString) {
+ *package_config_override_ = Utils::StrDup(item2->value.as_string);
+ }
+
+ ASSERT(GetArrayItem(message, 4)->type == Dart_CObject_kArray);
+ Dart_CObject* args = GetArrayItem(message, 4);
+ argc_ = args->value.as_array.length;
+ Dart_CObject** dart_args = args->value.as_array.values;
+
+ auto deleter = [](char** args) {
+ for (intptr_t i = 0; i < argc_; ++i) {
+ free(args[i]);
+ }
+ delete[] args;
+ };
+ argv_ =
+ std::unique_ptr<char*[], void (*)(char**)>(new char*[argc_], deleter);
+ for (intptr_t i = 0; i < argc_; ++i) {
+ argv_[i] = Utils::StrDup(dart_args[i]->value.as_string);
+ }
+ break;
+ }
+ case DartDevIsolate::DartDev_Result_RunExec: {
+ result_ = DartDevIsolate::DartDev_Result_RunExec;
+ ASSERT(GetArrayItem(message, 1)->type == Dart_CObject_kString);
+ auto item2 = GetArrayItem(message, 2);
+
+ ASSERT(item2->type == Dart_CObject_kString ||
+ item2->type == Dart_CObject_kNull);
+
+ auto item3 = GetArrayItem(message, 3);
+
+ ASSERT(item3->type == Dart_CObject_kBool);
+ const bool mark_main_isolate_as_system_isolate = item3->value.as_bool;
+ if (mark_main_isolate_as_system_isolate) {
+ Options::set_mark_main_isolate_as_system_isolate(true);
+ }
+
+ if (*script_ != nullptr) {
+ free(*script_);
+ }
+ if (*package_config_override_ != nullptr) {
+ free(*package_config_override_);
+ *package_config_override_ = nullptr;
+ }
+ *script_ = Utils::StrDup(GetArrayItem(message, 1)->value.as_string);
+
+ if (item2->type == Dart_CObject_kString) {
+ *package_config_override_ = Utils::StrDup(item2->value.as_string);
+ }
+
+ intptr_t num_vm_options = 0;
+ const char** vm_options = nullptr;
+ ASSERT(GetArrayItem(message, 4)->type == Dart_CObject_kArray);
+ Dart_CObject* args = GetArrayItem(message, 4);
+ intptr_t argc = args->value.as_array.length;
+ Dart_CObject** dart_args = args->value.as_array.values;
+
+ if (vm_options_ != nullptr) {
+ num_vm_options = vm_options_->count();
+ vm_options = vm_options_->arguments();
+ }
+ auto deleter = [](char** args) {
+ for (intptr_t i = 0; i < argc_; ++i) {
+ free(args[i]);
+ }
+ delete[] args;
+ };
+ // Total count of arguments to be passed to the script being execed.
+ argc_ = argc + num_vm_options + 1;
+
+ // Array of arguments to be passed to the script being execed.
+ argv_ = std::unique_ptr<char*[], void (*)(char**)>(new char*[argc_ + 1],
+ deleter);
+
+ intptr_t idx = 0;
+ // Copy in name of the script to run (dartaotruntime).
+ argv_[0] = Utils::StrDup(GetArrayItem(message, 1)->value.as_string);
+ idx += 1;
+ // Copy in any vm options that need to be passed to the execed process.
+ for (intptr_t i = 0; i < num_vm_options; ++i) {
+ argv_[i + idx] = Utils::StrDup(vm_options[i]);
+ }
+ idx += num_vm_options;
+ // Copy in the dart options that need to be passed to the command.
+ for (intptr_t i = 0; i < argc; ++i) {
+ argv_[i + idx] = Utils::StrDup(dart_args[i]->value.as_string);
+ }
+ // Null terminate the argv array.
+ argv_[argc + idx] = nullptr;
+
+ // Exec the script to be run and pass the arguments.
+ char err_msg[256];
+ err_msg[0] = '\0';
+ int ret = Process::Exec(nullptr, *script_,
+ const_cast<const char**>(argv_.get()), argc_,
+ nullptr, err_msg, sizeof(err_msg));
+ if (ret != 0) {
+ ProcessError(err_msg, kErrorExitCode);
+ }
+ break;
+ }
+ case DartDevIsolate::DartDev_Result_Exit: {
+ ASSERT(GetArrayItem(message, 1)->type == Dart_CObject_kInt32);
+ int32_t dartdev_exit_code = GetArrayItem(message, 1)->value.as_int32;
+
+ // If we're given a non-zero exit code, DartDev is signaling for us to
+ // shutdown.
+ int32_t exit_code =
+ print_usage_error_ ? kErrorExitCode : dartdev_exit_code;
+ Process::SetGlobalExitCode(exit_code);
+
+ // If DartDev hasn't signaled for us to do anything else, we can assume
+ // there's nothing else for the VM to run and that we can exit.
+ if (result_ == DartDevIsolate::DartDev_Result_Unknown) {
+ result_ = DartDevIsolate::DartDev_Result_Exit;
+ }
+
+ // DartDev is done processing the command. Unblock the main thread and
+ // continue the launch procedure.
+ DartDevRunner::monitor_->Notify();
+ break;
+ }
+ default:
+ UNREACHABLE();
+ }
+}
+
+void DartDevIsolate::DartDevRunner::RunCallback(uword args) {
+ MonitorLocker locker_(DartDevRunner::monitor_);
+ DartDevRunner* runner = reinterpret_cast<DartDevRunner*>(args);
+
+ // Hardcode flags to match those used to generate the DartDev snapshot.
+ Dart_IsolateFlags flags;
+ Dart_IsolateFlagsInitialize(&flags);
+ flags.enable_asserts = false;
+ flags.use_field_guards = true;
+ flags.use_osr = true;
+ flags.is_system_isolate = true;
+ flags.branch_coverage = true;
+ flags.coverage = false;
+
+ char* error = nullptr;
+ Dart_Isolate dartdev_isolate = runner->create_isolate_(
+ DART_DEV_ISOLATE_NAME, DART_DEV_ISOLATE_NAME, nullptr,
+ runner->packages_file_, &flags, /* callback_data */ nullptr,
+ const_cast<char**>(&error));
+
+ if (dartdev_isolate == nullptr) {
+ ProcessError(error, kErrorExitCode);
+ free(error);
+ return;
+ }
+
+ Dart_EnterIsolate(dartdev_isolate);
+ Dart_EnterScope();
+
+ // Retrieve the DartDev entrypoint.
+ Dart_Port send_port_id = ILLEGAL_PORT;
+ Dart_Handle root_lib = Dart_RootLibrary();
+ Dart_Handle main_closure =
+ Dart_GetField(root_lib, Dart_NewStringFromCString("main"));
+ CHECK_RESULT(main_closure);
+
+ if (!Dart_IsClosure(main_closure)) {
+ ProcessError("Unable to find 'main' in root library 'dartdev'",
+ kErrorExitCode);
+ Dart_ExitScope();
+ Dart_ShutdownIsolate();
+ return;
+ }
+
+ // Create a SendPort that DartDev can use to communicate its results over.
+ send_port_id =
+ Dart_NewNativePort(DART_DEV_ISOLATE_NAME, DartDevResultCallback, false);
+ ASSERT(send_port_id != ILLEGAL_PORT);
+ Dart_Handle send_port = Dart_NewSendPort(send_port_id);
+ CHECK_RESULT(send_port);
+
+ const intptr_t kNumIsolateArgs = 4;
+ Dart_Handle isolate_args[kNumIsolateArgs];
+ isolate_args[0] = main_closure; // entryPoint
+ isolate_args[1] = runner->dart_options_->CreateRuntimeOptions(); // args
+ isolate_args[2] = send_port; // message
+ isolate_args[3] = Dart_True(); // isSpawnUri
+
+ Dart_Handle isolate_lib =
+ Dart_LookupLibrary(Dart_NewStringFromCString("dart:isolate"));
+ Dart_Handle result =
+ Dart_Invoke(isolate_lib, Dart_NewStringFromCString("_startIsolate"),
+ kNumIsolateArgs, isolate_args);
+ CHECK_RESULT(result);
+ CHECK_RESULT(Dart_RunLoop());
+
+ Dart_CloseNativePort(send_port_id);
+
+ Dart_ExitScope();
+ Dart_ShutdownIsolate();
+}
+
+void DartDevIsolate::DartDevRunner::ProcessError(const char* msg,
+ int32_t exit_code) {
+ Syslog::PrintErr("%s.\n", msg);
+ Process::SetGlobalExitCode(exit_code);
+ result_ = DartDevIsolate::DartDev_Result_Exit;
+ DartDevRunner::monitor_->Notify();
+}
+
+DartDevIsolate::DartDev_Result DartDevIsolate::RunDartDev(
+ Dart_IsolateGroupCreateCallback create_isolate,
+ char** packages_file,
+ char** script,
+ CommandLineOptions* vm_options,
+ CommandLineOptions* dart_options) {
+ vm_options_ = vm_options;
+ runner_.Run(create_isolate, packages_file, script, dart_options);
+ return runner_.result();
+}
+
+} // namespace bin
+} // namespace dart
+
+#endif // if !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/bin/dartdev_isolate.h b/runtime/bin/dartdev_isolate.h
new file mode 100644
index 0000000..c5e476d
--- /dev/null
+++ b/runtime/bin/dartdev_isolate.h
@@ -0,0 +1,118 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#ifndef RUNTIME_BIN_DARTDEV_ISOLATE_H_
+#define RUNTIME_BIN_DARTDEV_ISOLATE_H_
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
+
+#include <memory>
+
+#include "bin/thread.h"
+#include "include/dart_api.h"
+#include "include/dart_native_api.h"
+#include "platform/globals.h"
+#include "platform/utils.h"
+
+#define DART_DEV_ISOLATE_NAME "dartdev"
+
+namespace dart {
+namespace bin {
+
+class CommandLineOptions;
+
+class DartDevIsolate {
+ public:
+ // Note: keep in sync with pkg/dartdev/lib/vm_interop_handler.dart
+ typedef enum {
+ DartDev_Result_Unknown = -1,
+ DartDev_Result_Run = 1,
+ DartDev_Result_RunExec = 2,
+ DartDev_Result_Exit = 3,
+ } DartDev_Result;
+
+ // Returns true if there does not exist a file at |script_uri| or the URI is
+ // not an HTTP resource.
+ static bool ShouldParseCommand(const char* script_uri);
+
+ // Returns true if VM options need to be recorded and passed to the VM
+ // that executes the command (this is true only for dart CL commands like
+ // 'run' and 'test'.
+ static bool ShouldParseVMOptions(const char* command);
+
+ static void set_should_run_dart_dev(bool enable) {
+ should_run_dart_dev_ = enable;
+ }
+
+ static void PrintUsageErrorOnRun() {
+ set_should_run_dart_dev(true);
+ print_usage_error_ = true;
+ }
+
+ static bool should_run_dart_dev() { return should_run_dart_dev_; }
+
+ // Attempts to find the path of the DartDev snapshot.
+ static CStringUniquePtr TryResolveDartDevSnapshotPath();
+
+ // Starts a DartDev instance in a new isolate and runs it to completion.
+ //
+ // Returns true if the VM should run the result in `script`, in which case
+ // `script` and `dart_options` will have been repopulated with the correct
+ // values.
+ static DartDev_Result RunDartDev(
+ Dart_IsolateGroupCreateCallback create_isolate,
+ char** packages_file,
+ char** script,
+ CommandLineOptions* vm_options,
+ CommandLineOptions* dart_options);
+
+ protected:
+ class DartDevRunner {
+ public:
+ DartDevRunner() {}
+
+ void Run(Dart_IsolateGroupCreateCallback create_isolate,
+ char** package_config_override_,
+ char** script,
+ CommandLineOptions* dart_options);
+
+ DartDev_Result result() const { return result_; }
+
+ private:
+ static void DartDevResultCallback(Dart_Port dest_port_id,
+ Dart_CObject* message);
+ static void RunCallback(uword arg);
+ static void ProcessError(const char* msg, int32_t exit_code);
+
+ static DartDev_Result result_;
+ static char** script_;
+ static char** package_config_override_;
+ static std::unique_ptr<char*[], void (*)(char**)> argv_;
+ static intptr_t argc_;
+ static Monitor* monitor_;
+
+ Dart_IsolateGroupCreateCallback create_isolate_;
+ CommandLineOptions* dart_options_;
+ const char* packages_file_;
+
+ DISALLOW_ALLOCATION();
+ };
+
+ private:
+ static CStringUniquePtr TryResolveArtifactPath(const char* filename);
+
+ static DartDevRunner runner_;
+ static bool should_run_dart_dev_;
+ static bool print_usage_error_;
+ static CommandLineOptions* vm_options_;
+
+ DISALLOW_ALLOCATION();
+ DISALLOW_IMPLICIT_CONSTRUCTORS(DartDevIsolate);
+};
+
+} // namespace bin
+} // namespace dart
+
+#endif // !defined(DART_PRECOMPILED_RUNTIME)
+#endif // RUNTIME_BIN_DARTDEV_ISOLATE_H_
diff --git a/runtime/bin/dartdev_options.cc b/runtime/bin/dartdev_options.cc
deleted file mode 100644
index 5a9a144..0000000
--- a/runtime/bin/dartdev_options.cc
+++ /dev/null
@@ -1,378 +0,0 @@
-// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "bin/dartdev_options.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "bin/common_options.h"
-#include "bin/error_exit.h"
-#include "bin/file_system_watcher.h"
-#include "bin/platform.h"
-#include "bin/socket.h"
-#include "bin/utils.h"
-#include "include/dart_api.h"
-#include "platform/assert.h"
-#include "platform/globals.h"
-#include "platform/hashmap.h"
-#include "platform/syslog.h"
-
-namespace dart {
-namespace bin {
-
-#if defined(DART_PRECOMPILED_RUNTIME)
-
-static bool PotentialDartdevCommand(const char* script_uri) {
- // If script_uri is a known DartDev command, we should not try to run it.
- //
- // Otherwise if script_uri is not a file path or of a known URI scheme, we
- // assume this is a mistyped DartDev command.
- //
- // This should be kept in sync with the commands in
- // `pkg/dartdev/lib/dartdev.dart`.
- return (
- (strcmp(script_uri, "analyze") == 0) ||
- (strcmp(script_uri, "compilation-server") == 0) ||
- (strcmp(script_uri, "build") == 0) ||
- (strcmp(script_uri, "compile") == 0) ||
- (strcmp(script_uri, "create") == 0) ||
- (strcmp(script_uri, "development-service") == 0) ||
- (strcmp(script_uri, "devtools") == 0) ||
- (strcmp(script_uri, "doc") == 0) || (strcmp(script_uri, "fix") == 0) ||
- (strcmp(script_uri, "format") == 0) ||
- (strcmp(script_uri, "info") == 0) ||
- (strcmp(script_uri, "mcp-server") == 0) ||
- (strcmp(script_uri, "pub") == 0) || (strcmp(script_uri, "run") == 0) ||
- (strcmp(script_uri, "test") == 0) || (strcmp(script_uri, "info") == 0) ||
- (strcmp(script_uri, "language-server") == 0) ||
- (strcmp(script_uri, "tooling-daemon") == 0) ||
- (!File::ExistsUri(nullptr, script_uri) &&
- (strncmp(script_uri, "http://", 7) != 0) &&
- (strncmp(script_uri, "https://", 8) != 0) &&
- (strncmp(script_uri, "file://", 7) != 0) &&
- (strncmp(script_uri, "package:", 8) != 0) &&
- (strncmp(script_uri, "google3://", 10) != 0)));
-}
-
-#define OPTION_FIELD(variable) Options::variable##_
-
-#define STRING_OPTION_DEFINITION(name, variable) \
- const char* OPTION_FIELD(variable) = nullptr; \
- DEFINE_STRING_OPTION(name, OPTION_FIELD(variable))
-STRING_OPTIONS_LIST(STRING_OPTION_DEFINITION)
-#undef STRING_OPTION_DEFINITION
-
-#define BOOL_OPTION_DEFINITION(name, variable) \
- bool OPTION_FIELD(variable) = false; \
- DEFINE_BOOL_OPTION(name, OPTION_FIELD(variable))
-BOOL_OPTIONS_LIST(BOOL_OPTION_DEFINITION)
-#undef BOOL_OPTION_DEFINITION
-
-#define SHORT_BOOL_OPTION_DEFINITION(short_name, long_name, variable) \
- bool OPTION_FIELD(variable) = false; \
- DEFINE_BOOL_OPTION_SHORT(short_name, long_name, OPTION_FIELD(variable))
-SHORT_BOOL_OPTIONS_LIST(SHORT_BOOL_OPTION_DEFINITION)
-#undef SHORT_BOOL_OPTION_DEFINITION
-
-#define CB_OPTION_DEFINITION(callback) \
- static bool callback##Helper(const char* arg, CommandLineOptions* o) { \
- return Options::callback(arg, o); \
- } \
- DEFINE_CB_OPTION(callback##Helper)
-CB_OPTIONS_LIST(CB_OPTION_DEFINITION)
-#undef CB_OPTION_DEFINITION
-
-// Explicitly handle VM flags that can be parsed by DartDev's run command.
-bool Options::ProcessVMOptions(const char* arg,
- CommandLineOptions* vm_options) {
-#define IS_VM_OPTION(name, arg) \
- if (OptionProcessor::ProcessOption(arg, name) != nullptr) { \
- vm_options->AddArgument(arg); \
- return true; \
- }
-
-// This is an exhaustive set of VM flags that are accepted by 'dart run' and
-// 'dart test' commands, these options need to be collected and passed to
-// the dart VM process that is going to run the command.
-//
-// NOTE: When updating this list of VM flags, be sure to make the corresponding
-// changes in pkg/dartdev/lib/src/commands/run.dart.
-#define HANDLE_DARTDEV_VM_OPTIONS(V, arg) \
- V("--enable-asserts", arg) \
- V("--pause-isolates-on-exit", arg) \
- V("--no-pause-isolates-on-exit", arg) \
- V("--pause-isolates-on-start", arg) \
- V("--no-pause-isolates-on-start", arg) \
- V("--pause-isolates-on-unhandled-exception", arg) \
- V("--no-pause-isolates-on-unhandled-exception", arg) \
- V("--warn-on-pause-with-no-debugger", arg) \
- V("--no-warn-on-pause-with-no-debugger", arg) \
- V("--timeline-streams", arg) \
- V("--timeline-recorder", arg) \
- V("--dds", arg) \
- V("--no-dds", arg) \
- V("--profiler", arg) \
- V("--disable-service-auth-codes", arg) \
- V("--write-service-info", arg) \
- V("--enable-service-port-fallback", arg) \
- V("--disable-service-auth-codes", arg) \
- V("--serve-observatory", arg) \
- V("--print-dtd", arg) \
- V("--packages", arg) \
- V("--resident", arg) \
- V("--resident-server-info-file", arg) \
- V("--resident-compiler-info-file", arg) \
- V("--observe", arg) \
- V("--enable-vm-service", arg) \
- V("--serve-devtools", arg) \
- V("--no-serve-devtools", arg) \
- V("--serve-observatory", arg) \
- V("--no-serve-observatory", arg) \
- V("--profile-microtasks", arg) \
- V("--enable-experiment", arg)
- HANDLE_DARTDEV_VM_OPTIONS(IS_VM_OPTION, arg);
-
-#undef IS_VM_OPTION
-#undef HANDLE_DARTDEV_VM_OPTIONS
-
- return false;
-}
-
-bool Options::ParseDartDevArguments(int argc,
- char** argv,
- CommandLineOptions* vm_options,
- CommandLineOptions* dart_vm_options,
- CommandLineOptions* dart_options,
- bool* skip_dartdev) {
- // First figure out if a dartdev command has been explicitly specified.
- *skip_dartdev = false;
- int tmp_i = 1;
- while (tmp_i < argc) {
- // Check if this flag is a potentially valid VM flag, we skip over all
- // VM flags until we see a command or a script file.
- if (!OptionProcessor::IsValidFlag(argv[tmp_i]) &&
- !OptionProcessor::IsValidShortFlag(argv[tmp_i])) {
- break;
- }
- tmp_i++;
- }
- if (tmp_i < argc) {
- // Check if we have a dartdev command.
- if (!PotentialDartdevCommand(argv[tmp_i])) {
- // We don't have a dartdev command so skip dartdev and execute the
- // script directly.
- *skip_dartdev = true;
- return true;
- }
- }
-
- bool enable_dartdev_analytics = false;
- bool disable_dartdev_analytics = false;
- char* packages_argument = nullptr;
-
- // First parse out the vm options into dart_vm_options so that it can be
- // passed down to the 'run' and 'test' commands.
- // Start processing arguments after argv[0] which would be the executable.
- int i = 1;
- while (i < argc) {
- bool skipVmOption = false;
- if (!OptionProcessor::TryProcess(argv[i], dart_vm_options)) {
- // Check if this flag is a potentially valid VM flag.
- if (!OptionProcessor::IsValidFlag(argv[i])) {
- break;
- }
- // The following flags are processed as DartDev flags and are not to
- // be treated as if they are VM flags.
- if (IsOption(argv[i], "enable-analytics")) {
- enable_dartdev_analytics = true;
- skipVmOption = true;
- } else if (IsOption(argv[i], "disable-analytics")) {
- disable_dartdev_analytics = true;
- skipVmOption = true;
- } else if (IsOption(argv[i], "disable-telemetry")) {
- disable_dartdev_analytics = true;
- skipVmOption = true;
- } else if (IsOption(argv[i], "suppress-analytics")) {
- dart_options->AddArgument("--suppress-analytics");
- skipVmOption = true;
- } else if (IsOption(argv[i], "no-analytics")) {
- // Just add this option even if we don't go to dartdev.
- // It is irrelevant for the vm.
- dart_options->AddArgument("--no-analytics");
- skipVmOption = true;
- } else if (IsOption(argv[i], "serve-observatory")) {
- // This flag is currently set by default in vmservice_io.dart, so we
- // ignore it. --no-serve-observatory is a VM flag so we don't need to
- // handle that case here.
- skipVmOption = true;
- } else if (IsOption(argv[i], "print-dtd-uri")) {
- skipVmOption = true;
- } else if (IsOption(argv[i], "executable-name")) {
- skipVmOption = true;
- } else if (IsOption(argv[i], "enable-experiment")) {
- dart_options->AddArgument(argv[i]);
- }
- }
- if (!skipVmOption) {
- dart_vm_options->AddArgument(argv[i]);
- }
- if (IsOption(argv[i], "packages")) {
- packages_argument = argv[i];
- }
- i++;
- }
-
- // The arguments to the VM are at positions 1 through i-1 in argv.
- Platform::SetExecutableArguments(i, argv);
-
- // If we have exhausted all the arguments and haven't see a dartdev
- // command then we set up some scenarios where it still makes sense
- // to start up dartdev and have it process the options.
- if (i >= argc) {
- // Handles following invocation arguments:
- // - dart help
- // - dart --help
- // - dart
- if (((Options::help_option() && !Options::verbose_option()) ||
- (argc == 1))) {
- // Let DartDev handle the default help message.
- dart_options->AddArgument("help");
- return true;
- }
- // Handles cases where only analytics flags are provided. We need to launch
- // DartDev for this.
- else if (enable_dartdev_analytics || disable_dartdev_analytics) { // NOLINT
- // The analytics flags are a special case as we don't have a target script
- // or DartDev command but we still want to launch DartDev.
- dart_options->AddArgument(enable_dartdev_analytics
- ? "--enable-analytics"
- : "--disable-analytics");
- return true;
- }
- // If it is not '--version' and '--help' we will launch DartDev
- // to print its help message and set an error exit code.
- else if (!Options::help_option() && !Options::version_option()) { // NOLINT
- // Pass in an invalid option so that dartdev prints the help message
- // and exits with an error exit code.
- dart_options->Reset();
- dart_options->AddArgument(argv[argc - 1]);
- dart_options->AddArgument("help");
- return true;
- }
- return false;
- }
-
- USE(enable_dartdev_analytics);
- USE(disable_dartdev_analytics);
- USE(packages_argument);
-
- // Record the dartdev command.
- dart_options->AddArgument(argv[i++]);
-
- // Bring any --packages option into the dartdev command
- if (packages_argument != nullptr) {
- dart_options->AddArgument(packages_argument);
- dart_vm_options->AddArgument(packages_argument);
- }
-
- // Scan remaining arguments and separate them into
- // dart_vm_options (vm options to be passed to the dart process executing
- // the dartdev command) or dart_options (options to be passed to the
- // executing dart script).
- bool script_seen = false;
- while (i < argc) {
- if (!IsOption(argv[i], "disable-dart-dev")) {
- if (!script_seen) {
- // We scan for VM options that are passed to the 'run' and 'test'
- // command. These options are accepted by both the VM and dartdev
- // commands and need to be carried over to the VM running the app for
- // these commands.
- if (Options::ProcessVMOptions(argv[i], dart_vm_options)) {
- // dartdev isn't able to parse these options properly. Since it
- // doesn't need to use the values from these options, just strip them
- // from the argument list passed to dartdev.
- if (!IsOption(argv[i], "observe") &&
- !IsOption(argv[i], "enable-vm-service")) {
- dart_options->AddArgument(argv[i]);
- }
- } else {
- if (!OptionProcessor::IsValidFlag(argv[i]) &&
- !OptionProcessor::IsValidShortFlag(argv[i])) {
- script_seen = true;
- }
- dart_options->AddArgument(argv[i]);
- }
- } else {
- dart_options->AddArgument(argv[i]);
- }
- } else {
- Syslog::PrintErr(
- "Attempted to use --disable-dart-dev with a Dart CLI command.\n");
- return false;
- }
- i++;
- }
-
- // Store the executable name.
- Platform::SetExecutableName(argv[0]);
-
- // Verify consistency of arguments.
- if ((packages_file_ != nullptr) && (strlen(packages_file_) == 0)) {
- Syslog::PrintErr("Empty package file name specified.\n");
- return false;
- }
-
- return true;
-}
-
-void Options::PrintVersion() {
- _PrintVersion();
-}
-
-// clang-format off
-void Options::PrintUsage() {
- _PrintUsage();
- if (!Options::verbose_option()) {
- _PrintNonVerboseUsage();
- } else {
- _PrintVerboseUsage();
- }
-}
-// clang-format on
-
-dart::SimpleHashMap* Options::environment_ = nullptr;
-bool Options::ProcessEnvironmentOption(const char* arg,
- CommandLineOptions* vm_options) {
- return OptionProcessor::ProcessEnvironmentOption(arg, vm_options,
- &Options::environment_);
-}
-
-void Options::Cleanup() {
- DestroyEnvironment();
-}
-
-void Options::DestroyEnvironment() {
- if (environment_ != nullptr) {
- for (SimpleHashMap::Entry* p = environment_->Start(); p != nullptr;
- p = environment_->Next(p)) {
- free(p->key);
- free(p->value);
- }
- delete environment_;
- environment_ = nullptr;
- }
-}
-
-char** Options::GetEnvArguments(int* argc) {
- return nullptr;
-}
-
-void Options::DestroyEnvArgv() {}
-
-#endif // defined(DART_PRECOMPILED_RUNTIME)
-
-} // namespace bin
-} // namespace dart
diff --git a/runtime/bin/dartdev_options.h b/runtime/bin/dartdev_options.h
deleted file mode 100644
index 912fa7f..0000000
--- a/runtime/bin/dartdev_options.h
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef RUNTIME_BIN_DARTDEV_OPTIONS_H_
-#define RUNTIME_BIN_DARTDEV_OPTIONS_H_
-
-#include "bin/dartutils.h"
-#include "bin/options.h"
-#include "platform/globals.h"
-#include "platform/growable_array.h"
-#include "platform/hashmap.h"
-
-namespace dart {
-namespace bin {
-
-#if defined(DART_PRECOMPILED_RUNTIME)
-
-// A list of options taking string arguments. Organized as:
-// V(flag_name, field_name)
-// The value of the flag can then be accessed with Options::field_name().
-#define STRING_OPTIONS_LIST(V) \
- V(packages, packages_file) \
- V(namespace, namespc)
-
-// As STRING_OPTIONS_LIST but for boolean valued options. The default value is
-// always false, and the presence of the flag switches the value to true.
-#define BOOL_OPTIONS_LIST(V) \
- V(disable_exit, exit_disabled) \
- V(version, version_option) \
- V(suppress_core_dump, suppress_core_dump)
-
-// Boolean flags that have a short form.
-#define SHORT_BOOL_OPTIONS_LIST(V) \
- V(h, help, help_option) \
- V(v, verbose, verbose_option)
-
-// Callbacks passed to DEFINE_CB_OPTION().
-#define CB_OPTIONS_LIST(V) \
- V(ProcessEnvironmentOption) \
- V(ProcessVMOptions)
-
-enum VerbosityLevel {
- kError,
- kWarning,
- kInfo,
- kAll,
-};
-
-static const char* const kVerbosityLevelNames[] = {
- "error", "warning", "info", "all", nullptr,
-};
-
-class Options {
- public:
- // Returns true if argument parsing succeeded. False otherwise.
- static bool ParseDartDevArguments(int argc,
- char** argv,
- CommandLineOptions* vm_options,
- CommandLineOptions* dart_vm_options,
- CommandLineOptions* dart_options,
- bool* skip_dartdev);
-
-#define STRING_OPTION_GETTER(flag, variable) \
- static const char* variable() { return variable##_; }
- STRING_OPTIONS_LIST(STRING_OPTION_GETTER)
-#undef STRING_OPTION_GETTER
-
-#define BOOL_OPTION_GETTER(flag, variable) \
- static bool variable() { return variable##_; }
- BOOL_OPTIONS_LIST(BOOL_OPTION_GETTER)
-#undef BOOL_OPTION_GETTER
-
-#define SHORT_BOOL_OPTION_GETTER(short_name, long_name, variable) \
- static bool variable() { return variable##_; }
- SHORT_BOOL_OPTIONS_LIST(SHORT_BOOL_OPTION_GETTER)
-#undef SHORT_BOOL_OPTION_GETTER
-
-// Callbacks have to be public.
-#define CB_OPTIONS_DECL(callback) \
- static bool callback(const char* arg, CommandLineOptions* vm_options);
- CB_OPTIONS_LIST(CB_OPTIONS_DECL)
-#undef CB_OPTIONS_DECL
-
- static dart::SimpleHashMap* environment() { return environment_; }
-
- static void PrintUsage();
- static void PrintVersion();
-
- static void Cleanup();
-
-#if defined(DART_PRECOMPILED_RUNTIME)
- // Get the list of options in DART_VM_OPTIONS.
- static char** GetEnvArguments(int* argc);
-#endif // defined(DART_PRECOMPILED_RUNTIME)
-
- private:
- static void DestroyEnvironment();
-#if defined(DART_PRECOMPILED_RUNTIME)
- static void DestroyEnvArgv();
-#endif // defined(DART_PRECOMPILED_RUNTIME)
-
-#define STRING_OPTION_DECL(flag, variable) static const char* variable##_;
- STRING_OPTIONS_LIST(STRING_OPTION_DECL)
-#undef STRING_OPTION_DECL
-
-#define BOOL_OPTION_DECL(flag, variable) static bool variable##_;
- BOOL_OPTIONS_LIST(BOOL_OPTION_DECL)
-#undef BOOL_OPTION_DECL
-
-#define SHORT_BOOL_OPTION_DECL(short_name, long_name, variable) \
- static bool variable##_;
- SHORT_BOOL_OPTIONS_LIST(SHORT_BOOL_OPTION_DECL)
-#undef SHORT_BOOL_OPTION_DECL
-
- static dart::SimpleHashMap* environment_;
-
- static char** env_argv_;
- static int env_argc_;
-
-#define OPTION_FRIEND(flag, variable) friend class OptionProcessor_##flag;
- STRING_OPTIONS_LIST(OPTION_FRIEND)
- BOOL_OPTIONS_LIST(OPTION_FRIEND)
-#undef OPTION_FRIEND
-
-#define SHORT_BOOL_OPTION_FRIEND(short_name, long_name, variable) \
- friend class OptionProcessor_##long_name;
- SHORT_BOOL_OPTIONS_LIST(SHORT_BOOL_OPTION_FRIEND)
-#undef SHORT_BOOL_OPTION_FRIEND
-
- DISALLOW_ALLOCATION();
- DISALLOW_IMPLICIT_CONSTRUCTORS(Options);
-};
-
-#endif // defined(DART_PRECOMPILED_RUNTIME)
-
-} // namespace bin
-} // namespace dart
-
-#endif // RUNTIME_BIN_DARTDEV_OPTIONS_H_
diff --git a/runtime/bin/main_impl.cc b/runtime/bin/main_impl.cc
index 656205d..2e4d3c6 100644
--- a/runtime/bin/main_impl.cc
+++ b/runtime/bin/main_impl.cc
@@ -15,6 +15,7 @@
#include "bin/builtin.h"
#include "bin/console.h"
#include "bin/crashpad.h"
+#include "bin/dartdev_isolate.h"
#include "bin/dartutils.h"
#include "bin/dfe.h"
#include "bin/error_exit.h"
@@ -390,6 +391,17 @@
CHECK_RESULT(result);
}
+#if !defined(DART_PRECOMPILED_RUNTIME)
+ // Disable pausing the DartDev isolate on start and exit.
+ const char* isolate_name = nullptr;
+ result = Dart_StringToCString(Dart_DebugName(), &isolate_name);
+ CHECK_RESULT(result);
+ if (strstr(isolate_name, DART_DEV_ISOLATE_NAME) != nullptr) {
+ Dart_SetShouldPauseOnStart(false);
+ Dart_SetShouldPauseOnExit(false);
+ }
+#endif // !defined(DART_PRECOMPILED_RUNTIME)
+
#if !defined(DART_PRECOMPILER)
NativeAssetsApi native_assets;
memset(&native_assets, 0, sizeof(native_assets));
@@ -562,7 +574,7 @@
CHECK_RESULT(result);
// We do not spawn the external dds process if DDS is explicitly disabled.
- bool wait_for_dds_to_advertise_service = Options::enable_dds();
+ bool wait_for_dds_to_advertise_service = !Options::disable_dds();
bool serve_devtools =
Options::enable_devtools() || !Options::disable_devtools();
// Load embedder specific bits and return.
@@ -594,6 +606,99 @@
#endif // !defined(PRODUCT)
}
+#if !defined(DART_PRECOMPILED_RUNTIME)
+
+static Dart_Isolate CreateAndSetupDartDevIsolate(const char* script_uri,
+ const char* packages_config,
+ Dart_IsolateFlags* flags,
+ char** error,
+ int* exit_code) {
+ int64_t start = Dart_TimelineGetMicros();
+
+ auto dartdev_path = DartDevIsolate::TryResolveDartDevSnapshotPath();
+ if (dartdev_path.get() == nullptr) {
+ Syslog::PrintErr(
+ "Failed to start the Dart CLI isolate. Could not resolve DartDev "
+ "snapshot or kernel.\n");
+ if (error != nullptr && *error != nullptr) {
+ free(*error);
+ *error = nullptr;
+ }
+ return nullptr;
+ }
+
+ Dart_Isolate isolate = nullptr;
+ const uint8_t* isolate_snapshot_data = core_isolate_snapshot_data;
+ const uint8_t* isolate_snapshot_instructions =
+ core_isolate_snapshot_instructions;
+ IsolateGroupData* isolate_group_data = nullptr;
+ IsolateData* isolate_data = nullptr;
+ AppSnapshot* app_snapshot = nullptr;
+ bool isolate_run_app_snapshot = true;
+ // dartdev isolate uses an app JIT snapshot or uses the dill file.
+ if (((app_snapshot = Snapshot::TryReadAppSnapshot(
+ dartdev_path.get(), /*force_load_from_memory=*/false,
+ /*decode_uri=*/false)) != nullptr) &&
+ app_snapshot->IsJIT()) {
+ const uint8_t* isolate_snapshot_data = nullptr;
+ const uint8_t* isolate_snapshot_instructions = nullptr;
+ const uint8_t* ignore_vm_snapshot_data;
+ const uint8_t* ignore_vm_snapshot_instructions;
+ app_snapshot->SetBuffers(
+ &ignore_vm_snapshot_data, &ignore_vm_snapshot_instructions,
+ &isolate_snapshot_data, &isolate_snapshot_instructions);
+ isolate_group_data = new IsolateGroupData(
+ DART_DEV_ISOLATE_NAME, /*asset_resolution_base=*/nullptr,
+ packages_config, app_snapshot, isolate_run_app_snapshot);
+ isolate_data = new IsolateData(isolate_group_data);
+ isolate = Dart_CreateIsolateGroup(
+ DART_DEV_ISOLATE_NAME, DART_DEV_ISOLATE_NAME, isolate_snapshot_data,
+ isolate_snapshot_instructions, flags, isolate_group_data, isolate_data,
+ error);
+ }
+
+ if (isolate == nullptr) {
+ // dartdev_path was not an application snapshot, try it as a kernel file.
+ // Clear error from app snapshot and retry from kernel.
+ if (error != nullptr && *error != nullptr) {
+ free(*error);
+ *error = nullptr;
+ }
+ isolate_run_app_snapshot = false;
+ if (app_snapshot != nullptr) {
+ delete app_snapshot;
+ }
+ isolate_group_data =
+ new IsolateGroupData(DART_DEV_ISOLATE_NAME, nullptr, packages_config,
+ nullptr, isolate_run_app_snapshot);
+ uint8_t* application_kernel_buffer = nullptr;
+ intptr_t application_kernel_buffer_size = 0;
+ dfe.ReadScript(dartdev_path.get(), nullptr, &application_kernel_buffer,
+ &application_kernel_buffer_size, /*decode_uri=*/false);
+ isolate_group_data->SetKernelBufferNewlyOwned(
+ application_kernel_buffer, application_kernel_buffer_size);
+
+ isolate_data = new IsolateData(isolate_group_data);
+ isolate = Dart_CreateIsolateGroup(
+ DART_DEV_ISOLATE_NAME, DART_DEV_ISOLATE_NAME, isolate_snapshot_data,
+ isolate_snapshot_instructions, flags, isolate_group_data, isolate_data,
+ error);
+ }
+
+ Dart_Isolate created_isolate =
+ IsolateSetupHelper(isolate, false, DART_DEV_ISOLATE_NAME, packages_config,
+ isolate_run_app_snapshot, flags, error, exit_code);
+
+ int64_t end = Dart_TimelineGetMicros();
+ Dart_RecordTimelineEvent("CreateAndSetupDartDevIsolate", start, end,
+ /*flow_id_count=*/0, nullptr,
+ Dart_Timeline_Event_Duration,
+ /*argument_count=*/0, nullptr, nullptr);
+ return created_isolate;
+}
+
+#endif // !defined(DART_PRECOMPILED_RUNTIME)
+
// Returns newly created Isolate on success, nullptr on failure.
static Dart_Isolate CreateIsolateGroupAndSetupHelper(
bool is_main_isolate,
@@ -852,6 +957,13 @@
}
#endif // !defined(EXCLUDE_CFE_AND_KERNEL_PLATFORM)
+#if !defined(DART_PRECOMPILED_RUNTIME)
+ if (strcmp(script_uri, DART_DEV_ISOLATE_NAME) == 0) {
+ return CreateAndSetupDartDevIsolate(script_uri, package_config, flags,
+ error, &exit_code);
+ }
+#endif // !defined(DART_PRECOMPILED_RUNTIME)
+
if (strcmp(script_uri, DART_VM_SERVICE_ISOLATE_NAME) == 0) {
return CreateAndSetupServiceIsolate(script_uri, package_config, flags,
error, &exit_code);
@@ -1098,11 +1210,13 @@
char* script_name = nullptr;
CStringUniquePtr asset_resolution_base = CStringUniquePtr();
+ // Allows the dartdev process to point to the desired package_config.
char* package_config_override = nullptr;
const int EXTRA_VM_ARGUMENTS = 10;
CommandLineOptions vm_options(argc + EXTRA_VM_ARGUMENTS);
CommandLineOptions dart_options(argc + EXTRA_VM_ARGUMENTS);
bool print_flags_seen = false;
+ bool verbose_debug_seen = false;
// Perform platform specific initialization.
if (!Platform::Initialize()) {
@@ -1134,36 +1248,39 @@
}
vm_options.AddArgument("--new_gen_growth_factor=4");
- auto parse_arguments =
- [&](int argc, char** argv, CommandLineOptions* vm_options,
- CommandLineOptions* dart_options, bool parsing_dart_vm_options) {
- bool success = Options::ParseArguments(
- argc, argv, vm_run_app_snapshot, parsing_dart_vm_options,
- vm_options, &script_name, dart_options, &print_flags_seen);
- if (!success) {
- if (Options::help_option()) {
- Options::PrintUsage();
- Platform::Exit(0);
- } else if (Options::version_option()) {
- Options::PrintVersion();
- Platform::Exit(0);
- } else if (print_flags_seen) {
- // Will set the VM flags, print them out and then we exit as no
- // script was specified on the command line.
- char* error =
- Dart_SetVMFlags(vm_options->count(), vm_options->arguments());
- if (error != nullptr) {
- Syslog::PrintErr("Setting VM flags failed: %s\n", error);
- free(error);
- Platform::Exit(kErrorExitCode);
- }
- Platform::Exit(0);
- } else {
- Options::PrintUsage();
- Platform::Exit(kErrorExitCode);
- }
+ auto parse_arguments = [&](int argc, char** argv,
+ CommandLineOptions* vm_options,
+ CommandLineOptions* dart_options,
+ bool parsing_dart_vm_options) {
+ bool success = Options::ParseArguments(
+ argc, argv, vm_run_app_snapshot, parsing_dart_vm_options, vm_options,
+ &script_name, dart_options, &print_flags_seen, &verbose_debug_seen);
+ if (!success) {
+ if (Options::help_option()) {
+ Options::PrintUsage();
+ Platform::Exit(0);
+ } else if (Options::version_option()) {
+ Options::PrintVersion();
+ Platform::Exit(0);
+ } else if (print_flags_seen) {
+ // Will set the VM flags, print them out and then we exit as no
+ // script was specified on the command line.
+ char* error =
+ Dart_SetVMFlags(vm_options->count(), vm_options->arguments());
+ if (error != nullptr) {
+ Syslog::PrintErr("Setting VM flags failed: %s\n", error);
+ free(error);
+ Platform::Exit(kErrorExitCode);
}
- };
+ Platform::Exit(0);
+ } else {
+ // This usage error case will only be invoked when
+ // Options::disable_dart_dev() is false.
+ Options::PrintUsage();
+ Platform::Exit(kErrorExitCode);
+ }
+ }
+ };
AppSnapshot* app_snapshot = nullptr;
#if defined(DART_PRECOMPILED_RUNTIME)
@@ -1261,8 +1378,9 @@
}
};
- // At this point, script_name now points to a script or a valid file path
- // was provided as the first non-flag argument.
+ // At this point, script_name now points to a script if DartDev is disabled
+ // or a valid file path was provided as the first non-flag argument.
+ // Otherwise, script_name can be nullptr if DartDev should be run.
if (script_name != nullptr) {
if (!CheckForInvalidPath(script_name)) {
Platform::Exit(0);
@@ -1366,21 +1484,36 @@
&ServiceStreamCancelCallback);
Dart_SetFileModifiedCallback(&FileModifiedCallback);
Dart_SetEmbedderInformationCallback(&EmbedderInformationCallback);
+ bool ran_dart_dev = false;
bool should_run_user_program = true;
#if !defined(DART_PRECOMPILED_RUNTIME)
- if (script_name == nullptr &&
- Options::gen_snapshot_kind() != SnapshotKind::kNone) {
+ if (DartDevIsolate::should_run_dart_dev() && !Options::disable_dart_dev() &&
+ Options::gen_snapshot_kind() == SnapshotKind::kNone) {
+ DartDevIsolate::DartDev_Result dartdev_result = DartDevIsolate::RunDartDev(
+ CreateIsolateGroupAndSetup, &package_config_override, &script_name,
+ &vm_options, &dart_options);
+ ASSERT(dartdev_result != DartDevIsolate::DartDev_Result_Unknown);
+ ran_dart_dev = true;
+ should_run_user_program =
+ (dartdev_result == DartDevIsolate::DartDev_Result_Run);
+ if (should_run_user_program) {
+ try_load_snapshots_lambda();
+ }
+ } else if (script_name == nullptr &&
+ Options::gen_snapshot_kind() != SnapshotKind::kNone) {
Syslog::PrintErr(
"Snapshot generation should be done using the 'dart compile' "
"command.\n");
Platform::Exit(kErrorExitCode);
}
- if (!Options::resident() &&
- (Options::resident_compiler_info_file_path() != nullptr ||
+
+ if (!ran_dart_dev &&
+ (Options::resident() ||
+ Options::resident_compiler_info_file_path() != nullptr ||
Options::resident_server_info_file_path() != nullptr)) {
Syslog::PrintErr(
- "Error: the --resident flag must be passed whenever the "
- "--resident-compiler-info-file option is passed.\n");
+ "Passing the `--resident` flag to `dart` is invalid. It must be passed "
+ "to `dart run`.\n");
Platform::Exit(kErrorExitCode);
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)
@@ -1417,6 +1550,9 @@
delete app_snapshot;
free(app_script_uri);
+ if (ran_dart_dev && script_name != nullptr) {
+ free(script_name);
+ }
asset_resolution_base.reset();
// Free copied argument strings if converted.
diff --git a/runtime/bin/main_options.cc b/runtime/bin/main_options.cc
index 0340f58..b94961c 100644
--- a/runtime/bin/main_options.cc
+++ b/runtime/bin/main_options.cc
@@ -8,7 +8,7 @@
#include <stdlib.h>
#include <string.h>
-#include "bin/common_options.h"
+#include "bin/dartdev_isolate.h"
#include "bin/error_exit.h"
#include "bin/file_system_watcher.h"
#if defined(DART_IO_SECURE_SOCKET_DISABLED)
@@ -16,6 +16,7 @@
#else // defined(DART_IO_SECURE_SOCKET_DISABLED)
#include "bin/io_service.h"
#endif // defined(DART_IO_SECURE_SOCKET_DISABLED)
+#include "bin/options.h"
#include "bin/platform.h"
#include "bin/utils.h"
#include "platform/syslog.h"
@@ -39,13 +40,14 @@
nullptr,
};
+// These strings must match the enum VerbosityLevel in main_options.h.
+static const char* const kVerbosityLevelNames[] = {
+ "error", "warning", "info", "all", nullptr,
+};
+
SnapshotKind Options::gen_snapshot_kind_ = kNone;
-
-#if !defined(DART_PRECOMPILED_RUNTIME)
-DFE* Options::dfe_ = nullptr;
-
-DEFINE_STRING_OPTION_CB(dfe, { Options::dfe()->set_frontend_filename(value); });
-#endif // !defined(DART_PRECOMPILED_RUNTIME)
+VerbosityLevel Options::verbosity_ = kAll;
+bool Options::enable_vm_service_ = false;
#define OPTION_FIELD(variable) Options::variable##_
@@ -83,6 +85,12 @@
CB_OPTIONS_LIST(CB_OPTION_DEFINITION)
#undef CB_OPTION_DEFINITION
+#if !defined(DART_PRECOMPILED_RUNTIME)
+DFE* Options::dfe_ = nullptr;
+
+DEFINE_STRING_OPTION_CB(dfe, { Options::dfe()->set_frontend_filename(value); });
+#endif // !defined(DART_PRECOMPILED_RUNTIME)
+
static void hot_reload_test_mode_callback(CommandLineOptions* vm_options) {
// Identity reload.
vm_options->AddArgument("--identity_reload");
@@ -123,175 +131,133 @@
DEFINE_BOOL_OPTION_CB(hot_reload_rollback_test_mode,
hot_reload_rollback_test_mode_callback);
-bool Options::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) {
- int i = 0;
-#if !defined(DART_PRECOMPILED_RUNTIME)
- // DART_VM_OPTIONS is only implemented for compiled executables.
- ASSERT(!parsing_dart_vm_options);
-#endif // !defined(DART_PRECOMPILED_RUNTIME)
- if (!parsing_dart_vm_options) {
- // Start processing arguments after argv[0] which would be the executable.
- i = 1;
- }
-
- CommandLineOptions temp_vm_options(vm_options->max_count());
- // Parse out the vm options.
- while (i < argc) {
- bool skipVmOption = false;
- if (!OptionProcessor::TryProcess(argv[i], &temp_vm_options)) {
- // Check if this flag is a potentially valid VM flag.
- if (!OptionProcessor::IsValidFlag(argv[i])) {
- break;
- }
- if (IsOption(argv[i], "print-flags")) {
- *print_flags_seen = true;
- } else if (IsOption(argv[i], "disable-dart-dev")) {
- skipVmOption = true;
- }
- if (!skipVmOption) {
- temp_vm_options.AddArgument(argv[i]);
- }
- } else if (IsOption(argv[i], "profile-microtasks")) {
- temp_vm_options.AddArgument(argv[i]);
- }
- i++;
- }
-
-#if !defined(DART_PRECOMPILED_RUNTIME)
- Options::dfe()->set_use_dfe();
-#endif // !defined(DART_PRECOMPILED_RUNTIME)
- if (Options::deterministic()) {
- // Both an embedder and VM flag.
- temp_vm_options.AddArgument("--deterministic");
- }
-
- Socket::set_short_socket_read(Options::short_socket_read());
- Socket::set_short_socket_write(Options::short_socket_write());
-#if !defined(DART_IO_SECURE_SOCKET_DISABLED)
- SSLCertContext::set_root_certs_file(Options::root_certs_file());
- SSLCertContext::set_root_certs_cache(Options::root_certs_cache());
- SSLCertContext::set_long_ssl_cert_evaluation(
- Options::long_ssl_cert_evaluation());
- SSLCertContext::set_bypass_trusting_system_roots(
- Options::bypass_trusting_system_roots());
-#endif // !defined(DART_IO_SECURE_SOCKET_DISABLED)
-
- FileSystemWatcher::set_delayed_filewatch_callback(
- Options::delayed_filewatch_callback());
-
- if (Options::deterministic()) {
- IOService::set_max_concurrency(1);
- }
-
- // The arguments to the VM are at positions 1 through i-1 in argv.
- Platform::SetExecutableArguments(i, argv);
-
- // Get the script name.
- if (i < argc) {
- *script_name = Utils::StrDup(argv[i]);
- i++;
- // Handle argument parsing errors and missing script / command name when not
- // processing options set via DART_VM_OPTIONS.
- } else if (!parsing_dart_vm_options || Options::help_option() || // NOLINT
- Options::version_option()) { // NOLINT
- return false;
- }
-
- const char** vm_argv = temp_vm_options.arguments();
- int vm_argc = temp_vm_options.count();
- vm_options->AddArguments(vm_argv, vm_argc);
-
-#if !defined(DART_PRECOMPILED_RUNTIME)
- // If we're parsing DART_VM_OPTIONS, there shouldn't be any script set or
- // Dart arguments left to parse.
- if (parsing_dart_vm_options) {
- ASSERT(i == argc);
- return true;
- }
-#endif // !defined(DART_PRECOMPILED_RUNTIME)
-
- // Parse out options to be passed to dart main.
- while (i < argc) {
- dart_options->AddArgument(argv[i]);
- i++;
- }
- if (!parsing_dart_vm_options) {
- // Store the executable name.
- if (Options::executable_name() != nullptr) {
- Platform::SetExecutableName(Options::executable_name());
- Platform::SetResolvedExecutableName(Options::executable_name());
- } else {
- Platform::SetExecutableName(argv[0]);
- }
- }
-
- // Verify consistency of arguments.
-
- // snapshot_depfile is an alias for depfile. Passing them both is an error.
- if ((snapshot_deps_filename_ != nullptr) && (depfile_ != nullptr)) {
- Syslog::PrintErr("Specify only one of --depfile and --snapshot_depfile\n");
- return false;
- }
- if (snapshot_deps_filename_ != nullptr) {
- depfile_ = snapshot_deps_filename_;
- snapshot_deps_filename_ = nullptr;
- }
-
- if ((packages_file_ != nullptr) && (strlen(packages_file_) == 0)) {
- Syslog::PrintErr("Empty package file name specified.\n");
- return false;
- }
- if ((gen_snapshot_kind_ != kNone) && (snapshot_filename_ == nullptr)) {
- Syslog::PrintErr(
- "Generating a snapshot requires a filename (--snapshot).\n");
- return false;
- }
- if ((gen_snapshot_kind_ == kNone) && (depfile_ != nullptr) &&
- (snapshot_filename_ == nullptr) &&
- (depfile_output_filename_ == nullptr)) {
- Syslog::PrintErr(
- "Generating a depfile requires an output filename"
- " (--depfile-output-filename or --snapshot).\n");
- return false;
- }
- if ((gen_snapshot_kind_ != kNone) && vm_run_app_snapshot) {
- Syslog::PrintErr(
- "Specifying an option to generate a snapshot and"
- " run using a snapshot is invalid.\n");
- return false;
- }
-
- // If --snapshot is given without --snapshot-kind, default to script snapshot.
- if ((snapshot_filename_ != nullptr) && (gen_snapshot_kind_ == kNone)) {
- gen_snapshot_kind_ = kKernel;
- }
-
- return true;
-}
-
-// These strings must match the enum VerbosityLevel in main_options.h.
-VerbosityLevel Options::verbosity_ = kAll;
-bool Options::enable_vm_service_ = false;
-bool Options::enable_dds_ = true;
-
void Options::PrintVersion() {
- _PrintVersion();
+ Syslog::Print("Dart SDK version: %s\n", Dart_VersionString());
}
// clang-format off
void Options::PrintUsage() {
- _PrintUsage();
+ Syslog::Print(
+ "Usage: dart [<vm-flags>] <dart-script-file> [<script-arguments>]\n"
+ "\n"
+ "Executes the Dart script <dart-script-file> with "
+ "the given list of <script-arguments>.\n"
+ "\n");
if (!Options::verbose_option()) {
- _PrintNonVerboseUsage();
+ Syslog::Print(
+"Common VM flags:\n"
+#if !defined(PRODUCT)
+"--enable-asserts\n"
+" Enable assert statements.\n"
+#endif // !defined(PRODUCT)
+"--help or -h\n"
+" Display this message (add -v or --verbose for information about\n"
+" all VM options).\n"
+"--packages=<path>\n"
+" Where to find a package spec file.\n"
+"--define=<key>=<value> or -D<key>=<value>\n"
+" Define an environment declaration. To specify multiple declarations,\n"
+" use multiple instances of this option.\n"
+#if !defined(PRODUCT)
+"--observe[=<port>[/<bind-address>]]\n"
+" The observe flag is a convenience flag used to run a program with a\n"
+" set of options which are often useful for debugging under Dart DevTools.\n"
+" These options are currently:\n"
+" --enable-vm-service[=<port>[/<bind-address>]]\n"
+" --serve-devtools\n"
+" --pause-isolates-on-exit\n"
+" --pause-isolates-on-unhandled-exceptions\n"
+" --warn-on-pause-with-no-debugger\n"
+" --timeline-streams=\"Compiler, Dart, GC, Microtask\"\n"
+" This set is subject to change.\n"
+" Please see these options (--help --verbose) for further documentation.\n"
+"--write-service-info=<file_uri>\n"
+" Outputs information necessary to connect to the VM service to the\n"
+" specified file in JSON format. Useful for clients which are unable to\n"
+" listen to stdout for the Dart VM service listening message.\n"
+#endif // !defined(PRODUCT)
+"--snapshot-kind=<snapshot_kind>\n"
+"--snapshot=<file_name>\n"
+" These snapshot options are used to generate a snapshot of the loaded\n"
+" Dart script:\n"
+" <snapshot-kind> controls the kind of snapshot, it could be\n"
+" kernel(default) or app-jit\n"
+" <file_name> specifies the file into which the snapshot is written\n"
+"--version\n"
+" Print the SDK version.\n");
} else {
- _PrintVerboseUsage();
+ Syslog::Print(
+"Supported options:\n"
+#if !defined(PRODUCT)
+"--enable-asserts\n"
+" Enable assert statements.\n"
+#endif // !defined(PRODUCT)
+"--help or -h\n"
+" Display this message (add -v or --verbose for information about\n"
+" all VM options).\n"
+"--packages=<path>\n"
+" Where to find a package spec file.\n"
+"--define=<key>=<value> or -D<key>=<value>\n"
+" Define an environment declaration. To specify multiple declarations,\n"
+" use multiple instances of this option.\n"
+#if !defined(PRODUCT)
+"--observe[=<port>[/<bind-address>]]\n"
+" The observe flag is a convenience flag used to run a program with a\n"
+" set of options which are often useful for debugging under Dart DevTools.\n"
+" These options are currently:\n"
+" --enable-vm-service[=<port>[/<bind-address>]]\n"
+" --serve-devtools\n"
+" --pause-isolates-on-exit\n"
+" --pause-isolates-on-unhandled-exceptions\n"
+" --warn-on-pause-with-no-debugger\n"
+" --timeline-streams=\"Compiler, Dart, GC, Microtask\"\n"
+" This set is subject to change.\n"
+" Please see these options for further documentation.\n"
+"--profile-microtasks\n"
+" Record information about each microtask. Information about completed\n"
+" microtasks will be written to the \"Microtask\" timeline stream.\n"
+#endif // !defined(PRODUCT)
+"--version\n"
+" Print the VM version.\n"
+"\n"
+"--trace-loading\n"
+" enables tracing of library and script loading\n"
+"\n"
+#if !defined(PRODUCT)
+"--enable-vm-service[=<port>[/<bind-address>]]\n"
+" Enables the VM service and listens on specified port for connections\n"
+" (default port number is 8181, default bind address is localhost).\n"
+"\n"
+"--disable-service-auth-codes\n"
+" Disables the requirement for an authentication code to communicate with\n"
+" the VM service. Authentication codes help protect against CSRF attacks,\n"
+" so it is not recommended to disable them unless behind a firewall on a\n"
+" secure device.\n"
+"\n"
+"--enable-service-port-fallback\n"
+" When the VM service is told to bind to a particular port, fallback to 0 if\n"
+" it fails to bind instead of failing to start.\n"
+"\n"
+#endif // !defined(PRODUCT)
+"--root-certs-file=<path>\n"
+" The path to a file containing the trusted root certificates to use for\n"
+" secure socket connections.\n"
+"--root-certs-cache=<path>\n"
+" The path to a cache directory containing the trusted root certificates to\n"
+" use for secure socket connections.\n"
+#if defined(DART_HOST_OS_LINUX) || \
+ defined(DART_HOST_OS_ANDROID) || \
+ defined(DART_HOST_OS_FUCHSIA)
+"--namespace=<path>\n"
+" The path to a directory that dart:io calls will treat as the root of the\n"
+" filesystem.\n"
+#endif // defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_ANDROID)
+"\n"
+"The following options are only used for VM development and may\n"
+"be changed in any future version:\n");
+ const char* print_flags = "--print_flags";
+ char* error = Dart_SetVMFlags(1, &print_flags);
+ ASSERT(error == nullptr);
}
}
// clang-format on
@@ -328,8 +294,8 @@
//
// DART_VM_OPTIONS should contain a list of comma-separated options and flags
// with no spaces. Options that support providing multiple values as
-// comma-separated lists (e.g., --timeline-streams=Dart,GC,Compiler,Microtask)
-// are not supported and will cause argument parsing to fail.
+// comma-separated lists (e.g., --timeline-streams=Dart,GC,Compiler) are not
+// supported and will cause argument parsing to fail.
char** Options::GetEnvArguments(int* argc) {
ASSERT(argc != nullptr);
const char* env_args_str = std::getenv("DART_VM_OPTIONS");
@@ -423,22 +389,36 @@
return true;
}
-#if !defined(PRODUCT)
-static constexpr const char* DEFAULT_VM_SERVICE_SERVER_IP = "localhost";
-static constexpr int DEFAULT_VM_SERVICE_SERVER_PORT = 8181;
-static constexpr int INVALID_VM_SERVICE_SERVER_PORT = -1;
+// Returns true if arg starts with the characters "--" followed by option, but
+// all '_' in the option name are treated as '-'.
+static bool IsOption(const char* arg, const char* option) {
+ if (arg[0] != '-' || arg[1] != '-') {
+ // Special case first two characters to avoid recognizing __flag.
+ return false;
+ }
+ for (int i = 0; option[i] != '\0'; i++) {
+ auto c = arg[i + 2];
+ if (c == '\0') {
+ // Not long enough.
+ return false;
+ }
+ if ((c == '_' ? '-' : c) != option[i]) {
+ return false;
+ }
+ }
+ return true;
+}
+
const char* Options::vm_service_server_ip_ = DEFAULT_VM_SERVICE_SERVER_IP;
int Options::vm_service_server_port_ = INVALID_VM_SERVICE_SERVER_PORT;
-#endif // !defined(PRODUCT)
-
bool Options::ProcessEnableVmServiceOption(const char* arg,
CommandLineOptions* vm_options) {
+#if !defined(PRODUCT)
const char* value =
OptionProcessor::ProcessOption(arg, "--enable-vm-service");
if (value == nullptr) {
return false;
}
-#if !defined(PRODUCT)
if (!ExtractPortAndAddress(
value, &vm_service_server_port_, &vm_service_server_ip_,
DEFAULT_VM_SERVICE_SERVER_PORT, DEFAULT_VM_SERVICE_SERVER_IP)) {
@@ -460,11 +440,11 @@
bool Options::ProcessObserveOption(const char* arg,
CommandLineOptions* vm_options) {
+#if !defined(PRODUCT)
const char* value = OptionProcessor::ProcessOption(arg, "--observe");
if (value == nullptr) {
return false;
}
-#if !defined(PRODUCT)
if (!ExtractPortAndAddress(
value, &vm_service_server_port_, &vm_service_server_ip_,
DEFAULT_VM_SERVICE_SERVER_PORT, DEFAULT_VM_SERVICE_SERVER_IP)) {
@@ -491,18 +471,352 @@
#endif // !defined(PRODUCT)
}
-bool Options::ProcessDdsOption(const char* arg,
- CommandLineOptions* vm_options) {
- const char* value = OptionProcessor::ProcessOption(arg, "--dds");
- if (value == nullptr) {
- value = OptionProcessor::ProcessOption(arg, "--no-dds");
- if (value == nullptr) {
- return false;
- }
- enable_dds_ = false;
- } else {
- enable_dds_ = true;
+bool Options::ProcessProfileMicrotasksOption(const char* arg,
+ CommandLineOptions* vm_options) {
+#if !defined(PRODUCT)
+ constexpr const char* kProfileMicrotasksFlagAsCstr = "--profile-microtasks";
+ constexpr const char* kAlternativeProfileMicrotasksFlagAsCstr =
+ "--profile_microtasks";
+ if (strncmp(kProfileMicrotasksFlagAsCstr, arg,
+ strlen(kProfileMicrotasksFlagAsCstr)) == 0 ||
+ strncmp(kAlternativeProfileMicrotasksFlagAsCstr, arg,
+ strlen(kAlternativeProfileMicrotasksFlagAsCstr)) == 0) {
+ profile_microtasks_ = true;
+ vm_options->AddArgument(kProfileMicrotasksFlagAsCstr);
+ return true;
}
+#endif // !defined(PRODUCT)
+ return false;
+}
+
+// Explicitly handle VM flags that can be parsed by DartDev's run command.
+bool Options::ProcessVMDebuggingOptions(const char* arg,
+ CommandLineOptions* vm_options) {
+#define IS_DEBUG_OPTION(name, arg) \
+ if (strncmp(name, arg, strlen(name)) == 0) { \
+ vm_options->AddArgument(arg); \
+ return true; \
+ }
+
+// This is an exhaustive set of VM flags that are accepted by 'dart run'. Flags
+// defined in main_options.h do not need to be handled here as they already
+// have handlers generated.
+//
+// NOTE: When updating this list of VM flags, be sure to make the corresponding
+// changes in pkg/dartdev/lib/src/commands/run.dart.
+#define HANDLE_DARTDEV_VM_DEBUG_OPTIONS(V, arg) \
+ V("--enable-asserts", arg) \
+ V("--pause-isolates-on-exit", arg) \
+ V("--no-pause-isolates-on-exit", arg) \
+ V("--pause-isolates-on-start", arg) \
+ V("--no-pause-isolates-on-start", arg) \
+ V("--pause-isolates-on-unhandled-exception", arg) \
+ V("--no-pause-isolates-on-unhandled-exception", arg) \
+ V("--warn-on-pause-with-no-debugger", arg) \
+ V("--no-warn-on-pause-with-no-debugger", arg) \
+ V("--timeline-streams", arg) \
+ V("--timeline-recorder", arg) \
+ V("--enable-experiment", arg)
+ HANDLE_DARTDEV_VM_DEBUG_OPTIONS(IS_DEBUG_OPTION, arg);
+
+#undef IS_DEBUG_OPTION
+#undef HANDLE_DARTDEV_VM_DEBUG_OPTIONS
+
+ return false;
+}
+
+bool Options::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) {
+ int i = 0;
+#if !defined(DART_PRECOMPILED_RUNTIME)
+ // DART_VM_OPTIONS is only implemented for compiled executables.
+ ASSERT(!parsing_dart_vm_options);
+#endif // !defined(DART_PRECOMPILED_RUNTIME)
+ if (!parsing_dart_vm_options) {
+ // Store the executable name.
+ Platform::SetExecutableName(argv[0]);
+
+ // Start the rest after the executable name.
+ i = 1;
+ }
+
+ CommandLineOptions temp_vm_options(vm_options->max_count());
+
+ bool enable_dartdev_analytics = false;
+ bool disable_dartdev_analytics = false;
+ char* packages_argument = nullptr;
+
+ // Parse out the vm options.
+ while (i < argc) {
+ bool skipVmOption = false;
+ if (!OptionProcessor::TryProcess(argv[i], &temp_vm_options)) {
+ // Check if this flag is a potentially valid VM flag.
+ if (!OptionProcessor::IsValidFlag(argv[i])) {
+ break;
+ }
+ // The following flags are processed as DartDev flags and are not to
+ // be treated as if they are VM flags.
+ if (IsOption(argv[i], "print-flags")) {
+ *print_flags_seen = true;
+ } else if (IsOption(argv[i], "verbose-debug")) {
+ *verbose_debug_seen = true;
+ } else if (IsOption(argv[i], "enable-analytics")) {
+ enable_dartdev_analytics = true;
+ skipVmOption = true;
+ } else if (IsOption(argv[i], "disable-analytics")) {
+ disable_dartdev_analytics = true;
+ skipVmOption = true;
+ } else if (IsOption(argv[i], "disable-telemetry")) {
+ disable_dartdev_analytics = true;
+ skipVmOption = true;
+ } else if (IsOption(argv[i], "suppress-analytics")) {
+ dart_options->AddArgument("--suppress-analytics");
+ skipVmOption = true;
+ } else if (IsOption(argv[i], "no-analytics")) {
+ // Just add this option even if we don't go to dartdev.
+ // It is irrelevant for the vm.
+ dart_options->AddArgument("--no-analytics");
+ skipVmOption = true;
+ } else if (IsOption(argv[i], "dds")) {
+ // This flag is set by default in dartdev, so we ignore it. --no-dds is
+ // a VM flag as disabling DDS changes how we configure the VM service,
+ // so we don't need to handle that case here.
+ skipVmOption = true;
+ } else if (IsOption(argv[i], "serve-observatory")) {
+ // This flag is currently set by default in vmservice_io.dart, so we
+ // ignore it. --no-serve-observatory is a VM flag so we don't need to
+ // handle that case here.
+ skipVmOption = true;
+ } else if (IsOption(argv[i], "print-dtd-uri")) {
+ skipVmOption = true;
+ }
+ if (!skipVmOption) {
+ temp_vm_options.AddArgument(argv[i]);
+ }
+ }
+ if (IsOption(argv[i], "packages")) {
+ packages_argument = argv[i];
+ }
+ i++;
+ }
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
+ Options::dfe()->set_use_dfe();
+#else
+ // DartDev is not supported in AOT.
+ Options::disable_dart_dev_ = true;
+#endif // !defined(DART_PRECOMPILED_RUNTIME)
+ if (Options::deterministic()) {
+ // Both an embedder and VM flag.
+ temp_vm_options.AddArgument("--deterministic");
+ }
+
+ Socket::set_short_socket_read(Options::short_socket_read());
+ Socket::set_short_socket_write(Options::short_socket_write());
+#if !defined(DART_IO_SECURE_SOCKET_DISABLED)
+ SSLCertContext::set_root_certs_file(Options::root_certs_file());
+ SSLCertContext::set_root_certs_cache(Options::root_certs_cache());
+ SSLCertContext::set_long_ssl_cert_evaluation(
+ Options::long_ssl_cert_evaluation());
+ SSLCertContext::set_bypass_trusting_system_roots(
+ Options::bypass_trusting_system_roots());
+#endif // !defined(DART_IO_SECURE_SOCKET_DISABLED)
+
+ FileSystemWatcher::set_delayed_filewatch_callback(
+ Options::delayed_filewatch_callback());
+
+ if (Options::deterministic()) {
+ IOService::set_max_concurrency(1);
+ }
+
+ // The arguments to the VM are at positions 1 through i-1 in argv.
+ Platform::SetExecutableArguments(i, argv);
+
+ bool run_script = false;
+ // Get the script name.
+ if (i < argc) {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+ // If the script name is a valid file or a URL, we'll run the script
+ // directly. Otherwise, this might be a DartDev command and we need to try
+ // to find the DartDev snapshot so we can forward the command and its
+ // arguments.
+ bool is_potential_file_path = !DartDevIsolate::ShouldParseCommand(argv[i]);
+#else
+ bool is_potential_file_path = true;
+#endif // !defined(DART_PRECOMPILED_RUNTIME)
+ if (Options::disable_dart_dev() ||
+ (Options::snapshot_filename() != nullptr) || is_potential_file_path) {
+ *script_name = Utils::StrDup(argv[i]);
+ run_script = true;
+ i++;
+ }
+#if !defined(DART_PRECOMPILED_RUNTIME)
+ else { // NOLINT
+ DartDevIsolate::set_should_run_dart_dev(true);
+ }
+#endif // !defined(DART_PRECOMPILED_RUNTIME)
+ }
+#if !defined(DART_PRECOMPILED_RUNTIME)
+ else if (!Options::disable_dart_dev()) { // NOLINT
+ // Handles following invocation arguments:
+ // - dart help
+ // - dart --help
+ // - dart
+ if (((Options::help_option() && !Options::verbose_option()) ||
+ (argc == 1))) {
+ DartDevIsolate::set_should_run_dart_dev(true);
+ // Let DartDev handle the default help message.
+ dart_options->AddArgument("help");
+ return true;
+ }
+ // Handles cases where only analytics flags are provided. We need to start
+ // the DartDev isolate to set this state.
+ else if (enable_dartdev_analytics || disable_dartdev_analytics) { // NOLINT
+ // The analytics flags are a special case as we don't have a target script
+ // or DartDev command but we still want to launch DartDev.
+ DartDevIsolate::set_should_run_dart_dev(true);
+ dart_options->AddArgument(enable_dartdev_analytics
+ ? "--enable-analytics"
+ : "--disable-analytics");
+ return true;
+ }
+ // Let the VM handle '--version' and '--help --disable-dart-dev'.
+ // Otherwise, we'll launch the DartDev isolate to print its help message
+ // and set an error exit code.
+ else if (!Options::help_option() && !Options::version_option()) { // NOLINT
+ DartDevIsolate::PrintUsageErrorOnRun();
+ return true;
+ }
+ return false;
+ }
+#endif // !defined(DART_PRECOMPILED_RUNTIME)
+ // Handle argument parsing errors and missing script / command name when not
+ // processing options set via DART_VM_OPTIONS.
+ else if (!parsing_dart_vm_options || Options::help_option() || // NOLINT
+ Options::version_option()) { // NOLINT
+ return false;
+ }
+ USE(enable_dartdev_analytics);
+ USE(disable_dartdev_analytics);
+ USE(packages_argument);
+
+ const char** vm_argv = temp_vm_options.arguments();
+ int vm_argc = temp_vm_options.count();
+
+ vm_options->AddArguments(vm_argv, vm_argc);
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
+ // If we're parsing DART_VM_OPTIONS, there shouldn't be any script set or
+ // Dart arguments left to parse.
+ if (parsing_dart_vm_options) {
+ ASSERT(i == argc);
+ return true;
+ }
+
+ // If running with dartdev, attempt to parse VM flags which are part of the
+ // dartdev command (e.g., --enable-vm-service, --observe, etc).
+ bool record_vm_options = false;
+ if ((i < argc) && DartDevIsolate::ShouldParseVMOptions(argv[i])) {
+ record_vm_options = true;
+ }
+ if (!run_script && record_vm_options) {
+ // Skip the command.
+ int tmp_i = i + 1;
+ while (tmp_i < argc) {
+ // Check if this flag is a potentially valid VM flag. If not, we've likely
+ // hit a script name and are done parsing VM flags.
+ if (!OptionProcessor::IsValidFlag(argv[tmp_i]) &&
+ !OptionProcessor::IsValidShortFlag(argv[tmp_i])) {
+ break;
+ }
+ OptionProcessor::TryProcess(argv[tmp_i], vm_options);
+ tmp_i++;
+ }
+ }
+#endif // !defined(DART_PRECOMPILED_RUNTIME)
+
+ bool first_option = true;
+ // Parse out options to be passed to dart main.
+ while (i < argc) {
+ // dart run isn't able to parse these options properly. Since it doesn't
+ // need to use the values from these options, just strip them from the
+ // argument list passed to dart run.
+ if (!IsOption(argv[i], "observe") &&
+ !IsOption(argv[i], "enable-vm-service")) {
+ dart_options->AddArgument(argv[i]);
+ }
+#if !defined(DART_PRECOMPILED_RUNTIME)
+ if (IsOption(argv[i], "disable-dart-dev")) {
+ Syslog::PrintErr(
+ "Attempted to use --disable-dart-dev with a Dart CLI command.\n");
+ Platform::Exit(kErrorExitCode);
+ }
+#endif // !defined(DART_PRECOMIPLED_RUNTIME)
+ i++;
+ // Add DDS specific flags immediately after the dartdev command.
+ if (first_option) {
+ // DDS is only enabled for the run command. Make sure we don't pass DDS
+ // specific flags along with other commands, otherwise argument parsing
+ // will fail unexpectedly.
+#if !defined(DART_PRECOMPILED_RUNTIME)
+ // Bring any --packages option into the dartdev command
+ if (DartDevIsolate::should_run_dart_dev() &&
+ packages_argument != nullptr) {
+ dart_options->AddArgument(packages_argument);
+ }
+#endif // !defined(DART_PRECOMPILED_RUNTIME)
+ first_option = false;
+ }
+ }
+
+ // Verify consistency of arguments.
+
+ // snapshot_depfile is an alias for depfile. Passing them both is an error.
+ if ((snapshot_deps_filename_ != nullptr) && (depfile_ != nullptr)) {
+ Syslog::PrintErr("Specify only one of --depfile and --snapshot_depfile\n");
+ return false;
+ }
+ if (snapshot_deps_filename_ != nullptr) {
+ depfile_ = snapshot_deps_filename_;
+ snapshot_deps_filename_ = nullptr;
+ }
+
+ if ((packages_file_ != nullptr) && (strlen(packages_file_) == 0)) {
+ Syslog::PrintErr("Empty package file name specified.\n");
+ return false;
+ }
+ if ((gen_snapshot_kind_ != kNone) && (snapshot_filename_ == nullptr)) {
+ Syslog::PrintErr(
+ "Generating a snapshot requires a filename (--snapshot).\n");
+ return false;
+ }
+ if ((gen_snapshot_kind_ == kNone) && (depfile_ != nullptr) &&
+ (snapshot_filename_ == nullptr) &&
+ (depfile_output_filename_ == nullptr)) {
+ Syslog::PrintErr(
+ "Generating a depfile requires an output filename"
+ " (--depfile-output-filename or --snapshot).\n");
+ return false;
+ }
+ if ((gen_snapshot_kind_ != kNone) && vm_run_app_snapshot) {
+ Syslog::PrintErr(
+ "Specifying an option to generate a snapshot and"
+ " run using a snapshot is invalid.\n");
+ return false;
+ }
+
+ // If --snapshot is given without --snapshot-kind, default to script snapshot.
+ if ((snapshot_filename_ != nullptr) && (gen_snapshot_kind_ == kNone)) {
+ gen_snapshot_kind_ = kKernel;
+ }
+
return true;
}
diff --git a/runtime/bin/main_options.h b/runtime/bin/main_options.h
index a4e9740..5b696f7 100644
--- a/runtime/bin/main_options.h
+++ b/runtime/bin/main_options.h
@@ -7,7 +7,6 @@
#include "bin/dartutils.h"
#include "bin/dfe.h"
-#include "bin/options.h"
#include "platform/globals.h"
#include "platform/growable_array.h"
#include "platform/hashmap.h"
@@ -28,7 +27,6 @@
V(root_certs_cache, root_certs_cache) \
V(namespace, namespc) \
V(write_service_info, vm_write_service_info_filename) \
- V(executable_name, executable_name) \
/* The purpose of these flags is documented in */ \
/* pkg/dartdev/lib/src/commands/compilation_server.dart. */ \
V(resident_server_info_file, resident_server_info_file_path) \
@@ -46,8 +44,11 @@
V(short_socket_read, short_socket_read) \
V(short_socket_write, short_socket_write) \
V(disable_exit, exit_disabled) \
+ V(preview_dart_2, nop_option) \
V(suppress_core_dump, suppress_core_dump) \
V(enable_service_port_fallback, enable_service_port_fallback) \
+ V(disable_dart_dev, disable_dart_dev) \
+ V(no_dds, disable_dds) \
V(long_ssl_cert_evaluation, long_ssl_cert_evaluation) \
V(bypass_trusting_system_roots, bypass_trusting_system_roots) \
V(delayed_filewatch_callback, delayed_filewatch_callback) \
@@ -84,7 +85,8 @@
V(ProcessEnvironmentOption) \
V(ProcessEnableVmServiceOption) \
V(ProcessObserveOption) \
- V(ProcessDdsOption)
+ V(ProcessProfileMicrotasksOption) \
+ V(ProcessVMDebuggingOptions)
// This enum must match the strings in kSnapshotKindNames in main_options.cc.
enum SnapshotKind {
@@ -93,6 +95,7 @@
kAppJIT,
};
+// This enum must match the strings in kVerbosityLevelNames in main_options.cc.
enum VerbosityLevel {
kError,
kWarning,
@@ -100,9 +103,9 @@
kAll,
};
-static const char* const kVerbosityLevelNames[] = {
- "error", "warning", "info", "all", nullptr,
-};
+static constexpr const char* DEFAULT_VM_SERVICE_SERVER_IP = "localhost";
+static constexpr int DEFAULT_VM_SERVICE_SERVER_PORT = 8181;
+static constexpr int INVALID_VM_SERVICE_SERVER_PORT = -1;
class Options {
public:
@@ -114,7 +117,8 @@
CommandLineOptions* vm_options,
char** script_name,
CommandLineOptions* dart_options,
- bool* print_flags_seen);
+ bool* print_flags_seen,
+ bool* verbose_debug_seen);
#define STRING_OPTION_GETTER(flag, variable) \
static const char* variable() { return variable##_; }
@@ -145,14 +149,21 @@
CB_OPTIONS_LIST(CB_OPTIONS_DECL)
#undef CB_OPTIONS_DECL
+ static bool preview_dart_2() { return true; }
+
static dart::SimpleHashMap* environment() { return environment_; }
static bool enable_vm_service() { return enable_vm_service_; }
-#if !defined(PRODUCT)
static const char* vm_service_server_ip() { return vm_service_server_ip_; }
static int vm_service_server_port() { return vm_service_server_port_; }
-#endif // !defined(PRODUCT)
- static bool enable_dds() { return enable_dds_; }
+
+ // TODO(bkonyi): remove once DartDev moves to AOT and this flag can be
+ // provided directly to the process spawned by `dart run` and `dart test`.
+ //
+ // See https://github.com/dart-lang/sdk/issues/53576
+ static void set_mark_main_isolate_as_system_isolate(bool state) {
+ mark_main_isolate_as_system_isolate_ = state;
+ }
static Dart_KernelCompilationVerbosityLevel verbosity_level() {
return VerbosityLevelToDartAPI(verbosity_);
@@ -227,13 +238,9 @@
}
// VM Service argument processing.
- static bool enable_vm_service_;
-#if !defined(PRODUCT)
static const char* vm_service_server_ip_;
+ static bool enable_vm_service_;
static int vm_service_server_port_;
-#endif // !defined(PRODUCT)
- static bool enable_dds_;
-
static bool ExtractPortAndAddress(const char* option_value,
int* out_port,
const char** out_ip,
diff --git a/runtime/bin/platform.h b/runtime/bin/platform.h
index d8b6409..74acf31 100644
--- a/runtime/bin/platform.h
+++ b/runtime/bin/platform.h
@@ -72,13 +72,6 @@
executable_name_ = executable_name;
}
static const char* GetExecutableName();
-
- // Stores the resolved executable name.
- static void SetResolvedExecutableName(const char* resolved_executable_name) {
- const char* expect_old_is_null = nullptr;
- resolved_executable_name_.compare_exchange_strong(expect_old_is_null,
- resolved_executable_name);
- }
static const char* GetResolvedExecutableName() {
if (resolved_executable_name_.load() == nullptr) {
// Try to resolve the executable path using platform specific APIs.
diff --git a/runtime/bin/process_linux.cc b/runtime/bin/process_linux.cc
index 4b26d9d..9778dd6 100644
--- a/runtime/bin/process_linux.cc
+++ b/runtime/bin/process_linux.cc
@@ -519,18 +519,15 @@
ReportChildError();
}
close(write_out_[0]);
- close(write_out_[1]);
if (TEMP_FAILURE_RETRY(dup2(read_in_[1], STDOUT_FILENO)) == -1) {
ReportChildError();
}
- close(read_in_[0]);
close(read_in_[1]);
if (TEMP_FAILURE_RETRY(dup2(read_err_[1], STDERR_FILENO)) == -1) {
ReportChildError();
}
- close(read_err_[0]);
close(read_err_[1]);
} else {
ASSERT(mode_ == kInheritStdio);
@@ -598,13 +595,12 @@
environ = program_environment_;
}
+ // Report the final PID and do the exec.
+ ReportPid(getpid()); // getpid cannot fail.
char realpath[PATH_MAX];
if (!FindPathInNamespace(realpath, PATH_MAX)) {
ReportChildError();
}
-
- // Report the final PID and do the exec.
- ReportPid(getpid()); // getpid cannot fail.
// TODO(dart:io) Test for the existence of execveat, and use it
// instead.
execvp(realpath, const_cast<char* const*>(program_arguments_));
diff --git a/runtime/bin/process_macos.cc b/runtime/bin/process_macos.cc
index 8aebf47..9bae25e 100644
--- a/runtime/bin/process_macos.cc
+++ b/runtime/bin/process_macos.cc
@@ -451,18 +451,15 @@
ReportChildError();
}
close(write_out_[0]);
- close(write_out_[1]);
if (TEMP_FAILURE_RETRY(dup2(read_in_[1], STDOUT_FILENO)) == -1) {
ReportChildError();
}
- close(read_in_[0]);
close(read_in_[1]);
if (TEMP_FAILURE_RETRY(dup2(read_err_[1], STDERR_FILENO)) == -1) {
ReportChildError();
}
- close(read_err_[0]);
close(read_err_[1]);
} else {
ASSERT(mode_ == kInheritStdio);
diff --git a/runtime/bin/process_win.cc b/runtime/bin/process_win.cc
index cfbfabe..a531acf 100644
--- a/runtime/bin/process_win.cc
+++ b/runtime/bin/process_win.cc
@@ -1044,7 +1044,10 @@
return -1;
}
CloseHandle(child_process);
- return retval;
+ // We exit the process here to simulate the same behaviour as exec on systems
+ // that support it.
+ ExitProcess(retval);
+ return 0;
}
bool Process::Kill(intptr_t id, int signal) {
diff --git a/runtime/bin/utils_win.cc b/runtime/bin/utils_win.cc
index c73d972..9945245 100644
--- a/runtime/bin/utils_win.cc
+++ b/runtime/bin/utils_win.cc
@@ -8,7 +8,6 @@
#include <errno.h> // NOLINT
#include <time.h> // NOLINT
#include <memory>
-#include <sstream>
#include "bin/utils.h"
#include "bin/utils_win.h"
@@ -189,70 +188,6 @@
StringUtilsWin::Utf8ToWide(const_cast<char*>(utf8), len, result_len));
}
-// This code is identical to the one in process_patch.dart, please ensure
-// changes made here are also done in process_patch.dart.
-char* StringUtilsWin::ArgumentEscape(const char* argument) {
- std::string arg_str(argument);
- if (arg_str.empty()) {
- return Utils::StrDup(R"("")");
- }
- std::string result_str = arg_str;
- if (arg_str.find('\t') != std::string::npos ||
- arg_str.find(' ') != std::string::npos ||
- arg_str.find('"') != std::string::npos) {
- // Produce something that the C runtime on Windows will parse
- // back as this string.
-
- // Replace any number of '\' followed by '"' with
- // twice as many '\' followed by '\"'.
- char backslash = '\\';
- std::stringstream sb;
- size_t nextPos = 0;
- size_t quotePos = arg_str.find('"', nextPos);
-
- while (quotePos != std::string::npos) {
- size_t numBackslash = 0;
- size_t pos = quotePos - 1;
- while (pos != std::string::npos && arg_str[pos] == backslash) {
- numBackslash++;
- pos--;
- }
- sb << arg_str.substr(nextPos, quotePos - numBackslash - nextPos);
- for (size_t i = 0; i < numBackslash; i++) {
- sb << R"(\\)";
- }
- sb << R"(\")";
- nextPos = quotePos + 1;
- quotePos = arg_str.find('"', nextPos);
- }
- sb << arg_str.substr(nextPos);
- result_str = sb.str();
-
- // Add '"' at the beginning and end and replace all '\' at
- // the end with two '\'.
- std::stringstream sb2;
- sb2 << '"';
- sb2 << result_str;
-
- // Find the last non-backslash character to determine the actual end
- // of the string
- size_t lastCharPos = arg_str.length() - 1;
- while (lastCharPos != std::string::npos &&
- arg_str[lastCharPos] == backslash) {
- sb2 << '\\';
- lastCharPos--;
- }
- sb2 << '"';
- result_str = sb2.str();
- }
- // Allocate memory for the C-style string and copy the content
- intptr_t len = result_str.length() + 1;
- char* c_str_result = static_cast<char*>(malloc(len * sizeof(char)));
- if (c_str_result == nullptr) return nullptr; // Allocation failure.
- snprintf(c_str_result, len * sizeof(char), "%s", result_str.c_str());
- return c_str_result;
-}
-
bool ShellUtils::GetUtf8Argv(int argc, char** argv) {
wchar_t* command_line = GetCommandLineW();
int unicode_argc;
diff --git a/runtime/bin/utils_win.h b/runtime/bin/utils_win.h
index 00b105f..101760e 100644
--- a/runtime/bin/utils_win.h
+++ b/runtime/bin/utils_win.h
@@ -6,7 +6,6 @@
#define RUNTIME_BIN_UTILS_WIN_H_
#include <memory>
-#include <string>
#include <utility>
#include "platform/utils.h"
@@ -44,7 +43,6 @@
static const wchar_t* Utf8ToWide(const char* utf8,
intptr_t len = -1,
intptr_t* result_len = nullptr);
- static char* ArgumentEscape(const char* argument);
private:
DISALLOW_ALLOCATION();
diff --git a/runtime/bin/vmservice_impl.cc b/runtime/bin/vmservice_impl.cc
index 4b040d1..c7bb1f7c 100644
--- a/runtime/bin/vmservice_impl.cc
+++ b/runtime/bin/vmservice_impl.cc
@@ -9,6 +9,7 @@
#include "bin/builtin.h"
#include "bin/dartutils.h"
#include "bin/isolate_data.h"
+#include "bin/main_options.h"
#include "bin/platform.h"
#include "bin/thread.h"
#include "bin/utils.h"
@@ -34,7 +35,6 @@
}
static constexpr const char* kVMServiceIOLibraryUri = "dart:vmservice_io";
-static constexpr const char* DEFAULT_VM_SERVICE_SERVER_IP = "localhost";
void NotifyServerState(Dart_NativeArguments args) {
Dart_EnterScope();
diff --git a/runtime/tests/vm/dart/exported_symbols_test.dart b/runtime/tests/vm/dart/exported_symbols_test.dart
index 7409613..dfeb535 100644
--- a/runtime/tests/vm/dart/exported_symbols_test.dart
+++ b/runtime/tests/vm/dart/exported_symbols_test.dart
@@ -4,7 +4,6 @@
import "dart:io";
import "package:expect/expect.dart";
-import 'package:path/path.dart' as p;
import "use_flag_test_helper.dart";
@@ -36,9 +35,7 @@
Platform.isMacOS ? "--extern-only" : "--dynamic",
"--defined-only",
"--format=just-symbols",
- isAOTRuntime
- ? Platform.executable
- : p.join(p.dirname(Platform.executable), 'dartvm'),
+ Platform.executable,
]);
if (result.exitCode != 0) {
print("nm failed");
diff --git a/runtime/tests/vm/dart/use_flag_test_helper.dart b/runtime/tests/vm/dart/use_flag_test_helper.dart
index 38c14c4..6d12ad9 100644
--- a/runtime/tests/vm/dart/use_flag_test_helper.dart
+++ b/runtime/tests/vm/dart/use_flag_test_helper.dart
@@ -58,7 +58,7 @@
}
throw 'Could not find gen_snapshot for build directory $buildDir';
}();
-final dart = path.join(buildDir, 'dartvm' + (Platform.isWindows ? '.exe' : ''));
+final dart = path.join(buildDir, 'dart' + (Platform.isWindows ? '.exe' : ''));
final dartPrecompiledRuntime = path.join(
buildDir,
'dartaotruntime' + (Platform.isWindows ? '.exe' : ''),
diff --git a/runtime/tools/entitlements/dart.plist b/runtime/tools/entitlements/dart.plist
index 3322fe1..eeda4be 100644
--- a/runtime/tools/entitlements/dart.plist
+++ b/runtime/tools/entitlements/dart.plist
@@ -2,7 +2,7 @@
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
- <key>com.apple.security.cs.allow-unsigned-executable-memory</key>
+ <key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
diff --git a/runtime/tools/entitlements/dartvm.plist b/runtime/tools/entitlements/dartvm.plist
deleted file mode 100644
index eeda4be..0000000
--- a/runtime/tools/entitlements/dartvm.plist
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
- <dict>
- <key>com.apple.security.cs.allow-jit</key>
- <true/>
- <key>com.apple.security.cs.disable-library-validation</key>
- <true/>
- </dict>
-</plist>
\ No newline at end of file
diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn
index 136e9e4..17b6222 100644
--- a/sdk/BUILD.gn
+++ b/sdk/BUILD.gn
@@ -23,7 +23,6 @@
dart_platform_sdk = true
# Path to stripped dart binaries relative to build output directory.
- dartvm_stripped_binary = "dartvm"
dart_stripped_binary = "dart"
dart_aotruntime_stripped_binary = "dartaotruntime_product"
gen_snapshot_stripped_binary = "gen_snapshot_product"
@@ -38,23 +37,27 @@
# ..dart-sdk/
# ....bin/
# ......dart or dart.exe (executable)
-# ......dartvm or dartvm.exe (executable)
# ......dart.lib (import library for VM native extensions on Windows)
# ......dartaotruntime or dartaotruntime.exe (executable)
# ......utils/gen_snapshot or utils/gen_snapshot.exe (if not on ia32)
# ......snapshots/
-# ........analysis_server.dart.snapshot (JIT snapshot)
+# ........analysis_server.dart.snapshot
# ........analysis_server_aot.dart.snapshot (AOT snapshot, if not on ia32)
# ........dart2bytecode.snapshot (AOT snapshot, for selected targets)
-# ........dart2js_aot.dart.snapshot (AOT snapshot)
-# ........dart2wasm_product.snapshot (AOT snapshot)
-# ........dartdev_aot.dart.snapshot (AOT snapshot)
-# ........dartdevc_aot.dart.snapshot (AOT snapshot)
-# ........dds_aot.dart.snapshot (AOT snapshot)
-# ........dart_tooling_daemon_aot.dart.snapshot (AOT snapshot)
-# ........frontend_server_aot.dart.snapshot (AOT snapshot)
-# ........gen_kernel_aot.dart.snapshot (AOT snapshot)
-# ........kernel-service.dart.snapshot (JIT snapshot)
+# ........dart2js_aot.dart.snapshot (AOT snapshot, if not on ia32)
+# ........dart2js.dart.snapshot (JIT snapshot only on ia32)
+# ........dart2wasm_product.snapshot (if not on ia32)
+# ........dartdev.dart.snapshot (app-jit snapshot or kernel dill file)
+# ........dartdevc_aot.dart.snapshot (AOT snapshot, if not on ia32)
+# ........dartdevc.dart.snapshot (JIT snapshot only on ia32)
+# ........dds_aot.dart.snapshot (AOT snapshot, if not on ia32)
+# ........dds.dart.snapshot (JIT snapshot only on ia32)
+# ........dart_tooling_daemon_aot.dart.snapshot (AOT snapshot, if not on ia32)
+# ........dart_tooling_daemon.dart.snapshot (JIT snapshot only on ia32)
+# ........frontend_server_aot.dart.snapshot (AOT snapshot, if not on ia32)
+# ........frontend_server.dart.snapshot (JIT snapshot only on ia32)
+# ........gen_kernel_aot.dart.snapshot (if not on ia32)
+# ........kernel-service.dart.snapshot
# ........kernel_worker_aot.dart.snapshot (AOT snapshot)
# ......resources/
# ........dartdoc/
@@ -109,11 +112,23 @@
_full_sdk_scripts = []
# Snapshots that go under bin/snapshots
-_platform_sdk_snapshots = [ [
- "analysis_server",
- "../utils/analysis_server",
- "analysis_server",
- ] ]
+_platform_sdk_snapshots = [
+ [
+ "analysis_server",
+ "../utils/analysis_server",
+ "analysis_server",
+ ],
+ [
+ "dartdev",
+ "../utils/dartdev:dartdev",
+ "dartdev",
+ ],
+ [
+ "dart_tooling_daemon",
+ "../utils/dtd:dtd",
+ "dart_tooling_daemon",
+ ],
+]
if (dart_target_arch != "ia32" && dart_target_arch != "x86") {
_platform_sdk_snapshots += [
[
@@ -127,11 +142,6 @@
"frontend_server_aot",
],
[
- "dartdev_aot",
- "../utils/dartdev:dartdev_aot",
- "dartdev_aot",
- ],
- [
"dds_aot_product",
"../utils/dds:dds_aot",
"dds_aot",
@@ -148,11 +158,18 @@
],
]
} else {
- _platform_sdk_snapshots += [ [
- "dds",
- "../utils/dds:dds",
- "dds",
- ] ]
+ _platform_sdk_snapshots += [
+ [
+ "frontend_server",
+ "../utils/kernel-service:frontend_server",
+ "frontend_server",
+ ],
+ [
+ "dds",
+ "../utils/dds:dds",
+ "dds",
+ ],
+ ]
}
if (dart_snapshot_kind == "app-jit") {
_platform_sdk_snapshots += [ [
@@ -173,6 +190,9 @@
] ]
}
+# AOT snapshots are not supported on the ia32 architecture, we continue
+# to use JIT snapshots on that architecture, the conditional code below
+# accounts for this.
if (dart_target_arch != "ia32" && dart_target_arch != "x86") {
_full_sdk_snapshots =
_platform_sdk_snapshots + [
@@ -201,7 +221,23 @@
],
]
} else {
- _full_sdk_snapshots = _platform_sdk_snapshots
+ _full_sdk_snapshots = _platform_sdk_snapshots + [
+ [
+ "dart2js",
+ "../utils/compiler:dart2js",
+ "dart2js",
+ ],
+ [
+ "dartdevc",
+ "../utils/ddc:dartdevc",
+ "dartdevc",
+ ],
+ [
+ "kernel_worker",
+ "../utils/bazel:kernel_worker",
+ "kernel_worker",
+ ],
+ ]
}
# Libraries that go under lib/
@@ -313,13 +349,13 @@
# make a link to the symlink rather than the symlink's target, and the
# relative symlink interpreted from a different containing directory
# will not find the actual binary.
- action("copy_dartvm") {
+ action("copy_dart") {
visibility = [ ":create_common_sdk" ]
- dart_label = "../runtime/bin:dartvm"
+ dart_label = "../runtime/bin:dart"
deps = [ dart_label ]
dart_out = get_label_info(dart_label, "root_out_dir")
- sources = [ "$dart_out/$dartvm_stripped_binary" ]
- outputs = [ "$root_out_dir/$dart_sdk_output/bin/$dartvm_stripped_binary" ]
+ sources = [ "$dart_out/$dart_stripped_binary" ]
+ outputs = [ "$root_out_dir/$dart_sdk_output/bin/$dart_stripped_binary" ]
script = "/bin/ln"
args = [
"-snf",
@@ -328,36 +364,18 @@
]
}
} else {
- copy("copy_dartvm") {
- visibility = [ ":create_common_sdk" ]
- deps = [ "../runtime/bin:dartvm" ]
- dart_out = get_label_info("../runtime/bin:dartvm", "root_out_dir")
- sources = [ "$dart_out/${dartvm_stripped_binary}${executable_suffix}" ]
- if (is_win && dart_lib_export_symbols) {
- sources += [ "$dart_out/dartvm.lib" ]
- }
- if (_has_dot_sym) {
- sources += [ "$dart_out/dartvm.sym" ]
- }
- outputs = [ "$root_out_dir/$dart_sdk_output/bin/{{source_file_part}}" ]
- }
-}
-
-if (dart_target_arch != "ia32" && dart_target_arch != "x86") {
copy("copy_dart") {
visibility = [ ":create_common_sdk" ]
deps = [ "../runtime/bin:dart" ]
- src_dir = get_label_info("../runtime/bin:dart", "root_out_dir")
- sources = [ "$src_dir/${dart_stripped_binary}${executable_suffix}" ]
- outputs = [ "$root_out_dir/$dart_sdk_output/bin/dart${executable_suffix}" ]
- }
-} else {
- copy("copy_dart") {
- visibility = [ ":create_common_sdk" ]
- deps = [ "../runtime/bin:dartvm" ]
- src_dir = get_label_info("../runtime/bin:dartvm", "root_out_dir")
- sources = [ "$src_dir/${dartvm_stripped_binary}${executable_suffix}" ]
- outputs = [ "$root_out_dir/$dart_sdk_output/bin/dart${executable_suffix}" ]
+ dart_out = get_label_info("../runtime/bin:dart", "root_out_dir")
+ sources = [ "$dart_out/${dart_stripped_binary}${executable_suffix}" ]
+ if (is_win && dart_lib_export_symbols) {
+ sources += [ "$dart_out/dart.lib" ]
+ }
+ if (_has_dot_sym) {
+ sources += [ "$dart_out/dart.sym" ]
+ }
+ outputs = [ "$root_out_dir/$dart_sdk_output/bin/{{source_file_part}}" ]
}
}
@@ -481,9 +499,9 @@
root = root_out_dir
}
- # The dartdev, dds and dtd snapshots are output to root_out_dir in order to
- # be compatible with the way the dart sdk is distributed internally.
- if (snapshot[0] == "dartdev_aot" || snapshot[0] == "dds_aot_product" ||
+ # The dds and dtd snapshots are output to root_out_dir in order to be
+ # compatible with the way the dart sdk is distributed internally.
+ if (snapshot[0] == "dds_aot_product" ||
snapshot[0] == "dart_tooling_daemon_aot_product") {
root = root_out_dir
}
@@ -800,7 +818,6 @@
":copy_api_readme",
":copy_dart",
":copy_dartdoc_files",
- ":copy_dartvm",
":copy_headers",
":copy_libraries_specification",
":copy_license",
diff --git a/sdk/lib/_internal/vm/bin/vmservice_server.dart b/sdk/lib/_internal/vm/bin/vmservice_server.dart
index b905a34..9ea25e4 100644
--- a/sdk/lib/_internal/vm/bin/vmservice_server.dart
+++ b/sdk/lib/_internal/vm/bin/vmservice_server.dart
@@ -167,14 +167,8 @@
if (FileSystemEntity.typeSync(script) == FileSystemEntityType.notFound) {
script = [dartDir, 'dds_aot.dart.snapshot'].join(Platform.pathSeparator);
if (FileSystemEntity.typeSync(script) == FileSystemEntityType.notFound) {
- // We could be running on IA32 architecture so check if the JIT
- // snapshot is available.
executable = [dartDir, dart].join(Platform.pathSeparator);
- script = [dartDir, 'dds.dart.snapshot'].join(Platform.pathSeparator);
- if (FileSystemEntity.typeSync(script) ==
- FileSystemEntityType.notFound) {
- script = 'development-service';
- }
+ script = 'development-service';
}
}
diff --git a/tests/ffi/native_assets/helpers.dart b/tests/ffi/native_assets/helpers.dart
index 18a82b0..40e95e6 100644
--- a/tests/ffi/native_assets/helpers.dart
+++ b/tests/ffi/native_assets/helpers.dart
@@ -29,10 +29,7 @@
final cwdUri = Directory.current.uri;
final platformExecutableUriAbsolute = cwdUri.resolveUri(
- Uri.file(
- Platform.resolvedExecutable.replaceAll(r'\', '/'),
- windows: Platform.isWindows,
- ),
+ Uri.file(Platform.resolvedExecutable),
);
/// The build folder on desktop platforms.
@@ -61,7 +58,7 @@
'gen_snapshot$standaloneExtensionExe',
);
-final dartUri = buildUriAbsolute.resolve('dartvm$standaloneExtensionExe');
+final dartUri = buildUriAbsolute.resolve('dart$standaloneExtensionExe');
final dartPrecompiledRuntimeUri = buildUriAbsolute.resolve(
'dartaotruntime$standaloneExtensionExe',
diff --git a/tests/standalone/regress_41329_absolute_test.dart b/tests/standalone/regress_41329_absolute_test.dart
index 97c333e..e0ae505 100644
--- a/tests/standalone/regress_41329_absolute_test.dart
+++ b/tests/standalone/regress_41329_absolute_test.dart
@@ -28,6 +28,6 @@
final link2 = Link('dart')..createSync(linkLocation, recursive: true);
final path = Uri.parse(link2.absolute.path).path;
Directory.current = origDir;
- final result = await Process.run('$path', ['--help']);
+ final result = await Process.run('$path', ['help']);
Expect.equals(result.exitCode, 0);
}
diff --git a/tests/standalone/regress_41329_relative_test.dart b/tests/standalone/regress_41329_relative_test.dart
index 2c29d9e..e35e126 100644
--- a/tests/standalone/regress_41329_relative_test.dart
+++ b/tests/standalone/regress_41329_relative_test.dart
@@ -27,6 +27,6 @@
final link2 = Link('dart')..createSync(linkLocation, recursive: true);
final path = Uri.parse(link2.absolute.path).path;
Directory.current = origDir;
- final result = await Process.run('${path}', ['--help']);
+ final result = await Process.run('${path}', ['help']);
Expect.equals(result.exitCode, 0);
}
diff --git a/tools/bots/try_benchmarks.sh b/tools/bots/try_benchmarks.sh
index 756a980..3183926 100755
--- a/tools/bots/try_benchmarks.sh
+++ b/tools/bots/try_benchmarks.sh
@@ -150,7 +150,6 @@
out/ReleaseX64/gen/kernel_service.dill \
out/ReleaseX64/dart-sdk \
out/ReleaseX64/dart \
- out/ReleaseX64/dartvm \
out/ReleaseX64/gen_snapshot \
out/ReleaseX64/kernel-service.dart.snapshot \
out/ReleaseX64/dart2wasm.snapshot \
diff --git a/tools/gn.py b/tools/gn.py
index ae9deb8..752c6aa 100755
--- a/tools/gn.py
+++ b/tools/gn.py
@@ -280,7 +280,6 @@
# We don't support stripping on Windows
if host_os != 'win':
gn_args['dart_stripped_binary'] = 'exe.stripped/dart'
- gn_args['dartvm_stripped_binary'] = 'exe.stripped/dartvm'
gn_args['dart_aotruntime_stripped_binary'] = (
'exe.stripped/dartaotruntime_product')
gn_args['gen_snapshot_stripped_binary'] = (
diff --git a/tools/task_kill.py b/tools/task_kill.py
index 7c54c57..46a5bf5 100755
--- a/tools/task_kill.py
+++ b/tools/task_kill.py
@@ -25,8 +25,7 @@
'win32': {
'chrome': 'chrome.exe',
'crashpad_handler': 'crashpad_handler.exe',
- 'dart': 'dart.exe',\
- 'dart_product': 'dart_product.exe',
+ 'dart': 'dart.exe',
'dartaotruntime': 'dartaotruntime.exe',
'dartaotruntime_product': 'dartaotruntime_product.exe',
'firefox': 'firefox.exe',
@@ -39,7 +38,6 @@
'linux': {
'chrome': 'chrome',
'dart': 'dart',
- 'dart_product': 'dart_product',
'dartaotruntime': 'dartaotruntime',
'dartaotruntime_product': 'dartaotruntime_product',
'firefox': 'firefox',
@@ -51,7 +49,6 @@
'chrome': 'Chrome',
'chrome_helper': 'Chrome Helper',
'dart': 'dart',
- 'dart_product': 'dart_product',
'dartaotruntime': 'dartaotruntime',
'dartaotruntime_product': 'dartaotruntime_product',
'firefox': 'firefox',
diff --git a/utils/application_snapshot.gni b/utils/application_snapshot.gni
index 414d25d..37037cf 100644
--- a/utils/application_snapshot.gni
+++ b/utils/application_snapshot.gni
@@ -186,7 +186,7 @@
assert(training_deps != "", "Ignoring unused argument")
}
} else {
- dartvm_action(target_name) {
+ dart_action(target_name) {
if (defined(invoker.pool)) {
pool = invoker.pool
}
diff --git a/utils/compiler/BUILD.gn b/utils/compiler/BUILD.gn
index c8dfe53..f621419 100644
--- a/utils/compiler/BUILD.gn
+++ b/utils/compiler/BUILD.gn
@@ -75,6 +75,13 @@
]
}
+aot_snapshot("dart2js_aot") {
+ deps = [ ":dart2js_create_snapshot_entry" ]
+
+ main_dart = "$target_gen_dir/dart2js.dart"
+ name = "dart2js_aot"
+}
+
aot_snapshot("dart2js_sdk_aot") {
deps = [ ":dart2js_create_snapshot_entry" ]
diff --git a/utils/dartdev/BUILD.gn b/utils/dartdev/BUILD.gn
index 9a58e7a..89d4379 100644
--- a/utils/dartdev/BUILD.gn
+++ b/utils/dartdev/BUILD.gn
@@ -3,34 +3,8 @@
# BSD-style license that can be found in the LICENSE file.
import("../../build/dart/copy_tree.gni")
-import("../aot_snapshot.gni")
import("../application_snapshot.gni")
-group("dartdev_aot") {
- public_deps = [
- ":copy_prebuilt_devtools",
- ":dartdev_aot_snapshot",
- ]
-}
-
-aot_snapshot("dartdev_aot_profile_snapshot") {
- main_dart = "../../pkg/dartdev/bin/dartdev.dart"
- output = "$root_out_dir/dartdev_aot_profile.dart.snapshot"
-}
-
-aot_snapshot("dartdev_aot_snapshot") {
- main_dart = "../../pkg/dartdev/bin/dartdev.dart"
- output = "$root_out_dir/dartdev_aot.dart.snapshot"
-
- # dart has dart_product_config applied to it,
- # so it is built in product mode in both release and
- # product builds, and is only built in debug mode in debug
- # builds. The following line ensures that the dart
- # and dartdev_aot snapshot in an SDK build are
- # always compatible with each other.
- force_product_mode = !dart_debug
-}
-
group("dartdev") {
public_deps = [
":copy_dartdev_snapshot",
@@ -38,12 +12,6 @@
]
}
-application_snapshot("generate_dartdev_snapshot") {
- main_dart = "../../pkg/dartdev/bin/dartdev.dart"
- training_args = [ "--help" ]
- output = "$root_gen_dir/dartdev.dart.snapshot"
-}
-
copy("copy_dartdev_snapshot") {
visibility = [ ":dartdev" ]
public_deps = [ ":generate_dartdev_snapshot" ]
@@ -51,11 +19,14 @@
outputs = [ "$root_out_dir/dartdev.dart.snapshot" ]
}
+application_snapshot("generate_dartdev_snapshot") {
+ main_dart = "../../pkg/dartdev/bin/dartdev.dart"
+ training_args = [ "--help" ]
+ output = "$root_gen_dir/dartdev.dart.snapshot"
+}
+
copy_tree("copy_prebuilt_devtools") {
- visibility = [
- ":dartdev",
- ":dartdev_aot",
- ]
+ visibility = [ ":dartdev" ]
source = "../../third_party/devtools/web"
dest = "$root_out_dir/devtools"
exclude = "{}"