Skip to main content

yulang_native/
cps_frame_trace.rs

1use std::cell::RefCell;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4pub enum CpsFrameTraceLayer {
5    CpsEval,
6    CpsRepr,
7}
8
9#[derive(Debug, Clone, PartialEq, Eq)]
10pub struct CpsFrameTraceSlot {
11    pub target: usize,
12    pub value: String,
13}
14
15#[derive(Debug, Clone, PartialEq, Eq)]
16pub enum CpsFrameTraceEvent {
17    HandlerEnvRead {
18        layer: CpsFrameTraceLayer,
19        function: String,
20        handler: usize,
21        entry: usize,
22        values: Vec<CpsFrameTraceSlot>,
23    },
24    HandlerEnvOverlay {
25        layer: CpsFrameTraceLayer,
26        function: String,
27        handler: usize,
28        entries: Vec<usize>,
29        values: Vec<CpsFrameTraceSlot>,
30    },
31}
32
33thread_local! {
34    static CPS_FRAME_TRACE: RefCell<Option<Vec<CpsFrameTraceEvent>>> = const { RefCell::new(None) };
35}
36
37pub fn with_cps_frame_trace<T>(f: impl FnOnce() -> T) -> (T, Vec<CpsFrameTraceEvent>) {
38    let previous = CPS_FRAME_TRACE.with(|trace| trace.replace(Some(Vec::new())));
39    let result = f();
40    let events = CPS_FRAME_TRACE
41        .with(|trace| trace.replace(previous))
42        .unwrap_or_default();
43    (result, events)
44}
45
46pub(crate) fn push_cps_frame_trace_event(event: CpsFrameTraceEvent) {
47    CPS_FRAME_TRACE.with(|trace| {
48        if let Some(events) = trace.borrow_mut().as_mut() {
49            events.push(event);
50        }
51    });
52}