| ... | @@ -1270,7 +1270,8 @@ pub const Object = struct { | ... | @@ -1270,7 +1270,8 @@ pub const Object = struct { |
| 1270 | offset = std.mem.alignForwardGeneric(u64, offset, payload_align); | 1270 | offset = std.mem.alignForwardGeneric(u64, offset, payload_align); |
| 1271 | const payload_offset = offset; | 1271 | const payload_offset = offset; |
| 1272 | | 1272 | |
| 1273 | const fields: [2]*llvm.DIType = .{ | 1273 | var len: u8 = 2; |
| | 1274 | var fields: [3]*llvm.DIType = .{ |
| 1274 | dib.createMemberType( | 1275 | dib.createMemberType( |
| 1275 | fwd_decl.toScope(), | 1276 | fwd_decl.toScope(), |
| 1276 | "tag", | 1277 | "tag", |
| ... | @@ -1293,8 +1294,22 @@ pub const Object = struct { | ... | @@ -1293,8 +1294,22 @@ pub const Object = struct { |
| 1293 | 0, // flags | 1294 | 0, // flags |
| 1294 | try o.lowerDebugType(payload_ty, .full), | 1295 | try o.lowerDebugType(payload_ty, .full), |
| 1295 | ), | 1296 | ), |
| | 1297 | undefined, |
| 1296 | }; | 1298 | }; |
| 1297 | | 1299 | |
| | 1300 | const error_size = Type.anyerror.abiSize(target); |
| | 1301 | if (payload_align > error_size) { |
| | 1302 | fields[2] = fields[1]; |
| | 1303 | const pad_len = @intCast(u32, payload_align - error_size); |
| | 1304 | fields[1] = dib.createArrayType( |
| | 1305 | pad_len * 8, |
| | 1306 | 8, |
| | 1307 | try o.lowerDebugType(Type.u8, .full), |
| | 1308 | @intCast(c_int, pad_len), |
| | 1309 | ); |
| | 1310 | len += 1; |
| | 1311 | } |
| | 1312 | |
| 1298 | const full_di_ty = dib.createStructType( | 1313 | const full_di_ty = dib.createStructType( |
| 1299 | compile_unit_scope, | 1314 | compile_unit_scope, |
| 1300 | name.ptr, | 1315 | name.ptr, |
| ... | @@ -1305,7 +1320,7 @@ pub const Object = struct { | ... | @@ -1305,7 +1320,7 @@ pub const Object = struct { |
| 1305 | 0, // flags | 1320 | 0, // flags |
| 1306 | null, // derived from | 1321 | null, // derived from |
| 1307 | &fields, | 1322 | &fields, |
| 1308 | fields.len, | 1323 | len, |
| 1309 | 0, // run time lang | 1324 | 0, // run time lang |
| 1310 | null, // vtable holder | 1325 | null, // vtable holder |
| 1311 | "", // unique id | 1326 | "", // unique id |
| ... | @@ -2156,8 +2171,16 @@ pub const DeclGen = struct { | ... | @@ -2156,8 +2171,16 @@ pub const DeclGen = struct { |
| 2156 | } | 2171 | } |
| 2157 | const llvm_payload_type = try dg.llvmType(payload_type); | 2172 | const llvm_payload_type = try dg.llvmType(payload_type); |
| 2158 | | 2173 | |
| 2159 | const fields: [2]*const llvm.Type = .{ llvm_error_type, llvm_payload_type }; | 2174 | const payload_align = payload_type.abiAlignment(target); |
| 2160 | return dg.context.structType(&fields, fields.len, .False); | 2175 | const error_size = error_type.abiSize(target); |
| | 2176 | if (payload_align > error_size) { |
| | 2177 | const pad_type = dg.context.intType(8).arrayType(@intCast(u32, payload_align - error_size)); |
| | 2178 | const fields: [3]*const llvm.Type = .{ llvm_error_type, pad_type, llvm_payload_type }; |
| | 2179 | return dg.context.structType(&fields, fields.len, .False); |
| | 2180 | } else { |
| | 2181 | const fields: [2]*const llvm.Type = .{ llvm_error_type, llvm_payload_type }; |
| | 2182 | return dg.context.structType(&fields, fields.len, .False); |
| | 2183 | } |
| 2161 | }, | 2184 | }, |
| 2162 | .ErrorSet => { | 2185 | .ErrorSet => { |
| 2163 | return dg.context.intType(16); | 2186 | return dg.context.intType(16); |
| ... | @@ -2687,8 +2710,8 @@ pub const DeclGen = struct { | ... | @@ -2687,8 +2710,8 @@ pub const DeclGen = struct { |
| 2687 | const err_val = if (!is_pl) tv.val else Value.initTag(.zero); | 2710 | const err_val = if (!is_pl) tv.val else Value.initTag(.zero); |
| 2688 | return dg.genTypedValue(.{ .ty = error_type, .val = err_val }); | 2711 | return dg.genTypedValue(.{ .ty = error_type, .val = err_val }); |
| 2689 | } | 2712 | } |
| 2690 | | 2713 | var len: u8 = 2; |
| 2691 | const fields: [2]*const llvm.Value = .{ | 2714 | var fields: [3]*const llvm.Value = .{ |
| 2692 | try dg.genTypedValue(.{ | 2715 | try dg.genTypedValue(.{ |
| 2693 | .ty = error_type, | 2716 | .ty = error_type, |
| 2694 | .val = if (is_pl) Value.initTag(.zero) else tv.val, | 2717 | .val = if (is_pl) Value.initTag(.zero) else tv.val, |
| ... | @@ -2697,8 +2720,18 @@ pub const DeclGen = struct { | ... | @@ -2697,8 +2720,18 @@ pub const DeclGen = struct { |
| 2697 | .ty = payload_type, | 2720 | .ty = payload_type, |
| 2698 | .val = if (tv.val.castTag(.eu_payload)) |pl| pl.data else Value.initTag(.undef), | 2721 | .val = if (tv.val.castTag(.eu_payload)) |pl| pl.data else Value.initTag(.undef), |
| 2699 | }), | 2722 | }), |
| | 2723 | undefined, |
| 2700 | }; | 2724 | }; |
| 2701 | return dg.context.constStruct(&fields, fields.len, .False); | 2725 | |
| | 2726 | const payload_align = payload_type.abiAlignment(target); |
| | 2727 | const error_size = error_type.abiSize(target); |
| | 2728 | if (payload_align > error_size) { |
| | 2729 | fields[2] = fields[1]; |
| | 2730 | const pad_type = dg.context.intType(8).arrayType(@intCast(u32, payload_align - error_size)); |
| | 2731 | fields[1] = pad_type.getUndef(); |
| | 2732 | len += 1; |
| | 2733 | } |
| | 2734 | return dg.context.constStruct(&fields, len, .False); |
| 2702 | }, | 2735 | }, |
| 2703 | .Struct => { | 2736 | .Struct => { |
| 2704 | const llvm_struct_ty = try dg.llvmType(tv.ty); | 2737 | const llvm_struct_ty = try dg.llvmType(tv.ty); |
| ... | @@ -3143,10 +3176,11 @@ pub const DeclGen = struct { | ... | @@ -3143,10 +3176,11 @@ pub const DeclGen = struct { |
| 3143 | break :blk parent_llvm_ptr; | 3176 | break :blk parent_llvm_ptr; |
| 3144 | } | 3177 | } |
| 3145 | | 3178 | |
| | 3179 | const payload_offset: u8 = if (payload_ty.abiAlignment(target) > Type.anyerror.abiSize(target)) 2 else 1; |
| 3146 | const llvm_u32 = dg.context.intType(32); | 3180 | const llvm_u32 = dg.context.intType(32); |
| 3147 | const indices: [2]*const llvm.Value = .{ | 3181 | const indices: [2]*const llvm.Value = .{ |
| 3148 | llvm_u32.constInt(0, .False), | 3182 | llvm_u32.constInt(0, .False), |
| 3149 | llvm_u32.constInt(1, .False), | 3183 | llvm_u32.constInt(payload_offset, .False), |
| 3150 | }; | 3184 | }; |
| 3151 | break :blk parent_llvm_ptr.constInBoundsGEP(&indices, indices.len); | 3185 | break :blk parent_llvm_ptr.constInBoundsGEP(&indices, indices.len); |
| 3152 | }, | 3186 | }, |
| ... | @@ -4834,11 +4868,14 @@ pub const FuncGen = struct { | ... | @@ -4834,11 +4868,14 @@ pub const FuncGen = struct { |
| 4834 | const result_ty = self.air.getRefType(ty_op.ty); | 4868 | const result_ty = self.air.getRefType(ty_op.ty); |
| 4835 | const payload_ty = if (operand_is_ptr) result_ty.childType() else result_ty; | 4869 | const payload_ty = if (operand_is_ptr) result_ty.childType() else result_ty; |
| 4836 | | 4870 | |
| | 4871 | const target = self.dg.module.getTarget(); |
| | 4872 | const offset: u8 = if (payload_ty.abiAlignment(target) > Type.anyerror.abiSize(target)) 2 else 1; |
| | 4873 | |
| 4837 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) return null; | 4874 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) return null; |
| 4838 | if (operand_is_ptr or isByRef(payload_ty)) { | 4875 | if (operand_is_ptr or isByRef(payload_ty)) { |
| 4839 | return self.builder.buildStructGEP(operand, 1, ""); | 4876 | return self.builder.buildStructGEP(operand, offset, ""); |
| 4840 | } | 4877 | } |
| 4841 | return self.builder.buildExtractValue(operand, 1, ""); | 4878 | return self.builder.buildExtractValue(operand, offset, ""); |
| 4842 | } | 4879 | } |
| 4843 | | 4880 | |
| 4844 | fn airErrUnionErr( | 4881 | fn airErrUnionErr( |
| ... | @@ -4894,9 +4931,12 @@ pub const FuncGen = struct { | ... | @@ -4894,9 +4931,12 @@ pub const FuncGen = struct { |
| 4894 | // Then return the payload pointer (only if it is used). | 4931 | // Then return the payload pointer (only if it is used). |
| 4895 | if (self.liveness.isUnused(inst)) | 4932 | if (self.liveness.isUnused(inst)) |
| 4896 | return null; | 4933 | return null; |
| | 4934 | |
| | 4935 | const target = self.dg.module.getTarget(); |
| | 4936 | const payload_offset: u8 = if (payload_ty.abiAlignment(target) > Type.anyerror.abiSize(target)) 2 else 1; |
| 4897 | const indices: [2]*const llvm.Value = .{ | 4937 | const indices: [2]*const llvm.Value = .{ |
| 4898 | index_type.constNull(), // dereference the pointer | 4938 | index_type.constNull(), // dereference the pointer |
| 4899 | index_type.constInt(1, .False), // second field is the payload | 4939 | index_type.constInt(payload_offset, .False), // second field is the payload |
| 4900 | }; | 4940 | }; |
| 4901 | return self.builder.buildInBoundsGEP(operand, &indices, indices.len, ""); | 4941 | return self.builder.buildInBoundsGEP(operand, &indices, indices.len, ""); |
| 4902 | } | 4942 | } |
| ... | @@ -4941,11 +4981,14 @@ pub const FuncGen = struct { | ... | @@ -4941,11 +4981,14 @@ pub const FuncGen = struct { |
| 4941 | const inst_ty = self.air.typeOfIndex(inst); | 4981 | const inst_ty = self.air.typeOfIndex(inst); |
| 4942 | const ok_err_code = self.context.intType(16).constNull(); | 4982 | const ok_err_code = self.context.intType(16).constNull(); |
| 4943 | const err_un_llvm_ty = try self.dg.llvmType(inst_ty); | 4983 | const err_un_llvm_ty = try self.dg.llvmType(inst_ty); |
| | 4984 | |
| | 4985 | const target = self.dg.module.getTarget(); |
| | 4986 | const payload_offset: u8 = if (payload_ty.abiAlignment(target) > Type.anyerror.abiSize(target)) 2 else 1; |
| 4944 | if (isByRef(inst_ty)) { | 4987 | if (isByRef(inst_ty)) { |
| 4945 | const result_ptr = self.buildAlloca(err_un_llvm_ty); | 4988 | const result_ptr = self.buildAlloca(err_un_llvm_ty); |
| 4946 | const err_ptr = self.builder.buildStructGEP(result_ptr, 0, ""); | 4989 | const err_ptr = self.builder.buildStructGEP(result_ptr, 0, ""); |
| 4947 | _ = self.builder.buildStore(ok_err_code, err_ptr); | 4990 | _ = self.builder.buildStore(ok_err_code, err_ptr); |
| 4948 | const payload_ptr = self.builder.buildStructGEP(result_ptr, 1, ""); | 4991 | const payload_ptr = self.builder.buildStructGEP(result_ptr, payload_offset, ""); |
| 4949 | var ptr_ty_payload: Type.Payload.ElemType = .{ | 4992 | var ptr_ty_payload: Type.Payload.ElemType = .{ |
| 4950 | .base = .{ .tag = .single_mut_pointer }, | 4993 | .base = .{ .tag = .single_mut_pointer }, |
| 4951 | .data = payload_ty, | 4994 | .data = payload_ty, |
| ... | @@ -4956,7 +4999,7 @@ pub const FuncGen = struct { | ... | @@ -4956,7 +4999,7 @@ pub const FuncGen = struct { |
| 4956 | } | 4999 | } |
| 4957 | | 5000 | |
| 4958 | const partial = self.builder.buildInsertValue(err_un_llvm_ty.getUndef(), ok_err_code, 0, ""); | 5001 | const partial = self.builder.buildInsertValue(err_un_llvm_ty.getUndef(), ok_err_code, 0, ""); |
| 4959 | return self.builder.buildInsertValue(partial, operand, 1, ""); | 5002 | return self.builder.buildInsertValue(partial, operand, payload_offset, ""); |
| 4960 | } | 5003 | } |
| 4961 | | 5004 | |
| 4962 | fn airWrapErrUnionErr(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 5005 | fn airWrapErrUnionErr(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { |
| ... | @@ -4970,11 +5013,14 @@ pub const FuncGen = struct { | ... | @@ -4970,11 +5013,14 @@ pub const FuncGen = struct { |
| 4970 | return operand; | 5013 | return operand; |
| 4971 | } | 5014 | } |
| 4972 | const err_un_llvm_ty = try self.dg.llvmType(err_un_ty); | 5015 | const err_un_llvm_ty = try self.dg.llvmType(err_un_ty); |
| | 5016 | |
| | 5017 | const target = self.dg.module.getTarget(); |
| | 5018 | const payload_offset: u8 = if (payload_ty.abiAlignment(target) > Type.anyerror.abiSize(target)) 2 else 1; |
| 4973 | if (isByRef(err_un_ty)) { | 5019 | if (isByRef(err_un_ty)) { |
| 4974 | const result_ptr = self.buildAlloca(err_un_llvm_ty); | 5020 | const result_ptr = self.buildAlloca(err_un_llvm_ty); |
| 4975 | const err_ptr = self.builder.buildStructGEP(result_ptr, 0, ""); | 5021 | const err_ptr = self.builder.buildStructGEP(result_ptr, 0, ""); |
| 4976 | _ = self.builder.buildStore(operand, err_ptr); | 5022 | _ = self.builder.buildStore(operand, err_ptr); |
| 4977 | const payload_ptr = self.builder.buildStructGEP(result_ptr, 1, ""); | 5023 | const payload_ptr = self.builder.buildStructGEP(result_ptr, payload_offset, ""); |
| 4978 | var ptr_ty_payload: Type.Payload.ElemType = .{ | 5024 | var ptr_ty_payload: Type.Payload.ElemType = .{ |
| 4979 | .base = .{ .tag = .single_mut_pointer }, | 5025 | .base = .{ .tag = .single_mut_pointer }, |
| 4980 | .data = payload_ty, | 5026 | .data = payload_ty, |