From 20ce7455b9acea004e985b4f4d4b1133899ea77b Mon Sep 17 00:00:00 2001 From: kcbanner Date: Mon, 24 Jul 2023 02:07:59 -0400 Subject: [PATCH 1/5] fixup inline switch --- lib/std/dwarf/call_frame.zig | 41 +++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/lib/std/dwarf/call_frame.zig b/lib/std/dwarf/call_frame.zig index c83cbad815..0f71bb00eb 100644 --- a/lib/std/dwarf/call_frame.zig +++ b/lib/std/dwarf/call_frame.zig @@ -203,23 +203,40 @@ pub const Instruction = union(Opcode) { stream: *std.io.FixedBufferStream([]const u8), addr_size_bytes: u8, endian: std.builtin.Endian, + ) !Instruction { - return switch (try stream.reader().readByte()) { - inline Opcode.lo_inline...Opcode.hi_inline => |opcode| blk: { + switch (try stream.reader().readByte()) { + Opcode.lo_inline...Opcode.hi_inline => |opcode| { const e: Opcode = @enumFromInt(opcode & 0b11000000); - var result = @unionInit(Instruction, @tagName(e), undefined); - try result.readOperands(stream, @as(u6, @intCast(opcode & 0b111111)), addr_size_bytes, endian); - break :blk result; + switch (e) { + inline .advance_loc, + .offset, + .restore, + => |tag| { + var result = @unionInit(Instruction, @tagName(tag), undefined); + try result.readOperands(stream, @as(u6, @intCast(opcode & 0b111111)), addr_size_bytes, endian); + return result; + }, + else => unreachable, + } }, - inline Opcode.lo_reserved...Opcode.hi_reserved => |opcode| blk: { + Opcode.lo_reserved...Opcode.hi_reserved => |opcode| { const e: Opcode = @enumFromInt(opcode); - var result = @unionInit(Instruction, @tagName(e), undefined); - try result.readOperands(stream, null, addr_size_bytes, endian); - break :blk result; + switch (e) { + .advance_loc, + .offset, + .restore, + => unreachable, + inline else => |tag| { + var result = @unionInit(Instruction, @tagName(tag), undefined); + try result.readOperands(stream, null, addr_size_bytes, endian); + return result; + }, + } }, - Opcode.lo_user...Opcode.hi_user => error.UnimplementedUserOpcode, - else => error.InvalidOpcode, - }; + Opcode.lo_user...Opcode.hi_user => return error.UnimplementedUserOpcode, + else => return error.InvalidOpcode, + } } }; From d1ed1c167bc3227398037b8e7ad2937146edf7a3 Mon Sep 17 00:00:00 2001 From: kcbanner Date: Mon, 24 Jul 2023 10:43:14 -0400 Subject: [PATCH 2/5] simplify call frame instruction parser --- lib/std/dwarf/call_frame.zig | 431 ++++++++++++++++++++--------------- 1 file changed, 244 insertions(+), 187 deletions(-) diff --git a/lib/std/dwarf/call_frame.zig b/lib/std/dwarf/call_frame.zig index 0f71bb00eb..1501a245f6 100644 --- a/lib/std/dwarf/call_frame.zig +++ b/lib/std/dwarf/call_frame.zig @@ -50,189 +50,246 @@ const Opcode = enum(u8) { pub const hi_user = 0x3f; }; -const Operand = enum { - opcode_delta, - opcode_register, - uleb128_register, - uleb128_offset, - sleb128_offset, - address, - u8_delta, - u16_delta, - u32_delta, - block, +fn readBlock(stream: *std.io.FixedBufferStream([]const u8)) ![]const u8 { + const reader = stream.reader(); + const block_len = try leb.readULEB128(usize, reader); + if (stream.pos + block_len > stream.buffer.len) return error.InvalidOperand; - fn Storage(comptime self: Operand) type { - return switch (self) { - .opcode_delta, .opcode_register => u8, - .uleb128_register => u8, - .uleb128_offset => u64, - .sleb128_offset => i64, - .address => u64, - .u8_delta => u8, - .u16_delta => u16, - .u32_delta => u32, - .block => []const u8, - }; - } + const block = stream.buffer[stream.pos..][0..block_len]; + reader.context.pos += block_len; - fn read( - comptime self: Operand, - stream: *std.io.FixedBufferStream([]const u8), - opcode_value: ?u6, - addr_size_bytes: u8, - endian: std.builtin.Endian, - ) !Storage(self) { - const reader = stream.reader(); - return switch (self) { - .opcode_delta, .opcode_register => opcode_value orelse return error.InvalidOperand, - .uleb128_register => try leb.readULEB128(u8, reader), - .uleb128_offset => try leb.readULEB128(u64, reader), - .sleb128_offset => try leb.readILEB128(i64, reader), - .address => switch (addr_size_bytes) { - 2 => try reader.readInt(u16, endian), - 4 => try reader.readInt(u32, endian), - 8 => try reader.readInt(u64, endian), - else => return error.InvalidAddrSize, - }, - .u8_delta => try reader.readByte(), - .u16_delta => try reader.readInt(u16, endian), - .u32_delta => try reader.readInt(u32, endian), - .block => { - const block_len = try leb.readULEB128(usize, reader); - if (stream.pos + block_len > stream.buffer.len) return error.InvalidOperand; - - const block = stream.buffer[stream.pos..][0..block_len]; - reader.context.pos += block_len; - - return block; - }, - }; - } -}; - -fn InstructionType(comptime definition: anytype) type { - const definition_type = @typeInfo(@TypeOf(definition)); - assert(definition_type == .Struct); - - const definition_len = definition_type.Struct.fields.len; - comptime var fields: [definition_len]std.builtin.Type.StructField = undefined; - inline for (definition_type.Struct.fields, &fields) |definition_field, *operands_field| { - const opcode = std.enums.nameCast(Operand, @field(definition, definition_field.name)); - const storage_type = opcode.Storage(); - operands_field.* = .{ - .name = definition_field.name, - .type = storage_type, - .default_value = null, - .is_comptime = false, - .alignment = @alignOf(storage_type), - }; - } - - const InstructionOperands = @Type(.{ - .Struct = .{ - .layout = .Auto, - .fields = &fields, - .decls = &.{}, - .is_tuple = false, - }, - }); - - return struct { - const Self = @This(); - operands: InstructionOperands, - - pub fn read( - stream: *std.io.FixedBufferStream([]const u8), - opcode_value: ?u6, - addr_size_bytes: u8, - endian: std.builtin.Endian, - ) !Self { - var operands: InstructionOperands = undefined; - inline for (definition_type.Struct.fields) |definition_field| { - const operand = comptime std.enums.nameCast(Operand, @field(definition, definition_field.name)); - @field(operands, definition_field.name) = try operand.read(stream, opcode_value, addr_size_bytes, endian); - } - - return .{ .operands = operands }; - } - }; + return block; } pub const Instruction = union(Opcode) { - advance_loc: InstructionType(.{ .delta = .opcode_delta }), - offset: InstructionType(.{ .register = .opcode_register, .offset = .uleb128_offset }), - offset_extended: InstructionType(.{ .register = .uleb128_register, .offset = .uleb128_offset }), - restore: InstructionType(.{ .register = .opcode_register }), - restore_extended: InstructionType(.{ .register = .uleb128_register }), - nop: InstructionType(.{}), - set_loc: InstructionType(.{ .address = .address }), - advance_loc1: InstructionType(.{ .delta = .u8_delta }), - advance_loc2: InstructionType(.{ .delta = .u16_delta }), - advance_loc4: InstructionType(.{ .delta = .u32_delta }), - undefined: InstructionType(.{ .register = .uleb128_register }), - same_value: InstructionType(.{ .register = .uleb128_register }), - register: InstructionType(.{ .register = .uleb128_register, .target_register = .uleb128_register }), - remember_state: InstructionType(.{}), - restore_state: InstructionType(.{}), - def_cfa: InstructionType(.{ .register = .uleb128_register, .offset = .uleb128_offset }), - def_cfa_register: InstructionType(.{ .register = .uleb128_register }), - def_cfa_offset: InstructionType(.{ .offset = .uleb128_offset }), - def_cfa_expression: InstructionType(.{ .block = .block }), - expression: InstructionType(.{ .register = .uleb128_register, .block = .block }), - offset_extended_sf: InstructionType(.{ .register = .uleb128_register, .offset = .sleb128_offset }), - def_cfa_sf: InstructionType(.{ .register = .uleb128_register, .offset = .sleb128_offset }), - def_cfa_offset_sf: InstructionType(.{ .offset = .sleb128_offset }), - val_offset: InstructionType(.{ .register = .uleb128_register, .offset = .uleb128_offset }), - val_offset_sf: InstructionType(.{ .register = .uleb128_register, .offset = .sleb128_offset }), - val_expression: InstructionType(.{ .register = .uleb128_register, .block = .block }), - - fn readOperands( - self: *Instruction, - stream: *std.io.FixedBufferStream([]const u8), - opcode_value: ?u6, - addr_size_bytes: u8, - endian: std.builtin.Endian, - ) !void { - switch (self.*) { - inline else => |*inst| inst.* = try @TypeOf(inst.*).read(stream, opcode_value, addr_size_bytes, endian), - } - } + advance_loc: struct { + delta: u8, + }, + offset: struct { + register: u8, + offset: u64, + }, + offset_extended: struct { + register: u8, + offset: u64, + }, + restore: struct { + register: u8, + }, + restore_extended: struct { + register: u8, + }, + nop: void, + set_loc: struct { + address: u64, + }, + advance_loc1: struct { + delta: u8, + }, + advance_loc2: struct { + delta: u16, + }, + advance_loc4: struct { + delta: u32, + }, + undefined: struct { + register: u8, + }, + same_value: struct { + register: u8, + }, + register: struct { + register: u8, + target_register: u8, + }, + remember_state: void, + restore_state: void, + def_cfa: struct { + register: u8, + offset: u64, + }, + def_cfa_register: struct { + register: u8, + }, + def_cfa_offset: struct { + offset: u64, + }, + def_cfa_expression: struct { + block: []const u8, + }, + expression: struct { + register: u8, + block: []const u8, + }, + offset_extended_sf: struct { + register: u8, + offset: i64, + }, + def_cfa_sf: struct { + register: u8, + offset: i64, + }, + def_cfa_offset_sf: struct { + offset: i64, + }, + val_offset: struct { + register: u8, + offset: u64, + }, + val_offset_sf: struct { + register: u8, + offset: i64, + }, + val_expression: struct { + register: u8, + block: []const u8, + }, pub fn read( stream: *std.io.FixedBufferStream([]const u8), addr_size_bytes: u8, endian: std.builtin.Endian, - ) !Instruction { - switch (try stream.reader().readByte()) { + const reader = stream.reader(); + switch (try reader.readByte()) { Opcode.lo_inline...Opcode.hi_inline => |opcode| { const e: Opcode = @enumFromInt(opcode & 0b11000000); - switch (e) { - inline .advance_loc, - .offset, - .restore, - => |tag| { - var result = @unionInit(Instruction, @tagName(tag), undefined); - try result.readOperands(stream, @as(u6, @intCast(opcode & 0b111111)), addr_size_bytes, endian); - return result; + const value: u6 = @intCast(opcode & 0b111111); + return switch (e) { + .advance_loc => .{ + .advance_loc = .{ .delta = value }, + }, + .offset => .{ + .offset = .{ + .register = value, + .offset = try leb.readULEB128(u64, reader), + }, + }, + .restore => .{ + .restore = .{ .register = value }, }, else => unreachable, - } + }; }, Opcode.lo_reserved...Opcode.hi_reserved => |opcode| { const e: Opcode = @enumFromInt(opcode); - switch (e) { + return switch (e) { .advance_loc, .offset, .restore, => unreachable, - inline else => |tag| { - var result = @unionInit(Instruction, @tagName(tag), undefined); - try result.readOperands(stream, null, addr_size_bytes, endian); - return result; + .nop => .{ .nop = {} }, + .set_loc => .{ + .set_loc = .{ + .address = switch (addr_size_bytes) { + 2 => try reader.readInt(u16, endian), + 4 => try reader.readInt(u32, endian), + 8 => try reader.readInt(u64, endian), + else => return error.InvalidAddrSize, + }, + }, }, - } + .advance_loc1 => .{ + .advance_loc1 = .{ .delta = try reader.readByte() }, + }, + .advance_loc2 => .{ + .advance_loc2 = .{ .delta = try reader.readInt(u16, endian) }, + }, + .advance_loc4 => .{ + .advance_loc4 = .{ .delta = try reader.readInt(u32, endian) }, + }, + .offset_extended => .{ + .offset_extended = .{ + .register = try leb.readULEB128(u8, reader), + .offset = try leb.readULEB128(u64, reader), + }, + }, + .restore_extended => .{ + .restore_extended = .{ + .register = try leb.readULEB128(u8, reader), + }, + }, + .undefined => .{ + .undefined = .{ + .register = try leb.readULEB128(u8, reader), + }, + }, + .same_value => .{ + .same_value = .{ + .register = try leb.readULEB128(u8, reader), + }, + }, + .register => .{ + .register = .{ + .register = try leb.readULEB128(u8, reader), + .target_register = try leb.readULEB128(u8, reader), + }, + }, + .remember_state => .{ .remember_state = {} }, + .restore_state => .{ .restore_state = {} }, + .def_cfa => .{ + .def_cfa = .{ + .register = try leb.readULEB128(u8, reader), + .offset = try leb.readULEB128(u64, reader), + }, + }, + .def_cfa_register => .{ + .def_cfa_register = .{ + .register = try leb.readULEB128(u8, reader), + }, + }, + .def_cfa_offset => .{ + .def_cfa_offset = .{ + .offset = try leb.readULEB128(u64, reader), + }, + }, + .def_cfa_expression => .{ + .def_cfa_expression = .{ + .block = try readBlock(stream), + }, + }, + .expression => .{ + .expression = .{ + .register = try leb.readULEB128(u8, reader), + .block = try readBlock(stream), + }, + }, + .offset_extended_sf => .{ + .offset_extended_sf = .{ + .register = try leb.readULEB128(u8, reader), + .offset = try leb.readILEB128(i64, reader), + }, + }, + .def_cfa_sf => .{ + .def_cfa_sf = .{ + .register = try leb.readULEB128(u8, reader), + .offset = try leb.readILEB128(i64, reader), + }, + }, + .def_cfa_offset_sf => .{ + .def_cfa_offset_sf = .{ + .offset = try leb.readILEB128(i64, reader), + }, + }, + .val_offset => .{ + .val_offset = .{ + .register = try leb.readULEB128(u8, reader), + .offset = try leb.readULEB128(u64, reader), + }, + }, + .val_offset_sf => .{ + .val_offset_sf = .{ + .register = try leb.readULEB128(u8, reader), + .offset = try leb.readILEB128(i64, reader), + }, + }, + .val_expression => .{ + .val_expression = .{ + .register = try leb.readULEB128(u8, reader), + .block = try readBlock(stream), + }, + }, + }; }, Opcode.lo_user...Opcode.hi_user => return error.UnimplementedUserOpcode, else => return error.InvalidOpcode, @@ -492,16 +549,16 @@ pub const VirtualMachine = struct { const prev_row = self.current_row; switch (instruction) { .set_loc => |i| { - if (i.operands.address <= self.current_row.offset) return error.InvalidOperation; + if (i.address <= self.current_row.offset) return error.InvalidOperation; // TODO: Check cie.segment_selector_size != 0 for DWARFV4 - self.current_row.offset = i.operands.address; + self.current_row.offset = i.address; }, inline .advance_loc, .advance_loc1, .advance_loc2, .advance_loc4, => |i| { - self.current_row.offset += i.operands.delta * cie.code_alignment_factor; + self.current_row.offset += i.delta * cie.code_alignment_factor; self.current_row.copy_on_write = true; }, inline .offset, @@ -509,35 +566,35 @@ pub const VirtualMachine = struct { .offset_extended_sf, => |i| { try self.resolveCopyOnWrite(allocator); - const column = try self.getOrAddColumn(allocator, i.operands.register); - column.rule = .{ .offset = @as(i64, @intCast(i.operands.offset)) * cie.data_alignment_factor }; + const column = try self.getOrAddColumn(allocator, i.register); + column.rule = .{ .offset = @as(i64, @intCast(i.offset)) * cie.data_alignment_factor }; }, inline .restore, .restore_extended, => |i| { try self.resolveCopyOnWrite(allocator); if (self.cie_row) |cie_row| { - const column = try self.getOrAddColumn(allocator, i.operands.register); + const column = try self.getOrAddColumn(allocator, i.register); column.rule = for (self.rowColumns(cie_row)) |cie_column| { - if (cie_column.register == i.operands.register) break cie_column.rule; + if (cie_column.register == i.register) break cie_column.rule; } else .{ .default = {} }; } else return error.InvalidOperation; }, .nop => {}, .undefined => |i| { try self.resolveCopyOnWrite(allocator); - const column = try self.getOrAddColumn(allocator, i.operands.register); + const column = try self.getOrAddColumn(allocator, i.register); column.rule = .{ .undefined = {} }; }, .same_value => |i| { try self.resolveCopyOnWrite(allocator); - const column = try self.getOrAddColumn(allocator, i.operands.register); + const column = try self.getOrAddColumn(allocator, i.register); column.rule = .{ .same_value = {} }; }, .register => |i| { try self.resolveCopyOnWrite(allocator); - const column = try self.getOrAddColumn(allocator, i.operands.register); - column.rule = .{ .register = i.operands.target_register }; + const column = try self.getOrAddColumn(allocator, i.register); + column.rule = .{ .register = i.target_register }; }, .remember_state => { try self.stack.append(allocator, self.current_row.columns); @@ -555,69 +612,69 @@ pub const VirtualMachine = struct { .def_cfa => |i| { try self.resolveCopyOnWrite(allocator); self.current_row.cfa = .{ - .register = i.operands.register, - .rule = .{ .val_offset = @intCast(i.operands.offset) }, + .register = i.register, + .rule = .{ .val_offset = @intCast(i.offset) }, }; }, .def_cfa_sf => |i| { try self.resolveCopyOnWrite(allocator); self.current_row.cfa = .{ - .register = i.operands.register, - .rule = .{ .val_offset = i.operands.offset * cie.data_alignment_factor }, + .register = i.register, + .rule = .{ .val_offset = i.offset * cie.data_alignment_factor }, }; }, .def_cfa_register => |i| { try self.resolveCopyOnWrite(allocator); if (self.current_row.cfa.register == null or self.current_row.cfa.rule != .val_offset) return error.InvalidOperation; - self.current_row.cfa.register = i.operands.register; + self.current_row.cfa.register = i.register; }, .def_cfa_offset => |i| { try self.resolveCopyOnWrite(allocator); if (self.current_row.cfa.register == null or self.current_row.cfa.rule != .val_offset) return error.InvalidOperation; self.current_row.cfa.rule = .{ - .val_offset = @intCast(i.operands.offset), + .val_offset = @intCast(i.offset), }; }, .def_cfa_offset_sf => |i| { try self.resolveCopyOnWrite(allocator); if (self.current_row.cfa.register == null or self.current_row.cfa.rule != .val_offset) return error.InvalidOperation; self.current_row.cfa.rule = .{ - .val_offset = i.operands.offset * cie.data_alignment_factor, + .val_offset = i.offset * cie.data_alignment_factor, }; }, .def_cfa_expression => |i| { try self.resolveCopyOnWrite(allocator); self.current_row.cfa.register = undefined; self.current_row.cfa.rule = .{ - .expression = i.operands.block, + .expression = i.block, }; }, .expression => |i| { try self.resolveCopyOnWrite(allocator); - const column = try self.getOrAddColumn(allocator, i.operands.register); + const column = try self.getOrAddColumn(allocator, i.register); column.rule = .{ - .expression = i.operands.block, + .expression = i.block, }; }, .val_offset => |i| { try self.resolveCopyOnWrite(allocator); - const column = try self.getOrAddColumn(allocator, i.operands.register); + const column = try self.getOrAddColumn(allocator, i.register); column.rule = .{ - .val_offset = @as(i64, @intCast(i.operands.offset)) * cie.data_alignment_factor, + .val_offset = @as(i64, @intCast(i.offset)) * cie.data_alignment_factor, }; }, .val_offset_sf => |i| { try self.resolveCopyOnWrite(allocator); - const column = try self.getOrAddColumn(allocator, i.operands.register); + const column = try self.getOrAddColumn(allocator, i.register); column.rule = .{ - .val_offset = i.operands.offset * cie.data_alignment_factor, + .val_offset = i.offset * cie.data_alignment_factor, }; }, .val_expression => |i| { try self.resolveCopyOnWrite(allocator); - const column = try self.getOrAddColumn(allocator, i.operands.register); + const column = try self.getOrAddColumn(allocator, i.register); column.rule = .{ - .val_expression = i.operands.block, + .val_expression = i.block, }; }, } From ab2e0b927d5de3fb838a897bb9530ec7955b0bd7 Mon Sep 17 00:00:00 2001 From: kcbanner Date: Mon, 24 Jul 2023 23:27:05 -0400 Subject: [PATCH 3/5] switch to sortUnstable when sorting FDEs (~16ms improvement) --- lib/std/dwarf.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/std/dwarf.zig b/lib/std/dwarf.zig index 639772cf6e..594116fa90 100644 --- a/lib/std/dwarf.zig +++ b/lib/std/dwarf.zig @@ -1638,7 +1638,7 @@ pub const DwarfInfo = struct { } } - std.mem.sort(FrameDescriptionEntry, di.fde_list.items, {}, struct { + std.mem.sortUnstable(FrameDescriptionEntry, di.fde_list.items, {}, struct { fn lessThan(ctx: void, a: FrameDescriptionEntry, b: FrameDescriptionEntry) bool { _ = ctx; return a.pc_begin < b.pc_begin; From 49fa3a987f0b5309d629072def14ae6c6793d0b1 Mon Sep 17 00:00:00 2001 From: kcbanner Date: Tue, 25 Jul 2023 00:45:47 -0400 Subject: [PATCH 4/5] reduce the number of duplicate instantiations due to differing stream parameters --- lib/std/dwarf.zig | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/std/dwarf.zig b/lib/std/dwarf.zig index 594116fa90..58db4a1698 100644 --- a/lib/std/dwarf.zig +++ b/lib/std/dwarf.zig @@ -741,7 +741,7 @@ pub const DwarfInfo = struct { fn scanAllFunctions(di: *DwarfInfo, allocator: mem.Allocator) !void { var stream = io.fixedBufferStream(di.section(.debug_info).?); const in = stream.reader(); - const seekable = &stream.seekableStream(); + const seekable = stream.seekableStream(); var this_unit_offset: u64 = 0; var tmp_arena = std.heap.ArenaAllocator.init(allocator); @@ -909,8 +909,8 @@ pub const DwarfInfo = struct { fn scanAllCompileUnits(di: *DwarfInfo, allocator: mem.Allocator) !void { var stream = io.fixedBufferStream(di.section(.debug_info).?); - const in = &stream.reader(); - const seekable = &stream.seekableStream(); + const in = stream.reader(); + const seekable = stream.seekableStream(); var this_unit_offset: u64 = 0; while (this_unit_offset < try seekable.getEndPos()) { @@ -1175,8 +1175,8 @@ pub const DwarfInfo = struct { fn parseAbbrevTable(di: *DwarfInfo, allocator: mem.Allocator, offset: u64) !AbbrevTable { var stream = io.fixedBufferStream(di.section(.debug_abbrev).?); - const in = &stream.reader(); - const seekable = &stream.seekableStream(); + const in = stream.reader(); + const seekable = stream.seekableStream(); try seekable.seekTo(offset); var result = AbbrevTable.init(allocator); @@ -1256,8 +1256,8 @@ pub const DwarfInfo = struct { target_address: u64, ) !debug.LineInfo { var stream = io.fixedBufferStream(di.section(.debug_line).?); - const in = &stream.reader(); - const seekable = &stream.seekableStream(); + const in = stream.reader(); + const seekable = stream.seekableStream(); const compile_unit_cwd = try compile_unit.die.getAttrString(di, AT.comp_dir, di.section(.debug_line_str), compile_unit); const line_info_offset = try compile_unit.die.getAttrSecOffset(AT.stmt_list); From 8e4cc0ce5a21d743bc59def79efa75584d06fee4 Mon Sep 17 00:00:00 2001 From: kcbanner Date: Tue, 25 Jul 2023 10:26:01 -0400 Subject: [PATCH 5/5] dwarf: small code size reduction in expression runner --- lib/std/dwarf/expressions.zig | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/lib/std/dwarf/expressions.zig b/lib/std/dwarf/expressions.zig index 88291eab0b..a57c9add90 100644 --- a/lib/std/dwarf/expressions.zig +++ b/lib/std/dwarf/expressions.zig @@ -318,6 +318,7 @@ pub fn StackMachine(comptime options: ExpressionOptions) type { const opcode = try stream.reader().readByte(); if (options.call_frame_context and !isOpcodeValidInCFA(opcode)) return error.InvalidCFAOpcode; + const operand = try readOperand(stream, opcode, context); switch (opcode) { // 2.5.1.1: Literal Encodings @@ -333,10 +334,10 @@ pub fn StackMachine(comptime options: ExpressionOptions) type { OP.const8s, OP.constu, OP.consts, - => try self.stack.append(allocator, .{ .generic = (try readOperand(stream, opcode, context)).?.generic }), + => try self.stack.append(allocator, .{ .generic = operand.?.generic }), OP.const_type => { - const const_type = (try readOperand(stream, opcode, context)).?.const_type; + const const_type = operand.?.const_type; try self.stack.append(allocator, .{ .const_type = .{ .type_offset = const_type.type_offset, .value_bytes = const_type.value_bytes, @@ -348,7 +349,7 @@ pub fn StackMachine(comptime options: ExpressionOptions) type { => { if (context.compile_unit == null) return error.IncompleteExpressionContext; if (context.debug_addr == null) return error.IncompleteExpressionContext; - const debug_addr_index = (try readOperand(stream, opcode, context)).?.generic; + const debug_addr_index = operand.?.generic; const offset = context.compile_unit.?.addr_base + debug_addr_index; if (offset >= context.debug_addr.?.len) return error.InvalidExpression; const value = mem.readIntSliceNative(usize, context.debug_addr.?[offset..][0..@sizeOf(usize)]); @@ -360,7 +361,7 @@ pub fn StackMachine(comptime options: ExpressionOptions) type { if (context.compile_unit == null) return error.IncompleteExpressionContext; if (context.compile_unit.?.frame_base == null) return error.IncompleteExpressionContext; - const offset: i64 = @intCast((try readOperand(stream, opcode, context)).?.generic); + const offset: i64 = @intCast(operand.?.generic); _ = offset; switch (context.compile_unit.?.frame_base.?.*) { @@ -384,7 +385,7 @@ pub fn StackMachine(comptime options: ExpressionOptions) type { => { if (context.thread_context == null) return error.IncompleteExpressionContext; - const base_register = (try readOperand(stream, opcode, context)).?.base_register; + const base_register = operand.?.base_register; var value: i64 = @intCast(mem.readIntSliceNative(usize, try abi.regBytes( context.thread_context.?, base_register.base_register, @@ -394,7 +395,7 @@ pub fn StackMachine(comptime options: ExpressionOptions) type { try self.stack.append(allocator, .{ .generic = @intCast(value) }); }, OP.regval_type => { - const register_type = (try readOperand(stream, opcode, context)).?.register_type; + const register_type = operand.?.register_type; const value = mem.readIntSliceNative(usize, try abi.regBytes( context.thread_context.?, register_type.register, @@ -418,7 +419,7 @@ pub fn StackMachine(comptime options: ExpressionOptions) type { _ = self.stack.pop(); }, OP.pick, OP.over => { - const stack_index = if (opcode == OP.over) 1 else (try readOperand(stream, opcode, context)).?.generic; + const stack_index = if (opcode == OP.over) 1 else operand.?.generic; if (stack_index >= self.stack.items.len) return error.InvalidExpression; try self.stack.append(allocator, self.stack.items[self.stack.items.len - 1 - stack_index]); }, @@ -459,8 +460,6 @@ pub fn StackMachine(comptime options: ExpressionOptions) type { _ = addr_space_identifier; if (context.isValidMemory) |isValidMemory| if (!isValidMemory(addr)) return error.InvalidExpression; - - const operand = try readOperand(stream, opcode, context); const size = switch (opcode) { OP.deref, OP.xderef, @@ -594,7 +593,7 @@ pub fn StackMachine(comptime options: ExpressionOptions) type { }, OP.plus_uconst => { if (self.stack.items.len == 0) return error.InvalidExpression; - const constant = (try readOperand(stream, opcode, context)).?.generic; + const constant = operand.?.generic; self.stack.items[self.stack.items.len - 1] = .{ .generic = try std.math.add(addr_type, try self.stack.items[self.stack.items.len - 1].asIntegral(), constant), }; @@ -663,7 +662,7 @@ pub fn StackMachine(comptime options: ExpressionOptions) type { } }, OP.skip, OP.bra => { - const branch_offset = (try readOperand(stream, opcode, context)).?.branch_offset; + const branch_offset = operand.?.branch_offset; const condition = if (opcode == OP.bra) blk: { if (self.stack.items.len == 0) return error.InvalidExpression; break :blk try self.stack.pop().asIntegral() != 0; @@ -683,7 +682,7 @@ pub fn StackMachine(comptime options: ExpressionOptions) type { OP.call4, OP.call_ref, => { - const debug_info_offset = (try readOperand(stream, opcode, context)).?.generic; + const debug_info_offset = operand.?.generic; _ = debug_info_offset; // TODO: Load a DIE entry at debug_info_offset in a .debug_info section (the spec says that it @@ -696,7 +695,7 @@ pub fn StackMachine(comptime options: ExpressionOptions) type { // 2.5.1.6: Type Conversions OP.convert => { if (self.stack.items.len == 0) return error.InvalidExpression; - const type_offset = (try readOperand(stream, opcode, context)).?.generic; + const type_offset = operand.?.generic; // TODO: Load the DW_TAG_base_type entries in context.compile_unit and verify both types are the same size const value = self.stack.items[self.stack.items.len - 1]; @@ -710,7 +709,7 @@ pub fn StackMachine(comptime options: ExpressionOptions) type { }, OP.reinterpret => { if (self.stack.items.len == 0) return error.InvalidExpression; - const type_offset = (try readOperand(stream, opcode, context)).?.generic; + const type_offset = operand.?.generic; // TODO: Load the DW_TAG_base_type entries in context.compile_unit and verify both types are the same size const value = self.stack.items[self.stack.items.len - 1]; @@ -745,7 +744,7 @@ pub fn StackMachine(comptime options: ExpressionOptions) type { // 2.5.1.7: Special Operations OP.nop => {}, OP.entry_value => { - const block = (try readOperand(stream, opcode, context)).?.block; + const block = operand.?.block; if (block.len == 0) return error.InvalidSubExpression; // TODO: The spec states that this sub-expression needs to observe the state (ie. registers)