[dart2wasm] Add JS compatibility mode.

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 <joshualitt@google.com>
Reviewed-by: Ömer Ağacan <omersa@google.com>
Reviewed-by: William Hesse <whesse@google.com>
This commit is contained in:
Joshua Litt 2023-07-18 19:34:38 +00:00 committed by Commit Queue
parent ba1577ce85
commit 9e37c2b480
14 changed files with 130 additions and 11 deletions

View file

@ -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",

View file

@ -4500,7 +4500,7 @@ const MessageCode messageFastaUsageLong =
Read the SDK platform from <file>, 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

View file

@ -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();

View file

@ -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;
}

View file

@ -2271,7 +2271,7 @@ FastaUsageLong:
Read the SDK platform from <file>, 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

View file

@ -738,6 +738,7 @@ dart
dart2js
dart2wasm
dart2wasm_stringref
dart2wasm_js_compatibility
dartdevc
data
date

View file

@ -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();
}

View file

@ -37,9 +37,7 @@ Future<Component> 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);

View file

@ -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",

View file

@ -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"

View file

@ -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": {

View file

@ -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:

View file

@ -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/",

View file

@ -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"
}