use crate::TypeKind;
use serde::{Deserialize, Serialize};
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout, Unaligned};
#[repr(C, packed)]
#[derive(Debug, Clone, Copy, FromBytes, IntoBytes, KnownLayout, Immutable, Unaligned)]
pub struct TraceEventHeader {
pub magic: u32,
}
#[repr(C, packed)]
#[derive(Debug, Clone, Copy, FromBytes, IntoBytes, KnownLayout, Immutable, Unaligned)]
pub struct TraceEventMessage {
pub trace_id: u64,
pub timestamp: u64,
pub pid: u32,
pub tid: u32,
}
#[repr(u8)]
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub enum InstructionType {
PrintStringIndex = 0x01, PrintVariableIndex = 0x02, PrintComplexVariable = 0x03, PrintComplexFormat = 0x05, Backtrace = 0x10, ExprError = 0x20,
EndInstruction = 0xFF, }
#[repr(C, packed)]
#[derive(Debug, Clone, Copy, FromBytes, KnownLayout, Immutable, Unaligned)]
pub struct InstructionHeader {
pub inst_type: u8, pub data_length: u16, pub reserved: u8,
}
#[repr(u8)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum VariableStatus {
Ok = 0,
NullDeref = 1,
ReadError = 2,
AccessError = 3,
Truncated = 4,
OffsetsUnavailable = 5,
ZeroLength = 6,
}
#[repr(C, packed)]
#[derive(Debug, Clone, Copy, FromBytes, KnownLayout, Immutable, Unaligned)]
pub struct PrintStringIndexData {
pub string_index: u16, }
#[repr(C, packed)]
#[derive(Debug, Clone, Copy, FromBytes, KnownLayout, Immutable, Unaligned)]
pub struct PrintVariableIndexData {
pub var_name_index: u16, pub type_encoding: u8, pub data_len: u16, pub type_index: u16, pub status: u8, }
#[repr(C, packed)]
#[derive(Debug, Clone, Copy, FromBytes, KnownLayout, Immutable, Unaligned)]
pub struct PrintComplexVariableData {
pub var_name_index: u16, pub type_index: u16, pub access_path_len: u8, pub status: u8, pub data_len: u16, }
#[repr(C, packed)]
#[derive(Debug, Clone, Copy, FromBytes, KnownLayout, Immutable, Unaligned)]
pub struct PrintComplexFormatData {
pub format_string_index: u16, pub arg_count: u8, pub reserved: u8, }
#[repr(C, packed)]
#[derive(Debug, Clone, Copy, FromBytes, KnownLayout, Immutable, Unaligned)]
pub struct BacktraceData {
pub depth: u8, pub flags: u8, pub reserved: u16, }
#[repr(C, packed)]
#[derive(Debug, Clone, Copy, FromBytes, KnownLayout, Immutable, Unaligned)]
pub struct ExprErrorData {
pub string_index: u16, pub error_code: u8, pub flags: u8, pub failing_addr: u64, }
#[repr(C, packed)]
#[derive(Debug, Clone, Copy, FromBytes, KnownLayout, Immutable, Unaligned)]
pub struct EndInstructionData {
pub total_instructions: u16, pub execution_status: u8, pub reserved: u8, }
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Instruction {
PrintStringIndex {
string_index: u16,
},
PrintVariableIndex {
var_name_index: u16,
type_encoding: TypeKind,
type_index: u16, data: Vec<u8>,
},
ExprError {
string_index: u16,
error_code: u8,
flags: u8,
failing_addr: u64,
},
Backtrace {
depth: u8,
flags: u8,
frames: Vec<u64>, },
EndInstruction {
total_instructions: u16,
execution_status: u8, },
}
impl Instruction {
pub fn instruction_type(&self) -> InstructionType {
match self {
Instruction::PrintStringIndex { .. } => InstructionType::PrintStringIndex,
Instruction::PrintVariableIndex { .. } => InstructionType::PrintVariableIndex,
Instruction::ExprError { .. } => InstructionType::ExprError,
Instruction::Backtrace { .. } => InstructionType::Backtrace,
Instruction::EndInstruction { .. } => InstructionType::EndInstruction,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_instruction_types() {
let inst1 = Instruction::PrintStringIndex { string_index: 0 };
assert_eq!(inst1.instruction_type(), InstructionType::PrintStringIndex);
}
#[test]
fn test_instruction_types_basic() {
let inst = Instruction::EndInstruction {
total_instructions: 5,
execution_status: 0,
};
assert_eq!(inst.instruction_type(), InstructionType::EndInstruction);
}
}