1use wasmer_types::TableType;
2
3use crate::{
4 AsStoreMut, AsStoreRef, ExportError, Exportable, Extern, StoreMut, StoreRef, Value,
5 error::RuntimeError,
6 macros::backend::{gen_rt_ty, match_rt},
7 store::BackendStore,
8 vm::{VMExtern, VMExternTable},
9};
10gen_rt_ty!(Table
20 @cfg feature = "artifact-size" => derive(loupe::MemoryUsage)
21 @derives Debug, Clone, PartialEq, Eq, derive_more::From
22);
23
24impl BackendTable {
25 #[inline]
31 pub fn new(
32 store: &mut impl AsStoreMut,
33 ty: TableType,
34 init: Value,
35 ) -> Result<Self, RuntimeError> {
36 match &store.as_store_mut().inner.store {
37 #[cfg(feature = "sys")]
38 BackendStore::Sys(_) => Ok(Self::Sys(
39 crate::backend::sys::entities::table::Table::new(store, ty, init)?,
40 )),
41 #[cfg(feature = "wamr")]
42 BackendStore::Wamr(_) => Ok(Self::Wamr(
43 crate::backend::wamr::entities::table::Table::new(store, ty, init)?,
44 )),
45 #[cfg(feature = "wasmi")]
46 BackendStore::Wasmi(_) => Ok(Self::Wasmi(
47 crate::backend::wasmi::entities::table::Table::new(store, ty, init)?,
48 )),
49 #[cfg(feature = "v8")]
50 BackendStore::V8(_) => Ok(Self::V8(crate::backend::v8::entities::table::Table::new(
51 store, ty, init,
52 )?)),
53 #[cfg(feature = "js")]
54 BackendStore::Js(_) => Ok(Self::Js(crate::backend::js::entities::table::Table::new(
55 store, ty, init,
56 )?)),
57 #[cfg(feature = "jsc")]
58 BackendStore::Jsc(_) => Ok(Self::Jsc(
59 crate::backend::jsc::entities::table::Table::new(store, ty, init)?,
60 )),
61 }
62 }
63
64 #[inline]
66 pub fn ty(&self, store: &impl AsStoreRef) -> TableType {
67 match_rt!(on self => s {
68 s.ty(store)
69 })
70 }
71
72 #[inline]
74 pub fn get(&self, store: &mut impl AsStoreMut, index: u32) -> Option<Value> {
75 match_rt!(on self => s {
76 s.get(store, index)
77 })
78 }
79
80 #[inline]
82 pub fn set(
83 &self,
84 store: &mut impl AsStoreMut,
85 index: u32,
86 val: Value,
87 ) -> Result<(), RuntimeError> {
88 match_rt!(on self => s {
89 s.set(store, index, val)
90 })
91 }
92
93 #[inline]
95 pub fn size(&self, store: &impl AsStoreRef) -> u32 {
96 match_rt!(on self => s {
97 s.size(store)
98 })
99 }
100
101 #[inline]
111 pub fn grow(
112 &self,
113 store: &mut impl AsStoreMut,
114 delta: u32,
115 init: Value,
116 ) -> Result<u32, RuntimeError> {
117 match_rt!(on self => s {
118 s.grow(store, delta, init)
119 })
120 }
121
122 #[inline]
130 pub fn copy(
131 store: &mut impl AsStoreMut,
132 dst_table: &Self,
133 dst_index: u32,
134 src_table: &Self,
135 src_index: u32,
136 len: u32,
137 ) -> Result<(), RuntimeError> {
138 match &store.as_store_mut().inner.store {
139 #[cfg(feature = "sys")]
140 BackendStore::Sys(_) => crate::backend::sys::entities::table::Table::copy(
141 store,
142 dst_table.as_sys(),
143 dst_index,
144 src_table.as_sys(),
145 src_index,
146 len,
147 ),
148 #[cfg(feature = "wamr")]
149 BackendStore::Wamr(_) => crate::backend::wamr::entities::table::Table::copy(
150 store,
151 dst_table.as_wamr(),
152 dst_index,
153 src_table.as_wamr(),
154 src_index,
155 len,
156 ),
157 #[cfg(feature = "wasmi")]
158 BackendStore::Wasmi(_) => crate::backend::wasmi::entities::table::Table::copy(
159 store,
160 dst_table.as_wasmi(),
161 dst_index,
162 src_table.as_wasmi(),
163 src_index,
164 len,
165 ),
166
167 #[cfg(feature = "v8")]
168 BackendStore::V8(_) => crate::backend::v8::entities::table::Table::copy(
169 store,
170 dst_table.as_v8(),
171 dst_index,
172 src_table.as_v8(),
173 src_index,
174 len,
175 ),
176 #[cfg(feature = "js")]
177 BackendStore::Js(_) => crate::backend::js::entities::table::Table::copy(
178 store,
179 dst_table.as_js(),
180 dst_index,
181 src_table.as_js(),
182 src_index,
183 len,
184 ),
185 #[cfg(feature = "jsc")]
186 BackendStore::Jsc(_) => crate::backend::jsc::entities::table::Table::copy(
187 store,
188 dst_table.as_jsc(),
189 dst_index,
190 src_table.as_jsc(),
191 src_index,
192 len,
193 ),
194 }
195 }
196
197 #[inline]
198 pub(crate) fn from_vm_extern(store: &mut impl AsStoreMut, ext: VMExternTable) -> Self {
199 match &store.as_store_mut().inner.store {
200 #[cfg(feature = "sys")]
201 BackendStore::Sys(_) => Self::Sys(
202 crate::backend::sys::entities::table::Table::from_vm_extern(store, ext),
203 ),
204 #[cfg(feature = "wamr")]
205 BackendStore::Wamr(_) => {
206 Self::Wamr(crate::backend::wamr::entities::table::Table::from_vm_extern(store, ext))
207 }
208 #[cfg(feature = "wasmi")]
209 BackendStore::Wasmi(_) => Self::Wasmi(
210 crate::backend::wasmi::entities::table::Table::from_vm_extern(store, ext),
211 ),
212 #[cfg(feature = "v8")]
213 BackendStore::V8(_) => Self::V8(
214 crate::backend::v8::entities::table::Table::from_vm_extern(store, ext),
215 ),
216 #[cfg(feature = "js")]
217 BackendStore::Js(_) => Self::Js(
218 crate::backend::js::entities::table::Table::from_vm_extern(store, ext),
219 ),
220 #[cfg(feature = "jsc")]
221 BackendStore::Jsc(_) => Self::Jsc(
222 crate::backend::jsc::entities::table::Table::from_vm_extern(store, ext),
223 ),
224 }
225 }
226
227 #[inline]
229 pub fn is_from_store(&self, store: &impl AsStoreRef) -> bool {
230 match_rt!(on self => s {
231 s.is_from_store(store)
232 })
233 }
234
235 #[inline]
236 pub(crate) fn to_vm_extern(&self) -> VMExtern {
237 match_rt!(on self => s {
238 s.to_vm_extern()
239 })
240 }
241}
242
243#[cfg(test)]
244mod test {
245 #[test]
247 #[cfg_attr(
248 feature = "wamr",
249 ignore = "wamr does not support direct calls to grow table"
250 )]
251 #[cfg_attr(feature = "wasmi", ignore = "wasmi does not support funcrefs")]
252 #[cfg_attr(
253 feature = "v8",
254 ignore = "growing tables in v8 is not currently supported"
255 )]
256 fn table_grow_issue_3197() {
257 use crate::{Instance, Module, Store, Table, TableType, Type, Value, imports};
258
259 const WAT: &str = r#"(module (table (import "env" "table") 100 funcref))"#;
260
261 let mut store = Store::default();
264 let module = Module::new(&store, WAT).unwrap();
265 let ty = TableType::new(Type::FuncRef, 0, None);
266 let table = Table::new(&mut store, ty, Value::FuncRef(None)).unwrap();
267 table.grow(&mut store, 100, Value::FuncRef(None)).unwrap();
268 assert_eq!(table.ty(&store).minimum, 0);
269 let imports = imports! {"env" => {"table" => table}};
270 let _instance = Instance::new(&mut store, &module, &imports).unwrap();
271 }
272}