1use crate::TypeKind;
2use serde::{Deserialize, Serialize};
3use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout, Unaligned};
4
5#[repr(C, packed)]
7#[derive(Debug, Clone, Copy, FromBytes, IntoBytes, KnownLayout, Immutable, Unaligned)]
8pub struct TraceEventHeader {
9 pub magic: u32,
10}
11
12#[repr(C, packed)]
13#[derive(Debug, Clone, Copy, FromBytes, IntoBytes, KnownLayout, Immutable, Unaligned)]
14pub struct TraceEventMessage {
15 pub trace_id: u64,
16 pub timestamp: u64,
17 pub pid: u32,
18 pub tid: u32,
19 }
21
22#[repr(u8)]
24#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
25pub enum InstructionType {
26 PrintStringIndex = 0x01, PrintVariableIndex = 0x02, PrintComplexVariable = 0x03, PrintComplexFormat = 0x05, Backtrace = 0x10, ExprError = 0x20,
33
34 EndInstruction = 0xFF, }
37
38#[repr(C, packed)]
40#[derive(Debug, Clone, Copy, FromBytes, KnownLayout, Immutable, Unaligned)]
41pub struct InstructionHeader {
42 pub inst_type: u8, pub data_length: u16, pub reserved: u8,
45}
46
47#[repr(u8)]
49#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
50pub enum VariableStatus {
51 Ok = 0,
52 NullDeref = 1,
53 ReadError = 2,
54 AccessError = 3,
55 Truncated = 4,
56 OffsetsUnavailable = 5,
59 ZeroLength = 6,
61}
62
63#[repr(C, packed)]
65#[derive(Debug, Clone, Copy, FromBytes, KnownLayout, Immutable, Unaligned)]
66pub struct PrintStringIndexData {
67 pub string_index: u16, }
69
70#[repr(C, packed)]
72#[derive(Debug, Clone, Copy, FromBytes, KnownLayout, Immutable, Unaligned)]
73pub struct PrintVariableIndexData {
74 pub var_name_index: u16, pub type_encoding: u8, pub data_len: u16, pub type_index: u16, pub status: u8, }
81
82#[repr(C, packed)]
84#[derive(Debug, Clone, Copy, FromBytes, KnownLayout, Immutable, Unaligned)]
85pub struct PrintComplexVariableData {
86 pub var_name_index: u16, pub type_index: u16, pub access_path_len: u8, pub status: u8, pub data_len: u16, }
93
94#[repr(C, packed)]
96#[derive(Debug, Clone, Copy, FromBytes, KnownLayout, Immutable, Unaligned)]
97pub struct PrintComplexFormatData {
98 pub format_string_index: u16, pub arg_count: u8, pub reserved: u8, }
105
106#[repr(C, packed)]
111#[derive(Debug, Clone, Copy, FromBytes, KnownLayout, Immutable, Unaligned)]
112pub struct BacktraceData {
113 pub depth: u8, pub flags: u8, pub reserved: u16, }
118#[repr(C, packed)]
120#[derive(Debug, Clone, Copy, FromBytes, KnownLayout, Immutable, Unaligned)]
121pub struct ExprErrorData {
122 pub string_index: u16, pub error_code: u8, pub flags: u8, pub failing_addr: u64, }
127
128#[repr(C, packed)]
130#[derive(Debug, Clone, Copy, FromBytes, KnownLayout, Immutable, Unaligned)]
131pub struct EndInstructionData {
132 pub total_instructions: u16, pub execution_status: u8, pub reserved: u8, }
136
137#[derive(Debug, Clone, Serialize, Deserialize)]
139pub enum Instruction {
140 PrintStringIndex {
141 string_index: u16,
142 },
143 PrintVariableIndex {
144 var_name_index: u16,
145 type_encoding: TypeKind,
146 type_index: u16, data: Vec<u8>,
148 },
149 ExprError {
151 string_index: u16,
152 error_code: u8,
153 flags: u8,
154 failing_addr: u64,
155 },
156 Backtrace {
157 depth: u8,
158 flags: u8,
159 frames: Vec<u64>, },
161 EndInstruction {
162 total_instructions: u16,
163 execution_status: u8, },
165}
166
167impl Instruction {
168 pub fn instruction_type(&self) -> InstructionType {
170 match self {
171 Instruction::PrintStringIndex { .. } => InstructionType::PrintStringIndex,
172 Instruction::PrintVariableIndex { .. } => InstructionType::PrintVariableIndex,
173 Instruction::ExprError { .. } => InstructionType::ExprError,
174 Instruction::Backtrace { .. } => InstructionType::Backtrace,
175 Instruction::EndInstruction { .. } => InstructionType::EndInstruction,
176 }
177 }
178}
179
180#[cfg(test)]
181mod tests {
182 use super::*;
183
184 #[test]
185 fn test_instruction_types() {
186 let inst1 = Instruction::PrintStringIndex { string_index: 0 };
187 assert_eq!(inst1.instruction_type(), InstructionType::PrintStringIndex);
188 }
189
190 #[test]
191 fn test_instruction_types_basic() {
192 let inst = Instruction::EndInstruction {
193 total_instructions: 5,
194 execution_status: 0,
195 };
196 assert_eq!(inst.instruction_type(), InstructionType::EndInstruction);
197 }
198}