fast_trap/
entire.rs

1use crate::{FlowContext, TrapHandler};
2use core::{
3    marker::PhantomData,
4    mem::{MaybeUninit, forget},
5    ops::{Deref, DerefMut},
6    ptr::NonNull,
7};
8
9/// 完整路径函数。
10pub type EntireHandler<T> = extern "C" fn(EntireContext<T>) -> EntireResult;
11
12/// 完整路径上下文。
13#[repr(transparent)]
14pub struct EntireContext<T: 'static = ()>(NonNull<TrapHandler>, PhantomData<T>);
15
16impl<T: 'static> EntireContext<T> {
17    /// 分离完整路径上下文和快速路径消息。
18    #[inline]
19    pub fn split(mut self) -> (EntireContextSeparated, FastMail<T>) {
20        let mail = unsafe { &mut *self.0.as_mut().locate_fast_mail() };
21        let mut handler = self.0;
22        forget(self);
23        (
24            EntireContextSeparated(unsafe { handler.as_mut() }),
25            FastMail(mail),
26        )
27    }
28}
29
30/// 如果没有调用分离,快速路径消息对象可以直接释放。
31impl<T: 'static> Drop for EntireContext<T> {
32    #[inline]
33    fn drop(&mut self) {
34        unsafe { (*self.0.as_mut().locate_fast_mail::<T>()).assume_init_drop() }
35    }
36}
37
38/// 分离了快速路径消息的完整路径上下文。
39#[repr(transparent)]
40pub struct EntireContextSeparated(&'static mut TrapHandler);
41
42impl EntireContextSeparated {
43    /// 获取控制流上下文。
44    #[inline]
45    pub fn regs(&mut self) -> &mut FlowContext {
46        unsafe { self.0.context.as_mut() }
47    }
48
49    /// 从完整路径恢复。
50    #[inline]
51    pub fn restore(self) -> EntireResult {
52        EntireResult::Restore
53    }
54}
55
56/// 快速路径消息。
57#[repr(transparent)]
58pub struct FastMail<T: 'static>(&'static mut MaybeUninit<T>);
59
60impl<T: 'static> FastMail<T> {
61    /// 获取快速路径消息。
62    #[inline]
63    pub fn get(self) -> T {
64        let ans = unsafe { core::mem::replace(self.0, MaybeUninit::uninit()).assume_init() };
65        forget(self);
66        ans
67    }
68}
69
70impl<T: 'static> Deref for FastMail<T> {
71    type Target = T;
72
73    #[inline]
74    fn deref(&self) -> &Self::Target {
75        unsafe { self.0.assume_init_ref() }
76    }
77}
78
79impl<T: 'static> DerefMut for FastMail<T> {
80    #[inline]
81    fn deref_mut(&mut self) -> &mut Self::Target {
82        unsafe { self.0.assume_init_mut() }
83    }
84}
85
86/// 快速路径消息如果未被取走,将自动释放。
87impl<T: 'static> Drop for FastMail<T> {
88    #[inline]
89    fn drop(&mut self) {
90        unsafe { self.0.assume_init_drop() }
91    }
92}
93
94/// 完整路径处理结果。
95#[repr(usize)]
96pub enum EntireResult {
97    /// 调用新上下文,只需设置 2 个或更少参数。
98    FastCall = 0,
99    /// 调用新上下文,需要设置超过 2 个参数。
100    Call = 1,
101    /// 切换到另一个上下文或从完整路径恢复。
102    Restore = 3,
103}