rune/runtime/
vm_diagnostics.rs1use core::ptr::NonNull;
2
3use crate::hash::Hash;
4use crate::runtime::{RuntimeContext, VmError};
5use crate::Diagnostics;
6
7pub trait VmDiagnostics {
9 fn function_used(
16 &mut self,
17 context: &RuntimeContext,
18 hash: Hash,
19 at: usize,
20 ) -> Result<(), VmError>;
21
22 #[doc(hidden)]
24 fn vtable(&self) -> &'static VmDiagnosticsObjVtable;
25}
26
27impl VmDiagnostics for Diagnostics {
28 #[inline]
29 fn function_used(
30 &mut self,
31 context: &RuntimeContext,
32 hash: Hash,
33 at: usize,
34 ) -> Result<(), VmError> {
35 if context.deprecation(&hash).is_some() {
39 self.runtime_used_deprecated(at, hash)?;
40 }
41
42 Ok(())
43 }
44
45 #[inline]
46 fn vtable(&self) -> &'static VmDiagnosticsObjVtable {
47 fn function_used_impl<T>(
48 ptr: NonNull<()>,
49 context: &RuntimeContext,
50 hash: Hash,
51 at: usize,
52 ) -> Result<(), VmError>
53 where
54 T: VmDiagnostics,
55 {
56 unsafe { VmDiagnostics::function_used(ptr.cast::<T>().as_mut(), context, hash, at) }
57 }
58
59 &VmDiagnosticsObjVtable {
60 function_used: function_used_impl::<Self>,
61 }
62 }
63}
64
65#[derive(Debug)]
66pub struct VmDiagnosticsObjVtable {
67 function_used: unsafe fn(
68 NonNull<()>,
69 context: &RuntimeContext,
70 hash: Hash,
71 at: usize,
72 ) -> Result<(), VmError>,
73}
74
75#[repr(C)]
76#[derive(Debug, Clone, Copy)]
77pub(crate) struct VmDiagnosticsObj {
78 ptr: NonNull<()>,
79 vtable: &'static VmDiagnosticsObjVtable,
80}
81
82impl VmDiagnosticsObj {
83 #[inline]
84 pub(crate) fn new(trait_obj: &mut dyn VmDiagnostics) -> Self {
85 let vtable = trait_obj.vtable();
86
87 Self {
88 ptr: unsafe { NonNull::new_unchecked(trait_obj as *mut _ as *mut ()) },
89 vtable,
90 }
91 }
92
93 #[inline]
94 pub(crate) fn function_used(
95 &mut self,
96 context: &RuntimeContext,
97 hash: Hash,
98 at: usize,
99 ) -> Result<(), VmError> {
100 unsafe { (self.vtable.function_used)(self.ptr, context, hash, at) }
101 }
102}