Skip to content
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

[dart2wasm] Add support detection mechanism #59951

Open
mkustermann opened this issue Jan 22, 2025 · 5 comments
Open

[dart2wasm] Add support detection mechanism #59951

mkustermann opened this issue Jan 22, 2025 · 5 comments
Labels
area-dart2wasm Issues for the dart2wasm compiler.

Comments

@mkustermann
Copy link
Member

The initial WasmGC support has landed in the spec and our compiler can rely on everything in it. Though the wasm spec will be evolving over time and we want to be able to take advantage of newer features. In many cases it may not be possible to polyfill those features (e.g. usage of new instructions, new builtins that aren't polyfillable, etc).

Because of this I'd like to us to introduce a support detection mechanism that users can call to detect if their environment allows running dart2wasm compiled code.

One way could be to make this part of the public API of our <app>.mjs e.g.

const bundle = await import('app.mjs');
if (bundle.supportsCurrentEnvironment()) {
  const compiledApp = await bundle.compileStreaming(fetch('app.wasm');
  const appInstance = await compiledApp.instantiate(...);
  appInstance.invokeMain();
} else {
  // fall back to JS
}

The downside of making this part of the <app>.mjs file is that users first have to load the mjs file (which may not be that small) in order to detect whether the wasm can be used before loading the actual wasm file (or loading the wasm file concurrently but possibly not use it).

So we could also emit an extra file

app.mjs
app.wasm
app.wasm.maps
app.support.mjs (New)

that has such an API function in it.

Then we as Dart team can decide when we start requiring new things (based on data of browser support and browser version usages out there) and/or allow the invoker of dart2wasm to tell us to use newer features.

/cc @osa1
/cc @kevmoo
/cc @yjbanov @eyebrowsoffire what mechanism would work best for flutter?

@mkustermann mkustermann added the area-dart2wasm Issues for the dart2wasm compiler. label Jan 22, 2025
@simolus3
Copy link
Contributor

Given that support.mjs will likely be small, I think it would be great it could be emitted in a format that allows build tools to pick it up and embed it in their own loaders (so ideally just a JS expression instead of a module with exports).

For reference, this is what build_web_compilers is doing today. Replacing that snippet with something generated by dart2wasm would be nice, but IMO loading another JavaScript module wouldn't be ideal since there is no bundler in that setup.

@mkustermann
Copy link
Member Author

Given that support.mjs will likely be small, I think it would be great it could be emitted in a format that allows build tools to pick it up and embed it in their own loaders (so ideally just a JS expression instead of a module with exports).

👍 That's a great suggestion, I think we'll do that!

@eyebrowsoffire
Copy link
Contributor

For Flutter's use-case, we have our own considerations when it comes to feature detection and when we want to roll out certain features on certain browsers. So our fallback logic is pretty specific to flutter and has considerations far outside of what dart knows or cares about (e.g. performance characteristics of rendering APIs in particular browser versions). So either Flutter should continue doing its own fallback logic, or we need the API to be flexible and pluggable enough to use combined logic from the Dart and Flutter stacks. To be honest, I feel like the latter seems a bit over-engineered. Since Dart and Flutter are always released together in lock-step, it probably is simplest to just keep the bootstrap fallback logic separate and update them individually whenever the requirements change.

@mkustermann
Copy link
Member Author

The support mechanism that flutter uses at runtime includes
a) requirements dart2wasm needs (e.g. wasm gc support)
b) browser api requirements (shared array buffer, offscren canvas, browser versions, ...)

So it's a union/superset of dart2wasm requirements. By emitting a support.js that will evaluate to a boolean, flutter should be able to integrate it into it's own mechanism.

Imagine a support.js can be copy&past'ed into any other JS file like this

// Flutter detection.
bool canUseSkwasm() {
  if (!<|contents of support.js|>) return false;
  if (!hasOffScreenCanvasSupport()) return false;
  ...
}

@eyebrowsoffire Would that work for flutter?

To be honest, I feel like the latter seems a bit over-engineered. Since Dart and Flutter are always released together in lock-step, it probably is simplest to just keep the bootstrap fallback logic separate and update them individually whenever the requirements change.

Flutter isn't the only user of dart2wasm. This mechanism will be required by any user of dart2wasm, so I don't think it makes sense to manually maintain a copy of requirements of dart2wasm in the flutter repository (and any other user that uses dart2wasm). It also complicates things, may require manual rolls, ...

@eyebrowsoffire
Copy link
Contributor

Your suggestion certainly looks reasonable to me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-dart2wasm Issues for the dart2wasm compiler.
Projects
None yet
Development

No branches or pull requests

3 participants