ghostscope_protocol/
type_kind.rs

1//! TypeKind enumeration and protocol constants
2
3use crate::type_info::TypeInfo;
4use serde::{Deserialize, Serialize};
5
6/// Variable type kind - used by compiler and streaming parser for runtime classification
7#[repr(u8)]
8#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
9pub enum TypeKind {
10    U8 = 0x01,
11    U16 = 0x02,
12    U32 = 0x03,
13    U64 = 0x04,
14    I8 = 0x05,
15    I16 = 0x06,
16    I32 = 0x07,
17    I64 = 0x08,
18    F32 = 0x09,
19    F64 = 0x0A,
20    Bool = 0x0B,
21    Char = 0x0C,
22
23    Pointer = 0x20,
24    NullPointer = 0x21,
25
26    Struct = 0x40,
27    Array = 0x41,
28    Union = 0x42,
29    Enum = 0x43,
30
31    CString = 0x50,
32    String = 0x51,
33
34    Unknown = 0x80,
35    OptimizedOut = 0x81,
36}
37
38impl TypeKind {
39    /// Convert a u8 value to TypeKind enum
40    pub fn from_u8(value: u8) -> Option<Self> {
41        match value {
42            x if x == (Self::U8 as u8) => Some(Self::U8),
43            x if x == (Self::U16 as u8) => Some(Self::U16),
44            x if x == (Self::U32 as u8) => Some(Self::U32),
45            x if x == (Self::U64 as u8) => Some(Self::U64),
46            x if x == (Self::I8 as u8) => Some(Self::I8),
47            x if x == (Self::I16 as u8) => Some(Self::I16),
48            x if x == (Self::I32 as u8) => Some(Self::I32),
49            x if x == (Self::I64 as u8) => Some(Self::I64),
50            x if x == (Self::F32 as u8) => Some(Self::F32),
51            x if x == (Self::F64 as u8) => Some(Self::F64),
52            x if x == (Self::Bool as u8) => Some(Self::Bool),
53            x if x == (Self::Char as u8) => Some(Self::Char),
54            x if x == (Self::Pointer as u8) => Some(Self::Pointer),
55            x if x == (Self::NullPointer as u8) => Some(Self::NullPointer),
56            x if x == (Self::Struct as u8) => Some(Self::Struct),
57            x if x == (Self::Array as u8) => Some(Self::Array),
58            x if x == (Self::Union as u8) => Some(Self::Union),
59            x if x == (Self::Enum as u8) => Some(Self::Enum),
60            x if x == (Self::CString as u8) => Some(Self::CString),
61            x if x == (Self::String as u8) => Some(Self::String),
62            x if x == (Self::Unknown as u8) => Some(Self::Unknown),
63            x if x == (Self::OptimizedOut as u8) => Some(Self::OptimizedOut),
64            _ => None,
65        }
66    }
67}
68
69impl From<&TypeInfo> for TypeKind {
70    /// Convert TypeInfo to TypeKind for runtime classification
71    fn from(type_info: &TypeInfo) -> Self {
72        match type_info {
73            TypeInfo::BaseType { size, encoding, .. } => {
74                // Use DWARF encoding constants for proper type mapping
75                match *encoding {
76                    1 => TypeKind::Pointer, // DW_ATE_address
77                    2 => TypeKind::Bool,    // DW_ATE_boolean
78                    4 => match size {
79                        // DW_ATE_float
80                        4 => TypeKind::F32,
81                        8 => TypeKind::F64,
82                        _ => TypeKind::F64, // Default to F64
83                    },
84                    5 => match size {
85                        // DW_ATE_signed
86                        1 => TypeKind::I8,
87                        2 => TypeKind::I16,
88                        4 => TypeKind::I32,
89                        8 => TypeKind::I64,
90                        _ => TypeKind::I64, // Default to I64
91                    },
92                    7 => match size {
93                        // DW_ATE_unsigned
94                        1 => TypeKind::U8,
95                        2 => TypeKind::U16,
96                        4 => TypeKind::U32,
97                        8 => TypeKind::U64,
98                        _ => TypeKind::U64, // Default to U64
99                    },
100                    6 => TypeKind::I8, // DW_ATE_signed_char
101                    8 => TypeKind::U8, // DW_ATE_unsigned_char
102                    _ => TypeKind::U8, // Default to byte for unknown encoding
103                }
104            }
105            TypeInfo::BitfieldType {
106                underlying_type, ..
107            } => TypeKind::from(underlying_type.as_ref()),
108            TypeInfo::PointerType { .. } => TypeKind::Pointer,
109            TypeInfo::ArrayType { .. } => TypeKind::Array,
110            TypeInfo::StructType { .. } => TypeKind::Struct,
111            TypeInfo::UnionType { .. } => TypeKind::Union,
112            TypeInfo::EnumType { .. } => TypeKind::I32, // Treat enum as integer
113            TypeInfo::TypedefType {
114                underlying_type, ..
115            } => TypeKind::from(underlying_type.as_ref()),
116            TypeInfo::QualifiedType {
117                underlying_type, ..
118            } => TypeKind::from(underlying_type.as_ref()),
119            TypeInfo::FunctionType { .. } => TypeKind::Pointer,
120            TypeInfo::UnknownType { .. } => TypeKind::U8, // Default to byte for unknown types
121            TypeInfo::OptimizedOut { .. } => TypeKind::OptimizedOut,
122        }
123    }
124}
125
126/// Protocol constants
127pub mod consts {
128    pub const MAGIC: u32 = 0x43484C53; // "CHLS" (Chelsea)
129
130    // Default values
131    pub const DEFAULT_TRACE_ID: u64 = 0;
132
133    // Type sizes (bytes) for 64-bit architecture
134    pub const CHAR_SIZE: u64 = 1;
135    pub const SHORT_SIZE: u64 = 2;
136    pub const INT_SIZE: u64 = 4;
137    pub const LONG_SIZE: u64 = 8; // 64-bit architecture
138    pub const LONG_LONG_SIZE: u64 = 8;
139    pub const FLOAT_SIZE: u64 = 4;
140    pub const DOUBLE_SIZE: u64 = 8;
141    pub const LONG_DOUBLE_SIZE: u64 = 16; // x86-64 extended precision
142    pub const BOOL_SIZE: u64 = 1;
143    pub const POINTER_SIZE: u64 = 8; // 64-bit pointers
144    pub const SIZE_T_SIZE: u64 = 8; // 64-bit architecture
145
146    // Trace event limits and sizes
147    /// Maximum number of instructions per trace event
148    pub const MAX_INSTRUCTIONS_PER_EVENT: u16 = 256;
149
150    /// Maximum size of a single trace event
151    pub const MAX_TRACE_EVENT_SIZE: u16 = 8192;
152
153    /// Trace event message size
154    pub const TRACE_EVENT_MESSAGE_SIZE: usize =
155        std::mem::size_of::<crate::trace_event::TraceEventMessage>();
156
157    /// Trace event header size
158    pub const TRACE_EVENT_HEADER_SIZE: usize =
159        std::mem::size_of::<crate::trace_event::TraceEventHeader>();
160
161    /// Instruction header size
162    pub const INSTRUCTION_HEADER_SIZE: usize =
163        std::mem::size_of::<crate::trace_event::InstructionHeader>();
164
165    /// Print variable index data size (extended with type_index)
166    pub const PRINT_VARIABLE_INDEX_DATA_SIZE: usize =
167        std::mem::size_of::<crate::trace_event::PrintVariableIndexData>();
168
169    // TraceEventMessage field offsets
170    pub const TRACE_EVENT_MESSAGE_TRACE_ID_OFFSET: usize = 0;
171    pub const TRACE_EVENT_MESSAGE_TIMESTAMP_OFFSET: usize = 8;
172    pub const TRACE_EVENT_MESSAGE_PID_OFFSET: usize = 16;
173    pub const TRACE_EVENT_MESSAGE_TID_OFFSET: usize = 20;
174
175    // InstructionHeader field offsets
176    pub const INSTRUCTION_HEADER_INST_TYPE_OFFSET: usize = 0;
177    pub const INSTRUCTION_HEADER_DATA_LENGTH_OFFSET: usize = 1;
178    pub const INSTRUCTION_HEADER_RESERVED_OFFSET: usize = 3;
179
180    // EndInstructionData relative offset from InstructionHeader start
181    pub const END_INSTRUCTION_DATA_OFFSET: usize = 4;
182    pub const END_INSTRUCTION_TOTAL_INSTRUCTIONS_OFFSET: usize = 0; // Within EndInstructionData
183    pub const END_INSTRUCTION_EXECUTION_STATUS_OFFSET: usize = 2; // Within EndInstructionData
184}