mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 00:13:50 +00:00
[dart2wasm] Add array.copy instruction and intrinsics
`array.copy` is used in [1] in `setRange` when source and destinations are both typed arrays with the same Wasm array type. [1]: https://dart-review.googlesource.com/c/sdk/+/312907 Change-Id: Iaeecea43c22805eca64b7d98751a52e607210a70 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/314080 Reviewed-by: Joshua Litt <joshualitt@google.com> Commit-Queue: Ömer Ağacan <omersa@google.com>
This commit is contained in:
parent
ea790e901c
commit
1d8dde36e1
|
@ -410,11 +410,35 @@ class Intrinsifier {
|
|||
}
|
||||
b.array_set(arrayType);
|
||||
return codeGen.voidMarker;
|
||||
default:
|
||||
throw "Unsupported array method: $name";
|
||||
}
|
||||
}
|
||||
|
||||
// WasmIntArray.copy
|
||||
// WasmFloatArray.copy
|
||||
if (cls.superclass == translator.wasmArrayRefClass && name == 'copy') {
|
||||
final DartType elementType =
|
||||
(receiverType as InterfaceType).typeArguments.single;
|
||||
final w.ArrayType arrayType =
|
||||
translator.arrayTypeForDartType(elementType);
|
||||
|
||||
final Expression destArray = receiver;
|
||||
final Expression destOffset = node.arguments.positional[0];
|
||||
final Expression sourceArray = node.arguments.positional[1];
|
||||
final Expression sourceOffset = node.arguments.positional[2];
|
||||
final Expression size = node.arguments.positional[3];
|
||||
|
||||
codeGen.wrap(destArray, w.RefType.def(arrayType, nullable: false));
|
||||
codeGen.wrap(destOffset, w.NumType.i64);
|
||||
b.i32_wrap_i64();
|
||||
codeGen.wrap(sourceArray, w.RefType.def(arrayType, nullable: false));
|
||||
codeGen.wrap(sourceOffset, w.NumType.i64);
|
||||
b.i32_wrap_i64();
|
||||
codeGen.wrap(size, w.NumType.i64);
|
||||
b.i32_wrap_i64();
|
||||
b.array_copy(arrayType, arrayType);
|
||||
return codeGen.voidMarker;
|
||||
}
|
||||
|
||||
// Wasm(I32|I64|F32|F64) conversions
|
||||
if (cls.superclass?.superclass == translator.wasmTypesBaseClass) {
|
||||
w.StorageType receiverType = translator.builtinTypes[cls]!;
|
||||
|
|
|
@ -1111,6 +1111,23 @@ class Instructions with SerializerMixin {
|
|||
if (isGlobalInitializer) module.dataReferencedFromGlobalInitializer = true;
|
||||
}
|
||||
|
||||
void array_copy(ArrayType destArrayType, ArrayType sourceArrayType) {
|
||||
assert(_verifyTypes([
|
||||
RefType.def(destArrayType, nullable: true), // dest
|
||||
NumType.i32, // dest_offset
|
||||
RefType.def(sourceArrayType, nullable: true), // source
|
||||
NumType.i32, // source_offset
|
||||
NumType.i32 // size
|
||||
], [], trace: [
|
||||
'array.copy',
|
||||
destArrayType,
|
||||
sourceArrayType
|
||||
]));
|
||||
writeBytes(const [0xFB, 0x18]);
|
||||
writeUnsigned(destArrayType.index);
|
||||
writeUnsigned(sourceArrayType.index);
|
||||
}
|
||||
|
||||
/// Emit an `i31.new` instruction.
|
||||
void i31_new() {
|
||||
assert(_verifyTypes(
|
||||
|
|
|
@ -180,6 +180,8 @@ class WasmIntArray<T extends _WasmInt> extends WasmArrayRef {
|
|||
external int readSigned(int index);
|
||||
external int readUnsigned(int index);
|
||||
external void write(int index, int value);
|
||||
external void copy(
|
||||
int offset, WasmIntArray<T> source, int sourceOffset, int size);
|
||||
}
|
||||
|
||||
/// A Wasm array with float element type.
|
||||
|
@ -189,6 +191,8 @@ class WasmFloatArray<T extends _WasmFloat> extends WasmArrayRef {
|
|||
|
||||
external double read(int index);
|
||||
external void write(int index, double value);
|
||||
external void copy(
|
||||
int offset, WasmFloatArray<T> source, int sourceOffset, int size);
|
||||
}
|
||||
|
||||
/// A Wasm array with reference element type, containing Dart objects.
|
||||
|
|
Loading…
Reference in a new issue