mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 17:56:11 +00:00
[dart2wasm] New typed data implementation
New typed data implementation that optimizes the common cases. This uses the best possible representation for the fast case with a representation like: class _I32List implements Int32List { final WasmIntArray<WasmI32> _data; int operator [](int index) { // range check return _data.read(index); } void operator []=(int index, int value) { // range check _data.writeSigned(index, value); } ... } This gives us the best possible runtime performance in the common cases of: - The list is used directly. - The list is used via a view of the same Wasm element type (e.g. a `Uint32List` view of a `Int32List`) and with aligned byte offset. All other classes (`ByteBuffer`, `ByteData`, and view classes) implemented to be able to support this representation. Summary of classes: - One list class per Dart typed data list, with the matching Wasm array as the buffer (as shown in the example above): `_I8List`, `_U8List`, `_U8ClampedList`, `_I16List`, `_U16List`, ... - One list class per Dart typed data list, with mismatching Wasm array as the buffer. These classes are used when a view is created from a list, and the original list has a Wasm array with different element type than the view needs. `_SlowI8List`, `_SlowU8List`, ... These classes use `ByteData` interface to update the buffer. - One list class for each of the classes listed above, for immutable views. `_UnmodifiableI32List`, `_UnmodifiableSlowU64List`, ... These classes inherit from their modifiable list classes and override update methods using a mixin. - One `ByteData` class for each Wasm array type: `_I8ByteData`, `_I16ByteData`, ... - One immutable `ByteData` view for each `ByteData` class. - One `ByteBuffer` class for each Wasm array type: `_I8ByteBuffer`, `_I16ByteBuffer`, ... - A single `ByteBuffer` class for the immutable view of a byte buffer. We don't need one immutable `ByteBuffer` view class per Wasm array type as `ByteBuffer` API does not provide direct access to the buffer. Other optimizations: - `setRange` now uses `array.copy` when possible, which causes a huge performance win in some benchmarks. - The new implementation is pure Dart and needs no support or special cases from the compiler other than the Wasm array type support and intrinsics like `array.copy`. As a result this removes a bunch of `entry-point` pragmas and significantly reduces code size in some cases. Other changes: - Patch and implementation files for typed data and SIMD types are split into separate files. `typed_data_patch.dart` and `simd_patch.dart` now only contains patched factories. Implementation classes are moved to `typed_data.dart` and `simd.dart` as libraries `dart:_typed_data` and `dart:_simd`. Benchmark results: This CL significantly improves common cases. New implementation is only slower than the current implementation when a view uses a Wasm array type with incompatible element type (for example, `Uint32List` created from a `Uint64List`). These cases can still be improved by overriding the relevant `ByteData` methods. For example, in the example of `Uint32List` view of a `Uint64List`, by overriding `_I64ByteData.getUint32` to do a single read then requested bytes don't cross element boundaries in the Wasm array. These optimizations are left as future work. Some sample benchmarks: vector_math matrix_bench before: Binary size: 133,104 bytes. MatrixMultiply(RunTime): 201 us. SIMDMatrixMultiply(RunTime): 3,608 us. VectorTransform(RunTime): 94 us. SIMDVectorTransform(RunTime): 833 us. setViewMatrix(RunTime): 506 us. aabb2Transform(RunTime): 987 us. aabb2Rotate(RunTime): 721 us. aabb3Transform(RunTime): 1,710 us. aabb3Rotate(RunTime): 1,156 us. Matrix3.determinant(RunTime): 171 us. Matrix3.transform(Vector3)(RunTime): 8,550 us. Matrix3.transform(Vector2)(RunTime): 3924 us. Matrix3.transposeMultiply(RunTime): 201 us. vector_math matrix_bench after: Binary size: 135,198 bytes. MatrixMultiply(RunTime): 42 us. SIMDMatrixMultiply(RunTime): 2,068 us. VectorTransform(RunTime): 12 us. SIMDVectorTransform(RunTime): 272 us. setViewMatrix(RunTime): 82 us. aabb2Transform(RunTime): 167 us. aabb2Rotate(RunTime): 147 us. aabb3Transform(RunTime): 194 us. aabb3Rotate(RunTime): 199 us. Matrix3.determinant(RunTime): 70 us. Matrix3.transform(Vector3)(RunTime): 726 us. Matrix3.transform(Vector2)(RunTime): 504 us. Matrix3.transposeMultiply(RunTime): 53 us. FluidMotion before: Binary size: 121,130 bytes. FluidMotion(RunTime): 270,625 us. FluidMotion after: Binary size: 110,674 bytes. FluidMotion(RunTime): 71,357 us. With bound checks omitted (not in this CL), FluidMotion becomes competitive with `dart2js -O4`: FluidMotion dart2js -O4: FluidMotion(RunTime): 47,813 us. FluidMotion this CL + boud checks omitted: FluidMotion(RunTime): 51,289 us. Fixes #52710. Tested: With existing tests. Change-Id: I33bf5585c3be5d3919a99af857659cf7d9393df0 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/312907 Reviewed-by: Joshua Litt <joshualitt@google.com> Commit-Queue: Ömer Ağacan <omersa@google.com>
This commit is contained in:
parent
9692a9dfef
commit
0f54180b51
|
@ -47,13 +47,6 @@ class FieldIndex {
|
|||
static const functionTypeNamedParameters = 9;
|
||||
static const recordTypeNames = 3;
|
||||
static const recordTypeFieldTypes = 4;
|
||||
static const typedListBaseLength = 2;
|
||||
static const typedListArray = 3;
|
||||
static const typedListViewTypedData = 3;
|
||||
static const typedListViewOffsetInBytes = 4;
|
||||
static const byteDataViewLength = 2;
|
||||
static const byteDataViewTypedData = 3;
|
||||
static const byteDataViewOffsetInBytes = 4;
|
||||
static const suspendStateIterator = 4;
|
||||
static const suspendStateContext = 5;
|
||||
static const suspendStateTargetIndex = 6;
|
||||
|
@ -215,16 +208,20 @@ class ClassInfoCollector {
|
|||
|
||||
/// Masquerades for implementation classes. For each entry of the map, all
|
||||
/// subtypes of the key masquerade as the value.
|
||||
late final Map<Class, Class> _masquerades = {
|
||||
translator.coreTypes.boolClass: translator.coreTypes.boolClass,
|
||||
translator.coreTypes.intClass: translator.coreTypes.intClass,
|
||||
translator.coreTypes.doubleClass: translator.coreTypes.doubleClass,
|
||||
translator.coreTypes.stringClass: translator.coreTypes.stringClass,
|
||||
translator.index.getClass("dart:core", "_Type"):
|
||||
translator.coreTypes.typeClass,
|
||||
translator.index.getClass("dart:core", "_ListBase"):
|
||||
translator.coreTypes.listClass,
|
||||
for (Class cls in const <String>[
|
||||
late final Map<Class, Class> _masquerades = _computeMasquerades();
|
||||
|
||||
Map<Class, Class> _computeMasquerades() {
|
||||
final map = {
|
||||
translator.coreTypes.boolClass: translator.coreTypes.boolClass,
|
||||
translator.coreTypes.intClass: translator.coreTypes.intClass,
|
||||
translator.coreTypes.doubleClass: translator.coreTypes.doubleClass,
|
||||
translator.coreTypes.stringClass: translator.coreTypes.stringClass,
|
||||
translator.index.getClass("dart:core", "_Type"):
|
||||
translator.coreTypes.typeClass,
|
||||
translator.index.getClass("dart:core", "_ListBase"):
|
||||
translator.coreTypes.listClass
|
||||
};
|
||||
for (String name in const <String>[
|
||||
"Int8List",
|
||||
"Uint8List",
|
||||
"Uint8ClampedList",
|
||||
|
@ -239,9 +236,14 @@ class ClassInfoCollector {
|
|||
"Int32x4List",
|
||||
"Float32x4List",
|
||||
"Float64x2List",
|
||||
].map((name) => translator.index.getClass("dart:typed_data", name)))
|
||||
cls: cls
|
||||
};
|
||||
]) {
|
||||
final Class? cls = translator.index.tryGetClass("dart:typed_data", name);
|
||||
if (cls != null) {
|
||||
map[cls] = cls;
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
late final Set<Class> _neverMasquerades = _computeNeverMasquerades();
|
||||
|
||||
|
@ -357,11 +359,7 @@ class ClassInfoCollector {
|
|||
// 3. The class is not a special class that contains hidden fields.
|
||||
bool canReuseSuperStruct =
|
||||
typeParameterMatch.length == cls.typeParameters.length &&
|
||||
cls.fields.where((f) => f.isInstanceMember).isEmpty &&
|
||||
cls != translator.typedListBaseClass &&
|
||||
cls != translator.typedListClass &&
|
||||
cls != translator.typedListViewClass &&
|
||||
cls != translator.byteDataViewClass;
|
||||
cls.fields.where((f) => f.isInstanceMember).isEmpty;
|
||||
w.StructType struct = canReuseSuperStruct
|
||||
? superInfo.struct
|
||||
: m.addStructType(cls.name, superType: superInfo.struct);
|
||||
|
@ -547,47 +545,7 @@ class ClassInfoCollector {
|
|||
}
|
||||
}
|
||||
|
||||
// Add hidden fields of typed_data classes.
|
||||
_addTypedDataFields();
|
||||
|
||||
// Validate that all internally used fields have the expected indices.
|
||||
FieldIndex.validate(translator);
|
||||
}
|
||||
|
||||
void _addTypedDataFields() {
|
||||
ClassInfo typedListBaseInfo =
|
||||
translator.classInfo[translator.typedListBaseClass]!;
|
||||
typedListBaseInfo._addField(w.FieldType(w.NumType.i32, mutable: false),
|
||||
FieldIndex.typedListBaseLength);
|
||||
|
||||
ClassInfo typedListInfo = translator.classInfo[translator.typedListClass]!;
|
||||
typedListInfo._addField(w.FieldType(w.NumType.i32, mutable: false),
|
||||
FieldIndex.typedListBaseLength);
|
||||
w.RefType bytesArrayType = w.RefType.def(
|
||||
translator.wasmArrayType(w.PackedType.i8, "i8"),
|
||||
nullable: false);
|
||||
typedListInfo._addField(
|
||||
w.FieldType(bytesArrayType, mutable: false), FieldIndex.typedListArray);
|
||||
|
||||
w.RefType typedListType =
|
||||
w.RefType.def(typedListInfo.struct, nullable: false);
|
||||
|
||||
ClassInfo typedListViewInfo =
|
||||
translator.classInfo[translator.typedListViewClass]!;
|
||||
typedListViewInfo._addField(w.FieldType(w.NumType.i32, mutable: false),
|
||||
FieldIndex.typedListBaseLength);
|
||||
typedListViewInfo._addField(w.FieldType(typedListType, mutable: false),
|
||||
FieldIndex.typedListViewTypedData);
|
||||
typedListViewInfo._addField(w.FieldType(w.NumType.i32, mutable: false),
|
||||
FieldIndex.typedListViewOffsetInBytes);
|
||||
|
||||
ClassInfo byteDataViewInfo =
|
||||
translator.classInfo[translator.byteDataViewClass]!;
|
||||
byteDataViewInfo._addField(w.FieldType(w.NumType.i32, mutable: false),
|
||||
FieldIndex.byteDataViewLength);
|
||||
byteDataViewInfo._addField(w.FieldType(typedListType, mutable: false),
|
||||
FieldIndex.byteDataViewTypedData);
|
||||
byteDataViewInfo._addField(w.FieldType(w.NumType.i32, mutable: false),
|
||||
FieldIndex.byteDataViewOffsetInBytes);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -273,131 +273,6 @@ class Intrinsifier {
|
|||
Procedure target = node.interfaceTarget;
|
||||
Class cls = target.enclosingClass!;
|
||||
|
||||
// _TypedList._(get|set)(Int|Uint|Float)(8|16|32|64)
|
||||
if (cls == translator.typedListClass) {
|
||||
Match? match = RegExp("^_(get|set)(Int|Uint|Float)(8|16|32|64)\$")
|
||||
.matchAsPrefix(name);
|
||||
if (match != null) {
|
||||
bool setter = match.group(1) == "set";
|
||||
bool signed = match.group(2) == "Int";
|
||||
bool float = match.group(2) == "Float";
|
||||
int bytes = int.parse(match.group(3)!) ~/ 8;
|
||||
bool wide = bytes == 8;
|
||||
|
||||
ClassInfo typedListInfo =
|
||||
translator.classInfo[translator.typedListClass]!;
|
||||
w.RefType arrayType = typedListInfo.struct
|
||||
.fields[FieldIndex.typedListArray].type.unpacked as w.RefType;
|
||||
w.ArrayType arrayHeapType = arrayType.heapType as w.ArrayType;
|
||||
w.ValueType valueType = float ? w.NumType.f64 : w.NumType.i64;
|
||||
w.ValueType intType = wide ? w.NumType.i64 : w.NumType.i32;
|
||||
|
||||
// Prepare array and offset
|
||||
w.Local array = codeGen.addLocal(arrayType);
|
||||
w.Local offset = codeGen.addLocal(w.NumType.i32);
|
||||
codeGen.wrap(receiver, typedListInfo.nonNullableType);
|
||||
b.struct_get(typedListInfo.struct, FieldIndex.typedListArray);
|
||||
b.local_set(array);
|
||||
codeGen.wrap(node.arguments.positional[0], w.NumType.i64);
|
||||
b.i32_wrap_i64();
|
||||
b.local_set(offset);
|
||||
|
||||
if (setter) {
|
||||
// Setter
|
||||
w.Local value = codeGen.addLocal(intType);
|
||||
codeGen.wrap(node.arguments.positional[1], valueType);
|
||||
if (wide) {
|
||||
if (float) {
|
||||
b.i64_reinterpret_f64();
|
||||
}
|
||||
} else {
|
||||
if (float) {
|
||||
b.f32_demote_f64();
|
||||
b.i32_reinterpret_f32();
|
||||
} else {
|
||||
b.i32_wrap_i64();
|
||||
}
|
||||
}
|
||||
b.local_set(value);
|
||||
|
||||
for (int i = 0; i < bytes; i++) {
|
||||
b.local_get(array);
|
||||
b.local_get(offset);
|
||||
if (i > 0) {
|
||||
b.i32_const(i);
|
||||
b.i32_add();
|
||||
}
|
||||
b.local_get(value);
|
||||
if (i > 0) {
|
||||
if (wide) {
|
||||
b.i64_const(i * 8);
|
||||
b.i64_shr_u();
|
||||
} else {
|
||||
b.i32_const(i * 8);
|
||||
b.i32_shr_u();
|
||||
}
|
||||
}
|
||||
if (wide) {
|
||||
b.i32_wrap_i64();
|
||||
}
|
||||
b.array_set(arrayHeapType);
|
||||
}
|
||||
return translator.voidMarker;
|
||||
} else {
|
||||
// Getter
|
||||
for (int i = 0; i < bytes; i++) {
|
||||
b.local_get(array);
|
||||
b.local_get(offset);
|
||||
if (i > 0) {
|
||||
b.i32_const(i);
|
||||
b.i32_add();
|
||||
}
|
||||
if (signed && i == bytes - 1) {
|
||||
b.array_get_s(arrayHeapType);
|
||||
} else {
|
||||
b.array_get_u(arrayHeapType);
|
||||
}
|
||||
if (wide) {
|
||||
if (signed) {
|
||||
b.i64_extend_i32_s();
|
||||
} else {
|
||||
b.i64_extend_i32_u();
|
||||
}
|
||||
}
|
||||
if (i > 0) {
|
||||
if (wide) {
|
||||
b.i64_const(i * 8);
|
||||
b.i64_shl();
|
||||
b.i64_or();
|
||||
} else {
|
||||
b.i32_const(i * 8);
|
||||
b.i32_shl();
|
||||
b.i32_or();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (wide) {
|
||||
if (float) {
|
||||
b.f64_reinterpret_i64();
|
||||
}
|
||||
} else {
|
||||
if (float) {
|
||||
b.f32_reinterpret_i32();
|
||||
b.f64_promote_f32();
|
||||
} else {
|
||||
if (signed) {
|
||||
b.i64_extend_i32_s();
|
||||
} else {
|
||||
b.i64_extend_i32_u();
|
||||
}
|
||||
}
|
||||
}
|
||||
return valueType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WasmAnyRef.toObject
|
||||
if (cls == translator.wasmAnyRefClass && name == "toObject") {
|
||||
w.Label succeed = b.block(const [], [translator.topInfo.nonNullableType]);
|
||||
|
@ -1448,151 +1323,6 @@ class Intrinsifier {
|
|||
return true;
|
||||
}
|
||||
|
||||
// (Int|Uint|Float)(8|16|32|64)(Clamped)?(List|ArrayView) constructors
|
||||
if (member.isExternal &&
|
||||
member.enclosingLibrary.name == "dart.typed_data") {
|
||||
if (member.isFactory) {
|
||||
String className = member.enclosingClass!.name;
|
||||
|
||||
Match? match = RegExp("^(Int|Uint|Float)(8|16|32|64)(Clamped)?List\$")
|
||||
.matchAsPrefix(className);
|
||||
if (match != null) {
|
||||
int elementSize = int.parse(match.group(2)!);
|
||||
int elementSizeInBytes = elementSize ~/ 8;
|
||||
int maxNumberOfElements = ((1 << 32) - 1) ~/ elementSizeInBytes;
|
||||
int shift = elementSizeInBytes.bitLength - 1;
|
||||
Class cls = member.enclosingLibrary.classes
|
||||
.firstWhere((c) => c.name == "_$className");
|
||||
ClassInfo info = translator.classInfo[cls]!;
|
||||
translator.functions.allocateClass(info.classId);
|
||||
w.ArrayType arrayType =
|
||||
translator.wasmArrayType(w.PackedType.i8, "i8");
|
||||
|
||||
w.Local length = paramLocals[0];
|
||||
|
||||
// Check array size
|
||||
b.local_get(length);
|
||||
b.i64_const(maxNumberOfElements);
|
||||
b.i64_gt_u();
|
||||
b.if_();
|
||||
// int value
|
||||
b.local_get(length);
|
||||
// int minValue
|
||||
b.i64_const(0);
|
||||
// int maxValue
|
||||
b.i64_const(maxNumberOfElements);
|
||||
// String? name
|
||||
b.ref_null(translator.objectInfo.struct);
|
||||
// String? message
|
||||
b.ref_null(translator.objectInfo.struct);
|
||||
b.call(translator.functions.getFunction(
|
||||
translator.rangeErrorCheckValueInInterval.reference));
|
||||
b.drop(); // call returns first argument (value)
|
||||
b.end();
|
||||
|
||||
b.i32_const(info.classId);
|
||||
b.i32_const(initialIdentityHash);
|
||||
b.local_get(length);
|
||||
b.i32_wrap_i64();
|
||||
b.local_get(length);
|
||||
if (shift > 0) {
|
||||
b.i64_const(shift);
|
||||
b.i64_shl();
|
||||
}
|
||||
b.i32_wrap_i64();
|
||||
b.array_new_default(arrayType);
|
||||
b.struct_new(info.struct);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool _createView() {
|
||||
ClassInfo info = translator.classInfo[member.enclosingClass]!;
|
||||
translator.functions.allocateClass(info.classId);
|
||||
|
||||
w.Local buffer = paramLocals[0];
|
||||
w.Local offsetInBytes = paramLocals[1];
|
||||
w.Local length = paramLocals[2];
|
||||
b.i32_const(info.classId);
|
||||
b.i32_const(initialIdentityHash);
|
||||
b.local_get(length);
|
||||
b.i32_wrap_i64();
|
||||
b.local_get(buffer);
|
||||
b.local_get(offsetInBytes);
|
||||
b.i32_wrap_i64();
|
||||
b.struct_new(info.struct);
|
||||
return true;
|
||||
}
|
||||
|
||||
match = RegExp(
|
||||
"^_(Int|Uint|Float)(8|16|32|64|32x4|64x2)(Clamped)?ArrayView\$")
|
||||
.matchAsPrefix(className);
|
||||
if (match != null ||
|
||||
member.enclosingClass == translator.byteDataViewClass) {
|
||||
return _createView();
|
||||
}
|
||||
|
||||
match = RegExp(
|
||||
"^_Unmodifiable(Int|Uint|Float)(8|16|32|64|32x4|64x2)(Clamped)?ArrayView\$")
|
||||
.matchAsPrefix(className);
|
||||
if (match != null ||
|
||||
member.enclosingClass == translator.unmodifiableByteDataViewClass) {
|
||||
return _createView();
|
||||
}
|
||||
}
|
||||
|
||||
// _TypedListBase.length
|
||||
// _TypedListView.offsetInBytes
|
||||
// _TypedListView._typedData
|
||||
// _ByteDataView.length
|
||||
// _ByteDataView.offsetInBytes
|
||||
// _ByteDataView._typedData
|
||||
if (member.isGetter) {
|
||||
Class cls = member.enclosingClass!;
|
||||
ClassInfo info = translator.classInfo[cls]!;
|
||||
b.local_get(paramLocals[0]);
|
||||
b.ref_cast(info.nonNullableType);
|
||||
// TODO(joshualitt): Because we currently merge getters to support
|
||||
// dynamic calls, the return types of `.length` and `.offsetInBytes` can
|
||||
// change. Should we decide to stop merging getters, we should remove
|
||||
// the conversions below.
|
||||
w.ValueType outputType = function.type.outputs.single;
|
||||
switch (name) {
|
||||
case "length":
|
||||
assert(cls == translator.typedListBaseClass ||
|
||||
cls == translator.byteDataViewClass);
|
||||
if (cls == translator.typedListBaseClass) {
|
||||
b.struct_get(info.struct, FieldIndex.typedListBaseLength);
|
||||
} else {
|
||||
b.struct_get(info.struct, FieldIndex.byteDataViewLength);
|
||||
}
|
||||
b.i64_extend_i32_u();
|
||||
translator.convertType(function, intType, outputType);
|
||||
return true;
|
||||
case "offsetInBytes":
|
||||
assert(cls == translator.typedListViewClass ||
|
||||
cls == translator.byteDataViewClass);
|
||||
if (cls == translator.typedListViewClass) {
|
||||
b.struct_get(info.struct, FieldIndex.typedListViewOffsetInBytes);
|
||||
} else {
|
||||
b.struct_get(info.struct, FieldIndex.byteDataViewOffsetInBytes);
|
||||
}
|
||||
b.i64_extend_i32_u();
|
||||
translator.convertType(function, intType, outputType);
|
||||
return true;
|
||||
case "_typedData":
|
||||
assert(cls == translator.typedListViewClass ||
|
||||
cls == translator.byteDataViewClass);
|
||||
if (cls == translator.typedListViewClass) {
|
||||
b.struct_get(info.struct, FieldIndex.typedListViewTypedData);
|
||||
} else {
|
||||
b.struct_get(info.struct, FieldIndex.byteDataViewTypedData);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
throw "Unrecognized typed data getter: ${cls.name}.$name";
|
||||
}
|
||||
}
|
||||
|
||||
// int members
|
||||
if (member.enclosingClass == translator.boxedIntClass &&
|
||||
member.function.body == null) {
|
||||
|
|
|
@ -114,18 +114,6 @@ mixin KernelNodes {
|
|||
late final Class ffiCompoundClass = index.getClass("dart:ffi", "_Compound");
|
||||
late final Class ffiPointerClass = index.getClass("dart:ffi", "Pointer");
|
||||
|
||||
// dart:typed_data classes
|
||||
late final Class typedListBaseClass =
|
||||
index.getClass("dart:typed_data", "_TypedListBase");
|
||||
late final Class typedListClass =
|
||||
index.getClass("dart:typed_data", "_TypedList");
|
||||
late final Class typedListViewClass =
|
||||
index.getClass("dart:typed_data", "_TypedListView");
|
||||
late final Class byteDataViewClass =
|
||||
index.getClass("dart:typed_data", "_ByteDataView");
|
||||
late final Class unmodifiableByteDataViewClass =
|
||||
index.getClass("dart:typed_data", "_UnmodifiableByteDataView");
|
||||
|
||||
// dart:_wasm classes
|
||||
late final Class wasmTypesBaseClass =
|
||||
index.getClass("dart:_wasm", "_WasmBase");
|
||||
|
|
|
@ -126,7 +126,9 @@ class WasmTarget extends Target {
|
|||
bool mayDefineRestrictedType(Uri uri) =>
|
||||
uri.isScheme('dart') &&
|
||||
(uri.path == 'core' ||
|
||||
uri.path == '_simd' ||
|
||||
uri.path == 'typed_data' ||
|
||||
uri.path == '_typed_data' ||
|
||||
uri.path == '_boxed_double' ||
|
||||
uri.path == '_boxed_int' ||
|
||||
uri.path == '_js_types');
|
||||
|
|
|
@ -45,7 +45,7 @@ if [[ "$3" == "--omit-checks" ]]; then
|
|||
fi
|
||||
|
||||
"$DART2WASM" "$1" "$TEMPFILE" $COMPILE_FLAGS
|
||||
"$BINARYEN" -all --closed-world -tnh -O3 --type-ssa --gufa -O3 --type-merging "$TEMPFILE" -o "$2"
|
||||
"$BINARYEN" -g -all --closed-world -tnh -O3 --type-ssa --gufa -O3 --type-merging "$TEMPFILE" -o "$2"
|
||||
|
||||
# Locate JS runtime and copy it to the same directory as "$2". We also rename it
|
||||
# using the basename of "$2".
|
||||
|
|
|
@ -2199,7 +2199,6 @@ class Int8List {
|
|||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
@pragma("wasm:entry-point")
|
||||
final class _Int8List extends _TypedList
|
||||
with _IntListMixin, _TypedIntListMixin<Int8List>
|
||||
implements Int8List {
|
||||
|
@ -2255,7 +2254,6 @@ class Uint8List {
|
|||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
@pragma("wasm:entry-point")
|
||||
final class _Uint8List extends _TypedList
|
||||
with _IntListMixin, _TypedIntListMixin<Uint8List>
|
||||
implements Uint8List {
|
||||
|
@ -2311,7 +2309,6 @@ class Uint8ClampedList {
|
|||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
@pragma("wasm:entry-point")
|
||||
final class _Uint8ClampedList extends _TypedList
|
||||
with _IntListMixin, _TypedIntListMixin<Uint8ClampedList>
|
||||
implements Uint8ClampedList {
|
||||
|
@ -2367,7 +2364,6 @@ class Int16List {
|
|||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
@pragma("wasm:entry-point")
|
||||
final class _Int16List extends _TypedList
|
||||
with _IntListMixin, _TypedIntListMixin<Int16List>
|
||||
implements Int16List {
|
||||
|
@ -2443,7 +2439,6 @@ class Uint16List {
|
|||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
@pragma("wasm:entry-point")
|
||||
final class _Uint16List extends _TypedList
|
||||
with _IntListMixin, _TypedIntListMixin<Uint16List>
|
||||
implements Uint16List {
|
||||
|
@ -2519,7 +2514,6 @@ class Int32List {
|
|||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
@pragma("wasm:entry-point")
|
||||
final class _Int32List extends _TypedList
|
||||
with _IntListMixin, _TypedIntListMixin<Int32List>
|
||||
implements Int32List {
|
||||
|
@ -2582,7 +2576,6 @@ class Uint32List {
|
|||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
@pragma("wasm:entry-point")
|
||||
final class _Uint32List extends _TypedList
|
||||
with _IntListMixin, _TypedIntListMixin<Uint32List>
|
||||
implements Uint32List {
|
||||
|
@ -2645,7 +2638,6 @@ class Int64List {
|
|||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
@pragma("wasm:entry-point")
|
||||
final class _Int64List extends _TypedList
|
||||
with _IntListMixin, _TypedIntListMixin<Int64List>
|
||||
implements Int64List {
|
||||
|
@ -2708,7 +2700,6 @@ class Uint64List {
|
|||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
@pragma("wasm:entry-point")
|
||||
final class _Uint64List extends _TypedList
|
||||
with _IntListMixin, _TypedIntListMixin<Uint64List>
|
||||
implements Uint64List {
|
||||
|
@ -2771,7 +2762,6 @@ class Float32List {
|
|||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
@pragma("wasm:entry-point")
|
||||
final class _Float32List extends _TypedList
|
||||
with _DoubleListMixin, _TypedDoubleListMixin<Float32List>
|
||||
implements Float32List {
|
||||
|
@ -2835,7 +2825,6 @@ class Float64List {
|
|||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
@pragma("wasm:entry-point")
|
||||
final class _Float64List extends _TypedList
|
||||
with _DoubleListMixin, _TypedDoubleListMixin<Float64List>
|
||||
implements Float64List {
|
||||
|
@ -3105,7 +3094,6 @@ final class _ExternalInt8Array extends _TypedList
|
|||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
@pragma("wasm:entry-point")
|
||||
final class _ExternalUint8Array extends _TypedList
|
||||
with _IntListMixin, _TypedIntListMixin<Uint8List>
|
||||
implements Uint8List {
|
||||
|
@ -4218,7 +4206,6 @@ abstract final class _TypedListView extends _TypedListBase
|
|||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
@pragma("wasm:entry-point")
|
||||
final class _Int8ArrayView extends _TypedListView
|
||||
with _IntListMixin, _TypedIntListMixin<Int8List>
|
||||
implements Int8List {
|
||||
|
@ -4262,7 +4249,6 @@ final class _Int8ArrayView extends _TypedListView
|
|||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
@pragma("wasm:entry-point")
|
||||
final class _Uint8ArrayView extends _TypedListView
|
||||
with _IntListMixin, _TypedIntListMixin<Uint8List>
|
||||
implements Uint8List {
|
||||
|
@ -4306,7 +4292,6 @@ final class _Uint8ArrayView extends _TypedListView
|
|||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
@pragma("wasm:entry-point")
|
||||
final class _Uint8ClampedArrayView extends _TypedListView
|
||||
with _IntListMixin, _TypedIntListMixin<Uint8ClampedList>
|
||||
implements Uint8ClampedList {
|
||||
|
@ -4350,7 +4335,6 @@ final class _Uint8ClampedArrayView extends _TypedListView
|
|||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
@pragma("wasm:entry-point")
|
||||
final class _Int16ArrayView extends _TypedListView
|
||||
with _IntListMixin, _TypedIntListMixin<Int16List>
|
||||
implements Int16List {
|
||||
|
@ -4407,7 +4391,6 @@ final class _Int16ArrayView extends _TypedListView
|
|||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
@pragma("wasm:entry-point")
|
||||
final class _Uint16ArrayView extends _TypedListView
|
||||
with _IntListMixin, _TypedIntListMixin<Uint16List>
|
||||
implements Uint16List {
|
||||
|
@ -4465,7 +4448,6 @@ final class _Uint16ArrayView extends _TypedListView
|
|||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
@pragma("wasm:entry-point")
|
||||
final class _Int32ArrayView extends _TypedListView
|
||||
with _IntListMixin, _TypedIntListMixin<Int32List>
|
||||
implements Int32List {
|
||||
|
@ -4509,7 +4491,6 @@ final class _Int32ArrayView extends _TypedListView
|
|||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
@pragma("wasm:entry-point")
|
||||
final class _Uint32ArrayView extends _TypedListView
|
||||
with _IntListMixin, _TypedIntListMixin<Uint32List>
|
||||
implements Uint32List {
|
||||
|
@ -4553,7 +4534,6 @@ final class _Uint32ArrayView extends _TypedListView
|
|||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
@pragma("wasm:entry-point")
|
||||
final class _Int64ArrayView extends _TypedListView
|
||||
with _IntListMixin, _TypedIntListMixin<Int64List>
|
||||
implements Int64List {
|
||||
|
@ -4597,7 +4577,6 @@ final class _Int64ArrayView extends _TypedListView
|
|||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
@pragma("wasm:entry-point")
|
||||
final class _Uint64ArrayView extends _TypedListView
|
||||
with _IntListMixin, _TypedIntListMixin<Uint64List>
|
||||
implements Uint64List {
|
||||
|
@ -4641,7 +4620,6 @@ final class _Uint64ArrayView extends _TypedListView
|
|||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
@pragma("wasm:entry-point")
|
||||
final class _Float32ArrayView extends _TypedListView
|
||||
with _DoubleListMixin, _TypedDoubleListMixin<Float32List>
|
||||
implements Float32List {
|
||||
|
@ -4685,7 +4663,6 @@ final class _Float32ArrayView extends _TypedListView
|
|||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
@pragma("wasm:entry-point")
|
||||
final class _Float64ArrayView extends _TypedListView
|
||||
with _DoubleListMixin, _TypedDoubleListMixin<Float64List>
|
||||
implements Float64List {
|
||||
|
@ -4729,7 +4706,6 @@ final class _Float64ArrayView extends _TypedListView
|
|||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
@pragma("wasm:entry-point")
|
||||
final class _Float32x4ArrayView extends _TypedListView
|
||||
with _Float32x4ListMixin
|
||||
implements Float32x4List {
|
||||
|
@ -4771,7 +4747,6 @@ final class _Float32x4ArrayView extends _TypedListView
|
|||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
@pragma("wasm:entry-point")
|
||||
final class _Int32x4ArrayView extends _TypedListView
|
||||
with _Int32x4ListMixin
|
||||
implements Int32x4List {
|
||||
|
@ -4813,7 +4788,6 @@ final class _Int32x4ArrayView extends _TypedListView
|
|||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
@pragma("wasm:entry-point")
|
||||
final class _Float64x2ArrayView extends _TypedListView
|
||||
with _Float64x2ListMixin
|
||||
implements Float64x2List {
|
||||
|
@ -4855,7 +4829,6 @@ final class _Float64x2ArrayView extends _TypedListView
|
|||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
@pragma("wasm:entry-point")
|
||||
final class _ByteDataView implements ByteData {
|
||||
@pragma("vm:recognized", "other")
|
||||
@pragma("vm:exact-result-type", _ByteDataView)
|
||||
|
@ -5398,7 +5371,6 @@ abstract class UnmodifiableFloat64ListView implements Float64List {
|
|||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
@pragma("wasm:entry-point")
|
||||
final class _UnmodifiableInt8ArrayView extends _Int8ArrayView
|
||||
implements UnmodifiableInt8ListView {
|
||||
@pragma("vm:recognized", "other")
|
||||
|
@ -5415,7 +5387,6 @@ final class _UnmodifiableInt8ArrayView extends _Int8ArrayView
|
|||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
@pragma("wasm:entry-point")
|
||||
final class _UnmodifiableUint8ArrayView extends _Uint8ArrayView
|
||||
implements UnmodifiableUint8ListView {
|
||||
@pragma("vm:recognized", "other")
|
||||
|
@ -5432,7 +5403,6 @@ final class _UnmodifiableUint8ArrayView extends _Uint8ArrayView
|
|||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
@pragma("wasm:entry-point")
|
||||
final class _UnmodifiableUint8ClampedArrayView extends _Uint8ClampedArrayView
|
||||
implements UnmodifiableUint8ClampedListView {
|
||||
@pragma("vm:recognized", "other")
|
||||
|
@ -5449,7 +5419,6 @@ final class _UnmodifiableUint8ClampedArrayView extends _Uint8ClampedArrayView
|
|||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
@pragma("wasm:entry-point")
|
||||
final class _UnmodifiableInt16ArrayView extends _Int16ArrayView
|
||||
implements UnmodifiableInt16ListView {
|
||||
@pragma("vm:recognized", "other")
|
||||
|
@ -5466,7 +5435,6 @@ final class _UnmodifiableInt16ArrayView extends _Int16ArrayView
|
|||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
@pragma("wasm:entry-point")
|
||||
final class _UnmodifiableUint16ArrayView extends _Uint16ArrayView
|
||||
implements UnmodifiableUint16ListView {
|
||||
@pragma("vm:recognized", "other")
|
||||
|
@ -5483,7 +5451,6 @@ final class _UnmodifiableUint16ArrayView extends _Uint16ArrayView
|
|||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
@pragma("wasm:entry-point")
|
||||
final class _UnmodifiableInt32ArrayView extends _Int32ArrayView
|
||||
implements UnmodifiableInt32ListView {
|
||||
@pragma("vm:recognized", "other")
|
||||
|
@ -5500,7 +5467,6 @@ final class _UnmodifiableInt32ArrayView extends _Int32ArrayView
|
|||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
@pragma("wasm:entry-point")
|
||||
final class _UnmodifiableUint32ArrayView extends _Uint32ArrayView
|
||||
implements UnmodifiableUint32ListView {
|
||||
@pragma("vm:recognized", "other")
|
||||
|
@ -5517,7 +5483,6 @@ final class _UnmodifiableUint32ArrayView extends _Uint32ArrayView
|
|||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
@pragma("wasm:entry-point")
|
||||
final class _UnmodifiableInt64ArrayView extends _Int64ArrayView
|
||||
implements UnmodifiableInt64ListView {
|
||||
@pragma("vm:recognized", "other")
|
||||
|
@ -5534,7 +5499,6 @@ final class _UnmodifiableInt64ArrayView extends _Int64ArrayView
|
|||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
@pragma("wasm:entry-point")
|
||||
final class _UnmodifiableUint64ArrayView extends _Uint64ArrayView
|
||||
implements UnmodifiableUint64ListView {
|
||||
@pragma("vm:recognized", "other")
|
||||
|
@ -5551,7 +5515,6 @@ final class _UnmodifiableUint64ArrayView extends _Uint64ArrayView
|
|||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
@pragma("wasm:entry-point")
|
||||
final class _UnmodifiableFloat32ArrayView extends _Float32ArrayView
|
||||
implements UnmodifiableFloat32ListView {
|
||||
@pragma("vm:recognized", "other")
|
||||
|
@ -5568,7 +5531,6 @@ final class _UnmodifiableFloat32ArrayView extends _Float32ArrayView
|
|||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
@pragma("wasm:entry-point")
|
||||
final class _UnmodifiableFloat64ArrayView extends _Float64ArrayView
|
||||
implements UnmodifiableFloat64ListView {
|
||||
@pragma("vm:recognized", "other")
|
||||
|
@ -5585,7 +5547,6 @@ final class _UnmodifiableFloat64ArrayView extends _Float64ArrayView
|
|||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
@pragma("wasm:entry-point")
|
||||
final class _UnmodifiableFloat32x4ArrayView extends _Float32x4ArrayView
|
||||
implements UnmodifiableFloat32x4ListView {
|
||||
@pragma("vm:recognized", "other")
|
||||
|
@ -5602,7 +5563,6 @@ final class _UnmodifiableFloat32x4ArrayView extends _Float32x4ArrayView
|
|||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
@pragma("wasm:entry-point")
|
||||
final class _UnmodifiableInt32x4ArrayView extends _Int32x4ArrayView
|
||||
implements UnmodifiableInt32x4ListView {
|
||||
@pragma("vm:recognized", "other")
|
||||
|
@ -5619,7 +5579,6 @@ final class _UnmodifiableInt32x4ArrayView extends _Int32x4ArrayView
|
|||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
@pragma("wasm:entry-point")
|
||||
final class _UnmodifiableFloat64x2ArrayView extends _Float64x2ArrayView
|
||||
implements UnmodifiableFloat64x2ListView {
|
||||
@pragma("vm:recognized", "other")
|
||||
|
@ -5636,7 +5595,6 @@ final class _UnmodifiableFloat64x2ArrayView extends _Float64x2ArrayView
|
|||
}
|
||||
|
||||
@pragma("vm:entry-point")
|
||||
@pragma("wasm:entry-point")
|
||||
final class _UnmodifiableByteDataView extends _ByteDataView
|
||||
implements UnmodifiableByteDataView {
|
||||
@pragma("vm:recognized", "other")
|
||||
|
|
822
sdk/lib/_internal/wasm/lib/simd.dart
Normal file
822
sdk/lib/_internal/wasm/lib/simd.dart
Normal file
|
@ -0,0 +1,822 @@
|
|||
// Copyright (c) 2023, 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.
|
||||
|
||||
library dart._simd;
|
||||
|
||||
import 'dart:_internal' show FixedLengthListMixin, unsafeCast;
|
||||
|
||||
import 'dart:collection' show ListMixin;
|
||||
import 'dart:math' as math;
|
||||
import 'dart:typed_data';
|
||||
|
||||
final class NaiveInt32x4List extends Object
|
||||
with ListMixin<Int32x4>, FixedLengthListMixin<Int32x4>
|
||||
implements Int32x4List {
|
||||
final Int32List _storage;
|
||||
|
||||
NaiveInt32x4List(int length) : _storage = Int32List(length * 4);
|
||||
|
||||
NaiveInt32x4List.externalStorage(Int32List storage) : _storage = storage;
|
||||
|
||||
NaiveInt32x4List._slowFromList(List<Int32x4> list)
|
||||
: _storage = Int32List(list.length * 4) {
|
||||
for (int i = 0; i < list.length; i++) {
|
||||
var e = list[i];
|
||||
_storage[(i * 4) + 0] = e.x;
|
||||
_storage[(i * 4) + 1] = e.y;
|
||||
_storage[(i * 4) + 2] = e.z;
|
||||
_storage[(i * 4) + 3] = e.w;
|
||||
}
|
||||
}
|
||||
|
||||
factory NaiveInt32x4List.fromList(List<Int32x4> list) {
|
||||
if (list is NaiveInt32x4List) {
|
||||
return NaiveInt32x4List.externalStorage(
|
||||
Int32List.fromList(list._storage));
|
||||
} else {
|
||||
return NaiveInt32x4List._slowFromList(list);
|
||||
}
|
||||
}
|
||||
|
||||
ByteBuffer get buffer => _storage.buffer;
|
||||
|
||||
int get lengthInBytes => _storage.lengthInBytes;
|
||||
|
||||
int get offsetInBytes => _storage.offsetInBytes;
|
||||
|
||||
int get elementSizeInBytes => Int32x4List.bytesPerElement;
|
||||
|
||||
int get length => _storage.length ~/ 4;
|
||||
|
||||
Int32x4 operator [](int index) {
|
||||
IndexError.check(index, length, indexable: this, name: "[]");
|
||||
int _x = _storage[(index * 4) + 0];
|
||||
int _y = _storage[(index * 4) + 1];
|
||||
int _z = _storage[(index * 4) + 2];
|
||||
int _w = _storage[(index * 4) + 3];
|
||||
return NaiveInt32x4._truncated(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
void operator []=(int index, Int32x4 value) {
|
||||
IndexError.check(index, length, indexable: this, name: "[]=");
|
||||
_storage[(index * 4) + 0] = value.x;
|
||||
_storage[(index * 4) + 1] = value.y;
|
||||
_storage[(index * 4) + 2] = value.z;
|
||||
_storage[(index * 4) + 3] = value.w;
|
||||
}
|
||||
|
||||
Int32x4List sublist(int start, [int? end]) {
|
||||
int stop = RangeError.checkValidRange(start, end, length);
|
||||
return NaiveInt32x4List.externalStorage(
|
||||
_storage.sublist(start * 4, stop * 4));
|
||||
}
|
||||
}
|
||||
|
||||
final class NaiveUnmodifiableInt32x4List extends NaiveInt32x4List
|
||||
implements UnmodifiableInt32x4ListView {
|
||||
NaiveUnmodifiableInt32x4List(Int32x4List list)
|
||||
: super.externalStorage(unsafeCast<NaiveInt32x4List>(list)._storage);
|
||||
|
||||
NaiveUnmodifiableInt32x4List.externalStorage(Int32List storage)
|
||||
: super.externalStorage(storage);
|
||||
|
||||
@override
|
||||
void operator []=(int index, Int32x4 value) {
|
||||
throw new UnsupportedError("Cannot modify an unmodifiable list");
|
||||
}
|
||||
|
||||
@override
|
||||
ByteBuffer get buffer => UnmodifiableByteBufferView(super.buffer);
|
||||
}
|
||||
|
||||
final class NaiveFloat32x4List extends Object
|
||||
with ListMixin<Float32x4>, FixedLengthListMixin<Float32x4>
|
||||
implements Float32x4List {
|
||||
final Float32List _storage;
|
||||
|
||||
NaiveFloat32x4List(int length) : _storage = Float32List(length * 4);
|
||||
|
||||
NaiveFloat32x4List.externalStorage(this._storage);
|
||||
|
||||
NaiveFloat32x4List._slowFromList(List<Float32x4> list)
|
||||
: _storage = Float32List(list.length * 4) {
|
||||
for (int i = 0; i < list.length; i++) {
|
||||
var e = list[i];
|
||||
_storage[(i * 4) + 0] = e.x;
|
||||
_storage[(i * 4) + 1] = e.y;
|
||||
_storage[(i * 4) + 2] = e.z;
|
||||
_storage[(i * 4) + 3] = e.w;
|
||||
}
|
||||
}
|
||||
|
||||
factory NaiveFloat32x4List.fromList(List<Float32x4> list) {
|
||||
if (list is NaiveFloat32x4List) {
|
||||
return NaiveFloat32x4List.externalStorage(
|
||||
Float32List.fromList(list._storage));
|
||||
} else {
|
||||
return NaiveFloat32x4List._slowFromList(list);
|
||||
}
|
||||
}
|
||||
|
||||
ByteBuffer get buffer => _storage.buffer;
|
||||
|
||||
int get lengthInBytes => _storage.lengthInBytes;
|
||||
|
||||
int get offsetInBytes => _storage.offsetInBytes;
|
||||
|
||||
int get elementSizeInBytes => Float32x4List.bytesPerElement;
|
||||
|
||||
int get length => _storage.length ~/ 4;
|
||||
|
||||
Float32x4 operator [](int index) {
|
||||
IndexError.check(index, length, indexable: this, name: "[]");
|
||||
double _x = _storage[(index * 4) + 0];
|
||||
double _y = _storage[(index * 4) + 1];
|
||||
double _z = _storage[(index * 4) + 2];
|
||||
double _w = _storage[(index * 4) + 3];
|
||||
return NaiveFloat32x4._truncated(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
void operator []=(int index, Float32x4 value) {
|
||||
IndexError.check(index, length, indexable: this, name: "[]=");
|
||||
_storage[(index * 4) + 0] = value.x;
|
||||
_storage[(index * 4) + 1] = value.y;
|
||||
_storage[(index * 4) + 2] = value.z;
|
||||
_storage[(index * 4) + 3] = value.w;
|
||||
}
|
||||
|
||||
Float32x4List sublist(int start, [int? end]) {
|
||||
int stop = RangeError.checkValidRange(start, end, length);
|
||||
return NaiveFloat32x4List.externalStorage(
|
||||
_storage.sublist(start * 4, stop * 4));
|
||||
}
|
||||
}
|
||||
|
||||
final class NaiveUnmodifiableFloat32x4List extends NaiveFloat32x4List
|
||||
implements UnmodifiableFloat32x4ListView {
|
||||
NaiveUnmodifiableFloat32x4List(Float32x4List list)
|
||||
: super.externalStorage(unsafeCast<NaiveFloat32x4List>(list)._storage);
|
||||
|
||||
NaiveUnmodifiableFloat32x4List.externalStorage(Float32List storage)
|
||||
: super.externalStorage(storage);
|
||||
|
||||
@override
|
||||
void operator []=(int index, Float32x4 value) {
|
||||
throw new UnsupportedError("Cannot modify an unmodifiable list");
|
||||
}
|
||||
|
||||
@override
|
||||
ByteBuffer get buffer => UnmodifiableByteBufferView(super.buffer);
|
||||
}
|
||||
|
||||
final class NaiveFloat64x2List extends Object
|
||||
with ListMixin<Float64x2>, FixedLengthListMixin<Float64x2>
|
||||
implements Float64x2List {
|
||||
final Float64List _storage;
|
||||
|
||||
NaiveFloat64x2List(int length) : _storage = Float64List(length * 2);
|
||||
|
||||
NaiveFloat64x2List.externalStorage(this._storage);
|
||||
|
||||
NaiveFloat64x2List._slowFromList(List<Float64x2> list)
|
||||
: _storage = Float64List(list.length * 2) {
|
||||
for (int i = 0; i < list.length; i++) {
|
||||
var e = list[i];
|
||||
_storage[(i * 2) + 0] = e.x;
|
||||
_storage[(i * 2) + 1] = e.y;
|
||||
}
|
||||
}
|
||||
|
||||
factory NaiveFloat64x2List.fromList(List<Float64x2> list) {
|
||||
if (list is NaiveFloat64x2List) {
|
||||
return NaiveFloat64x2List.externalStorage(
|
||||
Float64List.fromList(list._storage));
|
||||
} else {
|
||||
return NaiveFloat64x2List._slowFromList(list);
|
||||
}
|
||||
}
|
||||
|
||||
ByteBuffer get buffer => _storage.buffer;
|
||||
|
||||
int get lengthInBytes => _storage.lengthInBytes;
|
||||
|
||||
int get offsetInBytes => _storage.offsetInBytes;
|
||||
|
||||
int get elementSizeInBytes => Float64x2List.bytesPerElement;
|
||||
|
||||
int get length => _storage.length ~/ 2;
|
||||
|
||||
Float64x2 operator [](int index) {
|
||||
IndexError.check(index, length, indexable: this, name: "[]");
|
||||
double _x = _storage[(index * 2) + 0];
|
||||
double _y = _storage[(index * 2) + 1];
|
||||
return Float64x2(_x, _y);
|
||||
}
|
||||
|
||||
void operator []=(int index, Float64x2 value) {
|
||||
IndexError.check(index, length, indexable: this, name: "[]=");
|
||||
_storage[(index * 2) + 0] = value.x;
|
||||
_storage[(index * 2) + 1] = value.y;
|
||||
}
|
||||
|
||||
Float64x2List sublist(int start, [int? end]) {
|
||||
int stop = RangeError.checkValidRange(start, end, length);
|
||||
return NaiveFloat64x2List.externalStorage(
|
||||
_storage.sublist(start * 2, stop * 2));
|
||||
}
|
||||
}
|
||||
|
||||
final class NaiveUnmodifiableFloat64x2List extends NaiveFloat64x2List
|
||||
implements UnmodifiableFloat64x2ListView {
|
||||
NaiveUnmodifiableFloat64x2List(Float64x2List list)
|
||||
: super.externalStorage(unsafeCast<NaiveFloat64x2List>(list)._storage);
|
||||
|
||||
NaiveUnmodifiableFloat64x2List.externalStorage(Float64List storage)
|
||||
: super.externalStorage(storage);
|
||||
|
||||
@override
|
||||
void operator []=(int index, Float64x2 value) {
|
||||
throw new UnsupportedError("Cannot modify an unmodifiable list");
|
||||
}
|
||||
|
||||
@override
|
||||
ByteBuffer get buffer => UnmodifiableByteBufferView(super.buffer);
|
||||
}
|
||||
|
||||
final class NaiveFloat32x4 implements Float32x4 {
|
||||
final double x;
|
||||
final double y;
|
||||
final double z;
|
||||
final double w;
|
||||
|
||||
static final Float32List _list = Float32List(4);
|
||||
static final Uint32List _uint32view = _list.buffer.asUint32List();
|
||||
|
||||
static double _truncate(x) {
|
||||
_list[0] = x;
|
||||
return _list[0];
|
||||
}
|
||||
|
||||
NaiveFloat32x4(double x, double y, double z, double w)
|
||||
: this.x = _truncate(x),
|
||||
this.y = _truncate(y),
|
||||
this.z = _truncate(z),
|
||||
this.w = _truncate(w);
|
||||
|
||||
NaiveFloat32x4.splat(double v) : this(v, v, v, v);
|
||||
NaiveFloat32x4.zero() : this._truncated(0.0, 0.0, 0.0, 0.0);
|
||||
|
||||
factory NaiveFloat32x4.fromInt32x4Bits(Int32x4 i) {
|
||||
_uint32view[0] = i.x;
|
||||
_uint32view[1] = i.y;
|
||||
_uint32view[2] = i.z;
|
||||
_uint32view[3] = i.w;
|
||||
return NaiveFloat32x4._truncated(_list[0], _list[1], _list[2], _list[3]);
|
||||
}
|
||||
|
||||
NaiveFloat32x4.fromFloat64x2(Float64x2 v)
|
||||
: this._truncated(_truncate(v.x), _truncate(v.y), 0.0, 0.0);
|
||||
|
||||
NaiveFloat32x4._doubles(double x, double y, double z, double w)
|
||||
: this.x = _truncate(x),
|
||||
this.y = _truncate(y),
|
||||
this.z = _truncate(z),
|
||||
this.w = _truncate(w);
|
||||
|
||||
NaiveFloat32x4._truncated(this.x, this.y, this.z, this.w);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return '[${x.toStringAsFixed(6)}, '
|
||||
'${y.toStringAsFixed(6)}, '
|
||||
'${z.toStringAsFixed(6)}, '
|
||||
'${w.toStringAsFixed(6)}]';
|
||||
}
|
||||
|
||||
Float32x4 operator +(Float32x4 other) {
|
||||
double _x = x + other.x;
|
||||
double _y = y + other.y;
|
||||
double _z = z + other.z;
|
||||
double _w = w + other.w;
|
||||
return NaiveFloat32x4._doubles(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
Float32x4 operator -() {
|
||||
return NaiveFloat32x4._truncated(-x, -y, -z, -w);
|
||||
}
|
||||
|
||||
Float32x4 operator -(Float32x4 other) {
|
||||
double _x = x - other.x;
|
||||
double _y = y - other.y;
|
||||
double _z = z - other.z;
|
||||
double _w = w - other.w;
|
||||
return NaiveFloat32x4._doubles(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
Float32x4 operator *(Float32x4 other) {
|
||||
double _x = x * other.x;
|
||||
double _y = y * other.y;
|
||||
double _z = z * other.z;
|
||||
double _w = w * other.w;
|
||||
return NaiveFloat32x4._doubles(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
Float32x4 operator /(Float32x4 other) {
|
||||
double _x = x / other.x;
|
||||
double _y = y / other.y;
|
||||
double _z = z / other.z;
|
||||
double _w = w / other.w;
|
||||
return NaiveFloat32x4._doubles(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
Int32x4 lessThan(Float32x4 other) {
|
||||
bool _cx = x < other.x;
|
||||
bool _cy = y < other.y;
|
||||
bool _cz = z < other.z;
|
||||
bool _cw = w < other.w;
|
||||
return NaiveInt32x4._truncated(
|
||||
_cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0);
|
||||
}
|
||||
|
||||
Int32x4 lessThanOrEqual(Float32x4 other) {
|
||||
bool _cx = x <= other.x;
|
||||
bool _cy = y <= other.y;
|
||||
bool _cz = z <= other.z;
|
||||
bool _cw = w <= other.w;
|
||||
return NaiveInt32x4._truncated(
|
||||
_cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0);
|
||||
}
|
||||
|
||||
Int32x4 greaterThan(Float32x4 other) {
|
||||
bool _cx = x > other.x;
|
||||
bool _cy = y > other.y;
|
||||
bool _cz = z > other.z;
|
||||
bool _cw = w > other.w;
|
||||
return NaiveInt32x4._truncated(
|
||||
_cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0);
|
||||
}
|
||||
|
||||
Int32x4 greaterThanOrEqual(Float32x4 other) {
|
||||
bool _cx = x >= other.x;
|
||||
bool _cy = y >= other.y;
|
||||
bool _cz = z >= other.z;
|
||||
bool _cw = w >= other.w;
|
||||
return NaiveInt32x4._truncated(
|
||||
_cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0);
|
||||
}
|
||||
|
||||
Int32x4 equal(Float32x4 other) {
|
||||
bool _cx = x == other.x;
|
||||
bool _cy = y == other.y;
|
||||
bool _cz = z == other.z;
|
||||
bool _cw = w == other.w;
|
||||
return NaiveInt32x4._truncated(
|
||||
_cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0);
|
||||
}
|
||||
|
||||
Int32x4 notEqual(Float32x4 other) {
|
||||
bool _cx = x != other.x;
|
||||
bool _cy = y != other.y;
|
||||
bool _cz = z != other.z;
|
||||
bool _cw = w != other.w;
|
||||
return NaiveInt32x4._truncated(
|
||||
_cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0);
|
||||
}
|
||||
|
||||
Float32x4 scale(double s) {
|
||||
double _x = s * x;
|
||||
double _y = s * y;
|
||||
double _z = s * z;
|
||||
double _w = s * w;
|
||||
return NaiveFloat32x4._doubles(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
Float32x4 abs() {
|
||||
double _x = x.abs();
|
||||
double _y = y.abs();
|
||||
double _z = z.abs();
|
||||
double _w = w.abs();
|
||||
return NaiveFloat32x4._truncated(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
Float32x4 clamp(Float32x4 lowerLimit, Float32x4 upperLimit) {
|
||||
double _lx = lowerLimit.x;
|
||||
double _ly = lowerLimit.y;
|
||||
double _lz = lowerLimit.z;
|
||||
double _lw = lowerLimit.w;
|
||||
double _ux = upperLimit.x;
|
||||
double _uy = upperLimit.y;
|
||||
double _uz = upperLimit.z;
|
||||
double _uw = upperLimit.w;
|
||||
double _x = x;
|
||||
double _y = y;
|
||||
double _z = z;
|
||||
double _w = w;
|
||||
// MAX(MIN(self, upper), lower).
|
||||
_x = _x > _ux ? _ux : _x;
|
||||
_y = _y > _uy ? _uy : _y;
|
||||
_z = _z > _uz ? _uz : _z;
|
||||
_w = _w > _uw ? _uw : _w;
|
||||
_x = _x < _lx ? _lx : _x;
|
||||
_y = _y < _ly ? _ly : _y;
|
||||
_z = _z < _lz ? _lz : _z;
|
||||
_w = _w < _lw ? _lw : _w;
|
||||
return NaiveFloat32x4._truncated(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
int get signMask {
|
||||
var view = _uint32view;
|
||||
int mx, my, mz, mw;
|
||||
_list[0] = x;
|
||||
_list[1] = y;
|
||||
_list[2] = z;
|
||||
_list[3] = w;
|
||||
mx = (view[0] & 0x80000000) >> 31;
|
||||
my = (view[1] & 0x80000000) >> 30;
|
||||
mz = (view[2] & 0x80000000) >> 29;
|
||||
mw = (view[3] & 0x80000000) >> 28;
|
||||
return mx | my | mz | mw;
|
||||
}
|
||||
|
||||
Float32x4 shuffle(int mask) {
|
||||
if ((mask < 0) || (mask > 255)) {
|
||||
throw RangeError.range(mask, 0, 255, 'mask');
|
||||
}
|
||||
_list[0] = x;
|
||||
_list[1] = y;
|
||||
_list[2] = z;
|
||||
_list[3] = w;
|
||||
|
||||
double _x = _list[mask & 0x3];
|
||||
double _y = _list[(mask >> 2) & 0x3];
|
||||
double _z = _list[(mask >> 4) & 0x3];
|
||||
double _w = _list[(mask >> 6) & 0x3];
|
||||
return NaiveFloat32x4._truncated(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
Float32x4 shuffleMix(Float32x4 other, int mask) {
|
||||
if ((mask < 0) || (mask > 255)) {
|
||||
throw RangeError.range(mask, 0, 255, 'mask');
|
||||
}
|
||||
_list[0] = x;
|
||||
_list[1] = y;
|
||||
_list[2] = z;
|
||||
_list[3] = w;
|
||||
double _x = _list[mask & 0x3];
|
||||
double _y = _list[(mask >> 2) & 0x3];
|
||||
|
||||
_list[0] = other.x;
|
||||
_list[1] = other.y;
|
||||
_list[2] = other.z;
|
||||
_list[3] = other.w;
|
||||
double _z = _list[(mask >> 4) & 0x3];
|
||||
double _w = _list[(mask >> 6) & 0x3];
|
||||
return NaiveFloat32x4._truncated(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
Float32x4 withX(double newX) {
|
||||
double _newX = _truncate(newX);
|
||||
return NaiveFloat32x4._truncated(_newX, y, z, w);
|
||||
}
|
||||
|
||||
Float32x4 withY(double newY) {
|
||||
double _newY = _truncate(newY);
|
||||
return NaiveFloat32x4._truncated(x, _newY, z, w);
|
||||
}
|
||||
|
||||
Float32x4 withZ(double newZ) {
|
||||
double _newZ = _truncate(newZ);
|
||||
return NaiveFloat32x4._truncated(x, y, _newZ, w);
|
||||
}
|
||||
|
||||
Float32x4 withW(double newW) {
|
||||
double _newW = _truncate(newW);
|
||||
return NaiveFloat32x4._truncated(x, y, z, _newW);
|
||||
}
|
||||
|
||||
Float32x4 min(Float32x4 other) {
|
||||
double _x = x < other.x ? x : other.x;
|
||||
double _y = y < other.y ? y : other.y;
|
||||
double _z = z < other.z ? z : other.z;
|
||||
double _w = w < other.w ? w : other.w;
|
||||
return NaiveFloat32x4._truncated(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
Float32x4 max(Float32x4 other) {
|
||||
double _x = x > other.x ? x : other.x;
|
||||
double _y = y > other.y ? y : other.y;
|
||||
double _z = z > other.z ? z : other.z;
|
||||
double _w = w > other.w ? w : other.w;
|
||||
return NaiveFloat32x4._truncated(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
Float32x4 sqrt() {
|
||||
double _x = math.sqrt(x);
|
||||
double _y = math.sqrt(y);
|
||||
double _z = math.sqrt(z);
|
||||
double _w = math.sqrt(w);
|
||||
return NaiveFloat32x4._doubles(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
Float32x4 reciprocal() {
|
||||
double _x = 1.0 / x;
|
||||
double _y = 1.0 / y;
|
||||
double _z = 1.0 / z;
|
||||
double _w = 1.0 / w;
|
||||
return NaiveFloat32x4._doubles(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
Float32x4 reciprocalSqrt() {
|
||||
double _x = math.sqrt(1.0 / x);
|
||||
double _y = math.sqrt(1.0 / y);
|
||||
double _z = math.sqrt(1.0 / z);
|
||||
double _w = math.sqrt(1.0 / w);
|
||||
return NaiveFloat32x4._doubles(_x, _y, _z, _w);
|
||||
}
|
||||
}
|
||||
|
||||
final class NaiveFloat64x2 implements Float64x2 {
|
||||
final double x;
|
||||
final double y;
|
||||
|
||||
static Float64List _list = Float64List(2);
|
||||
static Uint32List _uint32View = _list.buffer.asUint32List();
|
||||
|
||||
NaiveFloat64x2(this.x, this.y);
|
||||
|
||||
NaiveFloat64x2.splat(double v) : this(v, v);
|
||||
|
||||
NaiveFloat64x2.zero() : this.splat(0.0);
|
||||
|
||||
NaiveFloat64x2.fromFloat32x4(Float32x4 v) : this(v.x, v.y);
|
||||
|
||||
NaiveFloat64x2._doubles(this.x, this.y);
|
||||
|
||||
String toString() => '[$x, $y]';
|
||||
|
||||
Float64x2 operator +(Float64x2 other) =>
|
||||
NaiveFloat64x2._doubles(x + other.x, y + other.y);
|
||||
|
||||
Float64x2 operator -() => NaiveFloat64x2._doubles(-x, -y);
|
||||
|
||||
Float64x2 operator -(Float64x2 other) =>
|
||||
NaiveFloat64x2._doubles(x - other.x, y - other.y);
|
||||
|
||||
Float64x2 operator *(Float64x2 other) =>
|
||||
NaiveFloat64x2._doubles(x * other.x, y * other.y);
|
||||
|
||||
Float64x2 operator /(Float64x2 other) =>
|
||||
NaiveFloat64x2._doubles(x / other.x, y / other.y);
|
||||
|
||||
Float64x2 scale(double s) => NaiveFloat64x2._doubles(x * s, y * s);
|
||||
|
||||
Float64x2 abs() => NaiveFloat64x2._doubles(x.abs(), y.abs());
|
||||
|
||||
Float64x2 clamp(Float64x2 lowerLimit, Float64x2 upperLimit) {
|
||||
double _lx = lowerLimit.x;
|
||||
double _ly = lowerLimit.y;
|
||||
double _ux = upperLimit.x;
|
||||
double _uy = upperLimit.y;
|
||||
double _x = x;
|
||||
double _y = y;
|
||||
// MAX(MIN(self, upper), lower).
|
||||
_x = _x > _ux ? _ux : _x;
|
||||
_y = _y > _uy ? _uy : _y;
|
||||
_x = _x < _lx ? _lx : _x;
|
||||
_y = _y < _ly ? _ly : _y;
|
||||
return NaiveFloat64x2._doubles(_x, _y);
|
||||
}
|
||||
|
||||
int get signMask {
|
||||
var view = _uint32View;
|
||||
_list[0] = x;
|
||||
_list[1] = y;
|
||||
var mx = (view[1] & 0x80000000) >> 31;
|
||||
var my = (view[3] & 0x80000000) >> 31;
|
||||
return mx | my << 1;
|
||||
}
|
||||
|
||||
Float64x2 withX(double x) => NaiveFloat64x2._doubles(x, y);
|
||||
|
||||
Float64x2 withY(double y) => NaiveFloat64x2._doubles(x, y);
|
||||
|
||||
Float64x2 min(Float64x2 other) => NaiveFloat64x2._doubles(
|
||||
x < other.x ? x : other.x, y < other.y ? y : other.y);
|
||||
|
||||
Float64x2 max(Float64x2 other) => NaiveFloat64x2._doubles(
|
||||
x > other.x ? x : other.x, y > other.y ? y : other.y);
|
||||
|
||||
Float64x2 sqrt() => NaiveFloat64x2._doubles(math.sqrt(x), math.sqrt(y));
|
||||
}
|
||||
|
||||
final class NaiveInt32x4 implements Int32x4 {
|
||||
final int x;
|
||||
final int y;
|
||||
final int z;
|
||||
final int w;
|
||||
|
||||
static final Int32List _list = Int32List(4);
|
||||
|
||||
static int _truncate(x) {
|
||||
_list[0] = x;
|
||||
return _list[0];
|
||||
}
|
||||
|
||||
NaiveInt32x4(int x, int y, int z, int w)
|
||||
: this.x = _truncate(x),
|
||||
this.y = _truncate(y),
|
||||
this.z = _truncate(z),
|
||||
this.w = _truncate(w);
|
||||
|
||||
NaiveInt32x4.bool(bool x, bool y, bool z, bool w)
|
||||
: this.x = x ? -1 : 0,
|
||||
this.y = y ? -1 : 0,
|
||||
this.z = z ? -1 : 0,
|
||||
this.w = w ? -1 : 0;
|
||||
|
||||
factory NaiveInt32x4.fromFloat32x4Bits(Float32x4 f) {
|
||||
Float32List floatList = NaiveFloat32x4._list;
|
||||
floatList[0] = f.x;
|
||||
floatList[1] = f.y;
|
||||
floatList[2] = f.z;
|
||||
floatList[3] = f.w;
|
||||
var view = floatList.buffer.asInt32List();
|
||||
return NaiveInt32x4._truncated(view[0], view[1], view[2], view[3]);
|
||||
}
|
||||
|
||||
NaiveInt32x4._truncated(this.x, this.y, this.z, this.w);
|
||||
|
||||
String toString() => '[${_int32ToHex(x)}, ${_int32ToHex(y)}, '
|
||||
'${_int32ToHex(z)}, ${_int32ToHex(w)}]';
|
||||
|
||||
Int32x4 operator |(Int32x4 other) {
|
||||
int _x = x | other.x;
|
||||
int _y = y | other.y;
|
||||
int _z = z | other.z;
|
||||
int _w = w | other.w;
|
||||
return NaiveInt32x4._truncated(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
Int32x4 operator &(Int32x4 other) {
|
||||
int _x = x & other.x;
|
||||
int _y = y & other.y;
|
||||
int _z = z & other.z;
|
||||
int _w = w & other.w;
|
||||
return NaiveInt32x4._truncated(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
Int32x4 operator ^(Int32x4 other) {
|
||||
int _x = x ^ other.x;
|
||||
int _y = y ^ other.y;
|
||||
int _z = z ^ other.z;
|
||||
int _w = w ^ other.w;
|
||||
return NaiveInt32x4._truncated(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
Int32x4 operator +(Int32x4 other) {
|
||||
int _x = x + other.x;
|
||||
int _y = y + other.y;
|
||||
int _z = z + other.z;
|
||||
int _w = w + other.w;
|
||||
return NaiveInt32x4._truncated(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
Int32x4 operator -(Int32x4 other) {
|
||||
int _x = x - other.x;
|
||||
int _y = y - other.y;
|
||||
int _z = z - other.z;
|
||||
int _w = w - other.w;
|
||||
return NaiveInt32x4._truncated(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
Int32x4 operator -() {
|
||||
return NaiveInt32x4._truncated(-x, -y, -z, -w);
|
||||
}
|
||||
|
||||
int get signMask {
|
||||
int mx = (x & 0x80000000) >> 31;
|
||||
int my = (y & 0x80000000) >> 31;
|
||||
int mz = (z & 0x80000000) >> 31;
|
||||
int mw = (w & 0x80000000) >> 31;
|
||||
return mx | my << 1 | mz << 2 | mw << 3;
|
||||
}
|
||||
|
||||
Int32x4 shuffle(int mask) {
|
||||
if ((mask < 0) || (mask > 255)) {
|
||||
throw RangeError.range(mask, 0, 255, 'mask');
|
||||
}
|
||||
_list[0] = x;
|
||||
_list[1] = y;
|
||||
_list[2] = z;
|
||||
_list[3] = w;
|
||||
int _x = _list[mask & 0x3];
|
||||
int _y = _list[(mask >> 2) & 0x3];
|
||||
int _z = _list[(mask >> 4) & 0x3];
|
||||
int _w = _list[(mask >> 6) & 0x3];
|
||||
return NaiveInt32x4._truncated(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
Int32x4 shuffleMix(Int32x4 other, int mask) {
|
||||
if ((mask < 0) || (mask > 255)) {
|
||||
throw RangeError.range(mask, 0, 255, 'mask');
|
||||
}
|
||||
_list[0] = x;
|
||||
_list[1] = y;
|
||||
_list[2] = z;
|
||||
_list[3] = w;
|
||||
int _x = _list[mask & 0x3];
|
||||
int _y = _list[(mask >> 2) & 0x3];
|
||||
|
||||
_list[0] = other.x;
|
||||
_list[1] = other.y;
|
||||
_list[2] = other.z;
|
||||
_list[3] = other.w;
|
||||
int _z = _list[(mask >> 4) & 0x3];
|
||||
int _w = _list[(mask >> 6) & 0x3];
|
||||
return NaiveInt32x4._truncated(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
Int32x4 withX(int x) {
|
||||
int _x = _truncate(x);
|
||||
return NaiveInt32x4._truncated(_x, y, z, w);
|
||||
}
|
||||
|
||||
Int32x4 withY(int y) {
|
||||
int _y = _truncate(y);
|
||||
return NaiveInt32x4._truncated(x, _y, z, w);
|
||||
}
|
||||
|
||||
Int32x4 withZ(int z) {
|
||||
int _z = _truncate(z);
|
||||
return NaiveInt32x4._truncated(x, y, _z, w);
|
||||
}
|
||||
|
||||
Int32x4 withW(int w) {
|
||||
int _w = _truncate(w);
|
||||
return NaiveInt32x4._truncated(x, y, z, _w);
|
||||
}
|
||||
|
||||
bool get flagX => x != 0;
|
||||
|
||||
bool get flagY => y != 0;
|
||||
|
||||
bool get flagZ => z != 0;
|
||||
|
||||
bool get flagW => w != 0;
|
||||
|
||||
Int32x4 withFlagX(bool flagX) {
|
||||
int _x = flagX ? -1 : 0;
|
||||
return NaiveInt32x4._truncated(_x, y, z, w);
|
||||
}
|
||||
|
||||
Int32x4 withFlagY(bool flagY) {
|
||||
int _y = flagY ? -1 : 0;
|
||||
return NaiveInt32x4._truncated(x, _y, z, w);
|
||||
}
|
||||
|
||||
Int32x4 withFlagZ(bool flagZ) {
|
||||
int _z = flagZ ? -1 : 0;
|
||||
return NaiveInt32x4._truncated(x, y, _z, w);
|
||||
}
|
||||
|
||||
Int32x4 withFlagW(bool flagW) {
|
||||
int _w = flagW ? -1 : 0;
|
||||
return NaiveInt32x4._truncated(x, y, z, _w);
|
||||
}
|
||||
|
||||
Float32x4 select(Float32x4 trueValue, Float32x4 falseValue) {
|
||||
var floatList = NaiveFloat32x4._list;
|
||||
var intView = NaiveFloat32x4._uint32view;
|
||||
|
||||
floatList[0] = trueValue.x;
|
||||
floatList[1] = trueValue.y;
|
||||
floatList[2] = trueValue.z;
|
||||
floatList[3] = trueValue.w;
|
||||
int stx = intView[0];
|
||||
int sty = intView[1];
|
||||
int stz = intView[2];
|
||||
int stw = intView[3];
|
||||
|
||||
floatList[0] = falseValue.x;
|
||||
floatList[1] = falseValue.y;
|
||||
floatList[2] = falseValue.z;
|
||||
floatList[3] = falseValue.w;
|
||||
int sfx = intView[0];
|
||||
int sfy = intView[1];
|
||||
int sfz = intView[2];
|
||||
int sfw = intView[3];
|
||||
int _x = (x & stx) | (~x & sfx);
|
||||
int _y = (y & sty) | (~y & sfy);
|
||||
int _z = (z & stz) | (~z & sfz);
|
||||
int _w = (w & stw) | (~w & sfw);
|
||||
intView[0] = _x;
|
||||
intView[1] = _y;
|
||||
intView[2] = _z;
|
||||
intView[3] = _w;
|
||||
return NaiveFloat32x4._truncated(
|
||||
floatList[0], floatList[1], floatList[2], floatList[3]);
|
||||
}
|
||||
}
|
||||
|
||||
String _int32ToHex(int i) => i.toRadixString(16).padLeft(8, '0');
|
|
@ -2,8 +2,9 @@
|
|||
// 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 patch, FixedLengthListMixin;
|
||||
import 'dart:_simd';
|
||||
import 'dart:collection' show ListMixin;
|
||||
import 'dart:_internal' show patch, FixedLengthListMixin, unsafeCast;
|
||||
import 'dart:math' as math;
|
||||
|
||||
// These are naive patches for SIMD typed data which we can use until Wasm
|
||||
|
@ -13,859 +14,96 @@ import 'dart:math' as math;
|
|||
@patch
|
||||
class Int32x4List {
|
||||
@patch
|
||||
factory Int32x4List(int length) = _NaiveInt32x4List;
|
||||
factory Int32x4List(int length) = NaiveInt32x4List;
|
||||
|
||||
@patch
|
||||
factory Int32x4List.fromList(List<Int32x4> elements) =
|
||||
_NaiveInt32x4List.fromList;
|
||||
NaiveInt32x4List.fromList;
|
||||
}
|
||||
|
||||
@patch
|
||||
class Float32x4List {
|
||||
@patch
|
||||
factory Float32x4List(int length) = _NaiveFloat32x4List;
|
||||
factory Float32x4List(int length) = NaiveFloat32x4List;
|
||||
|
||||
@patch
|
||||
factory Float32x4List.fromList(List<Float32x4> elements) =
|
||||
_NaiveFloat32x4List.fromList;
|
||||
NaiveFloat32x4List.fromList;
|
||||
}
|
||||
|
||||
@patch
|
||||
class Float64x2List {
|
||||
@patch
|
||||
factory Float64x2List(int length) = _NaiveFloat64x2List;
|
||||
factory Float64x2List(int length) = NaiveFloat64x2List;
|
||||
|
||||
@patch
|
||||
factory Float64x2List.fromList(List<Float64x2> elements) =
|
||||
_NaiveFloat64x2List.fromList;
|
||||
NaiveFloat64x2List.fromList;
|
||||
}
|
||||
|
||||
@patch
|
||||
abstract class UnmodifiableInt32x4ListView implements Int32x4List {
|
||||
@patch
|
||||
factory UnmodifiableInt32x4ListView(Int32x4List list) =>
|
||||
new _UnmodifiableInt32x4ArrayView._(
|
||||
unsafeCast<_TypedList>(unsafeCast<_NaiveInt32x4List>(list)._storage),
|
||||
list.offsetInBytes,
|
||||
list.length);
|
||||
NaiveUnmodifiableInt32x4List(list);
|
||||
}
|
||||
|
||||
@patch
|
||||
abstract class UnmodifiableFloat32x4ListView implements Float32x4List {
|
||||
@patch
|
||||
factory UnmodifiableFloat32x4ListView(Float32x4List list) =>
|
||||
new _UnmodifiableFloat32x4ArrayView._(
|
||||
unsafeCast<_TypedList>(
|
||||
unsafeCast<_NaiveFloat32x4List>(list)._storage),
|
||||
list.offsetInBytes,
|
||||
list.length);
|
||||
NaiveUnmodifiableFloat32x4List(list);
|
||||
}
|
||||
|
||||
@patch
|
||||
abstract class UnmodifiableFloat64x2ListView implements Float64x2List {
|
||||
@patch
|
||||
factory UnmodifiableFloat64x2ListView(Float64x2List list) =>
|
||||
new _UnmodifiableFloat64x2ArrayView._(
|
||||
unsafeCast<_TypedList>(
|
||||
unsafeCast<_NaiveFloat64x2List>(list)._storage),
|
||||
list.offsetInBytes,
|
||||
list.length);
|
||||
NaiveUnmodifiableFloat64x2List(list);
|
||||
}
|
||||
|
||||
@patch
|
||||
class Int32x4 {
|
||||
@patch
|
||||
factory Int32x4(int x, int y, int z, int w) = _NaiveInt32x4;
|
||||
factory Int32x4(int x, int y, int z, int w) = NaiveInt32x4;
|
||||
|
||||
@patch
|
||||
factory Int32x4.bool(bool x, bool y, bool z, bool w) = _NaiveInt32x4.bool;
|
||||
factory Int32x4.bool(bool x, bool y, bool z, bool w) = NaiveInt32x4.bool;
|
||||
|
||||
@patch
|
||||
factory Int32x4.fromFloat32x4Bits(Float32x4 x) =
|
||||
_NaiveInt32x4.fromFloat32x4Bits;
|
||||
NaiveInt32x4.fromFloat32x4Bits;
|
||||
}
|
||||
|
||||
@patch
|
||||
class Float32x4 {
|
||||
@patch
|
||||
factory Float32x4(double x, double y, double z, double w) = _NaiveFloat32x4;
|
||||
factory Float32x4(double x, double y, double z, double w) = NaiveFloat32x4;
|
||||
|
||||
@patch
|
||||
factory Float32x4.splat(double v) = _NaiveFloat32x4.splat;
|
||||
factory Float32x4.splat(double v) = NaiveFloat32x4.splat;
|
||||
|
||||
@patch
|
||||
factory Float32x4.zero() = _NaiveFloat32x4.zero;
|
||||
factory Float32x4.zero() = NaiveFloat32x4.zero;
|
||||
|
||||
@patch
|
||||
factory Float32x4.fromInt32x4Bits(Int32x4 x) =
|
||||
_NaiveFloat32x4.fromInt32x4Bits;
|
||||
factory Float32x4.fromInt32x4Bits(Int32x4 x) = NaiveFloat32x4.fromInt32x4Bits;
|
||||
|
||||
@patch
|
||||
factory Float32x4.fromFloat64x2(Float64x2 v) = _NaiveFloat32x4.fromFloat64x2;
|
||||
factory Float32x4.fromFloat64x2(Float64x2 v) = NaiveFloat32x4.fromFloat64x2;
|
||||
}
|
||||
|
||||
@patch
|
||||
class Float64x2 {
|
||||
@patch
|
||||
factory Float64x2(double x, double y) = _NaiveFloat64x2;
|
||||
factory Float64x2(double x, double y) = NaiveFloat64x2;
|
||||
|
||||
@patch
|
||||
factory Float64x2.splat(double v) = _NaiveFloat64x2.splat;
|
||||
factory Float64x2.splat(double v) = NaiveFloat64x2.splat;
|
||||
|
||||
@patch
|
||||
factory Float64x2.zero() = _NaiveFloat64x2.zero;
|
||||
factory Float64x2.zero() = NaiveFloat64x2.zero;
|
||||
|
||||
@patch
|
||||
factory Float64x2.fromFloat32x4(Float32x4 v) = _NaiveFloat64x2.fromFloat32x4;
|
||||
factory Float64x2.fromFloat32x4(Float32x4 v) = NaiveFloat64x2.fromFloat32x4;
|
||||
}
|
||||
|
||||
final class _NaiveInt32x4List extends Object
|
||||
with ListMixin<Int32x4>, FixedLengthListMixin<Int32x4>
|
||||
implements Int32x4List {
|
||||
final Int32List _storage;
|
||||
|
||||
_NaiveInt32x4List(int length) : _storage = Int32List(length * 4);
|
||||
|
||||
_NaiveInt32x4List._externalStorage(Int32List storage) : _storage = storage;
|
||||
|
||||
_NaiveInt32x4List._slowFromList(List<Int32x4> list)
|
||||
: _storage = Int32List(list.length * 4) {
|
||||
for (int i = 0; i < list.length; i++) {
|
||||
var e = list[i];
|
||||
_storage[(i * 4) + 0] = e.x;
|
||||
_storage[(i * 4) + 1] = e.y;
|
||||
_storage[(i * 4) + 2] = e.z;
|
||||
_storage[(i * 4) + 3] = e.w;
|
||||
}
|
||||
}
|
||||
|
||||
factory _NaiveInt32x4List.fromList(List<Int32x4> list) {
|
||||
if (list is _NaiveInt32x4List) {
|
||||
return _NaiveInt32x4List._externalStorage(
|
||||
Int32List.fromList(list._storage));
|
||||
} else {
|
||||
return _NaiveInt32x4List._slowFromList(list);
|
||||
}
|
||||
}
|
||||
|
||||
ByteBuffer get buffer => _storage.buffer;
|
||||
|
||||
int get lengthInBytes => _storage.lengthInBytes;
|
||||
|
||||
int get offsetInBytes => _storage.offsetInBytes;
|
||||
|
||||
int get elementSizeInBytes => Int32x4List.bytesPerElement;
|
||||
|
||||
int get length => _storage.length ~/ 4;
|
||||
|
||||
Int32x4 operator [](int index) {
|
||||
IndexError.check(index, length, indexable: this, name: "[]");
|
||||
int _x = _storage[(index * 4) + 0];
|
||||
int _y = _storage[(index * 4) + 1];
|
||||
int _z = _storage[(index * 4) + 2];
|
||||
int _w = _storage[(index * 4) + 3];
|
||||
return _NaiveInt32x4._truncated(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
void operator []=(int index, Int32x4 value) {
|
||||
IndexError.check(index, length, indexable: this, name: "[]=");
|
||||
_storage[(index * 4) + 0] = value.x;
|
||||
_storage[(index * 4) + 1] = value.y;
|
||||
_storage[(index * 4) + 2] = value.z;
|
||||
_storage[(index * 4) + 3] = value.w;
|
||||
}
|
||||
|
||||
Int32x4List sublist(int start, [int? end]) {
|
||||
int stop = RangeError.checkValidRange(start, end, length);
|
||||
return _NaiveInt32x4List._externalStorage(
|
||||
_storage.sublist(start * 4, stop * 4));
|
||||
}
|
||||
}
|
||||
|
||||
final class _NaiveFloat32x4List extends Object
|
||||
with ListMixin<Float32x4>, FixedLengthListMixin<Float32x4>
|
||||
implements Float32x4List {
|
||||
final Float32List _storage;
|
||||
|
||||
_NaiveFloat32x4List(int length) : _storage = Float32List(length * 4);
|
||||
|
||||
_NaiveFloat32x4List._externalStorage(this._storage);
|
||||
|
||||
_NaiveFloat32x4List._slowFromList(List<Float32x4> list)
|
||||
: _storage = Float32List(list.length * 4) {
|
||||
for (int i = 0; i < list.length; i++) {
|
||||
var e = list[i];
|
||||
_storage[(i * 4) + 0] = e.x;
|
||||
_storage[(i * 4) + 1] = e.y;
|
||||
_storage[(i * 4) + 2] = e.z;
|
||||
_storage[(i * 4) + 3] = e.w;
|
||||
}
|
||||
}
|
||||
|
||||
factory _NaiveFloat32x4List.fromList(List<Float32x4> list) {
|
||||
if (list is _NaiveFloat32x4List) {
|
||||
return _NaiveFloat32x4List._externalStorage(
|
||||
Float32List.fromList(list._storage));
|
||||
} else {
|
||||
return _NaiveFloat32x4List._slowFromList(list);
|
||||
}
|
||||
}
|
||||
|
||||
ByteBuffer get buffer => _storage.buffer;
|
||||
|
||||
int get lengthInBytes => _storage.lengthInBytes;
|
||||
|
||||
int get offsetInBytes => _storage.offsetInBytes;
|
||||
|
||||
int get elementSizeInBytes => Float32x4List.bytesPerElement;
|
||||
|
||||
int get length => _storage.length ~/ 4;
|
||||
|
||||
Float32x4 operator [](int index) {
|
||||
IndexError.check(index, length, indexable: this, name: "[]");
|
||||
double _x = _storage[(index * 4) + 0];
|
||||
double _y = _storage[(index * 4) + 1];
|
||||
double _z = _storage[(index * 4) + 2];
|
||||
double _w = _storage[(index * 4) + 3];
|
||||
return _NaiveFloat32x4._truncated(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
void operator []=(int index, Float32x4 value) {
|
||||
IndexError.check(index, length, indexable: this, name: "[]=");
|
||||
_storage[(index * 4) + 0] = value.x;
|
||||
_storage[(index * 4) + 1] = value.y;
|
||||
_storage[(index * 4) + 2] = value.z;
|
||||
_storage[(index * 4) + 3] = value.w;
|
||||
}
|
||||
|
||||
Float32x4List sublist(int start, [int? end]) {
|
||||
int stop = RangeError.checkValidRange(start, end, length);
|
||||
return _NaiveFloat32x4List._externalStorage(
|
||||
_storage.sublist(start * 4, stop * 4));
|
||||
}
|
||||
}
|
||||
|
||||
final class _NaiveFloat64x2List extends Object
|
||||
with ListMixin<Float64x2>, FixedLengthListMixin<Float64x2>
|
||||
implements Float64x2List {
|
||||
final Float64List _storage;
|
||||
|
||||
_NaiveFloat64x2List(int length) : _storage = Float64List(length * 2);
|
||||
|
||||
_NaiveFloat64x2List._externalStorage(this._storage);
|
||||
|
||||
_NaiveFloat64x2List._slowFromList(List<Float64x2> list)
|
||||
: _storage = Float64List(list.length * 2) {
|
||||
for (int i = 0; i < list.length; i++) {
|
||||
var e = list[i];
|
||||
_storage[(i * 2) + 0] = e.x;
|
||||
_storage[(i * 2) + 1] = e.y;
|
||||
}
|
||||
}
|
||||
|
||||
factory _NaiveFloat64x2List.fromList(List<Float64x2> list) {
|
||||
if (list is _NaiveFloat64x2List) {
|
||||
return _NaiveFloat64x2List._externalStorage(
|
||||
Float64List.fromList(list._storage));
|
||||
} else {
|
||||
return _NaiveFloat64x2List._slowFromList(list);
|
||||
}
|
||||
}
|
||||
|
||||
ByteBuffer get buffer => _storage.buffer;
|
||||
|
||||
int get lengthInBytes => _storage.lengthInBytes;
|
||||
|
||||
int get offsetInBytes => _storage.offsetInBytes;
|
||||
|
||||
int get elementSizeInBytes => Float64x2List.bytesPerElement;
|
||||
|
||||
int get length => _storage.length ~/ 2;
|
||||
|
||||
Float64x2 operator [](int index) {
|
||||
IndexError.check(index, length, indexable: this, name: "[]");
|
||||
double _x = _storage[(index * 2) + 0];
|
||||
double _y = _storage[(index * 2) + 1];
|
||||
return Float64x2(_x, _y);
|
||||
}
|
||||
|
||||
void operator []=(int index, Float64x2 value) {
|
||||
IndexError.check(index, length, indexable: this, name: "[]=");
|
||||
_storage[(index * 2) + 0] = value.x;
|
||||
_storage[(index * 2) + 1] = value.y;
|
||||
}
|
||||
|
||||
Float64x2List sublist(int start, [int? end]) {
|
||||
int stop = RangeError.checkValidRange(start, end, length);
|
||||
return _NaiveFloat64x2List._externalStorage(
|
||||
_storage.sublist(start * 2, stop * 2));
|
||||
}
|
||||
}
|
||||
|
||||
final class _NaiveFloat32x4 implements Float32x4 {
|
||||
final double x;
|
||||
final double y;
|
||||
final double z;
|
||||
final double w;
|
||||
|
||||
static final Float32List _list = Float32List(4);
|
||||
static final Uint32List _uint32view = _list.buffer.asUint32List();
|
||||
|
||||
static double _truncate(x) {
|
||||
_list[0] = x;
|
||||
return _list[0];
|
||||
}
|
||||
|
||||
_NaiveFloat32x4(double x, double y, double z, double w)
|
||||
: this.x = _truncate(x),
|
||||
this.y = _truncate(y),
|
||||
this.z = _truncate(z),
|
||||
this.w = _truncate(w);
|
||||
|
||||
_NaiveFloat32x4.splat(double v) : this(v, v, v, v);
|
||||
_NaiveFloat32x4.zero() : this._truncated(0.0, 0.0, 0.0, 0.0);
|
||||
|
||||
factory _NaiveFloat32x4.fromInt32x4Bits(Int32x4 i) {
|
||||
_uint32view[0] = i.x;
|
||||
_uint32view[1] = i.y;
|
||||
_uint32view[2] = i.z;
|
||||
_uint32view[3] = i.w;
|
||||
return _NaiveFloat32x4._truncated(_list[0], _list[1], _list[2], _list[3]);
|
||||
}
|
||||
|
||||
_NaiveFloat32x4.fromFloat64x2(Float64x2 v)
|
||||
: this._truncated(_truncate(v.x), _truncate(v.y), 0.0, 0.0);
|
||||
|
||||
_NaiveFloat32x4._doubles(double x, double y, double z, double w)
|
||||
: this.x = _truncate(x),
|
||||
this.y = _truncate(y),
|
||||
this.z = _truncate(z),
|
||||
this.w = _truncate(w);
|
||||
|
||||
_NaiveFloat32x4._truncated(this.x, this.y, this.z, this.w);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return '[${x.toStringAsFixed(6)}, '
|
||||
'${y.toStringAsFixed(6)}, '
|
||||
'${z.toStringAsFixed(6)}, '
|
||||
'${w.toStringAsFixed(6)}]';
|
||||
}
|
||||
|
||||
Float32x4 operator +(Float32x4 other) {
|
||||
double _x = x + other.x;
|
||||
double _y = y + other.y;
|
||||
double _z = z + other.z;
|
||||
double _w = w + other.w;
|
||||
return _NaiveFloat32x4._doubles(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
Float32x4 operator -() {
|
||||
return _NaiveFloat32x4._truncated(-x, -y, -z, -w);
|
||||
}
|
||||
|
||||
Float32x4 operator -(Float32x4 other) {
|
||||
double _x = x - other.x;
|
||||
double _y = y - other.y;
|
||||
double _z = z - other.z;
|
||||
double _w = w - other.w;
|
||||
return _NaiveFloat32x4._doubles(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
Float32x4 operator *(Float32x4 other) {
|
||||
double _x = x * other.x;
|
||||
double _y = y * other.y;
|
||||
double _z = z * other.z;
|
||||
double _w = w * other.w;
|
||||
return _NaiveFloat32x4._doubles(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
Float32x4 operator /(Float32x4 other) {
|
||||
double _x = x / other.x;
|
||||
double _y = y / other.y;
|
||||
double _z = z / other.z;
|
||||
double _w = w / other.w;
|
||||
return _NaiveFloat32x4._doubles(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
Int32x4 lessThan(Float32x4 other) {
|
||||
bool _cx = x < other.x;
|
||||
bool _cy = y < other.y;
|
||||
bool _cz = z < other.z;
|
||||
bool _cw = w < other.w;
|
||||
return _NaiveInt32x4._truncated(
|
||||
_cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0);
|
||||
}
|
||||
|
||||
Int32x4 lessThanOrEqual(Float32x4 other) {
|
||||
bool _cx = x <= other.x;
|
||||
bool _cy = y <= other.y;
|
||||
bool _cz = z <= other.z;
|
||||
bool _cw = w <= other.w;
|
||||
return _NaiveInt32x4._truncated(
|
||||
_cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0);
|
||||
}
|
||||
|
||||
Int32x4 greaterThan(Float32x4 other) {
|
||||
bool _cx = x > other.x;
|
||||
bool _cy = y > other.y;
|
||||
bool _cz = z > other.z;
|
||||
bool _cw = w > other.w;
|
||||
return _NaiveInt32x4._truncated(
|
||||
_cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0);
|
||||
}
|
||||
|
||||
Int32x4 greaterThanOrEqual(Float32x4 other) {
|
||||
bool _cx = x >= other.x;
|
||||
bool _cy = y >= other.y;
|
||||
bool _cz = z >= other.z;
|
||||
bool _cw = w >= other.w;
|
||||
return _NaiveInt32x4._truncated(
|
||||
_cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0);
|
||||
}
|
||||
|
||||
Int32x4 equal(Float32x4 other) {
|
||||
bool _cx = x == other.x;
|
||||
bool _cy = y == other.y;
|
||||
bool _cz = z == other.z;
|
||||
bool _cw = w == other.w;
|
||||
return _NaiveInt32x4._truncated(
|
||||
_cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0);
|
||||
}
|
||||
|
||||
Int32x4 notEqual(Float32x4 other) {
|
||||
bool _cx = x != other.x;
|
||||
bool _cy = y != other.y;
|
||||
bool _cz = z != other.z;
|
||||
bool _cw = w != other.w;
|
||||
return _NaiveInt32x4._truncated(
|
||||
_cx ? -1 : 0, _cy ? -1 : 0, _cz ? -1 : 0, _cw ? -1 : 0);
|
||||
}
|
||||
|
||||
Float32x4 scale(double s) {
|
||||
double _x = s * x;
|
||||
double _y = s * y;
|
||||
double _z = s * z;
|
||||
double _w = s * w;
|
||||
return _NaiveFloat32x4._doubles(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
Float32x4 abs() {
|
||||
double _x = x.abs();
|
||||
double _y = y.abs();
|
||||
double _z = z.abs();
|
||||
double _w = w.abs();
|
||||
return _NaiveFloat32x4._truncated(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
Float32x4 clamp(Float32x4 lowerLimit, Float32x4 upperLimit) {
|
||||
double _lx = lowerLimit.x;
|
||||
double _ly = lowerLimit.y;
|
||||
double _lz = lowerLimit.z;
|
||||
double _lw = lowerLimit.w;
|
||||
double _ux = upperLimit.x;
|
||||
double _uy = upperLimit.y;
|
||||
double _uz = upperLimit.z;
|
||||
double _uw = upperLimit.w;
|
||||
double _x = x;
|
||||
double _y = y;
|
||||
double _z = z;
|
||||
double _w = w;
|
||||
// MAX(MIN(self, upper), lower).
|
||||
_x = _x > _ux ? _ux : _x;
|
||||
_y = _y > _uy ? _uy : _y;
|
||||
_z = _z > _uz ? _uz : _z;
|
||||
_w = _w > _uw ? _uw : _w;
|
||||
_x = _x < _lx ? _lx : _x;
|
||||
_y = _y < _ly ? _ly : _y;
|
||||
_z = _z < _lz ? _lz : _z;
|
||||
_w = _w < _lw ? _lw : _w;
|
||||
return _NaiveFloat32x4._truncated(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
int get signMask {
|
||||
var view = _uint32view;
|
||||
int mx, my, mz, mw;
|
||||
_list[0] = x;
|
||||
_list[1] = y;
|
||||
_list[2] = z;
|
||||
_list[3] = w;
|
||||
mx = (view[0] & 0x80000000) >> 31;
|
||||
my = (view[1] & 0x80000000) >> 30;
|
||||
mz = (view[2] & 0x80000000) >> 29;
|
||||
mw = (view[3] & 0x80000000) >> 28;
|
||||
return mx | my | mz | mw;
|
||||
}
|
||||
|
||||
Float32x4 shuffle(int mask) {
|
||||
if ((mask < 0) || (mask > 255)) {
|
||||
throw RangeError.range(mask, 0, 255, 'mask');
|
||||
}
|
||||
_list[0] = x;
|
||||
_list[1] = y;
|
||||
_list[2] = z;
|
||||
_list[3] = w;
|
||||
|
||||
double _x = _list[mask & 0x3];
|
||||
double _y = _list[(mask >> 2) & 0x3];
|
||||
double _z = _list[(mask >> 4) & 0x3];
|
||||
double _w = _list[(mask >> 6) & 0x3];
|
||||
return _NaiveFloat32x4._truncated(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
Float32x4 shuffleMix(Float32x4 other, int mask) {
|
||||
if ((mask < 0) || (mask > 255)) {
|
||||
throw RangeError.range(mask, 0, 255, 'mask');
|
||||
}
|
||||
_list[0] = x;
|
||||
_list[1] = y;
|
||||
_list[2] = z;
|
||||
_list[3] = w;
|
||||
double _x = _list[mask & 0x3];
|
||||
double _y = _list[(mask >> 2) & 0x3];
|
||||
|
||||
_list[0] = other.x;
|
||||
_list[1] = other.y;
|
||||
_list[2] = other.z;
|
||||
_list[3] = other.w;
|
||||
double _z = _list[(mask >> 4) & 0x3];
|
||||
double _w = _list[(mask >> 6) & 0x3];
|
||||
return _NaiveFloat32x4._truncated(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
Float32x4 withX(double newX) {
|
||||
double _newX = _truncate(newX);
|
||||
return _NaiveFloat32x4._truncated(_newX, y, z, w);
|
||||
}
|
||||
|
||||
Float32x4 withY(double newY) {
|
||||
double _newY = _truncate(newY);
|
||||
return _NaiveFloat32x4._truncated(x, _newY, z, w);
|
||||
}
|
||||
|
||||
Float32x4 withZ(double newZ) {
|
||||
double _newZ = _truncate(newZ);
|
||||
return _NaiveFloat32x4._truncated(x, y, _newZ, w);
|
||||
}
|
||||
|
||||
Float32x4 withW(double newW) {
|
||||
double _newW = _truncate(newW);
|
||||
return _NaiveFloat32x4._truncated(x, y, z, _newW);
|
||||
}
|
||||
|
||||
Float32x4 min(Float32x4 other) {
|
||||
double _x = x < other.x ? x : other.x;
|
||||
double _y = y < other.y ? y : other.y;
|
||||
double _z = z < other.z ? z : other.z;
|
||||
double _w = w < other.w ? w : other.w;
|
||||
return _NaiveFloat32x4._truncated(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
Float32x4 max(Float32x4 other) {
|
||||
double _x = x > other.x ? x : other.x;
|
||||
double _y = y > other.y ? y : other.y;
|
||||
double _z = z > other.z ? z : other.z;
|
||||
double _w = w > other.w ? w : other.w;
|
||||
return _NaiveFloat32x4._truncated(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
Float32x4 sqrt() {
|
||||
double _x = math.sqrt(x);
|
||||
double _y = math.sqrt(y);
|
||||
double _z = math.sqrt(z);
|
||||
double _w = math.sqrt(w);
|
||||
return _NaiveFloat32x4._doubles(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
Float32x4 reciprocal() {
|
||||
double _x = 1.0 / x;
|
||||
double _y = 1.0 / y;
|
||||
double _z = 1.0 / z;
|
||||
double _w = 1.0 / w;
|
||||
return _NaiveFloat32x4._doubles(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
Float32x4 reciprocalSqrt() {
|
||||
double _x = math.sqrt(1.0 / x);
|
||||
double _y = math.sqrt(1.0 / y);
|
||||
double _z = math.sqrt(1.0 / z);
|
||||
double _w = math.sqrt(1.0 / w);
|
||||
return _NaiveFloat32x4._doubles(_x, _y, _z, _w);
|
||||
}
|
||||
}
|
||||
|
||||
final class _NaiveFloat64x2 implements Float64x2 {
|
||||
final double x;
|
||||
final double y;
|
||||
|
||||
static Float64List _list = Float64List(2);
|
||||
static Uint32List _uint32View = _list.buffer.asUint32List();
|
||||
|
||||
_NaiveFloat64x2(this.x, this.y);
|
||||
|
||||
_NaiveFloat64x2.splat(double v) : this(v, v);
|
||||
|
||||
_NaiveFloat64x2.zero() : this.splat(0.0);
|
||||
|
||||
_NaiveFloat64x2.fromFloat32x4(Float32x4 v) : this(v.x, v.y);
|
||||
|
||||
_NaiveFloat64x2._doubles(this.x, this.y);
|
||||
|
||||
String toString() => '[$x, $y]';
|
||||
|
||||
Float64x2 operator +(Float64x2 other) =>
|
||||
_NaiveFloat64x2._doubles(x + other.x, y + other.y);
|
||||
|
||||
Float64x2 operator -() => _NaiveFloat64x2._doubles(-x, -y);
|
||||
|
||||
Float64x2 operator -(Float64x2 other) =>
|
||||
_NaiveFloat64x2._doubles(x - other.x, y - other.y);
|
||||
|
||||
Float64x2 operator *(Float64x2 other) =>
|
||||
_NaiveFloat64x2._doubles(x * other.x, y * other.y);
|
||||
|
||||
Float64x2 operator /(Float64x2 other) =>
|
||||
_NaiveFloat64x2._doubles(x / other.x, y / other.y);
|
||||
|
||||
Float64x2 scale(double s) => _NaiveFloat64x2._doubles(x * s, y * s);
|
||||
|
||||
Float64x2 abs() => _NaiveFloat64x2._doubles(x.abs(), y.abs());
|
||||
|
||||
Float64x2 clamp(Float64x2 lowerLimit, Float64x2 upperLimit) {
|
||||
double _lx = lowerLimit.x;
|
||||
double _ly = lowerLimit.y;
|
||||
double _ux = upperLimit.x;
|
||||
double _uy = upperLimit.y;
|
||||
double _x = x;
|
||||
double _y = y;
|
||||
// MAX(MIN(self, upper), lower).
|
||||
_x = _x > _ux ? _ux : _x;
|
||||
_y = _y > _uy ? _uy : _y;
|
||||
_x = _x < _lx ? _lx : _x;
|
||||
_y = _y < _ly ? _ly : _y;
|
||||
return _NaiveFloat64x2._doubles(_x, _y);
|
||||
}
|
||||
|
||||
int get signMask {
|
||||
var view = _uint32View;
|
||||
_list[0] = x;
|
||||
_list[1] = y;
|
||||
var mx = (view[1] & 0x80000000) >> 31;
|
||||
var my = (view[3] & 0x80000000) >> 31;
|
||||
return mx | my << 1;
|
||||
}
|
||||
|
||||
Float64x2 withX(double x) => _NaiveFloat64x2._doubles(x, y);
|
||||
|
||||
Float64x2 withY(double y) => _NaiveFloat64x2._doubles(x, y);
|
||||
|
||||
Float64x2 min(Float64x2 other) => _NaiveFloat64x2._doubles(
|
||||
x < other.x ? x : other.x, y < other.y ? y : other.y);
|
||||
|
||||
Float64x2 max(Float64x2 other) => _NaiveFloat64x2._doubles(
|
||||
x > other.x ? x : other.x, y > other.y ? y : other.y);
|
||||
|
||||
Float64x2 sqrt() => _NaiveFloat64x2._doubles(math.sqrt(x), math.sqrt(y));
|
||||
}
|
||||
|
||||
final class _NaiveInt32x4 implements Int32x4 {
|
||||
final int x;
|
||||
final int y;
|
||||
final int z;
|
||||
final int w;
|
||||
|
||||
static final Int32List _list = Int32List(4);
|
||||
|
||||
static int _truncate(x) {
|
||||
_list[0] = x;
|
||||
return _list[0];
|
||||
}
|
||||
|
||||
_NaiveInt32x4(int x, int y, int z, int w)
|
||||
: this.x = _truncate(x),
|
||||
this.y = _truncate(y),
|
||||
this.z = _truncate(z),
|
||||
this.w = _truncate(w);
|
||||
|
||||
_NaiveInt32x4.bool(bool x, bool y, bool z, bool w)
|
||||
: this.x = x ? -1 : 0,
|
||||
this.y = y ? -1 : 0,
|
||||
this.z = z ? -1 : 0,
|
||||
this.w = w ? -1 : 0;
|
||||
|
||||
factory _NaiveInt32x4.fromFloat32x4Bits(Float32x4 f) {
|
||||
Float32List floatList = _NaiveFloat32x4._list;
|
||||
floatList[0] = f.x;
|
||||
floatList[1] = f.y;
|
||||
floatList[2] = f.z;
|
||||
floatList[3] = f.w;
|
||||
var view = floatList.buffer.asInt32List();
|
||||
return _NaiveInt32x4._truncated(view[0], view[1], view[2], view[3]);
|
||||
}
|
||||
|
||||
_NaiveInt32x4._truncated(this.x, this.y, this.z, this.w);
|
||||
|
||||
String toString() => '[${_int32ToHex(x)}, ${_int32ToHex(y)}, '
|
||||
'${_int32ToHex(z)}, ${_int32ToHex(w)}]';
|
||||
|
||||
Int32x4 operator |(Int32x4 other) {
|
||||
int _x = x | other.x;
|
||||
int _y = y | other.y;
|
||||
int _z = z | other.z;
|
||||
int _w = w | other.w;
|
||||
return _NaiveInt32x4._truncated(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
Int32x4 operator &(Int32x4 other) {
|
||||
int _x = x & other.x;
|
||||
int _y = y & other.y;
|
||||
int _z = z & other.z;
|
||||
int _w = w & other.w;
|
||||
return _NaiveInt32x4._truncated(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
Int32x4 operator ^(Int32x4 other) {
|
||||
int _x = x ^ other.x;
|
||||
int _y = y ^ other.y;
|
||||
int _z = z ^ other.z;
|
||||
int _w = w ^ other.w;
|
||||
return _NaiveInt32x4._truncated(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
Int32x4 operator +(Int32x4 other) {
|
||||
int _x = x + other.x;
|
||||
int _y = y + other.y;
|
||||
int _z = z + other.z;
|
||||
int _w = w + other.w;
|
||||
return _NaiveInt32x4._truncated(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
Int32x4 operator -(Int32x4 other) {
|
||||
int _x = x - other.x;
|
||||
int _y = y - other.y;
|
||||
int _z = z - other.z;
|
||||
int _w = w - other.w;
|
||||
return _NaiveInt32x4._truncated(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
Int32x4 operator -() {
|
||||
return _NaiveInt32x4._truncated(-x, -y, -z, -w);
|
||||
}
|
||||
|
||||
int get signMask {
|
||||
int mx = (x & 0x80000000) >> 31;
|
||||
int my = (y & 0x80000000) >> 31;
|
||||
int mz = (z & 0x80000000) >> 31;
|
||||
int mw = (w & 0x80000000) >> 31;
|
||||
return mx | my << 1 | mz << 2 | mw << 3;
|
||||
}
|
||||
|
||||
Int32x4 shuffle(int mask) {
|
||||
if ((mask < 0) || (mask > 255)) {
|
||||
throw RangeError.range(mask, 0, 255, 'mask');
|
||||
}
|
||||
_list[0] = x;
|
||||
_list[1] = y;
|
||||
_list[2] = z;
|
||||
_list[3] = w;
|
||||
int _x = _list[mask & 0x3];
|
||||
int _y = _list[(mask >> 2) & 0x3];
|
||||
int _z = _list[(mask >> 4) & 0x3];
|
||||
int _w = _list[(mask >> 6) & 0x3];
|
||||
return _NaiveInt32x4._truncated(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
Int32x4 shuffleMix(Int32x4 other, int mask) {
|
||||
if ((mask < 0) || (mask > 255)) {
|
||||
throw RangeError.range(mask, 0, 255, 'mask');
|
||||
}
|
||||
_list[0] = x;
|
||||
_list[1] = y;
|
||||
_list[2] = z;
|
||||
_list[3] = w;
|
||||
int _x = _list[mask & 0x3];
|
||||
int _y = _list[(mask >> 2) & 0x3];
|
||||
|
||||
_list[0] = other.x;
|
||||
_list[1] = other.y;
|
||||
_list[2] = other.z;
|
||||
_list[3] = other.w;
|
||||
int _z = _list[(mask >> 4) & 0x3];
|
||||
int _w = _list[(mask >> 6) & 0x3];
|
||||
return _NaiveInt32x4._truncated(_x, _y, _z, _w);
|
||||
}
|
||||
|
||||
Int32x4 withX(int x) {
|
||||
int _x = _truncate(x);
|
||||
return _NaiveInt32x4._truncated(_x, y, z, w);
|
||||
}
|
||||
|
||||
Int32x4 withY(int y) {
|
||||
int _y = _truncate(y);
|
||||
return _NaiveInt32x4._truncated(x, _y, z, w);
|
||||
}
|
||||
|
||||
Int32x4 withZ(int z) {
|
||||
int _z = _truncate(z);
|
||||
return _NaiveInt32x4._truncated(x, y, _z, w);
|
||||
}
|
||||
|
||||
Int32x4 withW(int w) {
|
||||
int _w = _truncate(w);
|
||||
return _NaiveInt32x4._truncated(x, y, z, _w);
|
||||
}
|
||||
|
||||
bool get flagX => x != 0;
|
||||
|
||||
bool get flagY => y != 0;
|
||||
|
||||
bool get flagZ => z != 0;
|
||||
|
||||
bool get flagW => w != 0;
|
||||
|
||||
Int32x4 withFlagX(bool flagX) {
|
||||
int _x = flagX ? -1 : 0;
|
||||
return _NaiveInt32x4._truncated(_x, y, z, w);
|
||||
}
|
||||
|
||||
Int32x4 withFlagY(bool flagY) {
|
||||
int _y = flagY ? -1 : 0;
|
||||
return _NaiveInt32x4._truncated(x, _y, z, w);
|
||||
}
|
||||
|
||||
Int32x4 withFlagZ(bool flagZ) {
|
||||
int _z = flagZ ? -1 : 0;
|
||||
return _NaiveInt32x4._truncated(x, y, _z, w);
|
||||
}
|
||||
|
||||
Int32x4 withFlagW(bool flagW) {
|
||||
int _w = flagW ? -1 : 0;
|
||||
return _NaiveInt32x4._truncated(x, y, z, _w);
|
||||
}
|
||||
|
||||
Float32x4 select(Float32x4 trueValue, Float32x4 falseValue) {
|
||||
var floatList = _NaiveFloat32x4._list;
|
||||
var intView = _NaiveFloat32x4._uint32view;
|
||||
|
||||
floatList[0] = trueValue.x;
|
||||
floatList[1] = trueValue.y;
|
||||
floatList[2] = trueValue.z;
|
||||
floatList[3] = trueValue.w;
|
||||
int stx = intView[0];
|
||||
int sty = intView[1];
|
||||
int stz = intView[2];
|
||||
int stw = intView[3];
|
||||
|
||||
floatList[0] = falseValue.x;
|
||||
floatList[1] = falseValue.y;
|
||||
floatList[2] = falseValue.z;
|
||||
floatList[3] = falseValue.w;
|
||||
int sfx = intView[0];
|
||||
int sfy = intView[1];
|
||||
int sfz = intView[2];
|
||||
int sfw = intView[3];
|
||||
int _x = (x & stx) | (~x & sfx);
|
||||
int _y = (y & sty) | (~y & sfy);
|
||||
int _z = (z & stz) | (~z & sfz);
|
||||
int _w = (w & stw) | (~w & sfw);
|
||||
intView[0] = _x;
|
||||
intView[1] = _y;
|
||||
intView[2] = _z;
|
||||
intView[3] = _w;
|
||||
return _NaiveFloat32x4._truncated(
|
||||
floatList[0], floatList[1], floatList[2], floatList[3]);
|
||||
}
|
||||
}
|
||||
|
||||
String _int32ToHex(int i) => i.toRadixString(16).padLeft(8, '0');
|
||||
|
|
3529
sdk/lib/_internal/wasm/lib/typed_data.dart
Normal file
3529
sdk/lib/_internal/wasm/lib/typed_data.dart
Normal file
File diff suppressed because it is too large
Load diff
|
@ -2,107 +2,274 @@
|
|||
// 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 ClassID, patch;
|
||||
import 'dart:_internal' show patch, unsafeCast;
|
||||
import 'dart:_typed_data';
|
||||
import 'dart:_wasm';
|
||||
|
||||
@patch
|
||||
abstract class _TypedListBase {
|
||||
class ByteData {
|
||||
@patch
|
||||
bool _setRange(int startInBytes, int lengthInBytes, _TypedListBase from,
|
||||
int startFromInBytes, int toCid, int fromCid) {
|
||||
// The way [_setRange] is called, both `this` and [from] are [_TypedList].
|
||||
_TypedList thisList = this as _TypedList;
|
||||
_TypedList fromList = from as _TypedList;
|
||||
bool shouldClamp = (toCid == ClassID.cidUint8ClampedList ||
|
||||
toCid == ClassID.cid_Uint8ClampedList ||
|
||||
toCid == ClassID.cidUint8ClampedArrayView) &&
|
||||
(fromCid == ClassID.cidInt8List ||
|
||||
fromCid == ClassID.cid_Int8List ||
|
||||
fromCid == ClassID.cidInt8ArrayView);
|
||||
// TODO(joshualitt): There are conditions where we can avoid the copy even
|
||||
// when the buffer is the same, i.e. if the ranges do not overlap, or we
|
||||
// could if the ranges overlap but the destination index is higher than the
|
||||
// source.
|
||||
bool needsCopy = thisList.buffer == fromList.buffer;
|
||||
if (shouldClamp) {
|
||||
if (needsCopy) {
|
||||
List<int> temp = List<int>.generate(lengthInBytes,
|
||||
(index) => fromList._getInt8(index + startFromInBytes));
|
||||
for (int i = 0; i < lengthInBytes; i++) {
|
||||
thisList._setUint8(i + startInBytes, temp[i].clamp(0, 255));
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < lengthInBytes; i++) {
|
||||
thisList._setUint8(i + startInBytes,
|
||||
fromList._getInt8(i + startFromInBytes).clamp(0, 255));
|
||||
}
|
||||
}
|
||||
} else if (needsCopy) {
|
||||
List<int> temp = List<int>.generate(lengthInBytes,
|
||||
(index) => fromList._getInt8(index + startFromInBytes));
|
||||
for (int i = 0; i < lengthInBytes; i++) {
|
||||
thisList._setUint8(i + startInBytes, temp[i]);
|
||||
}
|
||||
factory ByteData(int length) => I8ByteData(length);
|
||||
}
|
||||
|
||||
@patch
|
||||
class Int8List {
|
||||
@patch
|
||||
factory Int8List(int length) => I8List(length);
|
||||
|
||||
@patch
|
||||
factory Int8List.fromList(List<int> elements) =>
|
||||
I8List(elements.length)..setRange(0, elements.length, elements);
|
||||
}
|
||||
|
||||
@patch
|
||||
class Uint8List {
|
||||
@patch
|
||||
factory Uint8List(int length) => U8List(length);
|
||||
|
||||
@patch
|
||||
factory Uint8List.fromList(List<int> elements) =>
|
||||
U8List(elements.length)..setRange(0, elements.length, elements);
|
||||
}
|
||||
|
||||
@patch
|
||||
class Uint8ClampedList {
|
||||
@patch
|
||||
factory Uint8ClampedList(int length) => U8ClampedList(length);
|
||||
|
||||
@patch
|
||||
factory Uint8ClampedList.fromList(List<int> elements) =>
|
||||
U8ClampedList(elements.length)..setRange(0, elements.length, elements);
|
||||
}
|
||||
|
||||
@patch
|
||||
class Int16List {
|
||||
@patch
|
||||
factory Int16List(int length) => I16List(length);
|
||||
|
||||
@patch
|
||||
factory Int16List.fromList(List<int> elements) =>
|
||||
I16List(elements.length)..setRange(0, elements.length, elements);
|
||||
}
|
||||
|
||||
@patch
|
||||
class Uint16List {
|
||||
@patch
|
||||
factory Uint16List(int length) => U16List(length);
|
||||
|
||||
@patch
|
||||
factory Uint16List.fromList(List<int> elements) =>
|
||||
U16List(elements.length)..setRange(0, elements.length, elements);
|
||||
}
|
||||
|
||||
@patch
|
||||
class Int32List {
|
||||
@patch
|
||||
factory Int32List(int length) => I32List(length);
|
||||
|
||||
@patch
|
||||
factory Int32List.fromList(List<int> elements) =>
|
||||
I32List(elements.length)..setRange(0, elements.length, elements);
|
||||
}
|
||||
|
||||
@patch
|
||||
class Uint32List {
|
||||
@patch
|
||||
factory Uint32List(int length) => U32List(length);
|
||||
|
||||
@patch
|
||||
factory Uint32List.fromList(List<int> elements) =>
|
||||
U32List(elements.length)..setRange(0, elements.length, elements);
|
||||
}
|
||||
|
||||
@patch
|
||||
class Int64List {
|
||||
@patch
|
||||
factory Int64List(int length) => I64List(length);
|
||||
|
||||
@patch
|
||||
factory Int64List.fromList(List<int> elements) =>
|
||||
I64List(elements.length)..setRange(0, elements.length, elements);
|
||||
}
|
||||
|
||||
@patch
|
||||
class Uint64List {
|
||||
@patch
|
||||
factory Uint64List(int length) => U64List(length);
|
||||
|
||||
@patch
|
||||
factory Uint64List.fromList(List<int> elements) =>
|
||||
U64List(elements.length)..setRange(0, elements.length, elements);
|
||||
}
|
||||
|
||||
@patch
|
||||
class Float32List {
|
||||
@patch
|
||||
factory Float32List(int length) => F32List(length);
|
||||
|
||||
@patch
|
||||
factory Float32List.fromList(List<double> elements) =>
|
||||
F32List(elements.length)..setRange(0, elements.length, elements);
|
||||
}
|
||||
|
||||
@patch
|
||||
class Float64List {
|
||||
@patch
|
||||
factory Float64List(int length) => F64List(length);
|
||||
|
||||
@patch
|
||||
factory Float64List.fromList(List<double> elements) =>
|
||||
F64List(elements.length)..setRange(0, elements.length, elements);
|
||||
}
|
||||
|
||||
@patch
|
||||
class UnmodifiableUint8ListView {
|
||||
@patch
|
||||
factory UnmodifiableUint8ListView(Uint8List list) {
|
||||
if (list is U8List) {
|
||||
return UnmodifiableU8List(list);
|
||||
} else {
|
||||
for (int i = 0; i < lengthInBytes; i++) {
|
||||
thisList._setUint8(
|
||||
i + startInBytes, fromList._getInt8(i + startFromInBytes));
|
||||
}
|
||||
return UnmodifiableSlowU8List(list);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@patch
|
||||
abstract class _TypedList extends _TypedListBase {
|
||||
class UnmodifiableInt8ListView {
|
||||
@patch
|
||||
Float32x4 _getFloat32x4(int offsetInBytes) {
|
||||
ByteData data = buffer.asByteData();
|
||||
return Float32x4(
|
||||
data.getFloat32(offsetInBytes + 0 * 4, Endian.host),
|
||||
data.getFloat32(offsetInBytes + 1 * 4, Endian.host),
|
||||
data.getFloat32(offsetInBytes + 2 * 4, Endian.host),
|
||||
data.getFloat32(offsetInBytes + 3 * 4, Endian.host));
|
||||
}
|
||||
|
||||
@patch
|
||||
void _setFloat32x4(int offsetInBytes, Float32x4 value) {
|
||||
ByteData data = buffer.asByteData();
|
||||
data.setFloat32(offsetInBytes + 0 * 4, value.x, Endian.host);
|
||||
data.setFloat32(offsetInBytes + 1 * 4, value.y, Endian.host);
|
||||
data.setFloat32(offsetInBytes + 2 * 4, value.z, Endian.host);
|
||||
data.setFloat32(offsetInBytes + 3 * 4, value.w, Endian.host);
|
||||
}
|
||||
|
||||
@patch
|
||||
Int32x4 _getInt32x4(int offsetInBytes) {
|
||||
ByteData data = buffer.asByteData();
|
||||
return Int32x4(
|
||||
data.getInt32(offsetInBytes + 0 * 4, Endian.host),
|
||||
data.getInt32(offsetInBytes + 1 * 4, Endian.host),
|
||||
data.getInt32(offsetInBytes + 2 * 4, Endian.host),
|
||||
data.getInt32(offsetInBytes + 3 * 4, Endian.host));
|
||||
}
|
||||
|
||||
@patch
|
||||
void _setInt32x4(int offsetInBytes, Int32x4 value) {
|
||||
ByteData data = buffer.asByteData();
|
||||
data.setInt32(offsetInBytes + 0 * 4, value.x, Endian.host);
|
||||
data.setInt32(offsetInBytes + 1 * 4, value.y, Endian.host);
|
||||
data.setInt32(offsetInBytes + 2 * 4, value.z, Endian.host);
|
||||
data.setInt32(offsetInBytes + 3 * 4, value.w, Endian.host);
|
||||
}
|
||||
|
||||
@patch
|
||||
Float64x2 _getFloat64x2(int offsetInBytes) {
|
||||
ByteData data = buffer.asByteData();
|
||||
return Float64x2(data.getFloat64(offsetInBytes + 0 * 8, Endian.host),
|
||||
data.getFloat64(offsetInBytes + 1 * 8, Endian.host));
|
||||
}
|
||||
|
||||
@patch
|
||||
void _setFloat64x2(int offsetInBytes, Float64x2 value) {
|
||||
ByteData data = buffer.asByteData();
|
||||
data.setFloat64(offsetInBytes + 0 * 8, value.x, Endian.host);
|
||||
data.setFloat64(offsetInBytes + 1 * 8, value.y, Endian.host);
|
||||
factory UnmodifiableInt8ListView(Int8List list) {
|
||||
if (list is I8List) {
|
||||
return UnmodifiableI8List(list);
|
||||
} else {
|
||||
return UnmodifiableSlowI8List(list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@patch
|
||||
class UnmodifiableUint8ClampedListView {
|
||||
@patch
|
||||
factory UnmodifiableUint8ClampedListView(Uint8ClampedList list) {
|
||||
if (list is U8ClampedList) {
|
||||
return UnmodifiableU8ClampedList(list);
|
||||
} else {
|
||||
return UnmodifiableSlowU8ClampedList(list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@patch
|
||||
class UnmodifiableUint16ListView {
|
||||
@patch
|
||||
factory UnmodifiableUint16ListView(Uint16List list) {
|
||||
if (list is U16List) {
|
||||
return UnmodifiableU16List(list);
|
||||
} else {
|
||||
return UnmodifiableSlowU16List(list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@patch
|
||||
class UnmodifiableInt16ListView {
|
||||
@patch
|
||||
factory UnmodifiableInt16ListView(Int16List list) {
|
||||
if (list is I16List) {
|
||||
return UnmodifiableI16List(list);
|
||||
} else {
|
||||
return UnmodifiableSlowI16List(list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@patch
|
||||
class UnmodifiableUint32ListView {
|
||||
@patch
|
||||
factory UnmodifiableUint32ListView(Uint32List list) {
|
||||
if (list is U32List) {
|
||||
return UnmodifiableU32List(list);
|
||||
} else {
|
||||
return UnmodifiableSlowU32List(list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@patch
|
||||
class UnmodifiableInt32ListView {
|
||||
@patch
|
||||
factory UnmodifiableInt32ListView(Int32List list) {
|
||||
if (list is I32List) {
|
||||
return UnmodifiableI32List(list);
|
||||
} else {
|
||||
return UnmodifiableSlowI32List(list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@patch
|
||||
class UnmodifiableUint64ListView {
|
||||
@patch
|
||||
factory UnmodifiableUint64ListView(Uint64List list) {
|
||||
if (list is U64List) {
|
||||
return UnmodifiableU64List(list);
|
||||
} else {
|
||||
return UnmodifiableSlowU64List(list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@patch
|
||||
class UnmodifiableInt64ListView {
|
||||
@patch
|
||||
factory UnmodifiableInt64ListView(Int64List list) {
|
||||
if (list is I64List) {
|
||||
return UnmodifiableI64List(list);
|
||||
} else {
|
||||
return UnmodifiableSlowI64List(list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@patch
|
||||
class UnmodifiableFloat32ListView {
|
||||
@patch
|
||||
factory UnmodifiableFloat32ListView(Float32List list) {
|
||||
if (list is F32List) {
|
||||
return UnmodifiableF32List(list);
|
||||
} else {
|
||||
return UnmodifiableSlowF32List(list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@patch
|
||||
class UnmodifiableFloat64ListView {
|
||||
@patch
|
||||
factory UnmodifiableFloat64ListView(Float64List list) {
|
||||
if (list is F64List) {
|
||||
return UnmodifiableF64List(list);
|
||||
} else {
|
||||
return UnmodifiableSlowF64List(list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@patch
|
||||
class UnmodifiableByteBufferView implements ByteBuffer {
|
||||
@patch
|
||||
factory UnmodifiableByteBufferView(ByteBuffer data) =>
|
||||
// TODO(omersa): This will break when `data` is `JSArrayBufferImpl`.
|
||||
// Implement an interface for byte buffer that can be made unmodifiable
|
||||
// and implement it in all byte buffers, use that type here.
|
||||
UnmodifiableByteBuffer(unsafeCast<ByteBufferBase>(data));
|
||||
}
|
||||
|
||||
@patch
|
||||
class UnmodifiableByteDataView implements ByteData {
|
||||
@patch
|
||||
factory UnmodifiableByteDataView(ByteData data) =>
|
||||
// TODO(omersa): Same as above, this will break when `data` is
|
||||
// `JSDataViewImpl`. Add an interface for `ByteData` that can be made
|
||||
// immutable, implement it in all `ByteData` subtypes.
|
||||
unsafeCast<ByteDataBase>(data).immutable();
|
||||
}
|
||||
|
|
|
@ -217,6 +217,12 @@
|
|||
"_http": {
|
||||
"uri": "_http/http.dart"
|
||||
},
|
||||
"_simd": {
|
||||
"uri": "_internal/wasm/lib/simd.dart"
|
||||
},
|
||||
"_typed_data": {
|
||||
"uri": "_internal/wasm/lib/typed_data.dart"
|
||||
},
|
||||
"_internal": {
|
||||
"uri": "internal/internal.dart",
|
||||
"patches": [
|
||||
|
@ -315,7 +321,6 @@
|
|||
"typed_data": {
|
||||
"uri": "typed_data/typed_data.dart",
|
||||
"patches": [
|
||||
"_internal/vm/lib/typed_data_patch.dart",
|
||||
"_internal/wasm/lib/typed_data_patch.dart",
|
||||
"_internal/wasm/lib/simd_patch.dart"
|
||||
]
|
||||
|
|
|
@ -188,6 +188,10 @@ wasm_common:
|
|||
uri: _internal/wasm/lib/double_helper.dart
|
||||
_http:
|
||||
uri: _http/http.dart
|
||||
_simd:
|
||||
uri: _internal/wasm/lib/simd.dart
|
||||
_typed_data:
|
||||
uri: _internal/wasm/lib/typed_data.dart
|
||||
_internal:
|
||||
uri: internal/internal.dart
|
||||
patches:
|
||||
|
@ -259,7 +263,6 @@ wasm_common:
|
|||
typed_data:
|
||||
uri: typed_data/typed_data.dart
|
||||
patches:
|
||||
- _internal/vm/lib/typed_data_patch.dart
|
||||
- _internal/wasm/lib/typed_data_patch.dart
|
||||
- _internal/wasm/lib/simd_patch.dart
|
||||
|
||||
|
|
Loading…
Reference in a new issue