feature. See also
. The project being documented here (as the example) is the Zig library itself.
VirtualMachine.Instruction
pub const Instruction = union(enum)
File
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,
undefined,
same_value,
offset_uf: u64,
offset_sf: i64,
val_offset_uf: u64,
val_offset_sf: i64,
register: u8,
expr: usize,
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,
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,
},
},
};
}
}