For dart2wasm to support non-web runtimes (#53884), we need a Dart SDK without dart:js_interop (as that is specific to JavaScript). Instead, we would need to rely on host imports using dart:_wasm definitions to be able to eventually remove dart:js_interop from the standalone platform.
Unfortunately, dart:_wasm itself depends on dart:js_interop to define WASM-specific interop APIs (e.g. to convert between JSAny and WasmExternRef. For the standalone target, we need a dart:_wasm that doesn't use js_interop APIs.
In 152cc24, I've tried to implement that split using patch files: On dart2wasm_standalone_platform.dill, dart:_wasm doesn't import dart:js_interop and doesn't define WasmExternRefToJSAny / externRefForJSAny. But because the analyzer doesn't consider patch files when building summaries, this approach causes those two elements to become unavailable on all WASM targets as far as the analyzer is concerned, causing analysis errors for valid code:
+ /b/s/w/ir/cache/builder/sdk/out/ReleaseX64/dart-sdk/bin/dart analyze --suppress-analytics --fatal-infos
Analyzing web_ui...
error - lib/src/engine/skwasm/skwasm_impl/raw/raw_image.dart:45:5 - The function 'externRefForJSAny' isn't defined. Try importing the library that defines 'externRefForJSAny', correcting the name to the name of an existing function, or defining a function named 'externRefForJSAny'. - undefined_function
error - lib/src/engine/skwasm/skwasm_impl/raw/raw_surface.dart:30:54 - The function 'externRefForJSAny' isn't defined. Try importing the library that defines 'externRefForJSAny', correcting the name to the name of an existing function, or defining a function named 'externRefForJSAny'. - undefined_function
error - lib/src/engine/skwasm/skwasm_impl/surface.dart:68:39 - The getter 'toJS' isn't defined for the type 'WasmExternRef'. Try importing the library that defines 'toJS', correcting the name to the name of an existing getter, or defining a getter or field named 'toJS'. - undefined_getter
3 issues found.
Before trying to re-land those changes, I'd like to discuss better options to avoid dart:js_interop in dart:_wasm. Some ideas I've had are to:
- Add a
dart:_wasm_js library exporting the conversion methods. Initially, dart:_wasm would export dart:_wasm_js so that Flutter can migrate to a direct import. Later, we can drop that export and remove dart:_wasm_js from the standalone build.
- We could also do it the other way around and add a
dart:_wasm_standalone library defining WASM types without dart:js_interop (that dart:_wasm would export).
- Or, we can ignore the issue by including
dart:js_interop in the standalone target but making everything a throwing stub (similar to how dart:isolate and dart:io work on web targets). This might be the easiest option to implement initially.
Current status
For dart2wasm to support non-web runtimes (#53884), we need a Dart SDK without
dart:js_interop(as that is specific to JavaScript). Instead, we would need to rely on host imports usingdart:_wasmdefinitions to be able to eventually removedart:js_interopfrom the standalone platform.Unfortunately,
dart:_wasmitself depends ondart:js_interopto define WASM-specific interop APIs (e.g. to convert betweenJSAnyandWasmExternRef. For the standalone target, we need adart:_wasmthat doesn't usejs_interopAPIs.In 152cc24, I've tried to implement that split using patch files: On
dart2wasm_standalone_platform.dill,dart:_wasmdoesn't importdart:js_interopand doesn't defineWasmExternRefToJSAny/externRefForJSAny. But because the analyzer doesn't consider patch files when building summaries, this approach causes those two elements to become unavailable on all WASM targets as far as the analyzer is concerned, causing analysis errors for valid code:Before trying to re-land those changes, I'd like to discuss better options to avoid
dart:js_interopindart:_wasm. Some ideas I've had are to:dart:_wasm_jslibrary exporting the conversion methods. Initially,dart:_wasmwould exportdart:_wasm_jsso that Flutter can migrate to a direct import. Later, we can drop that export and removedart:_wasm_jsfrom the standalone build.dart:_wasm_standalonelibrary defining WASM types withoutdart:js_interop(thatdart:_wasmwould export).dart:js_interopin the standalone target but making everything a throwing stub (similar to howdart:isolateanddart:iowork on web targets). This might be the easiest option to implement initially.Current status
dart:_js_interop_wasmas a library for these helpers, and temporarily export that fromdart:_wasm.dart:_js_interop_wasmdirectly, this temporarily requires// ignorelines to silence warnings aboutdart:_wasmexporting this already (Importdart:_js_interop_wasmin addition todart:_wasmto convert betweenJSAnyandWasmExternRef?flutter/flutter#186974).dart:_wasm(https://dart-review.googlesource.com/c/sdk/+/505960).// ignores from Flutter.