use crate::{EntireHandler, FlowContext, TrapHandler};
use core::{mem::MaybeUninit, ptr::NonNull};
pub type FastHandler = extern "C" fn(
ctx: FastContext,
a1: usize,
a2: usize,
a3: usize,
a4: usize,
a5: usize,
a6: usize,
a7: usize,
) -> FastResult;
#[repr(transparent)]
pub struct FastContext(&'static mut TrapHandler);
impl FastContext {
#[inline]
pub fn a0(&self) -> usize {
self.0.scratch
}
#[inline]
pub fn regs(&mut self) -> &mut FlowContext {
unsafe { self.0.context.as_mut() }
}
#[inline]
pub fn swap_context(&mut self, new: NonNull<FlowContext>) -> NonNull<FlowContext> {
core::mem::replace(&mut self.0.context, new)
}
#[inline]
pub fn call(self, argc: usize) -> FastResult {
unsafe { self.0.context.as_ref().load_others() };
if argc <= 2 {
FastResult::FastCall
} else {
FastResult::Call
}
}
#[inline]
pub fn restore(self) -> FastResult {
FastResult::Restore
}
#[inline]
pub fn switch_to(self, others: NonNull<FlowContext>) -> FastResult {
unsafe { others.as_ref().load_others() };
self.0.context = others;
FastResult::Switch
}
#[inline]
pub fn continue_with<T: 'static>(self, f: EntireHandler<T>, t: T) -> FastResult {
unsafe { *self.0.locate_fast_mail() = MaybeUninit::new(t) };
self.0.scratch = f as _;
FastResult::Continue
}
}
#[repr(usize)]
pub enum FastResult {
FastCall = 0,
Call = 1,
Restore = 2,
Switch = 3,
Continue = 4,
}