Skip to content

Commit 0e109ad

Browse files
committed
stage2-wasm: clean memcpy + fix another bug in aggr_init for optionals arr
1 parent 15bc2ab commit 0e109ad

File tree

2 files changed

+16
-11
lines changed

2 files changed

+16
-11
lines changed

src/arch/wasm/CodeGen.zig

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1588,12 +1588,18 @@ fn toWasmBits(bits: u16) ?u16 {
15881588
/// Performs a copy of bytes for a given type. Copying all bytes
15891589
/// from rhs to lhs.
15901590
fn memcpy(cg: *CodeGen, dst: WValue, src: WValue, len: WValue) !void {
1591+
const len_known_neq_0 = switch (len) {
1592+
.imm32 => |val| if (val != 0) true else return,
1593+
.imm64 => |val| if (val != 0) true else return,
1594+
else => false,
1595+
};
15911596
// When bulk_memory is enabled, we lower it to wasm's memcpy instruction.
15921597
// If not, we lower it ourselves manually
15931598
if (std.Target.wasm.featureSetHas(cg.target.cpu.features, .bulk_memory)) {
15941599
const len0_ok = std.Target.wasm.featureSetHas(cg.target.cpu.features, .nontrapping_bulk_memory_len0);
1600+
const emit_check = !(len0_ok or len_known_neq_0);
15951601

1596-
if (!len0_ok) {
1602+
if (emit_check) {
15971603
try cg.startBlock(.block, .empty);
15981604

15991605
// Even if `len` is zero, the spec requires an implementation to trap if `src + len` or
@@ -1616,7 +1622,7 @@ fn memcpy(cg: *CodeGen, dst: WValue, src: WValue, len: WValue) !void {
16161622
try cg.emitWValue(len);
16171623
try cg.addExtended(.memory_copy);
16181624

1619-
if (!len0_ok) {
1625+
if (emit_check) {
16201626
try cg.endBlock();
16211627
}
16221628

@@ -5196,9 +5202,7 @@ fn airAggregateInit(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
51965202
const result = try cg.allocStack(result_ty);
51975203
const elem_ty = result_ty.childType(zcu);
51985204
const elem_size = @as(u32, @intCast(elem_ty.abiSize(zcu)));
5199-
const sentinel = if (result_ty.sentinel(zcu)) |sent| blk: {
5200-
break :blk try cg.lowerConstant(sent, elem_ty);
5201-
} else null;
5205+
const sentinel = result_ty.sentinel(zcu);
52025206

52035207
// When the element type is by reference, we must copy the entire
52045208
// value. It is therefore safer to move the offset pointer and store
@@ -5211,12 +5215,13 @@ fn airAggregateInit(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
52115215
const elem_val = try cg.resolveInst(elem);
52125216
try cg.store(offset, elem_val, elem_ty, 0);
52135217

5214-
if (elem_index < elements.len - 1 and sentinel == null) {
5218+
if (elem_index < elements.len - 1 or sentinel != null) {
52155219
_ = try cg.buildPointerOffset(offset, elem_size, .modify);
52165220
}
52175221
}
5218-
if (sentinel) |sent| {
5219-
try cg.store(offset, sent, elem_ty, 0);
5222+
if (sentinel) |s| {
5223+
const val = try cg.resolveInst(Air.internedToRef(s.toIntern()));
5224+
try cg.store(offset, val, elem_ty, 0);
52205225
}
52215226
} else {
52225227
var offset: u32 = 0;
@@ -5225,8 +5230,9 @@ fn airAggregateInit(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
52255230
try cg.store(result, elem_val, elem_ty, offset);
52265231
offset += elem_size;
52275232
}
5228-
if (sentinel) |sent| {
5229-
try cg.store(result, sent, elem_ty, offset);
5233+
if (sentinel) |s| {
5234+
const val = try cg.resolveInst(Air.internedToRef(s.toIntern()));
5235+
try cg.store(result, val, elem_ty, offset);
52305236
}
52315237
}
52325238
break :result_value result;

test/behavior/tuple.zig

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,6 @@ test "tuple with runtime value coerced into a slice with a sentinel" {
507507
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
508508
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
509509
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
510-
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
511510
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
512511
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
513512

0 commit comments

Comments
 (0)