From 3196571c9bc5e70a7568e84349890cd1192b89ca Mon Sep 17 00:00:00 2001 From: Simon Binder Date: Fri, 22 May 2026 04:06:27 -0700 Subject: [PATCH] [dart2wasm] Move wasm-js interop to `dart:_js_interop_wasm` Some features in `dart:_wasm` are relevant for all WebAssembly targets (like interop types or memory intrinsics). Others, in particular the helper methods to convert between `WasmExternRef` and `JSAny`, don't make sense for the standalone target. To be able to remove the `js_interop` library from the standalone target, we need to stop importing it from `dart:_wasm`. To prepare that step, this moves the helpers to a new library (`dart:_js_interop_wasm`) and re-exports them from `dart:_wasm`. Once Flutter has migrated to the new import, the export can be removed. Bug: https://github.com/dart-lang/sdk/issues/63166 Change-Id: I13fe875e509a13d16c48d420a5927d3130b90736 Cq-Include-Trybots: luci.dart.try:flutter-analyze-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/505080 Reviewed-by: Martin Kustermann Auto-Submit: Simon Binder Reviewed-by: Slava Egorov Commit-Queue: Slava Egorov --- pkg/dart2wasm/lib/target.dart | 3 ++- .../fuse_with_and.constraints.txt | 4 ++-- .../custom_split/fuse_with_and.default.txt | 4 ++-- .../custom_split/fuse_with_or.constraints.txt | 4 ++-- .../custom_split/fuse_with_or.default.txt | 4 ++-- .../custom_split/just_fuse.constraints.txt | 4 ++-- .../custom_split/just_fuse.default.txt | 4 ++-- sdk/BUILD.gn | 1 + .../sdk_library_metadata/lib/libraries.dart | 5 +++++ ..._patch.dart => js_interop_wasm_patch.dart} | 0 ..._patch.dart => js_interop_wasm_patch.dart} | 0 sdk/lib/_js_interop_wasm/js_interop_wasm.dart | 19 +++++++++++++++++++ .../js_interop_wasm_sources.gni | 5 +++++ sdk/lib/_wasm/wasm_types.dart | 13 +++---------- sdk/lib/libraries.json | 18 ++++++++++++++---- sdk/lib/libraries.yaml | 10 ++++++++-- tests/web/wasm/js_int_passing_test.dart | 1 + 17 files changed, 70 insertions(+), 29 deletions(-) rename sdk/lib/_internal/wasm/lib/{wasm_types_patch.dart => js_interop_wasm_patch.dart} (100%) rename sdk/lib/_internal/wasm_standalone/lib/{wasm_types_patch.dart => js_interop_wasm_patch.dart} (100%) create mode 100644 sdk/lib/_js_interop_wasm/js_interop_wasm.dart create mode 100644 sdk/lib/_js_interop_wasm/js_interop_wasm_sources.gni diff --git a/pkg/dart2wasm/lib/target.dart b/pkg/dart2wasm/lib/target.dart index c7be3f7a613..2c663f0165e 100644 --- a/pkg/dart2wasm/lib/target.dart +++ b/pkg/dart2wasm/lib/target.dart @@ -209,7 +209,8 @@ class WasmTarget extends Target { return true; } - if (imported.toString() == 'dart:_wasm') { + if (imported.toString() == 'dart:_wasm' || + imported.toString() == 'dart:_js_interop_wasm') { return enableExperimentalWasmInterop; } diff --git a/pkg/dart2wasm/test/deferred_loading/partition_tests_dart2js/custom_split/fuse_with_and.constraints.txt b/pkg/dart2wasm/test/deferred_loading/partition_tests_dart2js/custom_split/fuse_with_and.constraints.txt index b98051f92da..06027de75a4 100644 --- a/pkg/dart2wasm/test/deferred_loading/partition_tests_dart2js/custom_split/fuse_with_and.constraints.txt +++ b/pkg/dart2wasm/test/deferred_loading/partition_tests_dart2js/custom_split/fuse_with_and.constraints.txt @@ -6,8 +6,8 @@ Part 0 - pkg/compiler/test/custom_split/data/fuse_with_and/lib4.dart prefix: b4 References - dart:_boxed_int::BoxedInt::@methods::toRadixString - - dart:_string::@methods::dart:_string::_JS_Inline_173 - - dart:_string::@methods::dart:_string::_JS_Inline_181 + - dart:_string::@methods::dart:_string::_JS_Inline_179 + - dart:_string::@methods::dart:_string::_JS_Inline_187 - dart:_string::@methods::dart:_string::_jsIdentical - dart:_string::@methods::dart:_string::_jsStringToUpperCase - dart:_string::@methods::jsStringFromCharCodeArray diff --git a/pkg/dart2wasm/test/deferred_loading/partition_tests_dart2js/custom_split/fuse_with_and.default.txt b/pkg/dart2wasm/test/deferred_loading/partition_tests_dart2js/custom_split/fuse_with_and.default.txt index d9d272e904b..949df457003 100644 --- a/pkg/dart2wasm/test/deferred_loading/partition_tests_dart2js/custom_split/fuse_with_and.default.txt +++ b/pkg/dart2wasm/test/deferred_loading/partition_tests_dart2js/custom_split/fuse_with_and.default.txt @@ -6,8 +6,8 @@ Part 0 - pkg/compiler/test/custom_split/data/fuse_with_and/lib4.dart prefix: b4 References - dart:_boxed_int::BoxedInt::@methods::toRadixString - - dart:_string::@methods::dart:_string::_JS_Inline_173 - - dart:_string::@methods::dart:_string::_JS_Inline_181 + - dart:_string::@methods::dart:_string::_JS_Inline_179 + - dart:_string::@methods::dart:_string::_JS_Inline_187 - dart:_string::@methods::dart:_string::_jsIdentical - dart:_string::@methods::dart:_string::_jsStringToUpperCase - dart:_string::@methods::jsStringFromCharCodeArray diff --git a/pkg/dart2wasm/test/deferred_loading/partition_tests_dart2js/custom_split/fuse_with_or.constraints.txt b/pkg/dart2wasm/test/deferred_loading/partition_tests_dart2js/custom_split/fuse_with_or.constraints.txt index 6ed2762aff5..e8a0bd51f83 100644 --- a/pkg/dart2wasm/test/deferred_loading/partition_tests_dart2js/custom_split/fuse_with_or.constraints.txt +++ b/pkg/dart2wasm/test/deferred_loading/partition_tests_dart2js/custom_split/fuse_with_or.constraints.txt @@ -6,8 +6,8 @@ Part 0 - pkg/compiler/test/custom_split/data/fuse_with_or/lib4.dart prefix: b4 References - dart:_boxed_int::BoxedInt::@methods::toRadixString - - dart:_string::@methods::dart:_string::_JS_Inline_173 - - dart:_string::@methods::dart:_string::_JS_Inline_181 + - dart:_string::@methods::dart:_string::_JS_Inline_179 + - dart:_string::@methods::dart:_string::_JS_Inline_187 - dart:_string::@methods::dart:_string::_jsIdentical - dart:_string::@methods::dart:_string::_jsStringToUpperCase - dart:_string::@methods::jsStringFromCharCodeArray diff --git a/pkg/dart2wasm/test/deferred_loading/partition_tests_dart2js/custom_split/fuse_with_or.default.txt b/pkg/dart2wasm/test/deferred_loading/partition_tests_dart2js/custom_split/fuse_with_or.default.txt index b2f469ca986..64fe2643f8c 100644 --- a/pkg/dart2wasm/test/deferred_loading/partition_tests_dart2js/custom_split/fuse_with_or.default.txt +++ b/pkg/dart2wasm/test/deferred_loading/partition_tests_dart2js/custom_split/fuse_with_or.default.txt @@ -6,8 +6,8 @@ Part 0 - pkg/compiler/test/custom_split/data/fuse_with_or/lib4.dart prefix: b4 References - dart:_boxed_int::BoxedInt::@methods::toRadixString - - dart:_string::@methods::dart:_string::_JS_Inline_173 - - dart:_string::@methods::dart:_string::_JS_Inline_181 + - dart:_string::@methods::dart:_string::_JS_Inline_179 + - dart:_string::@methods::dart:_string::_JS_Inline_187 - dart:_string::@methods::dart:_string::_jsIdentical - dart:_string::@methods::dart:_string::_jsStringToUpperCase - dart:_string::@methods::jsStringFromCharCodeArray diff --git a/pkg/dart2wasm/test/deferred_loading/partition_tests_dart2js/custom_split/just_fuse.constraints.txt b/pkg/dart2wasm/test/deferred_loading/partition_tests_dart2js/custom_split/just_fuse.constraints.txt index d032b38c02f..d8533f0f1cd 100644 --- a/pkg/dart2wasm/test/deferred_loading/partition_tests_dart2js/custom_split/just_fuse.constraints.txt +++ b/pkg/dart2wasm/test/deferred_loading/partition_tests_dart2js/custom_split/just_fuse.constraints.txt @@ -6,8 +6,8 @@ Part 0 - pkg/compiler/test/custom_split/data/just_fuse/lib4.dart prefix: b4 References - dart:_boxed_int::BoxedInt::@methods::toRadixString - - dart:_string::@methods::dart:_string::_JS_Inline_173 - - dart:_string::@methods::dart:_string::_JS_Inline_181 + - dart:_string::@methods::dart:_string::_JS_Inline_179 + - dart:_string::@methods::dart:_string::_JS_Inline_187 - dart:_string::@methods::dart:_string::_jsIdentical - dart:_string::@methods::dart:_string::_jsStringToUpperCase - dart:_string::@methods::jsStringFromCharCodeArray diff --git a/pkg/dart2wasm/test/deferred_loading/partition_tests_dart2js/custom_split/just_fuse.default.txt b/pkg/dart2wasm/test/deferred_loading/partition_tests_dart2js/custom_split/just_fuse.default.txt index 7998286f7bc..fa1755cd53b 100644 --- a/pkg/dart2wasm/test/deferred_loading/partition_tests_dart2js/custom_split/just_fuse.default.txt +++ b/pkg/dart2wasm/test/deferred_loading/partition_tests_dart2js/custom_split/just_fuse.default.txt @@ -6,8 +6,8 @@ Part 0 - pkg/compiler/test/custom_split/data/just_fuse/lib4.dart prefix: b4 References - dart:_boxed_int::BoxedInt::@methods::toRadixString - - dart:_string::@methods::dart:_string::_JS_Inline_173 - - dart:_string::@methods::dart:_string::_JS_Inline_181 + - dart:_string::@methods::dart:_string::_JS_Inline_179 + - dart:_string::@methods::dart:_string::_JS_Inline_187 - dart:_string::@methods::dart:_string::_jsIdentical - dart:_string::@methods::dart:_string::_jsStringToUpperCase - dart:_string::@methods::jsStringFromCharCodeArray diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn index 7e4020221fe..c41ab7034db 100644 --- a/sdk/BUILD.gn +++ b/sdk/BUILD.gn @@ -248,6 +248,7 @@ _full_sdk_libraries = [ "js", "js_interop", "js_interop_unsafe", + "_js_interop_wasm", "js_util", "math", "mirrors", diff --git a/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart b/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart index 79b18d21a3a..bb09e79b8ef 100644 --- a/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart +++ b/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart @@ -337,6 +337,11 @@ const Map libraries = const { categories: '', documented: false, ), + '_js_interop_wasm': const LibraryInfo( + '_js_interop_wasm/js_interop_wasm.dart', + categories: '', + documented: false, + ), }; /// Information about a "dart:" library. diff --git a/sdk/lib/_internal/wasm/lib/wasm_types_patch.dart b/sdk/lib/_internal/wasm/lib/js_interop_wasm_patch.dart similarity index 100% rename from sdk/lib/_internal/wasm/lib/wasm_types_patch.dart rename to sdk/lib/_internal/wasm/lib/js_interop_wasm_patch.dart diff --git a/sdk/lib/_internal/wasm_standalone/lib/wasm_types_patch.dart b/sdk/lib/_internal/wasm_standalone/lib/js_interop_wasm_patch.dart similarity index 100% rename from sdk/lib/_internal/wasm_standalone/lib/wasm_types_patch.dart rename to sdk/lib/_internal/wasm_standalone/lib/js_interop_wasm_patch.dart diff --git a/sdk/lib/_js_interop_wasm/js_interop_wasm.dart b/sdk/lib/_js_interop_wasm/js_interop_wasm.dart new file mode 100644 index 00000000000..3214685492e --- /dev/null +++ b/sdk/lib/_js_interop_wasm/js_interop_wasm.dart @@ -0,0 +1,19 @@ +// Copyright (c) 2026, 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. + +/// Utilities to transform between `dart:js_interop` types and `WasmExternRef` +/// from `dart:_wasm`. +library; + +import 'dart:_wasm'; +import 'dart:js_interop'; + +extension WasmExternRefToJSAny on WasmExternRef { + external JSAny get toJS; +} + +// Note: We would make this an extension method on JSAny, but external methods +// on JS interop types are assumed to be JS interop functions, not methods that +// are patched in patch files. So instead we just use a plain function here. +external WasmExternRef? externRefForJSAny(JSAny object); diff --git a/sdk/lib/_js_interop_wasm/js_interop_wasm_sources.gni b/sdk/lib/_js_interop_wasm/js_interop_wasm_sources.gni new file mode 100644 index 00000000000..8862e6e22d9 --- /dev/null +++ b/sdk/lib/_js_interop_wasm/js_interop_wasm_sources.gni @@ -0,0 +1,5 @@ +# Copyright (c) 2026, 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. + +js_interop_wasm_sdk_sources = [ "js_interop_wasm.dart" ] diff --git a/sdk/lib/_wasm/wasm_types.dart b/sdk/lib/_wasm/wasm_types.dart index 0a239d777a0..46e34438c40 100644 --- a/sdk/lib/_wasm/wasm_types.dart +++ b/sdk/lib/_wasm/wasm_types.dart @@ -4,7 +4,9 @@ library dart._wasm; -import 'dart:js_interop'; +// TODO(63166): Remove this export after migrating Flutter to import that +// library directly. +export 'dart:_js_interop_wasm'; part 'memory.dart'; @@ -787,15 +789,6 @@ extension DoubleWasmInstructions on double { double sqrt() => this.toWasmF64().sqrt().toDouble(); } -extension WasmExternRefToJSAny on WasmExternRef { - external JSAny get toJS; -} - -// Note: We would make this an extension method on JSAny, but external methods -// on JS interop types are assumed to be JS interop functions, not methods that -// are patched in patch files. So instead we just use a plain function here. -external WasmExternRef? externRefForJSAny(JSAny object); - // Tests whether the given object's class is a subclass of T. // // NOTICE: If the object's class is a subtype of T but not a subclass this will diff --git a/sdk/lib/libraries.json b/sdk/lib/libraries.json index 756966bdf4a..35236170604 100644 --- a/sdk/lib/libraries.json +++ b/sdk/lib/libraries.json @@ -354,8 +354,7 @@ ] }, "_wasm": { - "uri": "_wasm/wasm_types.dart", - "patches": "_internal/wasm_standalone/lib/wasm_types_patch.dart" + "uri": "_wasm/wasm_types.dart" }, "math": { "uri": "math/math.dart", @@ -367,6 +366,12 @@ "js_interop": { "uri": "_internal/wasm_standalone/lib/js_interop.dart", "support_conditional_import": false + }, + "_js_interop_wasm": { + "uri": "_js_interop_wasm/js_interop_wasm.dart", + "patches": [ + "_internal/wasm_standalone/lib/js_interop_wasm_patch.dart" + ] } } }, @@ -395,8 +400,7 @@ ] }, "_wasm": { - "uri": "_wasm/wasm_types.dart", - "patches": "_internal/wasm/lib/wasm_types_patch.dart" + "uri": "_wasm/wasm_types.dart" }, "async": { "uri": "async/async.dart", @@ -431,6 +435,12 @@ "js_interop_unsafe": { "uri": "js_interop_unsafe/js_interop_unsafe.dart", "patches": "_internal/wasm/lib/js_interop_unsafe_patch.dart" + }, + "_js_interop_wasm": { + "uri": "_js_interop_wasm/js_interop_wasm.dart", + "patches": [ + "_internal/wasm/lib/js_interop_wasm_patch.dart" + ] } } }, diff --git a/sdk/lib/libraries.yaml b/sdk/lib/libraries.yaml index 55e1270744e..39c7cac6406 100644 --- a/sdk/lib/libraries.yaml +++ b/sdk/lib/libraries.yaml @@ -298,7 +298,6 @@ wasm_standalone: - _internal/vm_shared/lib/check_valid_weak_target_patch.dart _wasm: uri: _wasm/wasm_types.dart - patches: _internal/wasm_standalone/lib/wasm_types_patch.dart math: uri: math/math.dart patches: @@ -309,6 +308,10 @@ wasm_standalone: # currently added as a stub because APIs in dart:_wasm reference it. uri: _internal/wasm_standalone/lib/js_interop.dart support_conditional_import: false + _js_interop_wasm: + uri: _js_interop_wasm/js_interop_wasm.dart + patches: + - _internal/wasm_standalone/lib/js_interop_wasm_patch.dart wasm_js_common: include: @@ -329,7 +332,6 @@ wasm_js_common: - _internal/vm_shared/lib/check_valid_weak_target_patch.dart _wasm: uri: _wasm/wasm_types.dart - patches: _internal/wasm/lib/wasm_types_patch.dart async: uri: async/async.dart patches: @@ -354,6 +356,10 @@ wasm_js_common: js_interop_unsafe: uri: js_interop_unsafe/js_interop_unsafe.dart patches: _internal/wasm/lib/js_interop_unsafe_patch.dart + _js_interop_wasm: + uri: _js_interop_wasm/js_interop_wasm.dart + patches: + - _internal/wasm/lib/js_interop_wasm_patch.dart wasm_common: libraries: diff --git a/tests/web/wasm/js_int_passing_test.dart b/tests/web/wasm/js_int_passing_test.dart index 307d6747713..9b5c4219fdb 100644 --- a/tests/web/wasm/js_int_passing_test.dart +++ b/tests/web/wasm/js_int_passing_test.dart @@ -16,6 +16,7 @@ // dart2wasmOptions=--extra-compiler-option=--enable-experimental-wasm-interop import 'dart:_wasm'; +import 'dart:_js_interop_wasm'; import 'dart:js_interop'; import 'package:expect/expect.dart';