mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 17:40:04 +00:00
[dart2wasm] Update built-in string imports according to the latest spec
Spec: https://github.com/WebAssembly/js-string-builtins Change-Id: Idb387e6dd27b203ddca52291c44fb2aa15ee75cf Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/357560 Commit-Queue: Ömer Ağacan <omersa@google.com> Reviewed-by: Martin Kustermann <kustermann@google.com>
This commit is contained in:
parent
ef07a17210
commit
44c2e17600
|
@ -363,8 +363,20 @@ const main = async () => {
|
|||
}
|
||||
|
||||
const dart2wasm = await import(args[jsRuntimeArg]);
|
||||
function compile(filename) {
|
||||
// Create a Wasm module from the binary wasm file.
|
||||
|
||||
/// Returns whether the `js-string` built-in is supported.
|
||||
function detectImportedStrings() {
|
||||
let bytes = [
|
||||
0, 97, 115, 109, 1, 0, 0, 0, 1, 4, 1, 96, 0,
|
||||
0, 2, 23, 1, 14, 119, 97, 115, 109, 58, 106, 115, 45,
|
||||
115, 116, 114, 105, 110, 103, 4, 99, 97, 115, 116, 0, 0
|
||||
];
|
||||
return !WebAssembly.validate(
|
||||
new Uint8Array(bytes), {builtins: ['js-string']});
|
||||
}
|
||||
|
||||
function compile(filename, withJsStringBuiltins) {
|
||||
// Create a Wasm module from the binary Wasm file.
|
||||
var bytes;
|
||||
if (isJSC) {
|
||||
bytes = readFile(filename, "binary");
|
||||
|
@ -373,11 +385,10 @@ const main = async () => {
|
|||
} else {
|
||||
bytes = readRelativeToScript(filename, "binary");
|
||||
}
|
||||
return new WebAssembly.Module(bytes);
|
||||
}
|
||||
|
||||
function instantiate(filename, imports) {
|
||||
return new WebAssembly.Instance(compile(filename), imports);
|
||||
return WebAssembly.compile(
|
||||
bytes,
|
||||
withJsStringBuiltins ? {builtins: ['js-string']} : {}
|
||||
);
|
||||
}
|
||||
|
||||
globalThis.window ??= globalThis;
|
||||
|
@ -386,14 +397,17 @@ const main = async () => {
|
|||
|
||||
// Is an FFI module specified?
|
||||
if (args.length > 2) {
|
||||
// instantiate FFI module
|
||||
var ffiInstance = instantiate(args[ffiArg], {});
|
||||
// Make its exports available as imports under the 'ffi' module name
|
||||
// Instantiate FFI module.
|
||||
var ffiInstance = await WebAssembly.instantiate(await compile(args[ffiArg], false), {});
|
||||
// Make its exports available as imports under the 'ffi' module name.
|
||||
importObject.ffi = ffiInstance.exports;
|
||||
}
|
||||
|
||||
// Instantiate the Dart module, importing from the global scope.
|
||||
var dartInstance = await dart2wasm.instantiate(Promise.resolve(compile(args[wasmArg])), Promise.resolve(importObject));
|
||||
var dartInstance = await dart2wasm.instantiate(
|
||||
compile(args[wasmArg], detectImportedStrings()),
|
||||
Promise.resolve(importObject),
|
||||
);
|
||||
|
||||
// Call `main`. If tasks are placed into the event loop (by scheduling tasks
|
||||
// explicitly or awaiting Futures), these will automatically keep the script
|
||||
|
|
|
@ -113,22 +113,6 @@ const jsRuntimeBlobPart3 = r'''
|
|||
return wrapped;
|
||||
}
|
||||
|
||||
if (WebAssembly.String === undefined) {
|
||||
WebAssembly.String = {
|
||||
"charCodeAt": (s, i) => s.charCodeAt(i),
|
||||
"compare": (s1, s2) => {
|
||||
if (s1 < s2) return -1;
|
||||
if (s1 > s2) return 1;
|
||||
return 0;
|
||||
},
|
||||
"concat": (s1, s2) => s1 + s2,
|
||||
"equals": (s1, s2) => s1 === s2,
|
||||
"fromCharCode": (i) => String.fromCharCode(i),
|
||||
"length": (s) => s.length,
|
||||
"substring": (s, a, b) => s.substring(a, b),
|
||||
};
|
||||
}
|
||||
|
||||
// Imports
|
||||
const dart2wasm = {
|
||||
''';
|
||||
|
@ -150,9 +134,25 @@ const jsRuntimeBlobPart5 = r'''
|
|||
Array: Array,
|
||||
Reflect: Reflect,
|
||||
};
|
||||
|
||||
const jsStringPolyfill = {
|
||||
"charCodeAt": (s, i) => s.charCodeAt(i),
|
||||
"compare": (s1, s2) => {
|
||||
if (s1 < s2) return -1;
|
||||
if (s1 > s2) return 1;
|
||||
return 0;
|
||||
},
|
||||
"concat": (s1, s2) => s1 + s2,
|
||||
"equals": (s1, s2) => s1 === s2,
|
||||
"fromCharCode": (i) => String.fromCharCode(i),
|
||||
"length": (s) => s.length,
|
||||
"substring": (s, a, b) => s.substring(a, b),
|
||||
};
|
||||
|
||||
dartInstance = await WebAssembly.instantiate(await modulePromise, {
|
||||
...baseImports,
|
||||
...(await importObjectPromise),
|
||||
"wasm:js-string": jsStringPolyfill,
|
||||
});
|
||||
|
||||
return dartInstance;
|
||||
|
|
|
@ -81,7 +81,8 @@ final class JSStringImpl implements String {
|
|||
@override
|
||||
String operator +(String other) {
|
||||
if (other is JSStringImpl) {
|
||||
return JSStringImpl(_jsConcat(toExternRef, other.toExternRef));
|
||||
return JSStringImpl(
|
||||
_jsStringConcatImport(toExternRef, other.toExternRef));
|
||||
}
|
||||
|
||||
// TODO(joshualitt): Refactor `string_patch.dart` so we can directly
|
||||
|
@ -712,32 +713,51 @@ bool _jsIdentical(WasmExternRef? ref1, WasmExternRef? ref2) =>
|
|||
js.JS<bool>('Object.is', ref1, ref2);
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
int _jsCharCodeAt(WasmExternRef? stringRef, int index) => js
|
||||
.JS<WasmI32>(
|
||||
'WebAssembly.String.charCodeAt', stringRef, WasmI32.fromInt(index))
|
||||
int _jsCharCodeAt(WasmExternRef? stringRef, int index) =>
|
||||
_jsStringCharCodeAtImport(stringRef, WasmI32.fromInt(index))
|
||||
.toIntUnsigned();
|
||||
|
||||
WasmExternRef _jsConcat(WasmExternRef? s1, WasmExternRef? s2) =>
|
||||
js.JS<WasmExternRef>('WebAssembly.String.concat', s1, s2);
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
WasmExternRef _jsSubstring(
|
||||
WasmExternRef? stringRef, int startIndex, int endIndex) =>
|
||||
js.JS<WasmExternRef>('WebAssembly.String.substring', stringRef,
|
||||
WasmI32.fromInt(startIndex), WasmI32.fromInt(endIndex));
|
||||
_jsStringSubstringImport(
|
||||
stringRef, WasmI32.fromInt(startIndex), WasmI32.fromInt(endIndex));
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
int _jsLength(WasmExternRef? stringRef) =>
|
||||
js.JS<WasmI32>('WebAssembly.String.length', stringRef).toIntUnsigned();
|
||||
_jsStringLengthImport(stringRef).toIntUnsigned();
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
bool _jsEquals(WasmExternRef? s1, WasmExternRef? s2) =>
|
||||
js.JS<WasmI32>('WebAssembly.String.equals', s1, s2).toBool();
|
||||
_jsStringEqualsImport(s1, s2).toBool();
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
int _jsCompare(WasmExternRef? s1, WasmExternRef? s2) =>
|
||||
js.JS<WasmI32>('WebAssembly.String.compare', s1, s2).toIntSigned();
|
||||
_jsStringCompareImport(s1, s2).toIntSigned();
|
||||
|
||||
@pragma("wasm:prefer-inline")
|
||||
WasmExternRef _jsFromCharCode(int charCode) => js.JS<WasmExternRef>(
|
||||
'WebAssembly.String.fromCharCode', WasmI32.fromInt(charCode));
|
||||
WasmExternRef _jsFromCharCode(int charCode) =>
|
||||
_jsStringFromCharCodeImport(WasmI32.fromInt(charCode));
|
||||
|
||||
@pragma("wasm:import", "wasm:js-string.charCodeAt")
|
||||
external WasmI32 _jsStringCharCodeAtImport(WasmExternRef? s, WasmI32 index);
|
||||
|
||||
@pragma("wasm:import", "wasm:js-string.compare")
|
||||
external WasmI32 _jsStringCompareImport(WasmExternRef? s1, WasmExternRef? s2);
|
||||
|
||||
@pragma("wasm:import", "wasm:js-string.concat")
|
||||
external WasmExternRef _jsStringConcatImport(
|
||||
WasmExternRef? s1, WasmExternRef? s2);
|
||||
|
||||
@pragma("wasm:import", "wasm:js-string.equals")
|
||||
external WasmI32 _jsStringEqualsImport(WasmExternRef? s1, WasmExternRef? s2);
|
||||
|
||||
@pragma("wasm:import", "wasm:js-string.fromCharCode")
|
||||
external WasmExternRef _jsStringFromCharCodeImport(WasmI32 c);
|
||||
|
||||
@pragma("wasm:import", "wasm:js-string.length")
|
||||
external WasmI32 _jsStringLengthImport(WasmExternRef? s);
|
||||
|
||||
@pragma("wasm:import", "wasm:js-string.substring")
|
||||
external WasmExternRef _jsStringSubstringImport(
|
||||
WasmExternRef? s, WasmI32 startIndex, WasmI32 endIndex);
|
||||
|
|
Loading…
Reference in a new issue