| ... | @@ -3130,7 +3130,13 @@ fn lowerPtr(cg: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerErro | ... | @@ -3130,7 +3130,13 @@ fn lowerPtr(cg: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerErro |
| 3130 | .nav => |nav| return .{ .nav_ref = .{ .nav_index = nav, .offset = @intCast(offset) } }, | 3130 | .nav => |nav| return .{ .nav_ref = .{ .nav_index = nav, .offset = @intCast(offset) } }, |
| 3131 | .uav => |uav| return .{ .uav_ref = .{ .ip_index = uav.val, .offset = @intCast(offset), .orig_ptr_ty = uav.orig_ty } }, | 3131 | .uav => |uav| return .{ .uav_ref = .{ .ip_index = uav.val, .offset = @intCast(offset), .orig_ptr_ty = uav.orig_ty } }, |
| 3132 | .int => return cg.lowerConstant(try pt.intValue(Type.usize, offset), Type.usize), | 3132 | .int => return cg.lowerConstant(try pt.intValue(Type.usize, offset), Type.usize), |
| 3133 | .eu_payload => return cg.fail("Wasm TODO: lower error union payload pointer", .{}), | 3133 | .eu_payload => |eu_ptr| try cg.lowerPtr( |
| | 3134 | eu_ptr, |
| | 3135 | offset + codegen.errUnionPayloadOffset( |
| | 3136 | Value.fromInterned(eu_ptr).typeOf(zcu).childType(zcu), |
| | 3137 | zcu, |
| | 3138 | ), |
| | 3139 | ), |
| 3134 | .opt_payload => |opt_ptr| return cg.lowerPtr(opt_ptr, offset), | 3140 | .opt_payload => |opt_ptr| return cg.lowerPtr(opt_ptr, offset), |
| 3135 | .field => |field| { | 3141 | .field => |field| { |
| 3136 | const base_ptr = Value.fromInterned(field.base); | 3142 | const base_ptr = Value.fromInterned(field.base); |
| ... | @@ -4179,52 +4185,62 @@ fn airIsErr(cg: *CodeGen, inst: Air.Inst.Index, opcode: std.wasm.Opcode) InnerEr | ... | @@ -4179,52 +4185,62 @@ fn airIsErr(cg: *CodeGen, inst: Air.Inst.Index, opcode: std.wasm.Opcode) InnerEr |
| 4179 | return cg.finishAir(inst, result, &.{un_op}); | 4185 | return cg.finishAir(inst, result, &.{un_op}); |
| 4180 | } | 4186 | } |
| 4181 | | 4187 | |
| | 4188 | /// E!T -> T op_is_ptr == false |
| | 4189 | /// *(E!T) -> *T op_is_prt == true |
| 4182 | fn airUnwrapErrUnionPayload(cg: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) InnerError!void { | 4190 | fn airUnwrapErrUnionPayload(cg: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) InnerError!void { |
| 4183 | const zcu = cg.pt.zcu; | 4191 | const zcu = cg.pt.zcu; |
| 4184 | const ty_op = cg.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 4192 | const ty_op = cg.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4185 | | 4193 | |
| 4186 | const operand = try cg.resolveInst(ty_op.operand); | 4194 | const operand = try cg.resolveInst(ty_op.operand); |
| 4187 | const op_ty = cg.typeOf(ty_op.operand); | 4195 | const op_ty = cg.typeOf(ty_op.operand); |
| 4188 | const err_ty = if (op_is_ptr) op_ty.childType(zcu) else op_ty; | 4196 | const eu_ty = if (op_is_ptr) op_ty.childType(zcu) else op_ty; |
| 4189 | const payload_ty = err_ty.errorUnionPayload(zcu); | 4197 | const payload_ty = eu_ty.errorUnionPayload(zcu); |
| 4190 | | 4198 | |
| 4191 | const result: WValue = result: { | 4199 | const result: WValue = result: { |
| 4192 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | 4200 | if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { |
| 4193 | if (op_is_ptr) { | 4201 | if (op_is_ptr) { |
| 4194 | break :result cg.reuseOperand(ty_op.operand, operand); | 4202 | break :result cg.reuseOperand(ty_op.operand, operand); |
| | 4203 | } else { |
| | 4204 | break :result .none; |
| 4195 | } | 4205 | } |
| 4196 | break :result .none; | | |
| 4197 | } | 4206 | } |
| 4198 | | 4207 | |
| 4199 | const pl_offset = @as(u32, @intCast(errUnionPayloadOffset(payload_ty, zcu))); | 4208 | const pl_offset: u32 = @intCast(errUnionPayloadOffset(payload_ty, zcu)); |
| 4200 | if (op_is_ptr or isByRef(payload_ty, zcu, cg.target)) { | 4209 | if (op_is_ptr or isByRef(payload_ty, zcu, cg.target)) { |
| 4201 | break :result try cg.buildPointerOffset(operand, pl_offset, .new); | 4210 | break :result try cg.buildPointerOffset(operand, pl_offset, .new); |
| | 4211 | } else { |
| | 4212 | assert(isByRef(eu_ty, zcu, cg.target)); |
| | 4213 | break :result try cg.load(operand, payload_ty, pl_offset); |
| 4202 | } | 4214 | } |
| 4203 | | 4215 | |
| 4204 | break :result try cg.load(operand, payload_ty, pl_offset); | | |
| 4205 | }; | 4216 | }; |
| 4206 | return cg.finishAir(inst, result, &.{ty_op.operand}); | 4217 | return cg.finishAir(inst, result, &.{ty_op.operand}); |
| 4207 | } | 4218 | } |
| 4208 | | 4219 | |
| | 4220 | /// E!T -> E op_is_ptr == false |
| | 4221 | /// *(E!T) -> E op_is_prt == true |
| | 4222 | /// NOTE: op_is_ptr will not change return type |
| 4209 | fn airUnwrapErrUnionError(cg: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) InnerError!void { | 4223 | fn airUnwrapErrUnionError(cg: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) InnerError!void { |
| 4210 | const zcu = cg.pt.zcu; | 4224 | const zcu = cg.pt.zcu; |
| 4211 | const ty_op = cg.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 4225 | const ty_op = cg.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 4212 | | 4226 | |
| 4213 | const operand = try cg.resolveInst(ty_op.operand); | 4227 | const operand = try cg.resolveInst(ty_op.operand); |
| 4214 | const op_ty = cg.typeOf(ty_op.operand); | 4228 | const op_ty = cg.typeOf(ty_op.operand); |
| 4215 | const err_ty = if (op_is_ptr) op_ty.childType(zcu) else op_ty; | 4229 | const eu_ty = if (op_is_ptr) op_ty.childType(zcu) else op_ty; |
| 4216 | const payload_ty = err_ty.errorUnionPayload(zcu); | 4230 | const payload_ty = eu_ty.errorUnionPayload(zcu); |
| 4217 | | 4231 | |
| 4218 | const result: WValue = result: { | 4232 | const result: WValue = result: { |
| 4219 | if (err_ty.errorUnionSet(zcu).errorSetIsEmpty(zcu)) { | 4233 | if (eu_ty.errorUnionSet(zcu).errorSetIsEmpty(zcu)) { |
| 4220 | break :result .{ .imm32 = 0 }; | 4234 | break :result .{ .imm32 = 0 }; |
| 4221 | } | 4235 | } |
| 4222 | | 4236 | |
| 4223 | if (op_is_ptr or !payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { | 4237 | const err_offset: u32 = @intCast(errUnionErrorOffset(payload_ty, zcu)); |
| | 4238 | if (op_is_ptr or isByRef(eu_ty, zcu, cg.target)) { |
| | 4239 | break :result try cg.load(operand, Type.anyerror, err_offset); |
| | 4240 | } else { |
| | 4241 | assert(!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)); |
| 4224 | break :result cg.reuseOperand(ty_op.operand, operand); | 4242 | break :result cg.reuseOperand(ty_op.operand, operand); |
| 4225 | } | 4243 | } |
| 4226 | | | |
| 4227 | break :result try cg.load(operand, Type.anyerror, @intCast(errUnionErrorOffset(payload_ty, zcu))); | | |
| 4228 | }; | 4244 | }; |
| 4229 | return cg.finishAir(inst, result, &.{ty_op.operand}); | 4245 | return cg.finishAir(inst, result, &.{ty_op.operand}); |
| 4230 | } | 4246 | } |