wasmer_runtime_core_x/table/
anyfunc.rs1use crate::{
2 error::CreationError,
3 instance::DynFunc,
4 sig_registry::SigRegistry,
5 structures::TypedIndex,
6 types::{FuncSig, TableDescriptor},
7 vm,
8};
9
10use std::convert::TryFrom;
11use std::{ptr, sync::Arc};
12
13enum AnyfuncInner<'a> {
14 Host {
15 ptr: *const vm::Func,
16 signature: Arc<FuncSig>,
17 },
18 Managed(DynFunc<'a>),
19}
20
21pub struct Anyfunc<'a> {
23 inner: AnyfuncInner<'a>,
24}
25
26impl<'a> Anyfunc<'a> {
27 pub unsafe fn new<Sig>(func: *const vm::Func, signature: Sig) -> Self
29 where
30 Sig: Into<Arc<FuncSig>>,
31 {
32 Self {
33 inner: AnyfuncInner::Host {
34 ptr: func as _,
35 signature: signature.into(),
36 },
37 }
38 }
39}
40
41impl<'a> From<DynFunc<'a>> for Anyfunc<'a> {
42 fn from(function: DynFunc<'a>) -> Self {
43 Anyfunc {
44 inner: AnyfuncInner::Managed(function),
45 }
46 }
47}
48
49impl<'a> TryFrom<Anyfunc<'a>> for DynFunc<'a> {
50 type Error = ();
51
52 fn try_from(anyfunc: Anyfunc<'a>) -> Result<Self, Self::Error> {
53 match anyfunc.inner {
54 AnyfuncInner::Managed(df) => Ok(df),
55 _ => Err(()),
56 }
57 }
58}
59
60pub struct AnyfuncTable {
90 pub(crate) backing: Vec<vm::Anyfunc>,
91 max: Option<u32>,
92}
93
94impl AnyfuncTable {
95 pub fn new(
96 desc: TableDescriptor,
97 local: &mut vm::LocalTable,
98 ) -> Result<Box<Self>, CreationError> {
99 let initial_table_backing_len = desc.minimum as usize;
100
101 let mut storage = Box::new(AnyfuncTable {
102 backing: vec![vm::Anyfunc::null(); initial_table_backing_len],
103 max: desc.maximum,
104 });
105
106 let storage_ptr: *mut AnyfuncTable = &mut *storage;
107
108 local.base = storage.backing.as_mut_ptr() as *mut u8;
109 local.count = storage.backing.len();
110 local.table = storage_ptr as *mut ();
111
112 Ok(storage)
113 }
114
115 pub fn current_size(&self) -> u32 {
116 self.backing.len() as u32
117 }
118
119 pub fn internal_buffer(&mut self) -> &mut [vm::Anyfunc] {
120 &mut self.backing
121 }
122
123 pub fn grow(&mut self, delta: u32, local: &mut vm::LocalTable) -> Option<u32> {
124 let starting_len = self.backing.len() as u32;
125
126 let new_len = starting_len.checked_add(delta)?;
127
128 if let Some(max) = self.max {
129 if new_len > max {
130 return None;
131 }
132 }
133
134 self.backing.resize(new_len as usize, vm::Anyfunc::null());
135
136 local.base = self.backing.as_mut_ptr() as *mut u8;
137 local.count = self.backing.len();
138
139 Some(starting_len)
140 }
141
142 #[doc(hidden)]
144 pub(crate) fn get<'outer_table>(&self, index: u32) -> Option<Anyfunc<'outer_table>> {
146 let vm_any_func = self.backing.get(index as usize)?;
147 let signature = SigRegistry.lookup_signature(vm_any_func.sig_id.into());
148 Some(Anyfunc {
154 inner: AnyfuncInner::Host {
155 ptr: vm_any_func.func,
156 signature,
157 },
158 })
159 }
160
161 pub fn set(&mut self, index: u32, element: Anyfunc) -> Result<(), ()> {
162 if let Some(slot) = self.backing.get_mut(index as usize) {
163 let anyfunc = match element.inner {
164 AnyfuncInner::Host { ptr, signature } => {
165 let sig_index = SigRegistry.lookup_sig_index(signature);
166 let sig_id = vm::SigId(sig_index.index() as u32);
167
168 vm::Anyfunc {
169 func: ptr,
170 ctx: ptr::null_mut(),
171 sig_id,
172 }
173 }
174 AnyfuncInner::Managed(ref func) => {
175 let sig_index = SigRegistry.lookup_sig_index(Arc::clone(&func.signature));
176 let sig_id = vm::SigId(sig_index.index() as u32);
177
178 vm::Anyfunc {
179 func: func.raw(),
180 ctx: func.instance_inner.vmctx,
181 sig_id,
182 }
183 }
184 };
185
186 *slot = anyfunc;
187
188 Ok(())
189 } else {
190 Err(())
191 }
192 }
193}