authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-01-03 22:19:52+01:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-01-04 17:51:24+01:00
logc888485f854111ba20bb35255c6e82c99af31a03
tree07f1da41d69ac9f28b43a0296076b7cb5e72aded
parentc519d9c80e5b207a84b9bd414727bd41cb4fadfa
signaturelock-open Commit is signed but in an unrecognized format.

wasm: Fix lowering constant struct values to the stack

We now get the null.zig, this.zig and member_func.zig behavior tests passing.

1 files changed, 23 insertions(+), 11 deletions(-)

src/arch/wasm/CodeGen.zig+23-11
......@@ -1589,8 +1589,14 @@ fn store(self: *Self, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerErro
15891589 // Load values from `rhs` stack position and store in `lhs` instead
15901590 const tag_local = try self.load(rhs, tag_ty, 0);
15911591 if (payload_ty.hasCodeGenBits()) {
1592 const payload_local = try self.load(rhs, payload_ty, payload_offset);
1593 try self.store(lhs, payload_local, payload_ty, payload_offset);
1592 if (isByRef(payload_ty)) {
1593 const payload_ptr = try self.buildPointerOffset(rhs, payload_offset);
1594 const lhs_payload_ptr = try self.buildPointerOffset(lhs, payload_offset);
1595 try self.store(lhs_payload_ptr, payload_ptr, payload_ty, 0);
1596 } else {
1597 const payload_local = try self.load(rhs, payload_ty, payload_offset);
1598 try self.store(lhs, payload_local, payload_ty, payload_offset);
1599 }
15941600 }
15951601 return try self.store(lhs, tag_local, tag_ty, 0);
15961602 },
......@@ -1633,12 +1639,9 @@ fn store(self: *Self, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerErro
16331639 const len_offset = self.ptrSize();
16341640 if (val.castTag(.decl_ref)) |decl| {
16351641 // for decl references we also need to retrieve the length and the original decl's pointer
1636 try self.addMemArg(.i32_load, .{ .offset = 0, .alignment = Type.@"usize".abiAlignment(self.target) });
1642 try self.addMemArg(.i32_load, .{ .offset = 0, .alignment = self.ptrSize() });
16371643 try self.addLabel(.memory_address, decl.data.link.wasm.sym_index);
1638 try self.addMemArg(
1639 .i32_load,
1640 .{ .offset = len_offset, .alignment = Type.@"usize".abiAlignment(self.target) },
1641 );
1644 try self.addMemArg(.i32_load, .{ .offset = len_offset, .alignment = self.ptrSize() });
16421645 }
16431646 try self.addLabel(.local_set, len_local.local);
16441647 try self.addLabel(.local_set, ptr_local.local);
......@@ -1709,7 +1712,9 @@ fn load(self: *Self, operand: WValue, ty: Type, offset: u32) InnerError!WValue {
17091712 // load local's value from memory by its stack position
17101713 try self.emitWValue(operand);
17111714 // Build the opcode with the right bitsize
1712 const signedness: std.builtin.Signedness = if (ty.isUnsignedInt() or ty.zigTypeTag() == .ErrorSet)
1715 const signedness: std.builtin.Signedness = if (ty.isUnsignedInt() or
1716 ty.zigTypeTag() == .ErrorSet or
1717 ty.zigTypeTag() == .Bool)
17131718 .unsigned
17141719 else
17151720 .signed;
......@@ -1952,11 +1957,16 @@ fn emitConstant(self: *Self, val: Value, ty: Type) InnerError!void {
19521957 const result = try self.allocStack(ty);
19531958
19541959 const fields = ty.structFields();
1960 var offset: u32 = 0;
19551961 for (fields.values()) |field, index| {
1962 if (isByRef(field.ty)) {
1963 return self.fail("TODO: emitConstant for struct field type {}\n", .{field.ty});
1964 }
19561965 const tmp = try self.allocLocal(field.ty);
19571966 try self.emitConstant(struct_data.data[index], field.ty);
19581967 try self.addLabel(.local_set, tmp.local);
1959 try self.store(result, tmp, field.ty, field.offset);
1968 try self.store(result, tmp, field.ty, offset);
1969 offset += @intCast(u32, field.ty.abiSize(self.target));
19601970 }
19611971 try self.addLabel(.local_get, result.local);
19621972 },
......@@ -2187,7 +2197,7 @@ fn airNot(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
21872197 try self.addTag(.i32_eq);
21882198
21892199 // save the result in the local
2190 const not_tmp = try self.allocLocal(self.air.getRefType(ty_op.ty));
2200 const not_tmp = try self.allocLocal(Type.initTag(.i32));
21912201 try self.addLabel(.local_set, not_tmp.local);
21922202 return not_tmp;
21932203}
......@@ -2656,7 +2666,9 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
26562666 try self.addLabel(.local_get, result.local);
26572667 try self.addImm32(1);
26582668 try self.addMemArg(.i32_store8, .{ .offset = 0, .alignment = 1 });
2659 try self.store(result, operand, payload_ty, offset);
2669
2670 const payload_ptr = try self.buildPointerOffset(result, offset);
2671 try self.store(payload_ptr, operand, payload_ty, 0);
26602672
26612673 return result;
26622674}