rune/runtime/
vm_diagnostics.rs

1use core::ptr::NonNull;
2
3use crate::hash::Hash;
4use crate::runtime::VmResult;
5use crate::Diagnostics;
6
7pub trait VmDiagnostics {
8    fn function_used(&mut self, hash: Hash, at: usize) -> VmResult<()>;
9
10    fn vtable(&self) -> &'static VmDiagnosticsObjVtable;
11}
12
13impl VmDiagnostics for Diagnostics {
14    fn function_used(&mut self, hash: Hash, at: usize) -> VmResult<()> {
15        vm_try!(self.runtime_used_deprecated(at, hash));
16        VmResult::Ok(())
17    }
18
19    fn vtable(&self) -> &'static VmDiagnosticsObjVtable {
20        fn function_used_impl<T>(ptr: NonNull<()>, hash: Hash, at: usize) -> VmResult<()>
21        where
22            T: VmDiagnostics,
23        {
24            unsafe { VmDiagnostics::function_used(ptr.cast::<T>().as_mut(), hash, at) }
25        }
26
27        &VmDiagnosticsObjVtable {
28            function_used: function_used_impl::<Self>,
29        }
30    }
31}
32
33#[derive(Debug)]
34pub struct VmDiagnosticsObjVtable {
35    function_used: unsafe fn(NonNull<()>, hash: Hash, at: usize) -> VmResult<()>,
36}
37
38#[repr(C)]
39#[derive(Debug, Clone, Copy)]
40pub(crate) struct VmDiagnosticsObj {
41    ptr: NonNull<()>,
42    vtable: &'static VmDiagnosticsObjVtable,
43}
44
45impl VmDiagnosticsObj {
46    pub(crate) fn new(trait_obj: &mut dyn VmDiagnostics) -> Self {
47        let vtable = trait_obj.vtable();
48
49        Self {
50            ptr: unsafe { NonNull::new_unchecked(trait_obj as *mut _ as *mut ()) },
51            vtable,
52        }
53    }
54
55    pub(crate) fn function_used(&mut self, hash: Hash, at: usize) -> VmResult<()> {
56        unsafe { (self.vtable.function_used)(self.ptr, hash, at) }
57    }
58}