Zig 0.17.0-dev (Split by item)

This is an example of documentation generated by ZigDoc, an alternative to Zig's built-in Auto Doc feature. See also examples in other modes/formats. The project being documented here (as the example) is the Zig library itself.

Instruction

VirtualMachine.Instruction
pub const Instruction = union(enum)

File

lib/std/debug/Dwarf/Unwind/VirtualMachine.zig:339

Code

pub const Instruction = union(enum) {
    nop,
    remember_state,
    restore_state,
    advance_loc: u32,
    set_loc: u64,

    register: struct {
        index: u8,
        rule: union(enum) {
            restore, // restore from cie
            undefined,
            same_value,
            offset_uf: u64,
            offset_sf: i64,
            val_offset_uf: u64,
            val_offset_sf: i64,
            register: u8,
            /// Value is the number of bytes in the DWARF expression, which the caller must read.
            expr: usize,
            /// Value is the number of bytes in the DWARF expression, which the caller must read.
            val_expr: usize,
        },
    },

    def_cfa: struct {
        register: u8,
        offset: u64,
    },
    def_cfa_sf: struct {
        register: u8,
        offset_sf: i64,
    },
    def_cfa_reg: u8,
    def_cfa_offset: u64,
    def_cfa_offset_sf: i64,
    /// Value is the number of bytes in the DWARF expression, which the caller must read.
    def_cfa_expr: usize,

    pub fn read(
        reader: *std.Io.Reader,
        addr_size_bytes: u8,
        endian: std.builtin.Endian,
    ) !Instruction {
        const inst: OpcodeByte = @bitCast(try reader.takeByte());
        return switch (inst.opcode) {
            .advance_loc => .{ .advance_loc = inst.low.operand },
            .offset => .{ .register = .{
                .index = inst.low.operand,
                .rule = .{ .offset_uf = try reader.takeLeb128(u64) },
            } },
            .restore => .{ .register = .{
                .index = inst.low.operand,
                .rule = .restore,
            } },
            .extended => switch (inst.low.extended) {
                .nop => .nop,
                .remember_state => .remember_state,
                .restore_state => .restore_state,
                .advance_loc1 => .{ .advance_loc = try reader.takeByte() },
                .advance_loc2 => .{ .advance_loc = try reader.takeInt(u16, endian) },
                .advance_loc4 => .{ .advance_loc = try reader.takeInt(u32, endian) },
                .set_loc => .{ .set_loc = switch (addr_size_bytes) {
                    2 => try reader.takeInt(u16, endian),
                    4 => try reader.takeInt(u32, endian),
                    8 => try reader.takeInt(u64, endian),
                    else => return error.UnsupportedAddrSize,
                } },

                .offset_extended => .{ .register = .{
                    .index = try reader.takeLeb128(u8),
                    .rule = .{ .offset_uf = try reader.takeLeb128(u64) },
                } },
                .offset_extended_sf => .{ .register = .{
                    .index = try reader.takeLeb128(u8),
                    .rule = .{ .offset_sf = try reader.takeLeb128(i64) },
                } },
                .restore_extended => .{ .register = .{
                    .index = try reader.takeLeb128(u8),
                    .rule = .restore,
                } },
                .undefined => .{ .register = .{
                    .index = try reader.takeLeb128(u8),
                    .rule = .undefined,
                } },
                .same_value => .{ .register = .{
                    .index = try reader.takeLeb128(u8),
                    .rule = .same_value,
                } },
                .register => .{ .register = .{
                    .index = try reader.takeLeb128(u8),
                    .rule = .{ .register = try reader.takeLeb128(u8) },
                } },
                .val_offset => .{ .register = .{
                    .index = try reader.takeLeb128(u8),
                    .rule = .{ .val_offset_uf = try reader.takeLeb128(u64) },
                } },
                .val_offset_sf => .{ .register = .{
                    .index = try reader.takeLeb128(u8),
                    .rule = .{ .val_offset_sf = try reader.takeLeb128(i64) },
                } },
                .expression => .{ .register = .{
                    .index = try reader.takeLeb128(u8),
                    .rule = .{ .expr = try reader.takeLeb128(usize) },
                } },
                .val_expression => .{ .register = .{
                    .index = try reader.takeLeb128(u8),
                    .rule = .{ .val_expr = try reader.takeLeb128(usize) },
                } },

                .def_cfa => .{ .def_cfa = .{
                    .register = try reader.takeLeb128(u8),
                    .offset = try reader.takeLeb128(u64),
                } },
                .def_cfa_sf => .{ .def_cfa_sf = .{
                    .register = try reader.takeLeb128(u8),
                    .offset_sf = try reader.takeLeb128(i64),
                } },
                .def_cfa_register => .{ .def_cfa_reg = try reader.takeLeb128(u8) },
                .def_cfa_offset => .{ .def_cfa_offset = try reader.takeLeb128(u64) },
                .def_cfa_offset_sf => .{ .def_cfa_offset_sf = try reader.takeLeb128(i64) },
                .def_cfa_expression => .{ .def_cfa_expr = try reader.takeLeb128(usize) },

                _ => switch (@backingInt(inst.low.extended)) {
                    0x1C...0x3F => return error.UnimplementedUserOpcode,
                    else => return error.InvalidOpcode,
                },
            },
        };
    }
}