| ... | ... | @@ -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 | |