authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-01-21 20:06:03+01:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-01-25 19:00:48+01:00
log4b939fb34d3707258789e3ef71ff698a7d6bf552
tree8546f676e6d5429eaba1e4b742b5aea81878a143
parent0817d6b2150a00ab0d552888fc4822fced8e0f5f
signaturelock-open Commit is signed but in an unrecognized format.

wasm: Implement set_union_tag


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

src/arch/wasm/CodeGen.zig+27-2
...@@ -1454,6 +1454,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {...@@ -1454,6 +1454,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {
1454 .slice_ptr => self.airSlicePtr(inst),1454 .slice_ptr => self.airSlicePtr(inst),
1455 .store => self.airStore(inst),1455 .store => self.airStore(inst),
14561456
1457 .set_union_tag => self.airSetUnionTag(inst),
1457 .struct_field_ptr => self.airStructFieldPtr(inst),1458 .struct_field_ptr => self.airStructFieldPtr(inst),
1458 .struct_field_ptr_index_0 => self.airStructFieldPtrIndex(inst, 0),1459 .struct_field_ptr_index_0 => self.airStructFieldPtrIndex(inst, 0),
1459 .struct_field_ptr_index_1 => self.airStructFieldPtrIndex(inst, 1),1460 .struct_field_ptr_index_1 => self.airStructFieldPtrIndex(inst, 1),
...@@ -1494,7 +1495,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {...@@ -1494,7 +1495,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {
1494 .fpext,1495 .fpext,
1495 .unwrap_errunion_payload_ptr,1496 .unwrap_errunion_payload_ptr,
1496 .unwrap_errunion_err_ptr,1497 .unwrap_errunion_err_ptr,
1497 .set_union_tag,1498
1498 .get_union_tag,1499 .get_union_tag,
1499 .ptr_slice_len_ptr,1500 .ptr_slice_len_ptr,
1500 .ptr_slice_ptr_ptr,1501 .ptr_slice_ptr_ptr,
...@@ -1518,7 +1519,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {...@@ -1518,7 +1519,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {
1518 .sub_with_overflow,1519 .sub_with_overflow,
1519 .mul_with_overflow,1520 .mul_with_overflow,
1520 .shl_with_overflow,1521 .shl_with_overflow,
1521 => |tag| self.fail("TODO: Implement wasm inst: {s}", .{@tagName(tag)}),1522 => |tag| return self.fail("TODO: Implement wasm inst: {s}", .{@tagName(tag)}),
1522 };1523 };
1523}1524}
15241525
...@@ -1596,6 +1597,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index) InnerError!WValue {...@@ -1596,6 +1597,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
1596 break :blk func.data.owner_decl;1597 break :blk func.data.owner_decl;
1597 } else if (func_val.castTag(.extern_fn)) |ext_fn| {1598 } else if (func_val.castTag(.extern_fn)) |ext_fn| {
1598 break :blk ext_fn.data;1599 break :blk ext_fn.data;
1600 } else if (func_val.castTag(.decl_ref)) |decl_ref| {
1601 break :blk decl_ref.data;
1599 }1602 }
1600 return self.fail("Expected a function, but instead found type '{s}'", .{func_val.tag()});1603 return self.fail("Expected a function, but instead found type '{s}'", .{func_val.tag()});
1601 };1604 };
...@@ -3177,3 +3180,25 @@ fn cmpBigInt(self: *Self, lhs: WValue, rhs: WValue, operand_ty: Type, op: std.ma...@@ -3177,3 +3180,25 @@ fn cmpBigInt(self: *Self, lhs: WValue, rhs: WValue, operand_ty: Type, op: std.ma
3177 try self.addLabel(.local_set, result.local);3180 try self.addLabel(.local_set, result.local);
3178 return result;3181 return result;
3179}3182}
3183
3184fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
3185 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
3186 const un_ty = self.air.typeOf(bin_op.lhs).childType();
3187 const tag_ty = self.air.typeOf(bin_op.rhs);
3188 const layout = un_ty.unionGetLayout(self.target);
3189 if (layout.tag_size == 0) return WValue{ .none = {} };
3190 const union_ptr = try self.resolveInst(bin_op.lhs);
3191 const new_tag = try self.resolveInst(bin_op.rhs);
3192 if (layout.payload_size == 0) {
3193 try self.store(union_ptr, new_tag, tag_ty, 0);
3194 return WValue{ .none = {} };
3195 }
3196
3197 // when the tag alignment is smaller than the payload, the field will be stored
3198 // after the payload.
3199 const offset = if (layout.tag_align < layout.payload_align) blk: {
3200 break :blk @intCast(u32, layout.payload_size);
3201 } else @as(u32, 0);
3202 try self.store(union_ptr, new_tag, tag_ty, offset);
3203 return WValue{ .none = {} };
3204}