1use crate::{wasm_extern_t, wasm_ref_t, wasm_store_t, wasm_tabletype_t};
2use alloc::boxed::Box;
3use core::hint;
4use wasmi::{Extern, ExternRef, Func, Nullable, Ref, Table, TableType};
5
6#[derive(Clone)]
10#[repr(transparent)]
11pub struct wasm_table_t {
12 inner: wasm_extern_t,
13}
14
15wasmi_c_api_macros::declare_ref!(wasm_table_t);
16
17pub type wasm_table_size_t = u32;
19
20impl wasm_table_t {
21 pub(crate) fn try_from(e: &wasm_extern_t) -> Option<&wasm_table_t> {
22 match &e.which {
23 Extern::Table(_) => Some(unsafe { &*(e as *const _ as *const _) }),
24 _ => None,
25 }
26 }
27
28 pub(crate) fn try_from_mut(e: &mut wasm_extern_t) -> Option<&mut wasm_table_t> {
29 match &mut e.which {
30 Extern::Table(_) => Some(unsafe { &mut *(e as *mut _ as *mut _) }),
31 _ => None,
32 }
33 }
34
35 fn table(&self) -> Table {
37 match self.inner.which {
38 Extern::Table(t) => t,
39 _ => unsafe { hint::unreachable_unchecked() },
40 }
41 }
42}
43
44fn option_wasm_ref_t_to_ref(r: Option<&wasm_ref_t>, table_ty: &TableType) -> Ref {
48 r.map(|r| r.inner)
49 .unwrap_or_else(|| match table_ty.element() {
50 wasmi::RefType::Func => Ref::Func(<Nullable<Func>>::Null),
51 wasmi::RefType::Extern => Ref::Extern(<Nullable<ExternRef>>::Null),
52 })
53}
54
55#[cfg_attr(not(feature = "prefix-symbols"), unsafe(no_mangle))]
64#[cfg_attr(feature = "prefix-symbols", wasmi_c_api_macros::prefix_symbol)]
65pub unsafe extern "C" fn wasm_table_new(
66 store: &mut wasm_store_t,
67 tt: &wasm_tabletype_t,
68 init: Option<&wasm_ref_t>,
69) -> Option<Box<wasm_table_t>> {
70 unsafe {
71 let tt = tt.ty().ty;
72 let init = option_wasm_ref_t_to_ref(init, &tt);
73 let table = Table::new(store.inner.context_mut(), tt, init).ok()?;
74 Some(Box::new(wasm_table_t {
75 inner: wasm_extern_t {
76 store: store.inner.clone(),
77 which: table.into(),
78 },
79 }))
80 }
81}
82
83#[cfg_attr(not(feature = "prefix-symbols"), unsafe(no_mangle))]
92#[cfg_attr(feature = "prefix-symbols", wasmi_c_api_macros::prefix_symbol)]
93pub unsafe extern "C" fn wasm_table_type(t: &wasm_table_t) -> Box<wasm_tabletype_t> {
94 unsafe {
95 let table = t.table();
96 let store = t.inner.store.context();
97 Box::new(wasm_tabletype_t::new(table.ty(store)))
98 }
99}
100
101#[cfg_attr(not(feature = "prefix-symbols"), unsafe(no_mangle))]
110#[cfg_attr(feature = "prefix-symbols", wasmi_c_api_macros::prefix_symbol)]
111pub unsafe extern "C" fn wasm_table_get(
112 t: &mut wasm_table_t,
113 index: wasm_table_size_t,
114) -> Option<Box<wasm_ref_t>> {
115 unsafe {
116 let table = t.table();
117 let value = table.get(t.inner.store.context_mut(), u64::from(index))?;
118 wasm_ref_t::new(value)
119 }
120}
121
122#[cfg_attr(not(feature = "prefix-symbols"), unsafe(no_mangle))]
131#[cfg_attr(feature = "prefix-symbols", wasmi_c_api_macros::prefix_symbol)]
132pub unsafe extern "C" fn wasm_table_set(
133 t: &mut wasm_table_t,
134 index: wasm_table_size_t,
135 new_value: Option<&wasm_ref_t>,
136) -> bool {
137 unsafe {
138 let table = t.table();
139 let new_value = option_wasm_ref_t_to_ref(new_value, &table.ty(t.inner.store.context()));
140 table
141 .set(t.inner.store.context_mut(), u64::from(index), new_value)
142 .is_ok()
143 }
144}
145
146#[cfg_attr(not(feature = "prefix-symbols"), unsafe(no_mangle))]
155#[cfg_attr(feature = "prefix-symbols", wasmi_c_api_macros::prefix_symbol)]
156pub unsafe extern "C" fn wasm_table_size(t: &wasm_table_t) -> wasm_table_size_t {
157 unsafe {
158 let table = t.table();
159 let store = t.inner.store.context();
160 let size = table.size(store);
161 u32::try_from(size).unwrap()
162 }
163}
164#[cfg_attr(not(feature = "prefix-symbols"), unsafe(no_mangle))]
175#[cfg_attr(feature = "prefix-symbols", wasmi_c_api_macros::prefix_symbol)]
176pub unsafe extern "C" fn wasm_table_grow(
177 t: &mut wasm_table_t,
178 delta: wasm_table_size_t,
179 init: Option<&wasm_ref_t>,
180) -> bool {
181 unsafe {
182 let table = t.table();
183 let init = option_wasm_ref_t_to_ref(init, &table.ty(t.inner.store.context()));
184 table
185 .grow(t.inner.store.context_mut(), u64::from(delta), init)
186 .is_ok()
187 }
188}
189
190#[cfg_attr(not(feature = "prefix-symbols"), unsafe(no_mangle))]
192#[cfg_attr(feature = "prefix-symbols", wasmi_c_api_macros::prefix_symbol)]
193pub extern "C" fn wasm_table_as_extern(t: &mut wasm_table_t) -> &mut wasm_extern_t {
194 &mut t.inner
195}
196
197#[cfg_attr(not(feature = "prefix-symbols"), unsafe(no_mangle))]
199#[cfg_attr(feature = "prefix-symbols", wasmi_c_api_macros::prefix_symbol)]
200pub extern "C" fn wasm_table_as_extern_const(t: &wasm_table_t) -> &wasm_extern_t {
201 &t.inner
202}