use crate::{Bytes, Event, Reader};
#[derive(Debug)]
pub struct EventStream {}
#[cfg(feature = "debugger")]
#[derive(Debug)]
pub struct ActiveFrame {
pub frame_id: u64,
pub stack_pointer: u64,
pub program_counter: u64,
pub function_name: String,
pub function_id: lldb::SBFunctionId,
}
impl EventStream {
pub fn read_from(source: Bytes) -> Event {
let mut reader = Reader::new();
assert!(source.len() > 0);
let event = match source.get(0) {
b'B' => {
let reason = match source.get(1) {
b'B' => crate::Reason::Breakpoint,
b'P' => crate::Reason::Panic,
other => panic!("Unknown reason, got {other:?}"),
};
reader.set_source(source, 2);
let breakpoint_id = reader.read_int().unwrap() as u32;
let thread_id = reader.read_int().unwrap();
let frame_id = reader.read_int().unwrap();
let locals = reader.read_values();
Event::Breakpoint {
breakpoint_id,
thread_id,
frame_id,
reason,
locals,
}
}
b'F' => {
reader.set_source(source, 1);
let breakpoint_id = reader.read_int().unwrap() as u32;
let thread_id = reader.read_int().unwrap();
let frame_id = reader.read_int().unwrap();
let stack_pointer = reader.read_int().unwrap();
let function_name = reader.read_string().unwrap();
let arguments = reader.read_values();
Event::FunctionCall {
breakpoint_id,
thread_id,
frame_id,
stack_pointer,
function_name,
arguments,
}
}
b'R' => {
reader.set_source(source, 1);
let breakpoint_id = reader.read_int().unwrap() as u32;
let thread_id = reader.read_int().unwrap();
let frame_id = reader.read_int().unwrap();
let function_name = reader.read_string().unwrap();
let mut values = reader.read_values();
let (name, return_value) = values.remove(0);
assert_eq!(name, "return_value");
Event::FunctionReturn {
breakpoint_id,
thread_id,
frame_id,
function_name,
return_value,
}
}
o => panic!("Unknown Event {o:?}"),
};
event
}
}
#[cfg(feature = "debugger")]
impl EventStream {
pub fn breakpoint(
bp_id: crate::BpId,
thread_id: u64,
frame_id: u64,
reason: crate::Reason,
) -> Bytes {
let mut bytes = Bytes::new();
bytes.push_byte(b'B');
bytes.push_byte(match reason {
crate::Reason::Breakpoint => b'B',
crate::Reason::Panic => b'P',
});
bytes.integer(bp_id.0);
bytes.integer(thread_id);
bytes.integer(frame_id);
bytes
}
pub fn function_call(bp_id: crate::BpId, thread_id: u64, active_frame: &ActiveFrame) -> Bytes {
let mut bytes = Bytes::new();
bytes.push_byte(b'F');
bytes.integer(bp_id.0);
bytes.integer(thread_id);
bytes.integer(active_frame.frame_id);
bytes.integer(active_frame.stack_pointer);
bytes.identifier(&active_frame.function_name);
bytes
}
pub fn function_return(
bp_id: crate::BpId,
thread_id: u64,
active_frame: &ActiveFrame,
) -> Bytes {
let mut bytes = Bytes::new();
bytes.push_byte(b'R');
bytes.integer(bp_id.0);
bytes.integer(thread_id);
bytes.integer(active_frame.frame_id);
bytes.identifier(&active_frame.function_name);
bytes
}
}