@@ -3130,7 +3130,13 @@ fn lowerPtr(cg: *CodeGen, ptr_val: InternPool.Index, prev_offset: u64) InnerErro
3130
3130
.nav = > | nav | return .{ .nav_ref = .{ .nav_index = nav , .offset = @intCast (offset ) } },
3131
3131
.uav = > | uav | return .{ .uav_ref = .{ .ip_index = uav .val , .offset = @intCast (offset ), .orig_ptr_ty = uav .orig_ty } },
3132
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
3140
.opt_payload = > | opt_ptr | return cg .lowerPtr (opt_ptr , offset ),
3135
3141
.field = > | field | {
3136
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
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
4190
fn airUnwrapErrUnionPayload (cg : * CodeGen , inst : Air.Inst.Index , op_is_ptr : bool ) InnerError ! void {
4183
4191
const zcu = cg .pt .zcu ;
4184
4192
const ty_op = cg .air .instructions .items (.data )[@intFromEnum (inst )].ty_op ;
4185
4193
4186
4194
const operand = try cg .resolveInst (ty_op .operand );
4187
4195
const op_ty = cg .typeOf (ty_op .operand );
4188
- const err_ty = if (op_is_ptr ) op_ty .childType (zcu ) else op_ty ;
4189
- const payload_ty = err_ty .errorUnionPayload (zcu );
4196
+ const eu_ty = if (op_is_ptr ) op_ty .childType (zcu ) else op_ty ;
4197
+ const payload_ty = eu_ty .errorUnionPayload (zcu );
4190
4198
4191
4199
const result : WValue = result : {
4192
4200
if (! payload_ty .hasRuntimeBitsIgnoreComptime (zcu )) {
4193
4201
if (op_is_ptr ) {
4194
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
4209
if (op_is_ptr or isByRef (payload_ty , zcu , cg .target )) {
4201
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
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
4223
fn airUnwrapErrUnionError (cg : * CodeGen , inst : Air.Inst.Index , op_is_ptr : bool ) InnerError ! void {
4210
4224
const zcu = cg .pt .zcu ;
4211
4225
const ty_op = cg .air .instructions .items (.data )[@intFromEnum (inst )].ty_op ;
4212
4226
4213
4227
const operand = try cg .resolveInst (ty_op .operand );
4214
4228
const op_ty = cg .typeOf (ty_op .operand );
4215
- const err_ty = if (op_is_ptr ) op_ty .childType (zcu ) else op_ty ;
4216
- const payload_ty = err_ty .errorUnionPayload (zcu );
4229
+ const eu_ty = if (op_is_ptr ) op_ty .childType (zcu ) else op_ty ;
4230
+ const payload_ty = eu_ty .errorUnionPayload (zcu );
4217
4231
4218
4232
const result : WValue = result : {
4219
- if (err_ty .errorUnionSet (zcu ).errorSetIsEmpty (zcu )) {
4233
+ if (eu_ty .errorUnionSet (zcu ).errorSetIsEmpty (zcu )) {
4220
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
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
4245
return cg .finishAir (inst , result , &.{ty_op .operand });
4230
4246
}
0 commit comments