[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:
Ömer Sinan Ağacan 2023-07-17 16:51:25 +00:00 committed by Commit Queue
parent ea790e901c
commit 1d8dde36e1
3 changed files with 47 additions and 2 deletions

View file

@ -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]!;

View file

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

View file

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