1use crate::{FlowContext, TrapHandler};
2use core::{
3 marker::PhantomData,
4 mem::{MaybeUninit, forget},
5 ops::{Deref, DerefMut},
6 ptr::NonNull,
7};
8
9pub type EntireHandler<T> = extern "C" fn(EntireContext<T>) -> EntireResult;
11
12#[repr(transparent)]
14pub struct EntireContext<T: 'static = ()>(NonNull<TrapHandler>, PhantomData<T>);
15
16impl<T: 'static> EntireContext<T> {
17 #[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
30impl<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#[repr(transparent)]
40pub struct EntireContextSeparated(&'static mut TrapHandler);
41
42impl EntireContextSeparated {
43 #[inline]
45 pub fn regs(&mut self) -> &mut FlowContext {
46 unsafe { self.0.context.as_mut() }
47 }
48
49 #[inline]
51 pub fn restore(self) -> EntireResult {
52 EntireResult::Restore
53 }
54}
55
56#[repr(transparent)]
58pub struct FastMail<T: 'static>(&'static mut MaybeUninit<T>);
59
60impl<T: 'static> FastMail<T> {
61 #[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
86impl<T: 'static> Drop for FastMail<T> {
88 #[inline]
89 fn drop(&mut self) {
90 unsafe { self.0.assume_init_drop() }
91 }
92}
93
94#[repr(usize)]
96pub enum EntireResult {
97 FastCall = 0,
99 Call = 1,
101 Restore = 3,
103}