Skip to main content

wasmtime_c_api/types/
table.rs

1use crate::{CExternType, wasm_externtype_t, wasm_limits_t, wasm_valtype_t};
2use std::sync::OnceLock;
3use wasmtime::{TableType, ValType};
4
5#[repr(transparent)]
6#[derive(Clone)]
7pub struct wasm_tabletype_t {
8    ext: wasm_externtype_t,
9}
10
11wasmtime_c_api_macros::declare_ty!(wasm_tabletype_t);
12
13#[derive(Clone)]
14pub(crate) struct CTableType {
15    pub(crate) ty: TableType,
16    element_cache: OnceLock<wasm_valtype_t>,
17    limits_cache: OnceLock<wasm_limits_t>,
18}
19
20impl wasm_tabletype_t {
21    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
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
34    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
42impl CTableType {
43    pub(crate) fn new(ty: TableType) -> CTableType {
44        CTableType {
45            ty,
46            element_cache: OnceLock::new(),
47            limits_cache: OnceLock::new(),
48        }
49    }
50}
51
52#[unsafe(no_mangle)]
53pub 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).as_ref()?.clone();
58    let ty = TableType::new(ty, limits.min, limits.max()).ok()?;
59    Some(Box::new(wasm_tabletype_t::new(ty)))
60}
61
62#[unsafe(no_mangle)]
63pub extern "C" fn wasm_tabletype_element(tt: &wasm_tabletype_t) -> &wasm_valtype_t {
64    let tt = tt.ty();
65    tt.element_cache
66        .get_or_init(|| ValType::Ref(tt.ty.element().clone()))
67}
68
69#[unsafe(no_mangle)]
70pub extern "C" fn wasm_tabletype_limits(tt: &wasm_tabletype_t) -> &wasm_limits_t {
71    let tt = tt.ty();
72    tt.limits_cache.get_or_init(|| wasm_limits_t {
73        min: u32::try_from(tt.ty.minimum()).unwrap(),
74        max: u32::try_from(tt.ty.maximum().unwrap_or(u64::from(u32::MAX))).unwrap(),
75    })
76}
77
78#[unsafe(no_mangle)]
79pub extern "C" fn wasmtime_tabletype_minimum(tt: &wasm_tabletype_t) -> u64 {
80    tt.ty().ty.minimum()
81}
82
83#[unsafe(no_mangle)]
84pub extern "C" fn wasmtime_tabletype_maximum(tt: &wasm_tabletype_t, out: &mut u64) -> bool {
85    match tt.ty().ty.maximum() {
86        Some(max) => {
87            *out = max;
88            true
89        }
90        None => false,
91    }
92}
93
94#[unsafe(no_mangle)]
95pub extern "C" fn wasmtime_tabletype_is64(tt: &wasm_tabletype_t) -> bool {
96    tt.ty().ty.is_64()
97}
98
99#[unsafe(no_mangle)]
100pub extern "C" fn wasm_tabletype_as_externtype(ty: &wasm_tabletype_t) -> &wasm_externtype_t {
101    &ty.ext
102}
103
104#[unsafe(no_mangle)]
105pub extern "C" fn wasm_tabletype_as_externtype_const(ty: &wasm_tabletype_t) -> &wasm_externtype_t {
106    &ty.ext
107}