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