Reland "[dart2wasm] Use DataView in JS typed arrays"

This is a reland of commit b9b7de14e0

Previous version broke engine tests because of incorrect array impl
class (e.g. `JSUint16ArrayImpl`) to JS array externref conversion. Since
array implementation classes now store an `externref` to a `DataView`,
we can't use `toExternRef`, we need to use the new `toJSArrayExternRef`.

Original change's description:
> [dart2wasm] Use DataView in JS typed arrays
>
> Refcator JS typed array classes to store JS `DataView`s (instead of JS
> typed array with the matching type), and use V8's new optimized
> `DataView` imports.
>
> Brings JS typed array class performance from unusable to reasonable
> levels. In `SkeletalAnimation` benchmark:
>
> - Before: 1444 us.
> - After: 101 us.
>
> Future work:
>
> - Make immutable classes extend the mutable ones. This will allow `[]`
>   calls to be always inlined in JSCM.
>
> - Move list mixin applications from the base class to implementation
>   classes. This will allow members like `elementAt`, `forEach` etc. to
>   have direct calls to other methods of the same class.
>
> - Try adding a `length` field to avoid JS calls in bounds checks.
>
> Change-Id: Ief6165fe9c4a825072077db820b105c4fca30dce
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/328920
> Reviewed-by: Aske Simon Christensen <askesc@google.com>
> Commit-Queue: Ömer Ağacan <omersa@google.com>

Change-Id: If913aed837d09570b82b0f6dcb9553abb17fd708
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/334468
Commit-Queue: Ömer Ağacan <omersa@google.com>
Reviewed-by: Aske Simon Christensen <askesc@google.com>
This commit is contained in:
Ömer Sinan Ağacan 2023-11-09 10:23:31 +00:00 committed by Commit Queue
parent 446881d53f
commit f78759775e
12 changed files with 1133 additions and 600 deletions

View file

@ -264,7 +264,6 @@ class ClassInfoCollector {
final Set<String> jsCompatibilityTypes = {
"JSStringImpl",
"JSArrayBufferImpl",
"JSArrayBufferViewImpl",
"JSDataViewImpl",
"JSInt8ArrayImpl",
"JSUint8ArrayImpl",

View file

@ -357,21 +357,38 @@ class Intrinsifier {
b.i32_ne();
return w.NumType.i32;
default:
throw 'Unknown i32 conversion to $receiverType';
throw 'Unknown WasmI32 member $name';
}
case w.NumType.i64:
assert(name == "toInt");
codeGen.wrap(receiver, w.NumType.i64);
return w.NumType.i64;
switch (name) {
case "toInt":
codeGen.wrap(receiver, w.NumType.i64);
return w.NumType.i64;
case "leU":
codeGen.wrap(receiver, w.NumType.i64);
codeGen.wrap(node.arguments.positional[0], w.NumType.i64);
b.i64_le_u();
return boolType;
default:
throw 'Unknown WasmI64 member $name';
}
case w.NumType.f32:
assert(name == "toDouble");
codeGen.wrap(receiver, w.NumType.f32);
b.f64_promote_f32();
return w.NumType.f64;
case w.NumType.f64:
assert(name == "toDouble");
codeGen.wrap(receiver, w.NumType.f64);
return w.NumType.f64;
switch (name) {
case "toDouble":
codeGen.wrap(receiver, w.NumType.f64);
return w.NumType.f64;
case "truncSatS":
codeGen.wrap(receiver, w.NumType.f64);
b.i64_trunc_sat_f64_s();
return w.NumType.i64;
default:
throw 'Unknown WasmF64 member $name';
}
}
}

View file

@ -358,23 +358,23 @@ WasmExternRef? jsifyRaw(Object? object) {
} else if (object is String) {
return jsStringFromDartString(object);
} else if (object is js_types.JSInt8ArrayImpl) {
return object.toExternRef;
return object.toJSArrayExternRef();
} else if (object is js_types.JSUint8ArrayImpl) {
return object.toExternRef;
return object.toJSArrayExternRef();
} else if (object is js_types.JSUint8ClampedArrayImpl) {
return object.toExternRef;
return object.toJSArrayExternRef();
} else if (object is js_types.JSInt16ArrayImpl) {
return object.toExternRef;
return object.toJSArrayExternRef();
} else if (object is js_types.JSUint16ArrayImpl) {
return object.toExternRef;
return object.toJSArrayExternRef();
} else if (object is js_types.JSInt32ArrayImpl) {
return object.toExternRef;
return object.toJSArrayExternRef();
} else if (object is js_types.JSUint32ArrayImpl) {
return object.toExternRef;
return object.toJSArrayExternRef();
} else if (object is js_types.JSFloat32ArrayImpl) {
return object.toExternRef;
return object.toJSArrayExternRef();
} else if (object is js_types.JSFloat64ArrayImpl) {
return object.toExternRef;
return object.toJSArrayExternRef();
} else if (object is Int8List) {
return jsInt8ArrayFromDartInt8List(object);
} else if (object is Uint8List) {
@ -422,27 +422,27 @@ Object? dartifyRaw(WasmExternRef? ref) {
} else if (isJSString(ref)) {
return js_types.JSStringImpl.box(ref);
} else if (isJSInt8Array(ref)) {
return js_types.JSInt8ArrayImpl(ref);
return js_types.JSInt8ArrayImpl.fromJSArray(ref);
} else if (isJSUint8Array(ref)) {
return js_types.JSUint8ArrayImpl(ref);
return js_types.JSUint8ArrayImpl.fromJSArray(ref);
} else if (isJSUint8ClampedArray(ref)) {
return js_types.JSUint8ClampedArrayImpl(ref);
return js_types.JSUint8ClampedArrayImpl.fromJSArray(ref);
} else if (isJSInt16Array(ref)) {
return js_types.JSInt16ArrayImpl(ref);
return js_types.JSInt16ArrayImpl.fromJSArray(ref);
} else if (isJSUint16Array(ref)) {
return js_types.JSUint16ArrayImpl(ref);
return js_types.JSUint16ArrayImpl.fromJSArray(ref);
} else if (isJSInt32Array(ref)) {
return js_types.JSInt32ArrayImpl(ref);
return js_types.JSInt32ArrayImpl.fromJSArray(ref);
} else if (isJSUint32Array(ref)) {
return js_types.JSUint32ArrayImpl(ref);
return js_types.JSUint32ArrayImpl.fromJSArray(ref);
} else if (isJSFloat32Array(ref)) {
return js_types.JSFloat32ArrayImpl(ref);
return js_types.JSFloat32ArrayImpl.fromJSArray(ref);
} else if (isJSFloat64Array(ref)) {
return js_types.JSFloat64ArrayImpl(ref);
return js_types.JSFloat64ArrayImpl.fromJSArray(ref);
} else if (isJSArrayBuffer(ref)) {
return js_types.JSArrayBufferImpl(ref);
return js_types.JSArrayBufferImpl.fromRef(ref);
} else if (isJSDataView(ref)) {
return js_types.JSDataViewImpl(ref);
return js_types.JSDataViewImpl.fromRef(ref);
} else if (isJSArray(ref)) {
return toDartList(ref);
} else if (isJSWrappedDartFunction(ref)) {

View file

@ -136,7 +136,7 @@ extension JSPromiseToFuture on JSPromise {
@patch
extension JSArrayBufferToByteBuffer on JSArrayBuffer {
@patch
ByteBuffer get toDart => js_types.JSArrayBufferImpl(toExternRef);
ByteBuffer get toDart => js_types.JSArrayBufferImpl.fromRef(toExternRef);
}
@patch
@ -156,7 +156,7 @@ extension ByteBufferToJSArrayBuffer on ByteBuffer {
@patch
extension JSDataViewToByteData on JSDataView {
@patch
ByteData get toDart => js_types.JSDataViewImpl(toExternRef);
ByteData get toDart => js_types.JSDataViewImpl.fromRef(toExternRef);
}
@patch
@ -174,7 +174,7 @@ extension ByteDataToJSDataView on ByteData {
@patch
extension JSInt8ArrayToInt8List on JSInt8Array {
@patch
Int8List get toDart => js_types.JSInt8ArrayImpl(toExternRef);
Int8List get toDart => js_types.JSInt8ArrayImpl.fromJSArray(toExternRef);
}
@patch
@ -183,7 +183,7 @@ extension Int8ListToJSInt8Array on Int8List {
JSInt8Array get toJS {
final t = this;
return _box<JSInt8Array>(t is js_types.JSInt8ArrayImpl
? t.toExternRef
? t.toJSArrayExternRef()
: jsInt8ArrayFromDartInt8List(t));
}
}
@ -192,7 +192,7 @@ extension Int8ListToJSInt8Array on Int8List {
@patch
extension JSUint8ArrayToUint8List on JSUint8Array {
@patch
Uint8List get toDart => js_types.JSUint8ArrayImpl(toExternRef);
Uint8List get toDart => js_types.JSUint8ArrayImpl.fromJSArray(toExternRef);
}
@patch
@ -201,7 +201,7 @@ extension Uint8ListToJSUint8Array on Uint8List {
JSUint8Array get toJS {
final t = this;
return _box<JSUint8Array>(t is js_types.JSUint8ArrayImpl
? t.toExternRef
? t.toJSArrayExternRef()
: jsUint8ArrayFromDartUint8List(t));
}
}
@ -210,7 +210,8 @@ extension Uint8ListToJSUint8Array on Uint8List {
@patch
extension JSUint8ClampedArrayToUint8ClampedList on JSUint8ClampedArray {
@patch
Uint8ClampedList get toDart => js_types.JSUint8ClampedArrayImpl(toExternRef);
Uint8ClampedList get toDart =>
js_types.JSUint8ClampedArrayImpl.fromJSArray(toExternRef);
}
@patch
@ -219,7 +220,7 @@ extension Uint8ClampedListToJSUint8ClampedArray on Uint8ClampedList {
JSUint8ClampedArray get toJS {
final t = this;
return _box<JSUint8ClampedArray>(t is js_types.JSUint8ClampedArrayImpl
? t.toExternRef
? t.toJSArrayExternRef()
: jsUint8ClampedArrayFromDartUint8ClampedList(t));
}
}
@ -228,7 +229,7 @@ extension Uint8ClampedListToJSUint8ClampedArray on Uint8ClampedList {
@patch
extension JSInt16ArrayToInt16List on JSInt16Array {
@patch
Int16List get toDart => js_types.JSInt16ArrayImpl(toExternRef);
Int16List get toDart => js_types.JSInt16ArrayImpl.fromJSArray(toExternRef);
}
@patch
@ -237,7 +238,7 @@ extension Int16ListToJSInt16Array on Int16List {
JSInt16Array get toJS {
final t = this;
return _box<JSInt16Array>(t is js_types.JSInt16ArrayImpl
? t.toExternRef
? t.toJSArrayExternRef()
: jsInt16ArrayFromDartInt16List(t));
}
}
@ -246,7 +247,7 @@ extension Int16ListToJSInt16Array on Int16List {
@patch
extension JSUint16ArrayToInt16List on JSUint16Array {
@patch
Uint16List get toDart => js_types.JSUint16ArrayImpl(toExternRef);
Uint16List get toDart => js_types.JSUint16ArrayImpl.fromJSArray(toExternRef);
}
@patch
@ -255,7 +256,7 @@ extension Uint16ListToJSInt16Array on Uint16List {
JSUint16Array get toJS {
final t = this;
return _box<JSUint16Array>(t is js_types.JSUint16ArrayImpl
? t.toExternRef
? t.toJSArrayExternRef()
: jsUint16ArrayFromDartUint16List(t));
}
}
@ -264,7 +265,7 @@ extension Uint16ListToJSInt16Array on Uint16List {
@patch
extension JSInt32ArrayToInt32List on JSInt32Array {
@patch
Int32List get toDart => js_types.JSInt32ArrayImpl(toExternRef);
Int32List get toDart => js_types.JSInt32ArrayImpl.fromJSArray(toExternRef);
}
@patch
@ -273,7 +274,7 @@ extension Int32ListToJSInt32Array on Int32List {
JSInt32Array get toJS {
final t = this;
return _box<JSInt32Array>(t is js_types.JSInt32ArrayImpl
? t.toExternRef
? t.toJSArrayExternRef()
: jsInt32ArrayFromDartInt32List(t));
}
}
@ -282,7 +283,7 @@ extension Int32ListToJSInt32Array on Int32List {
@patch
extension JSUint32ArrayToUint32List on JSUint32Array {
@patch
Uint32List get toDart => js_types.JSUint32ArrayImpl(toExternRef);
Uint32List get toDart => js_types.JSUint32ArrayImpl.fromJSArray(toExternRef);
}
@patch
@ -291,7 +292,7 @@ extension Uint32ListToJSUint32Array on Uint32List {
JSUint32Array get toJS {
final t = this;
return _box<JSUint32Array>(t is js_types.JSUint32ArrayImpl
? t.toExternRef
? t.toJSArrayExternRef()
: jsUint32ArrayFromDartUint32List(t));
}
}
@ -300,7 +301,8 @@ extension Uint32ListToJSUint32Array on Uint32List {
@patch
extension JSFloat32ArrayToFloat32List on JSFloat32Array {
@patch
Float32List get toDart => js_types.JSFloat32ArrayImpl(toExternRef);
Float32List get toDart =>
js_types.JSFloat32ArrayImpl.fromJSArray(toExternRef);
}
@patch
@ -309,7 +311,7 @@ extension Float32ListToJSFloat32Array on Float32List {
JSFloat32Array get toJS {
final t = this;
return _box<JSFloat32Array>(t is js_types.JSFloat32ArrayImpl
? t.toExternRef
? t.toJSArrayExternRef()
: jsFloat32ArrayFromDartFloat32List(t));
}
}
@ -318,7 +320,8 @@ extension Float32ListToJSFloat32Array on Float32List {
@patch
extension JSFloat64ArrayToFloat64List on JSFloat64Array {
@patch
Float64List get toDart => js_types.JSFloat64ArrayImpl(toExternRef);
Float64List get toDart =>
js_types.JSFloat64ArrayImpl.fromJSArray(toExternRef);
}
@patch
@ -327,7 +330,7 @@ extension Float64ListToJSFloat64Array on Float64List {
JSFloat64Array get toJS {
final t = this;
return _box<JSFloat64Array>(t is js_types.JSFloat64ArrayImpl
? t.toExternRef
? t.toJSArrayExternRef()
: jsFloat64ArrayFromDartFloat64List(t));
}
}

View file

@ -314,7 +314,7 @@ final class JSStringImpl implements String {
String substring(int start, [int? end]) {
end = RangeError.checkValidRange(start, end, this.length);
return JSStringImpl(js.JS<WasmExternRef?>('(o, s, i) => o.substring(s, i)',
toExternRef, start.toDouble().toExternRef, end.toDouble().toExternRef));
toExternRef, start.toDouble(), end.toDouble()));
}
@override

File diff suppressed because it is too large Load diff

View file

@ -24,6 +24,7 @@ import 'dart:_internal'
Sort,
SubListIterable,
TakeWhileIterable,
unsafeCast,
WhereIterable,
WhereTypeIterable;
import 'dart:_js_helper' as js;

View file

@ -9,57 +9,6 @@ import 'dart:_simd';
// we implement intrinsics for Wasm SIMD.
// TODO(joshualitt): Implement SIMD intrinsics and delete this patch.
@patch
class Int32x4List {
@patch
factory Int32x4List(int length) = NaiveInt32x4List;
@patch
factory Int32x4List.fromList(List<Int32x4> elements) =
NaiveInt32x4List.fromList;
}
@patch
class Float32x4List {
@patch
factory Float32x4List(int length) = NaiveFloat32x4List;
@patch
factory Float32x4List.fromList(List<Float32x4> elements) =
NaiveFloat32x4List.fromList;
}
@patch
class Float64x2List {
@patch
factory Float64x2List(int length) = NaiveFloat64x2List;
@patch
factory Float64x2List.fromList(List<Float64x2> elements) =
NaiveFloat64x2List.fromList;
}
@patch
abstract class UnmodifiableInt32x4ListView implements Int32x4List {
@patch
factory UnmodifiableInt32x4ListView(Int32x4List list) =>
NaiveUnmodifiableInt32x4List(list);
}
@patch
abstract class UnmodifiableFloat32x4ListView implements Float32x4List {
@patch
factory UnmodifiableFloat32x4ListView(Float32x4List list) =>
NaiveUnmodifiableFloat32x4List(list);
}
@patch
abstract class UnmodifiableFloat64x2ListView implements Float64x2List {
@patch
factory UnmodifiableFloat64x2ListView(Float64x2List list) =>
NaiveUnmodifiableFloat64x2List(list);
}
@patch
class Int32x4 {
@patch

View file

@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:_internal' show patch, unsafeCast;
import 'dart:_simd';
import 'dart:_typed_data';
import 'dart:_wasm';
@ -273,3 +274,54 @@ class UnmodifiableByteDataView implements ByteData {
// immutable, implement it in all `ByteData` subtypes.
unsafeCast<ByteDataBase>(data).immutable();
}
@patch
class Int32x4List {
@patch
factory Int32x4List(int length) = NaiveInt32x4List;
@patch
factory Int32x4List.fromList(List<Int32x4> elements) =
NaiveInt32x4List.fromList;
}
@patch
class Float32x4List {
@patch
factory Float32x4List(int length) = NaiveFloat32x4List;
@patch
factory Float32x4List.fromList(List<Float32x4> elements) =
NaiveFloat32x4List.fromList;
}
@patch
class Float64x2List {
@patch
factory Float64x2List(int length) = NaiveFloat64x2List;
@patch
factory Float64x2List.fromList(List<Float64x2> elements) =
NaiveFloat64x2List.fromList;
}
@patch
abstract class UnmodifiableInt32x4ListView implements Int32x4List {
@patch
factory UnmodifiableInt32x4ListView(Int32x4List list) =>
NaiveUnmodifiableInt32x4List(list);
}
@patch
abstract class UnmodifiableFloat32x4ListView implements Float32x4List {
@patch
factory UnmodifiableFloat32x4ListView(Float32x4List list) =>
NaiveUnmodifiableFloat32x4List(list);
}
@patch
abstract class UnmodifiableFloat64x2ListView implements Float64x2List {
@patch
factory UnmodifiableFloat64x2ListView(Float64x2List list) =>
NaiveUnmodifiableFloat64x2List(list);
}

View file

@ -55,14 +55,13 @@ class String {
// Create JS string from `list`.
const kMaxApply = 500;
if (index <= kMaxApply) {
return _fromCharCodeApplySubarray(list.toExternRef, 0, index.toDouble());
return _fromCharCodeApplySubarray(list, 0, index);
}
String result = '';
for (int i = 0; i < index; i += kMaxApply) {
final chunkEnd = (i + kMaxApply < index) ? i + kMaxApply : index;
result += _fromCharCodeApplySubarray(
list.toExternRef, i.toDouble(), chunkEnd.toDouble());
result += _fromCharCodeApplySubarray(list, i, chunkEnd);
}
return result;
}
@ -93,10 +92,11 @@ class String {
}
static String _fromCharCodeApplySubarray(
WasmExternRef? charCodes, double index, double end) =>
JSStringImpl(js.JS<WasmExternRef?>(
'(c, i, e) => String.fromCharCode.apply(null, c.subarray(i, e))',
charCodes,
index,
end));
JSUint32ArrayImpl charCodes, int index, int end) {
return JSStringImpl(js.JS<WasmExternRef?>(
'(c, i, e) => String.fromCharCode.apply(null, new Uint32Array(c.buffer, c.byteOffset + i, e))',
charCodes.toExternRef,
WasmI32.fromInt(index * 4),
WasmI32.fromInt(end - index)));
}
}

View file

@ -2,227 +2,164 @@
// 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.
import 'dart:_internal' show FixedLengthListMixin, patch, UnmodifiableListBase;
import 'dart:_js_helper' as js;
import 'dart:_internal' show patch;
import 'dart:_js_types';
import 'dart:_string_helper';
import 'dart:_wasm';
import 'dart:typed_data';
import 'dart:js_interop';
// TODO(joshualitt): Optimizations for this file:
// * Move list to JS and allocate on the JS side for `fromLength`
// constructors.
@patch
class ByteData {
@patch
factory ByteData(int length) {
return JSDataViewImpl(js.JS<WasmExternRef?>(
'l => new DataView(new ArrayBuffer(l))', length.toDouble()));
}
factory ByteData(int length) = JSDataViewImpl;
}
@patch
class Uint8List {
@patch
factory Uint8List(int length) {
return JSUint8ArrayImpl(
js.JS<WasmExternRef?>('l => new Uint8Array(l)', length.toDouble()));
}
factory Uint8List(int length) = JSUint8ArrayImpl;
@patch
factory Uint8List.fromList(List<int> elements) =>
Uint8List(elements.length)..setRange(0, elements.length, elements);
JSUint8ArrayImpl(elements.length)..setRange(0, elements.length, elements);
}
@patch
class Int8List {
@patch
factory Int8List(int length) {
return JSInt8ArrayImpl(
js.JS<WasmExternRef?>('l => new Int8Array(l)', length.toDouble()));
}
factory Int8List(int length) = JSInt8ArrayImpl;
@patch
factory Int8List.fromList(List<int> elements) =>
Int8List(elements.length)..setRange(0, elements.length, elements);
JSInt8ArrayImpl(elements.length)..setRange(0, elements.length, elements);
}
@patch
class Uint8ClampedList {
@patch
factory Uint8ClampedList(int length) {
return JSUint8ClampedArrayImpl(js.JS<WasmExternRef?>(
'l => new Uint8ClampedArray(l)', length.toDouble()));
}
factory Uint8ClampedList(int length) = JSUint8ClampedArrayImpl;
@patch
factory Uint8ClampedList.fromList(List<int> elements) =>
Uint8ClampedList(elements.length)..setRange(0, elements.length, elements);
JSUint8ClampedArrayImpl(elements.length)
..setRange(0, elements.length, elements);
}
@patch
class Uint16List {
@patch
factory Uint16List(int length) {
return JSUint16ArrayImpl(
js.JS<WasmExternRef?>('l => new Uint16Array(l)', length.toDouble()));
}
factory Uint16List(int length) = JSUint16ArrayImpl;
@patch
factory Uint16List.fromList(List<int> elements) =>
Uint16List(elements.length)..setRange(0, elements.length, elements);
JSUint16ArrayImpl(elements.length)
..setRange(0, elements.length, elements);
}
@patch
class Int16List {
@patch
factory Int16List(int length) {
return JSInt16ArrayImpl(
js.JS<WasmExternRef?>('l => new Int16Array(l)', length.toDouble()));
}
factory Int16List(int length) = JSInt16ArrayImpl;
@patch
factory Int16List.fromList(List<int> elements) =>
Int16List(elements.length)..setRange(0, elements.length, elements);
JSInt16ArrayImpl(elements.length)..setRange(0, elements.length, elements);
}
@patch
class Uint32List {
@patch
factory Uint32List(int length) {
return JSUint32ArrayImpl(
js.JS<WasmExternRef?>('l => new Uint32Array(l)', length.toDouble()));
}
factory Uint32List(int length) = JSUint32ArrayImpl;
@patch
factory Uint32List.fromList(List<int> elements) =>
Uint32List(elements.length)..setRange(0, elements.length, elements);
JSUint32ArrayImpl(elements.length)
..setRange(0, elements.length, elements);
}
@patch
class Int32List {
@patch
factory Int32List(int length) {
return JSInt32ArrayImpl(
js.JS<WasmExternRef?>('l => new Int32Array(l)', length.toDouble()));
}
factory Int32List(int length) = JSInt32ArrayImpl;
@patch
factory Int32List.fromList(List<int> elements) =>
Int32List(elements.length)..setRange(0, elements.length, elements);
JSInt32ArrayImpl(elements.length)..setRange(0, elements.length, elements);
}
@patch
class Int32x4List {
@patch
factory Int32x4List(int length) {
return JSInt32x4ArrayImpl.externalStorage(JSInt32ArrayImpl(js
.JS<WasmExternRef?>('l => new Int32Array(l * 4)', length.toDouble())));
}
factory Int32x4List(int length) =>
JSInt32x4ArrayImpl.externalStorage(JSInt32ArrayImpl(length * 4));
@patch
factory Int32x4List.fromList(List<Int32x4> elements) {
final length = elements.length;
final l = Int32x4List(length);
for (var i = 0; i < length; i++) {
l[i] = elements[i];
}
return l;
}
factory Int32x4List.fromList(List<Int32x4> elements) =>
Int32x4List(elements.length)..setRange(0, elements.length, elements);
}
@patch
class Int64List {
@patch
factory Int64List(int length) {
return JSBigInt64ArrayImpl(
js.JS<WasmExternRef?>('l => new BigInt64Array(l)', length.toDouble()));
}
factory Int64List(int length) = JSBigInt64ArrayImpl;
@patch
factory Int64List.fromList(List<int> elements) =>
Int64List(elements.length)..setRange(0, elements.length, elements);
JSBigInt64ArrayImpl(elements.length)
..setRange(0, elements.length, elements);
}
@patch
class Uint64List {
@patch
factory Uint64List(int length) {
return JSBigUint64ArrayImpl(
js.JS<WasmExternRef?>('l => new BigUint64Array(l)', length.toDouble()));
}
factory Uint64List(int length) = JSBigUint64ArrayImpl;
@patch
factory Uint64List.fromList(List<int> elements) =>
Uint64List(elements.length)..setRange(0, elements.length, elements);
JSBigUint64ArrayImpl(elements.length)
..setRange(0, elements.length, elements);
}
@patch
class Float32List {
@patch
factory Float32List(int length) {
return JSFloat32ArrayImpl(
js.JS<WasmExternRef?>('l => new Float32Array(l)', length.toDouble()));
}
factory Float32List(int length) = JSFloat32ArrayImpl;
@patch
factory Float32List.fromList(List<double> elements) =>
Float32List(elements.length)..setRange(0, elements.length, elements);
JSFloat32ArrayImpl(elements.length)
..setRange(0, elements.length, elements);
}
@patch
class Float32x4List {
@patch
factory Float32x4List(int length) {
return JSFloat32x4ArrayImpl.externalStorage(JSFloat32ArrayImpl(
js.JS<WasmExternRef?>(
'l => new Float32Array(l * 4)', length.toDouble())));
}
factory Float32x4List(int length) =>
JSFloat32x4ArrayImpl.externalStorage(JSFloat32ArrayImpl(length * 4));
@patch
factory Float32x4List.fromList(List<Float32x4> elements) {
final length = elements.length;
final l = Float32x4List(length);
for (var i = 0; i < length; i++) {
l[i] = elements[i];
}
return l;
}
factory Float32x4List.fromList(List<Float32x4> elements) =>
Float32x4List(elements.length)..setRange(0, elements.length, elements);
}
@patch
class Float64List {
@patch
factory Float64List(int length) {
return JSFloat64ArrayImpl(
js.JS<WasmExternRef?>('l => new Float64Array(l)', length.toDouble()));
}
factory Float64List(int length) = JSFloat64ArrayImpl;
@patch
factory Float64List.fromList(List<double> elements) =>
Float64List(elements.length)..setRange(0, elements.length, elements);
JSFloat64ArrayImpl(elements.length)
..setRange(0, elements.length, elements);
}
@patch
class Float64x2List {
@patch
factory Float64x2List(int length) {
return JSFloat64x2ArrayImpl.externalStorage(JSFloat64ArrayImpl(
js.JS<WasmExternRef?>(
'l => new Float64Array(l * 2)', length.toDouble())));
}
factory Float64x2List(int length) =>
JSFloat64x2ArrayImpl.externalStorage(JSFloat64ArrayImpl(length * 2));
@patch
factory Float64x2List.fromList(List<Float64x2> elements) {
final length = elements.length;
final l = Float64x2List(length);
for (var i = 0; i < length; i++) {
l[i] = elements[i];
}
return l;
}
factory Float64x2List.fromList(List<Float64x2> elements) =>
Float64x2List(elements.length)..setRange(0, elements.length, elements);
}
@patch

View file

@ -151,7 +151,11 @@ class WasmI64 extends _WasmInt {
const WasmI64(this._value);
external factory WasmI64.fromInt(int value);
external int toInt();
/// `i64.le_u`.
external bool leU(WasmI64 other);
}
/// The Wasm `f32` type.
@ -177,7 +181,11 @@ class WasmF64 extends _WasmFloat {
const WasmF64(this._value);
external factory WasmF64.fromDouble(double value);
external double toDouble();
/// `i64.trunc_sat_f64_s`.
external WasmI64 truncSatS();
}
/// A Wasm array with integer element type.