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...@@ -1589,8 +1589,14 @@ fn store(self: *Self, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerErro
1589 // Load values from `rhs` stack position and store in `lhs` instead1589 // Load values from `rhs` stack position and store in `lhs` instead
1590 const tag_local = try self.load(rhs, tag_ty, 0);1590 const tag_local = try self.load(rhs, tag_ty, 0);
1591 if (payload_ty.hasCodeGenBits()) {1591 if (payload_ty.hasCodeGenBits()) {
1592 const payload_local = try self.load(rhs, payload_ty, payload_offset);1592 if (isByRef(payload_ty)) {
1593 try self.store(lhs, payload_local, payload_ty, payload_offset);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 }
1594 }1600 }
1595 return try self.store(lhs, tag_local, tag_ty, 0);1601 return try self.store(lhs, tag_local, tag_ty, 0);
1596 },1602 },
...@@ -1633,12 +1639,9 @@ fn store(self: *Self, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerErro...@@ -1633,12 +1639,9 @@ fn store(self: *Self, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerErro
1633 const len_offset = self.ptrSize();1639 const len_offset = self.ptrSize();
1634 if (val.castTag(.decl_ref)) |decl| {1640 if (val.castTag(.decl_ref)) |decl| {
1635 // for decl references we also need to retrieve the length and the original decl's pointer1641 // 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() });
1637 try self.addLabel(.memory_address, decl.data.link.wasm.sym_index);1643 try self.addLabel(.memory_address, decl.data.link.wasm.sym_index);
1638 try self.addMemArg(1644 try self.addMemArg(.i32_load, .{ .offset = len_offset, .alignment = self.ptrSize() });
1639 .i32_load,
1640 .{ .offset = len_offset, .alignment = Type.@"usize".abiAlignment(self.target) },
1641 );
1642 }1645 }
1643 try self.addLabel(.local_set, len_local.local);1646 try self.addLabel(.local_set, len_local.local);
1644 try self.addLabel(.local_set, ptr_local.local);1647 try self.addLabel(.local_set, ptr_local.local);
...@@ -1709,7 +1712,9 @@ fn load(self: *Self, operand: WValue, ty: Type, offset: u32) InnerError!WValue {...@@ -1709,7 +1712,9 @@ fn load(self: *Self, operand: WValue, ty: Type, offset: u32) InnerError!WValue {
1709 // load local's value from memory by its stack position1712 // load local's value from memory by its stack position
1710 try self.emitWValue(operand);1713 try self.emitWValue(operand);
1711 // Build the opcode with the right bitsize1714 // 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)
1713 .unsigned1718 .unsigned
1714 else1719 else
1715 .signed;1720 .signed;
...@@ -1952,11 +1957,16 @@ fn emitConstant(self: *Self, val: Value, ty: Type) InnerError!void {...@@ -1952,11 +1957,16 @@ fn emitConstant(self: *Self, val: Value, ty: Type) InnerError!void {
1952 const result = try self.allocStack(ty);1957 const result = try self.allocStack(ty);
19531958
1954 const fields = ty.structFields();1959 const fields = ty.structFields();
1960 var offset: u32 = 0;
1955 for (fields.values()) |field, index| {1961 for (fields.values()) |field, index| {
1962 if (isByRef(field.ty)) {
1963 return self.fail("TODO: emitConstant for struct field type {}\n", .{field.ty});
1964 }
1956 const tmp = try self.allocLocal(field.ty);1965 const tmp = try self.allocLocal(field.ty);
1957 try self.emitConstant(struct_data.data[index], field.ty);1966 try self.emitConstant(struct_data.data[index], field.ty);
1958 try self.addLabel(.local_set, tmp.local);1967 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));
1960 }1970 }
1961 try self.addLabel(.local_get, result.local);1971 try self.addLabel(.local_get, result.local);
1962 },1972 },
...@@ -2187,7 +2197,7 @@ fn airNot(self: *Self, inst: Air.Inst.Index) InnerError!WValue {...@@ -2187,7 +2197,7 @@ fn airNot(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
2187 try self.addTag(.i32_eq);2197 try self.addTag(.i32_eq);
21882198
2189 // save the result in the local2199 // 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));
2191 try self.addLabel(.local_set, not_tmp.local);2201 try self.addLabel(.local_set, not_tmp.local);
2192 return not_tmp;2202 return not_tmp;
2193}2203}
...@@ -2656,7 +2666,9 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) InnerError!WValue {...@@ -2656,7 +2666,9 @@ fn airWrapOptional(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
2656 try self.addLabel(.local_get, result.local);2666 try self.addLabel(.local_get, result.local);
2657 try self.addImm32(1);2667 try self.addImm32(1);
2658 try self.addMemArg(.i32_store8, .{ .offset = 0, .alignment = 1 });2668 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
2661 return result;2673 return result;
2662}2674}