From 9e37c2b480126a47ea87d560f19aff11932a543d Mon Sep 17 00:00:00 2001 From: Joshua Litt Date: Tue, 18 Jul 2023 19:34:38 +0000 Subject: [PATCH] [dart2wasm] Add JS compatibility mode. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The purpose of the wasm_js_compatibility target is to facilitate experiments with a JS compatibility mode for Dart2Wasm. Initially, we're just going to focus on typed data, but this will give us a place to experiment with moving List and String to JS as well. In addition, someday down the road we hope to experiment with two additional compatibility changes: 1) Exclusively using double for all Dart numbers 2) Allowing undefined to flow as null. The two major benefits of this approach are: 1) Much faster JS interop 2) To make it easier to bring up Dart2JS applications on Dart2Wasm The only downside will be access overhead on the Wasm side, but the JS builtins proposal could potentially bring us close to parity with Wasm builtins someday. Tested: Wasm specific trivial refactor. Change-Id: I2c09426b6999507c1de6e584e9bc7072a088bda9 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/313240 Commit-Queue: Joshua Litt Reviewed-by: Ömer Ağacan Reviewed-by: William Hesse --- BUILD.gn | 1 + .../lib/src/messages/codes_generated.dart | 2 +- pkg/dart2wasm/lib/target.dart | 32 +++++++++++++++++-- .../compute_platform_binaries_location.dart | 11 +++++++ pkg/front_end/messages.yaml | 2 +- .../test/spell_checking_list_common.txt | 1 + .../tool/_fasta/additional_targets.dart | 6 +++- pkg/vm/test/common_test_utils.dart | 4 +-- sdk/BUILD.gn | 5 +++ sdk/bin/dart2wasm | 7 ++-- sdk/lib/libraries.json | 28 ++++++++++++++++ sdk/lib/libraries.yaml | 22 +++++++++++++ tools/bots/test_matrix.json | 2 ++ utils/dart2wasm/BUILD.gn | 18 +++++++++++ 14 files changed, 130 insertions(+), 11 deletions(-) diff --git a/BUILD.gn b/BUILD.gn index 233a0900e55..aaebd136ff1 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -110,6 +110,7 @@ group("dart2js") { group("dart2wasm_platform") { deps = [ ":runtime_precompiled", + "utils/dart2wasm:compile_dart2wasm_js_compatibility_platform", "utils/dart2wasm:compile_dart2wasm_platform", "utils/dart2wasm:compile_dart2wasm_stringref_platform", "utils/dart2wasm:dart2wasm_snapshot", diff --git a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart index fafdecbefe4..c483a5d8e7e 100644 --- a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart +++ b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart @@ -4500,7 +4500,7 @@ const MessageCode messageFastaUsageLong = Read the SDK platform from , which should be in Dill/Kernel IR format and contain the Dart SDK. - --target=dart2js|dart2js_server|dart2wasm|dart2wasm_stringref|dart_runner|dartdevc|flutter|flutter_runner|none|vm + --target=dart2js|dart2js_server|dart2wasm|dart2wasm_js_compatibility|dart2wasm_stringref|dart_runner|dartdevc|flutter|flutter_runner|none|vm Specify the target configuration. --enable-asserts diff --git a/pkg/dart2wasm/lib/target.dart b/pkg/dart2wasm/lib/target.dart index 6fa2abb14d8..d4b726dcc52 100644 --- a/pkg/dart2wasm/lib/target.dart +++ b/pkg/dart2wasm/lib/target.dart @@ -34,11 +34,17 @@ import 'package:dart2wasm/ffi_native_transformer.dart' as wasmFfiNativeTrans; import 'package:dart2wasm/records.dart' show RecordShape; import 'package:dart2wasm/transformers.dart' as wasmTrans; +enum Mode { + regular, + stringref, + jsCompatibility, +} + class WasmTarget extends Target { - WasmTarget({this.removeAsserts = true, this.useStringref = false}); + WasmTarget({this.removeAsserts = true, this.mode = Mode.regular}); bool removeAsserts; - bool useStringref; + Mode mode; Class? _growableList; Class? _immutableList; Class? _wasmDefaultMap; @@ -59,7 +65,27 @@ class WasmTarget extends Target { Verification get verification => const WasmVerification(); @override - String get name => useStringref ? 'wasm_stringref' : 'wasm'; + String get name { + switch (mode) { + case Mode.regular: + return 'wasm'; + case Mode.stringref: + return 'wasm_stringref'; + case Mode.jsCompatibility: + return 'wasm_js_compatibility'; + } + } + + String get platformFile { + switch (mode) { + case Mode.regular: + return 'dart2wasm_platform.dill'; + case Mode.stringref: + return 'dart2wasm_stringref_platform.dill'; + case Mode.jsCompatibility: + return 'dart2wasm_js_compatibility_platform.dill'; + } + } @override TargetFlags get flags => TargetFlags(); diff --git a/pkg/front_end/lib/src/compute_platform_binaries_location.dart b/pkg/front_end/lib/src/compute_platform_binaries_location.dart index bba274a1b85..012c9f74d9c 100644 --- a/pkg/front_end/lib/src/compute_platform_binaries_location.dart +++ b/pkg/front_end/lib/src/compute_platform_binaries_location.dart @@ -86,6 +86,17 @@ String? computePlatformDillName( break; } break; + case 'wasm_js_compatibility': + switch (nnbdMode) { + case NnbdMode.Strong: + return 'dart2wasm_js_compatibility_outline.dill'; + //TODO(johnniwinther): Support using the full dill. + //return 'dart2wasm_js_compatibility_platform.dill'; + case NnbdMode.Weak: + case NnbdMode.Agnostic: + break; + } + break; default: break; } diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml index 74a67d33dab..5b6b43f2bbf 100644 --- a/pkg/front_end/messages.yaml +++ b/pkg/front_end/messages.yaml @@ -2271,7 +2271,7 @@ FastaUsageLong: Read the SDK platform from , which should be in Dill/Kernel IR format and contain the Dart SDK. - --target=dart2js|dart2js_server|dart2wasm|dart2wasm_stringref|dart_runner|dartdevc|flutter|flutter_runner|none|vm + --target=dart2js|dart2js_server|dart2wasm|dart2wasm_js_compatibility|dart2wasm_stringref|dart_runner|dartdevc|flutter|flutter_runner|none|vm Specify the target configuration. --enable-asserts diff --git a/pkg/front_end/test/spell_checking_list_common.txt b/pkg/front_end/test/spell_checking_list_common.txt index a98aab153d9..3ff607d1441 100644 --- a/pkg/front_end/test/spell_checking_list_common.txt +++ b/pkg/front_end/test/spell_checking_list_common.txt @@ -738,6 +738,7 @@ dart dart2js dart2wasm dart2wasm_stringref +dart2wasm_js_compatibility dartdevc data date diff --git a/pkg/front_end/tool/_fasta/additional_targets.dart b/pkg/front_end/tool/_fasta/additional_targets.dart index 6fbfda28d92..01a77853894 100644 --- a/pkg/front_end/tool/_fasta/additional_targets.dart +++ b/pkg/front_end/tool/_fasta/additional_targets.dart @@ -12,6 +12,8 @@ import 'package:dev_compiler/src/kernel/target.dart' show DevCompilerTarget; import 'package:dart2wasm/target.dart' show WasmTarget; +import 'package:dart2wasm/target.dart' as wasm show Mode; + import 'package:vm/target/install.dart' as vm_target_install show installAdditionalTargets; @@ -25,6 +27,8 @@ void installAdditionalTargets() { targets["dartdevc"] = (TargetFlags flags) => new DevCompilerTarget(flags); targets["dart2wasm"] = (TargetFlags flags) => new WasmTarget(); targets["dart2wasm_stringref"] = - (TargetFlags flags) => new WasmTarget(useStringref: true); + (TargetFlags flags) => new WasmTarget(mode: wasm.Mode.stringref); + targets["dart2wasm_js_compatibility"] = + (TargetFlags flags) => new WasmTarget(mode: wasm.Mode.jsCompatibility); vm_target_install.installAdditionalTargets(); } diff --git a/pkg/vm/test/common_test_utils.dart b/pkg/vm/test/common_test_utils.dart index 8ebf5681808..5bd142209e5 100644 --- a/pkg/vm/test/common_test_utils.dart +++ b/pkg/vm/test/common_test_utils.dart @@ -37,9 +37,7 @@ Future compileTestCaseToKernelProgram(Uri sourceUri, Directory? tempDirectory; try { final platformFileName = (target is WasmTarget) - ? target.useStringref - ? 'dart2wasm_stringref_platform.dill' - : 'dart2wasm_platform.dill' + ? target.platformFile : 'vm_platform_strong.dill'; final platformKernel = computePlatformBinariesLocation().resolve(platformFileName); diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn index d84f0693dca..94b4fc3b70b 100644 --- a/sdk/BUILD.gn +++ b/sdk/BUILD.gn @@ -70,6 +70,8 @@ declare_args() { # ........dart2wasm_platform.dill (if not on ia32) # ........dart2wasm_stringref_outline.dill (if not on ia32) # ........dart2wasm_stringref_platform.dill (if not on ia32) +# ........dart2wasm_js_compatibility_outline.dill (if not on ia32) +# ........dart2wasm_js_compatibility_platform.dill (if not on ia32) # ........ddc_outline.dill # ........ddc_platform.dill # ........vm_platform_strong.dill @@ -474,10 +476,13 @@ copy("copy_dart2wasm_platform") { deps = [ ":copy_libraries", "../:dart2wasm_platform", + "../utils/dart2wasm:compile_dart2wasm_js_compatibility_platform", "../utils/dart2wasm:compile_dart2wasm_platform", "../utils/dart2wasm:compile_dart2wasm_stringref_platform", ] sources = [ + "$root_out_dir/dart2wasm_js_compatibility_outline.dill", + "$root_out_dir/dart2wasm_js_compatibility_platform.dill", "$root_out_dir/dart2wasm_outline.dill", "$root_out_dir/dart2wasm_platform.dill", "$root_out_dir/dart2wasm_stringref_outline.dill", diff --git a/sdk/bin/dart2wasm b/sdk/bin/dart2wasm index 2f860fad891..3997e2da4e1 100755 --- a/sdk/bin/dart2wasm +++ b/sdk/bin/dart2wasm @@ -65,12 +65,15 @@ SDK_ARG="--dart-sdk=$SDK_DIR" # Point to built platform dill. PLATFORM="$BIN_DIR/dart2wasm_platform.dill" -# Not the prettiest way to check for stringref, and it doesn't support changing -# the default, but it will do for the experiment. +# Not the prettiest way to check for a target, and it doesn't support changing +# the default, but it will do for experiments. for arg in "$@"; do if [[ "$arg" == "--stringref" ]]; then PLATFORM="$BIN_DIR/dart2wasm_stringref_platform.dill" fi + if [[ "$arg" == "--js-compatibility" ]]; then + PLATFORM="$BIN_DIR/dart2wasm_js_compatibility_platform.dill" + fi done PLATFORM_ARG="--platform=$PLATFORM" diff --git a/sdk/lib/libraries.json b/sdk/lib/libraries.json index 171fdb5fa85..b25c195ad55 100644 --- a/sdk/lib/libraries.json +++ b/sdk/lib/libraries.json @@ -175,6 +175,34 @@ } } }, + "wasm_js_compatibility": { + "include": [ + { + "target": "wasm_common" + } + ], + "libraries": { + "core": { + "uri": "core/core.dart", + "patches": [ + "_internal/wasm/lib/core_patch.dart", + "_internal/vm_shared/lib/array_patch.dart", + "_internal/vm_shared/lib/bigint_patch.dart", + "_internal/vm_shared/lib/bool_patch.dart", + "_internal/vm_shared/lib/date_patch.dart", + "_internal/vm_shared/lib/integers_patch.dart", + "_internal/vm_shared/lib/map_patch.dart", + "_internal/vm_shared/lib/null_patch.dart", + "_internal/vm_shared/lib/string_buffer_patch.dart", + "_internal/wasm/lib/date_patch_patch.dart", + "_internal/wasm/lib/string_buffer_create.dart", + "_internal/wasm/lib/string_patch.dart", + "_internal/wasm/lib/sync_star_patch.dart", + "_internal/wasm/lib/weak_patch.dart" + ] + } + } + }, "wasm_common": { "libraries": { "_http": { diff --git a/sdk/lib/libraries.yaml b/sdk/lib/libraries.yaml index be7edc7cdbf..003f98ccc8a 100644 --- a/sdk/lib/libraries.yaml +++ b/sdk/lib/libraries.yaml @@ -156,6 +156,28 @@ wasm_stringref: - _internal/wasm/lib/sync_star_patch.dart - _internal/wasm/lib/weak_patch.dart +wasm_js_compatibility: + include: + - target: "wasm_common" + libraries: + core: + uri: core/core.dart + patches: + - _internal/wasm/lib/core_patch.dart + - _internal/vm_shared/lib/array_patch.dart + - _internal/vm_shared/lib/bigint_patch.dart + - _internal/vm_shared/lib/bool_patch.dart + - _internal/vm_shared/lib/date_patch.dart + - _internal/vm_shared/lib/integers_patch.dart + - _internal/vm_shared/lib/map_patch.dart + - _internal/vm_shared/lib/null_patch.dart + - _internal/vm_shared/lib/string_buffer_patch.dart + - _internal/wasm/lib/date_patch_patch.dart + - _internal/wasm/lib/string_buffer_create.dart + - _internal/wasm/lib/string_patch.dart + - _internal/wasm/lib/sync_star_patch.dart + - _internal/wasm/lib/weak_patch.dart + wasm_common: libraries: _http: diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json index 460077a3c30..b3c7d5db89b 100644 --- a/tools/bots/test_matrix.json +++ b/tools/bots/test_matrix.json @@ -126,6 +126,8 @@ "out/ReleaseX64/dart2wasm_platform.dill", "out/ReleaseX64/dart2wasm_stringref_outline.dill", "out/ReleaseX64/dart2wasm_stringref_platform.dill", + "out/ReleaseX64/dart2wasm_js_compatibility_outline.dill", + "out/ReleaseX64/dart2wasm_js_compatibility_platform.dill", "out/ReleaseX64/wasm/", "pkg/", "runtime/tests/", diff --git a/utils/dart2wasm/BUILD.gn b/utils/dart2wasm/BUILD.gn index 8dde81e68c7..226b0e9579a 100644 --- a/utils/dart2wasm/BUILD.gn +++ b/utils/dart2wasm/BUILD.gn @@ -77,6 +77,24 @@ compile_platform("compile_dart2wasm_stringref_platform") { ] } +compile_platform("compile_dart2wasm_js_compatibility_platform") { + single_root_scheme = "org-dartlang-sdk" + single_root_base = rebase_path("$sdk_root/") + libraries_specification_uri = "org-dartlang-sdk:///lib/libraries.json" + + outputs = [ + "$root_out_dir/dart2wasm_js_compatibility_platform.dill", + "$root_out_dir/dart2wasm_js_compatibility_outline.dill", + ] + + args = [ + "--target=dart2wasm_js_compatibility", + "--no-defines", + "dart:core", + "--nnbd-strong", + ] +} + wasm_module("ffi_native_test_wasm_module") { module_name = "ffi_native_test_module" }