| ... | @@ -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), |
| 1456 | | 1456 | |
| | 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 | } |
| 1524 | | 1525 | |
| ... | @@ -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 | |
| | 3184 | fn 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 | } |