authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2023-05-21 15:16:48+02:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2023-05-31 18:04:31+02:00
log00dedabc41322bc2b4978ddc39ee17b72193f194
tree7efb90f93aca22dd4b1a7dbdd1f0c1e3e0b6c85c
parentcd1417dbdf098634641e87dba4c3be2806d76250
signaturelock-open Commit is signed but in an unrecognized format.

wasm: `memcpy` support elem abi-size > 1

Previously it was incorrectly assumed that all memcopy's generated by the `memcpy` AIR instruction had an element size of 1 byte. However, this would result in miscompilations for pointer's to arrays where the element size of the array was larger than 1 byte. We now corectly calculate this size.

1 files changed, 14 insertions(+), 2 deletions(-)

src/arch/wasm/CodeGen.zig+14-2
......@@ -5295,11 +5295,23 @@ fn airMemcpy(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
52955295 const bin_op = func.air.instructions.items(.data)[inst].bin_op;
52965296 const dst = try func.resolveInst(bin_op.lhs);
52975297 const dst_ty = func.air.typeOf(bin_op.lhs);
5298 const ptr_elem_ty = dst_ty.childType();
52985299 const src = try func.resolveInst(bin_op.rhs);
52995300 const src_ty = func.air.typeOf(bin_op.rhs);
53005301 const len = switch (dst_ty.ptrSize()) {
5301 .Slice => try func.sliceLen(dst),
5302 .One => @as(WValue, .{ .imm32 = @intCast(u32, dst_ty.childType().arrayLen()) }),
5302 .Slice => blk: {
5303 const slice_len = try func.sliceLen(dst);
5304 if (ptr_elem_ty.abiSize(func.target) != 1) {
5305 try func.emitWValue(slice_len);
5306 try func.emitWValue(.{ .imm32 = @intCast(u32, ptr_elem_ty.abiSize(func.target)) });
5307 try func.addTag(.i32_mul);
5308 try func.addLabel(.local_set, slice_len.local.value);
5309 }
5310 break :blk slice_len;
5311 },
5312 .One => @as(WValue, .{
5313 .imm32 = @intCast(u32, ptr_elem_ty.arrayLen() * ptr_elem_ty.childType().abiSize(func.target)),
5314 }),
53035315 .C, .Many => unreachable,
53045316 };
53055317 const dst_ptr = try func.sliceOrArrayPtr(dst, dst_ty);