1 use crate::{CExternType, wasm_externtype_t, wasm_limits_t, wasm_valtype_t};
2 use std::cell::OnceCell;
3 use wasmtime::{TableType, ValType};
4 
5 #[repr(transparent)]
6 #[derive(Clone)]
7 pub struct wasm_tabletype_t {
8     ext: wasm_externtype_t,
9 }
10 
11 wasmtime_c_api_macros::declare_ty!(wasm_tabletype_t);
12 
13 #[derive(Clone)]
14 pub(crate) struct CTableType {
15     pub(crate) ty: TableType,
16     element_cache: OnceCell<wasm_valtype_t>,
17     limits_cache: OnceCell<wasm_limits_t>,
18 }
19 
20 impl wasm_tabletype_t {
new(ty: TableType) -> wasm_tabletype_t21     pub(crate) fn new(ty: TableType) -> wasm_tabletype_t {
22         wasm_tabletype_t {
23             ext: wasm_externtype_t::from_extern_type(ty.into()),
24         }
25     }
26 
try_from(e: &wasm_externtype_t) -> Option<&wasm_tabletype_t>27     pub(crate) fn try_from(e: &wasm_externtype_t) -> Option<&wasm_tabletype_t> {
28         match &e.which {
29             CExternType::Table(_) => Some(unsafe { &*(e as *const _ as *const _) }),
30             _ => None,
31         }
32     }
33 
ty(&self) -> &CTableType34     pub(crate) fn ty(&self) -> &CTableType {
35         match &self.ext.which {
36             CExternType::Table(f) => &f,
37             _ => unsafe { std::hint::unreachable_unchecked() },
38         }
39     }
40 }
41 
42 impl CTableType {
new(ty: TableType) -> CTableType43     pub(crate) fn new(ty: TableType) -> CTableType {
44         CTableType {
45             ty,
46             element_cache: OnceCell::new(),
47             limits_cache: OnceCell::new(),
48         }
49     }
50 }
51 
52 #[unsafe(no_mangle)]
wasm_tabletype_new( ty: Box<wasm_valtype_t>, limits: &wasm_limits_t, ) -> Option<Box<wasm_tabletype_t>>53 pub extern "C" fn wasm_tabletype_new(
54     ty: Box<wasm_valtype_t>,
55     limits: &wasm_limits_t,
56 ) -> Option<Box<wasm_tabletype_t>> {
57     let ty = ty.ty.as_ref()?.clone();
58     Some(Box::new(wasm_tabletype_t::new(TableType::new(
59         ty,
60         limits.min,
61         limits.max(),
62     ))))
63 }
64 
65 #[unsafe(no_mangle)]
wasm_tabletype_element(tt: &wasm_tabletype_t) -> &wasm_valtype_t66 pub extern "C" fn wasm_tabletype_element(tt: &wasm_tabletype_t) -> &wasm_valtype_t {
67     let tt = tt.ty();
68     tt.element_cache.get_or_init(|| wasm_valtype_t {
69         ty: ValType::Ref(tt.ty.element().clone()),
70     })
71 }
72 
73 #[unsafe(no_mangle)]
wasm_tabletype_limits(tt: &wasm_tabletype_t) -> &wasm_limits_t74 pub extern "C" fn wasm_tabletype_limits(tt: &wasm_tabletype_t) -> &wasm_limits_t {
75     let tt = tt.ty();
76     tt.limits_cache.get_or_init(|| wasm_limits_t {
77         min: u32::try_from(tt.ty.minimum()).unwrap(),
78         max: u32::try_from(tt.ty.maximum().unwrap_or(u64::from(u32::MAX))).unwrap(),
79     })
80 }
81 
82 #[unsafe(no_mangle)]
wasm_tabletype_as_externtype(ty: &wasm_tabletype_t) -> &wasm_externtype_t83 pub extern "C" fn wasm_tabletype_as_externtype(ty: &wasm_tabletype_t) -> &wasm_externtype_t {
84     &ty.ext
85 }
86 
87 #[unsafe(no_mangle)]
wasm_tabletype_as_externtype_const(ty: &wasm_tabletype_t) -> &wasm_externtype_t88 pub extern "C" fn wasm_tabletype_as_externtype_const(ty: &wasm_tabletype_t) -> &wasm_externtype_t {
89     &ty.ext
90 }
91