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}