[vm] Introduce --script_uri_override to support Platform.script in dart run -r
If a script uses `Platform.script` running it with as `dart
<script.dart>` and `dart run <script.dart>` would give the correct
script ("<script.dart>"), but running it with `dart run -r
<script.dart>` would report a dill file in the temp directory which is
not only surprising, but also breaking and for instance running the CFEs
strong_suite.dart via `dart run -r` didn't work.
This CL introduces --script_uri_override to the VM and makes the
resident compiler setup pass it so that when running `dart run -r
<script.dart>`, even though the vm is actually launched from a dill file
that resides in temp, `Platform.script` will actually return
`<script.dart>` - and running the CFEs strong_suite.dart via `dart run
-r` now actually works.
Tested: Added pkg/dartdev/test/commands/run_test.dart and manual testing.
Change-Id: Ia65c01834485fe06af63584baf0448dd5b9ffdb4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/510343
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Jens Johansen <jensj@google.com>
This commit is contained in:
committed by
dart-scoped@luci-project-accounts.iam.gserviceaccount.com
parent
f3d47ab020
commit
b32e313620
@@ -550,6 +550,7 @@ See https://dart.dev/to/package-descriptors for more details.''', verbose) {
|
||||
log.stderr(e.message);
|
||||
return errorExitCode;
|
||||
}
|
||||
DartExecutableWithPackageConfig executableOriginal = executable;
|
||||
|
||||
if (useResidentCompiler) {
|
||||
final File? residentCompilerInfoFile =
|
||||
@@ -616,6 +617,9 @@ See https://dart.dev/to/package-descriptors for more details.''', verbose) {
|
||||
packageConfigOverride:
|
||||
args.option('packages') ?? executable.packageConfig,
|
||||
useExecProcess: true,
|
||||
scriptUriOverride: identical(executable, executableOriginal)
|
||||
? null
|
||||
: executableOriginal.executable,
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -34,6 +34,11 @@ abstract class VmInteropHandler {
|
||||
// See https://github.com/dart-lang/sdk/issues/53576
|
||||
bool markMainIsolateAsSystemIsolate = false,
|
||||
bool useExecProcess = false,
|
||||
|
||||
/// When [useExecProcess] pass this path to signal that it originates from
|
||||
/// another file. Used for launching from a dill file while behaving as if
|
||||
/// launched directly from a dart file.
|
||||
String? scriptUriOverride,
|
||||
}) {
|
||||
List<String> argsList;
|
||||
if (useExecProcess && Platform.isWindows) {
|
||||
@@ -45,6 +50,12 @@ abstract class VmInteropHandler {
|
||||
// Escape paths that may contain spaces
|
||||
script = '"$script"';
|
||||
}
|
||||
if (scriptUriOverride != null &&
|
||||
scriptUriOverride.contains(' ') &&
|
||||
!scriptUriOverride.contains('"')) {
|
||||
// Escape paths that may contain spaces
|
||||
scriptUriOverride = '"$scriptUriOverride"';
|
||||
}
|
||||
argsList = [
|
||||
for (int i = 0; i < args.length; i++) _windowsArgumentEscape(args[i]),
|
||||
];
|
||||
@@ -57,6 +68,7 @@ abstract class VmInteropHandler {
|
||||
final message = <dynamic>[
|
||||
useExecProcess ? _kResultRunExec : _kResultRun,
|
||||
script,
|
||||
if (useExecProcess) scriptUriOverride,
|
||||
packageConfigOverride,
|
||||
markMainIsolateAsSystemIsolate,
|
||||
argsList,
|
||||
|
||||
@@ -972,6 +972,95 @@ Future<void> main() async {
|
||||
expect(result.exitCode, 0);
|
||||
});
|
||||
|
||||
test(
|
||||
'resident compiler invocation has working Platform.script',
|
||||
() async {
|
||||
p = project(name: 'foo');
|
||||
p.file('pubspec.yaml', '''
|
||||
name: foo
|
||||
environment:
|
||||
sdk: '>=2.12.0<3.0.0'
|
||||
''');
|
||||
p.file('bin/script1.dart', r'''
|
||||
import "dart:io";
|
||||
import "dart:isolate";
|
||||
|
||||
Future<void> main() async {
|
||||
print("Script1: ${Platform.script}");
|
||||
var exitPort = ReceivePort();
|
||||
var isolate = await Isolate.spawn(
|
||||
entryPoint,
|
||||
"",
|
||||
onExit: exitPort.sendPort,
|
||||
);
|
||||
await exitPort.first;
|
||||
|
||||
exitPort = ReceivePort();
|
||||
await Isolate.spawnUri(
|
||||
Uri.parse("script2.dart"),
|
||||
[],
|
||||
"",
|
||||
onExit: exitPort.sendPort,
|
||||
);
|
||||
await exitPort.first;
|
||||
}
|
||||
|
||||
void entryPoint(String arg) {
|
||||
print(" -> ${Platform.script}");
|
||||
}
|
||||
''');
|
||||
p.file('bin/script2.dart', r'''
|
||||
import "dart:io";
|
||||
import "dart:isolate";
|
||||
|
||||
Future<void> main() async {
|
||||
print("Script2: ${Platform.script}");
|
||||
var exitPort = ReceivePort();
|
||||
var isolate = await Isolate.spawn(
|
||||
entryPoint,
|
||||
"",
|
||||
onExit: exitPort.sendPort,
|
||||
);
|
||||
await exitPort.first;
|
||||
}
|
||||
|
||||
void entryPoint(String arg) {
|
||||
print(" -> ${Platform.script}");
|
||||
}
|
||||
''');
|
||||
|
||||
var script1 = File(path.join(p.dir.path, 'bin/script1.dart'));
|
||||
expect(script1.existsSync(), true);
|
||||
var script2 = File(path.join(p.dir.path, 'bin/script2.dart'));
|
||||
expect(script2.existsSync(), true);
|
||||
|
||||
ProcessResult pubGetResult = await p.run(['pub', 'get']);
|
||||
expect(pubGetResult.stderr, isEmpty);
|
||||
expect(pubGetResult.exitCode, 0);
|
||||
|
||||
ProcessResult result = await p.run([
|
||||
'run',
|
||||
'--resident',
|
||||
'--$residentCompilerInfoFileOption=$serverInfoFile',
|
||||
'bin/script1.dart',
|
||||
]);
|
||||
|
||||
String stdout = result.stdout.toString().trim();
|
||||
expect(
|
||||
stdout,
|
||||
'''
|
||||
Script1: ${script1.uri}
|
||||
-> ${script1.uri}
|
||||
Script2: ${script2.uri}
|
||||
-> ${script2.uri}
|
||||
'''
|
||||
.trim(),
|
||||
);
|
||||
expect(result.stderr, isEmpty);
|
||||
expect(result.exitCode, 0);
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
'passing --resident is a prerequisite for passing --resident-compiler-info-file',
|
||||
() async {
|
||||
|
||||
+40
-9
@@ -606,33 +606,48 @@ class DartDev {
|
||||
Syslog::PrintErr("Unable to locate the Dart VM executable");
|
||||
Platform::Exit(kErrorExitCode);
|
||||
}
|
||||
|
||||
ASSERT(GetArrayItem(message, 1)->type == Dart_CObject_kString);
|
||||
|
||||
// scriptUriOverride.
|
||||
auto item2 = GetArrayItem(message, 2);
|
||||
|
||||
ASSERT(item2->type == Dart_CObject_kString ||
|
||||
item2->type == Dart_CObject_kNull);
|
||||
|
||||
// packageConfigOverride.
|
||||
auto item3 = GetArrayItem(message, 3);
|
||||
|
||||
ASSERT(item3->type == Dart_CObject_kString ||
|
||||
item3->type == Dart_CObject_kNull);
|
||||
|
||||
package_config_override_ = nullptr;
|
||||
|
||||
if (item2->type == Dart_CObject_kString) {
|
||||
package_config_override_ = Utils::StrDup(item2->value.as_string);
|
||||
if (item3->type == Dart_CObject_kString) {
|
||||
package_config_override_ = Utils::StrDup(item3->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);
|
||||
// markMainIsolateAsSystemIsolate
|
||||
auto item4 = GetArrayItem(message, 4);
|
||||
ASSERT(item4->type == Dart_CObject_kBool);
|
||||
const bool mark_main_isolate_as_system_isolate = item4->value.as_bool;
|
||||
|
||||
// argsList
|
||||
ASSERT(GetArrayItem(message, 5)->type == Dart_CObject_kArray);
|
||||
Dart_CObject* args = GetArrayItem(message, 5);
|
||||
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;
|
||||
};
|
||||
|
||||
intptr_t num_vm_options = dart_vm_options_->count();
|
||||
const char** vm_options = dart_vm_options_->arguments();
|
||||
|
||||
// Total count of arguments to be passed to the script being execed.
|
||||
if (mark_main_isolate_as_system_isolate) {
|
||||
argc_ = argc + num_vm_options + 5;
|
||||
@@ -642,6 +657,9 @@ class DartDev {
|
||||
if (package_config_override_ != nullptr) {
|
||||
argc_++;
|
||||
}
|
||||
if (item2->type == Dart_CObject_kString) {
|
||||
argc_++;
|
||||
}
|
||||
|
||||
// Array of arguments to be passed to the script being execed.
|
||||
argv_ = std::unique_ptr<char*[], void (*)(char**)>(new char*[argc_ + 1],
|
||||
@@ -697,6 +715,19 @@ class DartDev {
|
||||
argv_[idx++] = Utils::SCreate("--packages=%s", package_config_override_);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (item2->value.as_string != nullptr) {
|
||||
#if defined(DART_HOST_OS_WINDOWS)
|
||||
char* script_uri_override =
|
||||
Utils::SCreate("--script_uri_override=%s", item2->value.as_string);
|
||||
argv_[idx++] = StringUtilsWin::ArgumentEscape(script_uri_override);
|
||||
free(script_uri_override);
|
||||
#else
|
||||
argv_[idx++] =
|
||||
Utils::SCreate("--script_uri_override=%s", item2->value.as_string);
|
||||
#endif
|
||||
}
|
||||
|
||||
// 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.
|
||||
|
||||
@@ -690,9 +690,12 @@ static Dart_Isolate CreateIsolateGroupAndSetupHelper(
|
||||
PathSanitizer packages_config_sanitizer(packages_config);
|
||||
#endif // !defined(DART_PRECOMPILED_RUNTIME)
|
||||
|
||||
auto isolate_group_data =
|
||||
new IsolateGroupData(script_uri, asset_resolution_base, packages_config,
|
||||
app_snapshot, isolate_run_app_snapshot);
|
||||
auto isolate_group_data = new IsolateGroupData(
|
||||
is_main_isolate && Options::script_uri_override() != nullptr
|
||||
? Options::script_uri_override()
|
||||
: script_uri,
|
||||
asset_resolution_base, packages_config, app_snapshot,
|
||||
isolate_run_app_snapshot);
|
||||
if (kernel_buffer != nullptr) {
|
||||
isolate_group_data->SetKernelBufferNewlyOwned(kernel_buffer,
|
||||
kernel_buffer_size);
|
||||
|
||||
@@ -31,6 +31,7 @@ namespace bin {
|
||||
V(executable_name, executable_name) \
|
||||
V(resolved_executable_name, resolved_executable_name) \
|
||||
V(load_module_snapshot, load_module_snapshot) \
|
||||
V(script_uri_override, script_uri_override) \
|
||||
/* 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) \
|
||||
|
||||
Reference in New Issue
Block a user