diff options
| author | Luuk de Gram <luuk@degram.dev> | 2023-05-21 15:16:48 +0200 |
|---|---|---|
| committer | Luuk de Gram <luuk@degram.dev> | 2023-05-31 18:04:31 +0200 |
| commit | 00dedabc41322bc2b4978ddc39ee17b72193f194 (patch) | |
| tree | 7efb90f93aca22dd4b1a7dbdd1f0c1e3e0b6c85c | |
| parent | cd1417dbdf098634641e87dba4c3be2806d76250 (diff) | |
| download | zig-00dedabc41322bc2b4978ddc39ee17b72193f194.tar.gz zig-00dedabc41322bc2b4978ddc39ee17b72193f194.zip | |
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.
| -rw-r--r-- | src/arch/wasm/CodeGen.zig | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig index bdbe9640c2..7872d89e9b 100644 --- a/src/arch/wasm/CodeGen.zig +++ b/src/arch/wasm/CodeGen.zig @@ -5295,11 +5295,23 @@ fn airMemcpy(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { const bin_op = func.air.instructions.items(.data)[inst].bin_op; const dst = try func.resolveInst(bin_op.lhs); const dst_ty = func.air.typeOf(bin_op.lhs); + const ptr_elem_ty = dst_ty.childType(); const src = try func.resolveInst(bin_op.rhs); const src_ty = func.air.typeOf(bin_op.rhs); const len = switch (dst_ty.ptrSize()) { - .Slice => try func.sliceLen(dst), - .One => @as(WValue, .{ .imm32 = @intCast(u32, dst_ty.childType().arrayLen()) }), + .Slice => blk: { + const slice_len = try func.sliceLen(dst); + if (ptr_elem_ty.abiSize(func.target) != 1) { + try func.emitWValue(slice_len); + try func.emitWValue(.{ .imm32 = @intCast(u32, ptr_elem_ty.abiSize(func.target)) }); + try func.addTag(.i32_mul); + try func.addLabel(.local_set, slice_len.local.value); + } + break :blk slice_len; + }, + .One => @as(WValue, .{ + .imm32 = @intCast(u32, ptr_elem_ty.arrayLen() * ptr_elem_ty.childType().abiSize(func.target)), + }), .C, .Many => unreachable, }; const dst_ptr = try func.sliceOrArrayPtr(dst, dst_ty); |
