| ... | ... | @@ -1454,6 +1454,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { |
| 1454 | 1454 | .slice_ptr => self.airSlicePtr(inst), |
| 1455 | 1455 | .store => self.airStore(inst), |
| 1456 | 1456 | |
| 1457 | .set_union_tag => self.airSetUnionTag(inst), |
| 1457 | 1458 | .struct_field_ptr => self.airStructFieldPtr(inst), |
| 1458 | 1459 | .struct_field_ptr_index_0 => self.airStructFieldPtrIndex(inst, 0), |
| 1459 | 1460 | .struct_field_ptr_index_1 => self.airStructFieldPtrIndex(inst, 1), |
| ... | ... | @@ -1494,7 +1495,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { |
| 1494 | 1495 | .fpext, |
| 1495 | 1496 | .unwrap_errunion_payload_ptr, |
| 1496 | 1497 | .unwrap_errunion_err_ptr, |
| 1497 | | .set_union_tag, |
| 1498 | |
| 1498 | 1499 | .get_union_tag, |
| 1499 | 1500 | .ptr_slice_len_ptr, |
| 1500 | 1501 | .ptr_slice_ptr_ptr, |
| ... | ... | @@ -1518,7 +1519,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue { |
| 1518 | 1519 | .sub_with_overflow, |
| 1519 | 1520 | .mul_with_overflow, |
| 1520 | 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 | 1597 | break :blk func.data.owner_decl; |
| 1597 | 1598 | } else if (func_val.castTag(.extern_fn)) |ext_fn| { |
| 1598 | 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 | 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 | 3180 | try self.addLabel(.local_set, result.local); |
| 3178 | 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 | } |