yulang-native 0.1.1

Native backend experiments for Yulang
Documentation
use std::cell::RefCell;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CpsFrameTraceLayer {
    CpsEval,
    CpsRepr,
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CpsFrameTraceSlot {
    pub target: usize,
    pub value: String,
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum CpsFrameTraceEvent {
    HandlerEnvRead {
        layer: CpsFrameTraceLayer,
        function: String,
        handler: usize,
        entry: usize,
        values: Vec<CpsFrameTraceSlot>,
    },
    HandlerEnvOverlay {
        layer: CpsFrameTraceLayer,
        function: String,
        handler: usize,
        entries: Vec<usize>,
        values: Vec<CpsFrameTraceSlot>,
    },
}

thread_local! {
    static CPS_FRAME_TRACE: RefCell<Option<Vec<CpsFrameTraceEvent>>> = const { RefCell::new(None) };
}

pub fn with_cps_frame_trace<T>(f: impl FnOnce() -> T) -> (T, Vec<CpsFrameTraceEvent>) {
    let previous = CPS_FRAME_TRACE.with(|trace| trace.replace(Some(Vec::new())));
    let result = f();
    let events = CPS_FRAME_TRACE
        .with(|trace| trace.replace(previous))
        .unwrap_or_default();
    (result, events)
}

pub(crate) fn push_cps_frame_trace_event(event: CpsFrameTraceEvent) {
    CPS_FRAME_TRACE.with(|trace| {
        if let Some(events) = trace.borrow_mut().as_mut() {
            events.push(event);
        }
    });
}