yulang_native/
cps_frame_trace.rs1use 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}