Skip to content

Platform.script should be reworked to always return the Dart entrypoint path #60498

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
bkonyi opened this issue Apr 8, 2025 · 4 comments
Open
Labels
area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. library-io P3 A lower priority bug or feature request triaged Issue has been triaged by sub team type-enhancement A request for a change that isn't a bug

Comments

@bkonyi
Copy link
Contributor

bkonyi commented Apr 8, 2025

Platform.script behaves differently depending on how a Dart program is invoked:

  • When running from source, it returns the path to the file containing the entrypoint
  • When run with dart test, the resident compiler, or a precompiled snapshot, the path to the intermediate artifact (e.g., dill, or snapshot) is returned

This makes it difficult to resolve URIs relative to the entrypoint script, something that is frequently done within tests to load resources or spawn child processes. The difference in behavior depending on how the script was executed is also surprising and confusing.

We should consider providing a way to consistently provide the path to the entrypoint script for a given isolate, regardless of how it was run. Some ideas:

  • Rework Platform.script to not return paths to compilation artifacts (this would be a breaking change)
  • Provide a new API that can be used to consistently retrieve the entrypoint path (Platform.entrypointUri?)
  • Provide an IOOverride for script, which would at least allow for package:test to possibly override the path to the correct entrypoint
@bkonyi bkonyi added area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. library-io type-enhancement A request for a change that isn't a bug labels Apr 8, 2025
@a-siva a-siva added triaged Issue has been triaged by sub team P3 A lower priority bug or feature request labels Apr 9, 2025
@a-siva
Copy link
Contributor

a-siva commented Apr 9, 2025

//cc @lrhn

@lrhn
Copy link
Member

lrhn commented Apr 9, 2025

There are two meaningful options for how script can work.

  1. Platform.script points to the entry point of compilation, the script .dart library file. That cannot be expected to work with any kind of AoT.
    If the code is not run directly from the source, as by dart run, then there can be no expectation that the script file path is valid or useful, and then it should not be available at all. The getter should simply throw if not actually run directly from the script file.
  2. Platform.script points to the entry point of execution. If AoT compiled, as by dart compile anything, the entry point is the file that was fed to the final execution step, whether that is the .exe file itself or whatever file that is passed to dart to run.

The latter is a superset of the former, and it's what we do. It works both for running from from source and running an exe.
I don't think we should change that generally, and if we did, we should still not bake a source path into a movable artifact.
(Isolate.resolvePackageUri should also only work when run directly from source.)

We could allow some intermediate forms to be considered "transitory", and let them keep compilation environment information, like script path and package resolution, with the clear understanding that they should be run on the same system where they were created, and that they only exist as a local optimization step.

I don't know which kind of intermediate forms we have, but anything short of an exe could probably be configured that way, given the right flags. Anything that can be a step in a compilation.

The default is to not remember source system information, and you have to ask to have it included. It won't be useful if you move the artifact to another system, or maybe even if you keep it for too long, so the source paths are no longer correct.

If we want to be defensive, a Dart installation could assign itself a random number, and bake that into local-only artifacts, and then refuse to run them if the number doesn't match. Maybe a new number every time the SDK is updated. Or every free days.

That's my suggestion, a compilation flag that makes the VM remember source paths, as they would be if run from source, through intermediate representations. Preferably in a way that makes it hard to accidentally think such a compilation artifact of useful anywhere else.

@dcharkes
Copy link
Contributor

With dart compile exe and dart build (and flutter build) we don't have access to source directories at all. So if you want access to some files relative to your source path, they should be bundled. Probably DataAssets from build hooks (once they are available in Dart)?

Now, for package:test (dart-lang/test#110) we always have sources, even though the tests get compiled to kernel for performance reasons. So that is a special case in which we can actually give access to files without using something like data assets.

@lrhn
Copy link
Member

lrhn commented Apr 22, 2025

Technically, dart compile exe may be run immediately on the same machine, so the source files are exactly where expected.
Nothing prevents dart compile exe --local-paths foo.dart from remembering those source paths, so you can run it to behave the same as dart run foo.dart. It would obviously not work if you move that exe file anywhere else, but ... then don't do that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. library-io P3 A lower priority bug or feature request triaged Issue has been triaged by sub team type-enhancement A request for a change that isn't a bug
Projects
None yet
Development

No branches or pull requests

4 participants