diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2024-12-03 20:35:23 -0800 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2025-01-15 15:11:35 -0800 |
| commit | 9bf715de74a7d5badeae932afb594b7c6b33afa3 (patch) | |
| tree | 302e2c5a42d30e379c5bb2e86c24360ea49ab3fb /src/codegen.zig | |
| parent | 77accf597d845245847b143e42ec4109c9468480 (diff) | |
| download | zig-9bf715de74a7d5badeae932afb594b7c6b33afa3.tar.gz zig-9bf715de74a7d5badeae932afb594b7c6b33afa3.zip | |
rework error handling in the backends
Diffstat (limited to 'src/codegen.zig')
| -rw-r--r-- | src/codegen.zig | 169 |
1 files changed, 56 insertions, 113 deletions
diff --git a/src/codegen.zig b/src/codegen.zig index 8ab6fb33b6..0f49e44b97 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -24,13 +24,6 @@ const Zir = std.zig.Zir; const Alignment = InternPool.Alignment; const dev = @import("dev.zig"); -pub const Result = union(enum) { - /// The `code` parameter passed to `generateSymbol` has the value. - ok, - /// There was a codegen error. - fail: *ErrorMsg, -}; - pub const CodeGenError = error{ OutOfMemory, /// Compiler was asked to operate on a number larger than supported. @@ -64,7 +57,7 @@ pub fn generateFunction( liveness: Liveness, code: *std.ArrayList(u8), debug_output: link.File.DebugInfoOutput, -) CodeGenError!Result { +) CodeGenError!void { const zcu = pt.zcu; const func = zcu.funcInfo(func_index); const target = zcu.navFileScope(func.owner_nav).mod.resolved_target.result; @@ -89,7 +82,7 @@ pub fn generateLazyFunction( lazy_sym: link.File.LazySymbol, code: *std.ArrayList(u8), debug_output: link.File.DebugInfoOutput, -) CodeGenError!Result { +) CodeGenError!void { const zcu = pt.zcu; const file = Type.fromInterned(lazy_sym.ty).typeDeclInstAllowGeneratedTag(zcu).?.resolveFile(&zcu.intern_pool); const target = zcu.fileByIndex(file).mod.resolved_target.result; @@ -120,17 +113,17 @@ pub fn generateLazySymbol( code: *std.ArrayList(u8), debug_output: link.File.DebugInfoOutput, reloc_parent: link.File.RelocInfo.Parent, -) CodeGenError!Result { +) CodeGenError!void { _ = reloc_parent; const tracy = trace(@src()); defer tracy.end(); const comp = bin_file.comp; - const ip = &pt.zcu.intern_pool; + const zcu = pt.zcu; + const ip = &zcu.intern_pool; const target = comp.root_mod.resolved_target.result; const endian = target.cpu.arch.endian(); - const gpa = comp.gpa; log.debug("generateLazySymbol: kind = {s}, ty = {}", .{ @tagName(lazy_sym.kind), @@ -161,26 +154,29 @@ pub fn generateLazySymbol( string_index += @intCast(err_name.len + 1); } mem.writeInt(u32, code.items[offset_index..][0..4], string_index, endian); - return .ok; - } else if (Type.fromInterned(lazy_sym.ty).zigTypeTag(pt.zcu) == .@"enum") { + } else if (Type.fromInterned(lazy_sym.ty).zigTypeTag(zcu) == .@"enum") { alignment.* = .@"1"; const enum_ty = Type.fromInterned(lazy_sym.ty); - const tag_names = enum_ty.enumFields(pt.zcu); + const tag_names = enum_ty.enumFields(zcu); for (0..tag_names.len) |tag_index| { const tag_name = tag_names.get(ip)[tag_index].toSlice(ip); try code.ensureUnusedCapacity(tag_name.len + 1); code.appendSliceAssumeCapacity(tag_name); code.appendAssumeCapacity(0); } - return .ok; - } else return .{ .fail = try .create( - gpa, - src_loc, - "TODO implement generateLazySymbol for {s} {}", - .{ @tagName(lazy_sym.kind), Type.fromInterned(lazy_sym.ty).fmt(pt) }, - ) }; + } else { + return zcu.codegenFailType(lazy_sym.ty, "TODO implement generateLazySymbol for {s} {}", .{ + @tagName(lazy_sym.kind), Type.fromInterned(lazy_sym.ty).fmt(pt), + }); + } } +pub const GenerateSymbolError = error{ + OutOfMemory, + /// Compiler was asked to operate on a number larger than supported. + Overflow, +}; + pub fn generateSymbol( bin_file: *link.File, pt: Zcu.PerThread, @@ -188,7 +184,7 @@ pub fn generateSymbol( val: Value, code: *std.ArrayList(u8), reloc_parent: link.File.RelocInfo.Parent, -) CodeGenError!Result { +) GenerateSymbolError!void { const tracy = trace(@src()); defer tracy.end(); @@ -204,7 +200,7 @@ pub fn generateSymbol( if (val.isUndefDeep(zcu)) { const abi_size = math.cast(usize, ty.abiSize(zcu)) orelse return error.Overflow; try code.appendNTimes(0xaa, abi_size); - return .ok; + return; } switch (ip.indexToKey(val.toIntern())) { @@ -266,7 +262,7 @@ pub fn generateSymbol( if (!payload_ty.hasRuntimeBitsIgnoreComptime(zcu)) { try code.writer().writeInt(u16, err_val, endian); - return .ok; + return; } const payload_align = payload_ty.abiAlignment(zcu); @@ -281,13 +277,10 @@ pub fn generateSymbol( // emit payload part of the error union { const begin = code.items.len; - switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(switch (error_union.val) { + try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(switch (error_union.val) { .err_name => try pt.intern(.{ .undef = payload_ty.toIntern() }), .payload => |payload| payload, - }), code, reloc_parent)) { - .ok => {}, - .fail => |em| return .{ .fail = em }, - } + }), code, reloc_parent); const unpadded_end = code.items.len - begin; const padded_end = abi_align.forward(unpadded_end); const padding = math.cast(usize, padded_end - unpadded_end) orelse return error.Overflow; @@ -312,10 +305,7 @@ pub fn generateSymbol( }, .enum_tag => |enum_tag| { const int_tag_ty = ty.intTagType(zcu); - switch (try generateSymbol(bin_file, pt, src_loc, try pt.getCoerced(Value.fromInterned(enum_tag.int), int_tag_ty), code, reloc_parent)) { - .ok => {}, - .fail => |em| return .{ .fail = em }, - } + try generateSymbol(bin_file, pt, src_loc, try pt.getCoerced(Value.fromInterned(enum_tag.int), int_tag_ty), code, reloc_parent); }, .float => |float| switch (float.storage) { .f16 => |f16_val| writeFloat(f16, f16_val, target, endian, try code.addManyAsArray(2)), @@ -328,19 +318,10 @@ pub fn generateSymbol( }, .f128 => |f128_val| writeFloat(f128, f128_val, target, endian, try code.addManyAsArray(16)), }, - .ptr => switch (try lowerPtr(bin_file, pt, src_loc, val.toIntern(), code, reloc_parent, 0)) { - .ok => {}, - .fail => |em| return .{ .fail = em }, - }, + .ptr => try lowerPtr(bin_file, pt, src_loc, val.toIntern(), code, reloc_parent, 0), .slice => |slice| { - switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.ptr), code, reloc_parent)) { - .ok => {}, - .fail => |em| return .{ .fail = em }, - } - switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.len), code, reloc_parent)) { - .ok => {}, - .fail => |em| return .{ .fail = em }, - } + try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.ptr), code, reloc_parent); + try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(slice.len), code, reloc_parent); }, .opt => { const payload_type = ty.optionalChild(zcu); @@ -349,10 +330,7 @@ pub fn generateSymbol( if (ty.optionalReprIsPayload(zcu)) { if (payload_val) |value| { - switch (try generateSymbol(bin_file, pt, src_loc, value, code, reloc_parent)) { - .ok => {}, - .fail => |em| return Result{ .fail = em }, - } + try generateSymbol(bin_file, pt, src_loc, value, code, reloc_parent); } else { try code.appendNTimes(0, abi_size); } @@ -362,10 +340,7 @@ pub fn generateSymbol( const value = payload_val orelse Value.fromInterned(try pt.intern(.{ .undef = payload_type.toIntern(), })); - switch (try generateSymbol(bin_file, pt, src_loc, value, code, reloc_parent)) { - .ok => {}, - .fail => |em| return Result{ .fail = em }, - } + try generateSymbol(bin_file, pt, src_loc, value, code, reloc_parent); } try code.writer().writeByte(@intFromBool(payload_val != null)); try code.appendNTimes(0, padding); @@ -377,17 +352,14 @@ pub fn generateSymbol( .elems, .repeated_elem => { var index: u64 = 0; while (index < array_type.lenIncludingSentinel()) : (index += 1) { - switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(switch (aggregate.storage) { + try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(switch (aggregate.storage) { .bytes => unreachable, .elems => |elems| elems[@intCast(index)], .repeated_elem => |elem| if (index < array_type.len) elem else array_type.sentinel, - }), code, reloc_parent)) { - .ok => {}, - .fail => |em| return .{ .fail = em }, - } + }), code, reloc_parent); } }, }, @@ -437,16 +409,13 @@ pub fn generateSymbol( .elems, .repeated_elem => { var index: u64 = 0; while (index < vector_type.len) : (index += 1) { - switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(switch (aggregate.storage) { + try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(switch (aggregate.storage) { .bytes => unreachable, .elems => |elems| elems[ math.cast(usize, index) orelse return error.Overflow ], .repeated_elem => |elem| elem, - }), code, reloc_parent)) { - .ok => {}, - .fail => |em| return .{ .fail = em }, - } + }), code, reloc_parent); } }, } @@ -476,10 +445,7 @@ pub fn generateSymbol( .repeated_elem => |elem| elem, }; - switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), code, reloc_parent)) { - .ok => {}, - .fail => |em| return Result{ .fail = em }, - } + try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), code, reloc_parent); const unpadded_field_end = code.items.len - struct_begin; // Pad struct members if required @@ -518,10 +484,8 @@ pub fn generateSymbol( return error.Overflow; var tmp_list = try std.ArrayList(u8).initCapacity(code.allocator, field_size); defer tmp_list.deinit(); - switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), &tmp_list, reloc_parent)) { - .ok => @memcpy(code.items[current_pos..][0..tmp_list.items.len], tmp_list.items), - .fail => |em| return Result{ .fail = em }, - } + try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), &tmp_list, reloc_parent); + @memcpy(code.items[current_pos..][0..tmp_list.items.len], tmp_list.items); } else { Value.fromInterned(field_val).writeToPackedMemory(Type.fromInterned(field_ty), pt, code.items[current_pos..], bits) catch unreachable; } @@ -553,10 +517,7 @@ pub fn generateSymbol( ) orelse return error.Overflow; if (padding > 0) try code.appendNTimes(0, padding); - switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), code, reloc_parent)) { - .ok => {}, - .fail => |em| return Result{ .fail = em }, - } + try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(field_val), code, reloc_parent); } const size = struct_type.sizeUnordered(ip); @@ -582,10 +543,7 @@ pub fn generateSymbol( // Check if we should store the tag first. if (layout.tag_size > 0 and layout.tag_align.compare(.gte, layout.payload_align)) { - switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), code, reloc_parent)) { - .ok => {}, - .fail => |em| return Result{ .fail = em }, - } + try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), code, reloc_parent); } const union_obj = zcu.typeToUnion(ty).?; @@ -595,10 +553,7 @@ pub fn generateSymbol( if (!field_ty.hasRuntimeBits(zcu)) { try code.appendNTimes(0xaa, math.cast(usize, layout.payload_size) orelse return error.Overflow); } else { - switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.val), code, reloc_parent)) { - .ok => {}, - .fail => |em| return Result{ .fail = em }, - } + try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.val), code, reloc_parent); const padding = math.cast(usize, layout.payload_size - field_ty.abiSize(zcu)) orelse return error.Overflow; if (padding > 0) { @@ -606,17 +561,11 @@ pub fn generateSymbol( } } } else { - switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.val), code, reloc_parent)) { - .ok => {}, - .fail => |em| return Result{ .fail = em }, - } + try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.val), code, reloc_parent); } if (layout.tag_size > 0 and layout.tag_align.compare(.lt, layout.payload_align)) { - switch (try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), code, reloc_parent)) { - .ok => {}, - .fail => |em| return Result{ .fail = em }, - } + try generateSymbol(bin_file, pt, src_loc, Value.fromInterned(un.tag), code, reloc_parent); if (layout.padding > 0) { try code.appendNTimes(0, layout.padding); @@ -625,7 +574,6 @@ pub fn generateSymbol( }, .memoized_call => unreachable, } - return .ok; } fn lowerPtr( @@ -636,7 +584,7 @@ fn lowerPtr( code: *std.ArrayList(u8), reloc_parent: link.File.RelocInfo.Parent, prev_offset: u64, -) CodeGenError!Result { +) GenerateSymbolError!void { const zcu = pt.zcu; const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr; const offset: u64 = prev_offset + ptr.byte_offset; @@ -689,7 +637,7 @@ fn lowerUavRef( code: *std.ArrayList(u8), reloc_parent: link.File.RelocInfo.Parent, offset: u64, -) CodeGenError!Result { +) GenerateSymbolError!void { const zcu = pt.zcu; const gpa = zcu.gpa; const ip = &zcu.intern_pool; @@ -702,14 +650,7 @@ fn lowerUavRef( const is_fn_body = uav_ty.zigTypeTag(zcu) == .@"fn"; if (!is_fn_body and !uav_ty.hasRuntimeBits(zcu)) { try code.appendNTimes(0xaa, ptr_width_bytes); - return .ok; - } - - const uav_align = ip.indexToKey(uav.orig_ty).ptr_type.flags.alignment; - const res = try lf.lowerUav(pt, uav_val, uav_align, src_loc); - switch (res) { - .mcv => {}, - .fail => |em| return .{ .fail = em }, + return; } switch (lf.tag) { @@ -727,11 +668,17 @@ fn lowerUavRef( .pointee = .{ .uav_index = uav.val }, }); try code.appendNTimes(0, ptr_width_bytes); - return .ok; + return; }, else => {}, } + const uav_align = ip.indexToKey(uav.orig_ty).ptr_type.flags.alignment; + switch (try lf.lowerUav(pt, uav_val, uav_align, src_loc)) { + .mcv => {}, + .fail => |em| std.debug.panic("TODO rework lowerUav. internal error: {s}", .{em.msg}), + } + const vaddr = try lf.getUavVAddr(uav_val, .{ .parent = reloc_parent, .offset = code.items.len, @@ -744,8 +691,6 @@ fn lowerUavRef( 8 => mem.writeInt(u64, try code.addManyAsArray(8), vaddr, endian), else => unreachable, } - - return Result.ok; } fn lowerNavRef( @@ -756,7 +701,7 @@ fn lowerNavRef( code: *std.ArrayList(u8), reloc_parent: link.File.RelocInfo.Parent, offset: u64, -) CodeGenError!Result { +) GenerateSymbolError!void { _ = src_loc; const zcu = pt.zcu; const gpa = zcu.gpa; @@ -768,7 +713,7 @@ fn lowerNavRef( const is_fn_body = nav_ty.zigTypeTag(zcu) == .@"fn"; if (!is_fn_body and !nav_ty.hasRuntimeBits(zcu)) { try code.appendNTimes(0xaa, ptr_width_bytes); - return Result.ok; + return; } switch (lf.tag) { @@ -786,16 +731,16 @@ fn lowerNavRef( .pointee = .{ .nav_index = nav_index }, }); try code.appendNTimes(0, ptr_width_bytes); - return .ok; + return; }, else => {}, } - const vaddr = try lf.getNavVAddr(pt, nav_index, .{ + const vaddr = lf.getNavVAddr(pt, nav_index, .{ .parent = reloc_parent, .offset = code.items.len, .addend = @intCast(offset), - }); + }) catch @panic("TODO rework getNavVAddr"); const endian = target.cpu.arch.endian(); switch (ptr_width_bytes) { 2 => mem.writeInt(u16, try code.addManyAsArray(2), @intCast(vaddr), endian), @@ -803,8 +748,6 @@ fn lowerNavRef( 8 => mem.writeInt(u64, try code.addManyAsArray(8), vaddr, endian), else => unreachable, } - - return .ok; } /// Helper struct to denote that the value is in memory but requires a linker relocation fixup: |
