open_entry_bindings/
event.rs

1use std::{fmt::Debug, sync::Arc, marker::PhantomData};
2
3use crate::shutdown_type::ShutdownType;
4
5#[derive(Debug)]
6pub enum EventType {
7    VMRun,
8    VMEnd,
9    VMShutdown(ShutdownType),
10    Foreign {
11        from: u32, 
12        event: u32, 
13        payload: UnsafeEventArgs
14    },
15}
16
17#[repr(transparent)]
18pub struct UnsafeEventArgs(pub(crate) usize);
19
20impl UnsafeEventArgs {
21    pub(crate) fn new<T: Sized>(data: T) -> UnsafeEventArgs {
22        UnsafeEventArgs(Arc::into_raw(Arc::new(data)) as usize)
23    }
24
25    // This can transmute something internally
26    #[inline(always)]
27    pub(crate) unsafe fn get<T: Sized>(&self) -> Arc<T> {
28        Arc::from_raw(self.0 as *const T).clone()
29    }
30
31    // Unsafe because of heap corruption
32    #[inline(always)]
33    pub(crate) unsafe fn drop<T: Sized>(&self) {
34        Arc::decrement_strong_count(self.0 as *const T)
35    }
36}
37
38#[repr(transparent)]
39pub struct EventArgs<T: Sized>(UnsafeEventArgs, PhantomData<T>);
40
41impl<T: Sized> EventArgs<T> {
42    pub fn new(data: T) -> EventArgs<T> {
43        EventArgs(UnsafeEventArgs::new(data), PhantomData)
44    }
45
46    pub fn get(&self) -> Arc<T> {
47        // Safe because we use always same generic type. No transmute happens
48        unsafe { self.0.get::<T>() }
49    }
50}
51
52impl<T: Sized> Debug for EventArgs<T> {
53    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
54        f.write_fmt(format_args!("EventArgs(0x{:016x})", self.0.0))
55    }
56}
57
58impl<T: Sized> Into<UnsafeEventArgs> for EventArgs<T> {
59    fn into(self) -> UnsafeEventArgs {
60        let ptr = self.0.0;
61
62        // Make sure UnsafeEventArgs should not be dropped
63        std::mem::forget(self);
64
65        UnsafeEventArgs(ptr)
66    }
67}
68
69impl<T: Sized> Into<EventArgs<T>> for UnsafeEventArgs {
70    fn into(self) -> EventArgs<T> {
71        EventArgs(self, PhantomData)
72    }
73}
74
75impl<T: Sized> Drop for EventArgs<T> {
76    fn drop(&mut self) {
77        // Safe because we use always same generic type. No heap corruption happens
78        unsafe { self.0.drop::<T>() }
79    }
80}
81
82impl Debug for UnsafeEventArgs {
83    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
84        f.write_fmt(format_args!("UnsafeEventArgs(0x{:016x})", self.0))
85    }
86}