@@ -10414,11 +10414,12 @@ pub const Value = struct {
10414
10414
} },
10415
10415
.error_union => |error_union| {
10416
10416
const error_union_type = ip.indexToKey(error_union.ty).error_union_type;
10417
+ const error_set_ty: ZigType = .fromInterned(error_union_type.error_set_type);
10417
10418
const payload_ty: ZigType = .fromInterned(error_union_type.payload_type);
10418
- if (!ip.isNoReturn(error_union_type.error_set_type) and
10419
- offset == codegen.errUnionErrorOffset(payload_ty, zcu))
10420
- {
10421
- offset = 0 ;
10419
+ const error_set_offset = codegen.errUnionErrorOffset(payload_ty, zcu);
10420
+ const error_set_size = error_set_ty.abiSize( zcu);
10421
+ if (offset >= error_set_offset and offset + size <= error_set_offset + error_set_size) {
10422
+ offset -= error_set_offset ;
10422
10423
continue :constant_key switch (error_union.val) {
10423
10424
.err_name => |err_name| .{ .err = .{
10424
10425
.ty = error_union_type.error_set_type,
@@ -10430,15 +10431,18 @@ pub const Value = struct {
10430
10431
} },
10431
10432
};
10432
10433
}
10433
- assert(payload_ty.hasRuntimeBitsIgnoreComptime(zcu));
10434
- offset -= @intCast(codegen.errUnionPayloadOffset(payload_ty, zcu));
10435
- switch (error_union.val) {
10436
- .err_name => continue :constant_key .{ .undef = error_union_type.payload_type },
10437
- .payload => |payload| {
10438
- constant = payload;
10439
- constant_key = ip.indexToKey(payload);
10440
- continue :constant_key constant_key;
10441
- },
10434
+ const payload_offset = codegen.errUnionPayloadOffset(payload_ty, zcu);
10435
+ const payload_size = payload_ty.abiSize(zcu);
10436
+ if (offset >= payload_offset and offset + size <= payload_offset + payload_size) {
10437
+ offset -= payload_offset;
10438
+ switch (error_union.val) {
10439
+ .err_name => continue :constant_key .{ .undef = error_union_type.payload_type },
10440
+ .payload => |payload| {
10441
+ constant = payload;
10442
+ constant_key = ip.indexToKey(payload);
10443
+ continue :constant_key constant_key;
10444
+ },
10445
+ }
10442
10446
}
10443
10447
},
10444
10448
.enum_tag => |enum_tag| continue :constant_key .{ .int = ip.indexToKey(enum_tag.int).int },
@@ -10975,7 +10979,17 @@ fn hasRepeatedByteRepr(isel: *Select, constant: Constant) error{OutOfMemory}!?u8
10975
10979
fn writeToMemory(isel: *Select, constant: Constant, buffer: []u8) error{OutOfMemory}!bool {
10976
10980
const zcu = isel.pt.zcu;
10977
10981
const ip = &zcu.intern_pool;
10978
- switch (ip.indexToKey(constant.toIntern())) {
10982
+ if (try isel.writeKeyToMemory(ip.indexToKey(constant.toIntern()), buffer)) return true;
10983
+ constant.writeToMemory(isel.pt, buffer) catch |err| switch (err) {
10984
+ error.OutOfMemory => return error.OutOfMemory,
10985
+ error.ReinterpretDeclRef, error.Unimplemented, error.IllDefinedMemoryLayout => return false,
10986
+ };
10987
+ return true;
10988
+ }
10989
+ fn writeKeyToMemory(isel: *Select, constant_key: InternPool.Key, buffer: []u8) error{OutOfMemory}!bool {
10990
+ const zcu = isel.pt.zcu;
10991
+ const ip = &zcu.intern_pool;
10992
+ switch (constant_key) {
10979
10993
.int_type,
10980
10994
.ptr_type,
10981
10995
.array_type,
@@ -10997,6 +11011,37 @@ fn writeToMemory(isel: *Select, constant: Constant, buffer: []u8) error{OutOfMem
10997
11011
.empty_enum_value,
10998
11012
.memoized_call,
10999
11013
=> unreachable, // not a runtime value
11014
+ .err => |err| {
11015
+ const error_int = ip.getErrorValueIfExists(err.name).?;
11016
+ switch (buffer.len) {
11017
+ else => unreachable,
11018
+ inline 1...4 => |size| std.mem.writeInt(
11019
+ @Type(.{ .int = .{ .signedness = .unsigned, .bits = 8 * size } }),
11020
+ buffer[0..size],
11021
+ @intCast(error_int),
11022
+ isel.target.cpu.arch.endian(),
11023
+ ),
11024
+ }
11025
+ },
11026
+ .error_union => |error_union| {
11027
+ const error_union_type = ip.indexToKey(error_union.ty).error_union_type;
11028
+ const error_set_ty: ZigType = .fromInterned(error_union_type.error_set_type);
11029
+ const payload_ty: ZigType = .fromInterned(error_union_type.payload_type);
11030
+ const error_set = buffer[@intCast(codegen.errUnionErrorOffset(payload_ty, zcu))..][0..@intCast(error_set_ty.abiSize(zcu))];
11031
+ switch (error_union.val) {
11032
+ .err_name => |err_name| if (!try isel.writeKeyToMemory(.{ .err = .{
11033
+ .ty = error_set_ty.toIntern(),
11034
+ .name = err_name,
11035
+ } }, error_set)) return false,
11036
+ .payload => |payload| {
11037
+ if (!try isel.writeToMemory(
11038
+ .fromInterned(payload),
11039
+ buffer[@intCast(codegen.errUnionPayloadOffset(payload_ty, zcu))..][0..@intCast(payload_ty.abiSize(zcu))],
11040
+ )) return false;
11041
+ @memset(error_set, 0);
11042
+ },
11043
+ }
11044
+ },
11000
11045
.opt => |opt| {
11001
11046
const child_size: usize = @intCast(ZigType.fromInterned(ip.indexToKey(opt.ty).opt_type).abiSize(zcu));
11002
11047
switch (opt.val) {
@@ -11008,7 +11053,6 @@ fn writeToMemory(isel: *Select, constant: Constant, buffer: []u8) error{OutOfMem
11008
11053
if (!ZigType.fromInterned(opt.ty).optionalReprIsPayload(zcu)) buffer[child_size] = @intFromBool(true);
11009
11054
},
11010
11055
}
11011
- return true;
11012
11056
},
11013
11057
.aggregate => |aggregate| switch (ip.indexToKey(aggregate.ty)) {
11014
11058
else => unreachable,
@@ -11027,9 +11071,8 @@ fn writeToMemory(isel: *Select, constant: Constant, buffer: []u8) error{OutOfMem
11027
11071
elem_offset += elem_size;
11028
11072
},
11029
11073
}
11030
- return true;
11031
11074
},
11032
- .vector_type => {} ,
11075
+ .vector_type => return false ,
11033
11076
.struct_type => {
11034
11077
const loaded_struct = ip.loadStructType(aggregate.ty);
11035
11078
switch (loaded_struct.layout) {
@@ -11052,9 +11095,8 @@ fn writeToMemory(isel: *Select, constant: Constant, buffer: []u8) error{OutOfMem
11052
11095
}), buffer[@intCast(field_offset)..][0..@intCast(field_size)])) return false;
11053
11096
field_offset += field_size;
11054
11097
}
11055
- return true;
11056
11098
},
11057
- .@"extern", .@"packed" => {} ,
11099
+ .@"extern", .@"packed" => return false ,
11058
11100
}
11059
11101
},
11060
11102
.tuple_type => |tuple_type| {
@@ -11071,15 +11113,10 @@ fn writeToMemory(isel: *Select, constant: Constant, buffer: []u8) error{OutOfMem
11071
11113
}), buffer[@intCast(field_offset)..][0..@intCast(field_size)])) return false;
11072
11114
field_offset += field_size;
11073
11115
}
11074
- return true;
11075
11116
},
11076
11117
},
11077
- else => {} ,
11118
+ else => return false ,
11078
11119
}
11079
- constant.writeToMemory(isel.pt, buffer) catch |err| switch (err) {
11080
- error.OutOfMemory => return error.OutOfMemory,
11081
- error.ReinterpretDeclRef, error.Unimplemented, error.IllDefinedMemoryLayout => return false,
11082
- };
11083
11120
return true;
11084
11121
}
11085
11122
0 commit comments