17a1b7cdfSAlex Crichton use crate::{
290ac295eSAlex Crichton WasmtimeStoreContext, WasmtimeStoreContextMut, handle_result, wasm_extern_t, wasm_ref_t,
390ac295eSAlex Crichton wasm_store_t, wasm_tabletype_t, wasmtime_error_t, wasmtime_val_t,
47a1b7cdfSAlex Crichton };
57a1b7cdfSAlex Crichton use std::mem::MaybeUninit;
6*dc029724SNick Fitzgerald use wasmtime::{Extern, Ref, RootScope, Table, TableType, format_err};
76ef09359SAlex Crichton
86ef09359SAlex Crichton #[derive(Clone)]
96ef09359SAlex Crichton #[repr(transparent)]
106ef09359SAlex Crichton pub struct wasm_table_t {
116ef09359SAlex Crichton ext: wasm_extern_t,
126ef09359SAlex Crichton }
136ef09359SAlex Crichton
146ef09359SAlex Crichton wasmtime_c_api_macros::declare_ref!(wasm_table_t);
156ef09359SAlex Crichton
166ef09359SAlex Crichton pub type wasm_table_size_t = u32;
176ef09359SAlex Crichton
186ef09359SAlex Crichton impl wasm_table_t {
try_from(e: &wasm_extern_t) -> Option<&wasm_table_t>196ef09359SAlex Crichton pub(crate) fn try_from(e: &wasm_extern_t) -> Option<&wasm_table_t> {
206ef09359SAlex Crichton match &e.which {
21cca558cdSAlex Crichton Extern::Table(_) => Some(unsafe { &*(e as *const _ as *const _) }),
226ef09359SAlex Crichton _ => None,
236ef09359SAlex Crichton }
246ef09359SAlex Crichton }
256ef09359SAlex Crichton
table(&self) -> Table267a1b7cdfSAlex Crichton fn table(&self) -> Table {
277a1b7cdfSAlex Crichton match self.ext.which {
28cca558cdSAlex Crichton Extern::Table(t) => t,
296ef09359SAlex Crichton _ => unsafe { std::hint::unreachable_unchecked() },
306ef09359SAlex Crichton }
316ef09359SAlex Crichton }
326ef09359SAlex Crichton }
336ef09359SAlex Crichton
option_wasm_ref_t_to_ref(r: Option<&wasm_ref_t>, table_ty: &TableType) -> Ref34ff93bce0SNick Fitzgerald fn option_wasm_ref_t_to_ref(r: Option<&wasm_ref_t>, table_ty: &TableType) -> Ref {
3562329048SNick Fitzgerald r.map(|r| r.r.clone())
3662329048SNick Fitzgerald .unwrap_or_else(|| Ref::null(table_ty.element().heap_type()))
37aaf4c941SNick Fitzgerald }
38aaf4c941SNick Fitzgerald
39ae84e6edSAlex Crichton #[unsafe(no_mangle)]
wasm_table_new( store: &mut wasm_store_t, tt: &wasm_tabletype_t, init: Option<&wasm_ref_t>, ) -> Option<Box<wasm_table_t>>407a1b7cdfSAlex Crichton pub unsafe extern "C" fn wasm_table_new(
417a1b7cdfSAlex Crichton store: &mut wasm_store_t,
426ef09359SAlex Crichton tt: &wasm_tabletype_t,
4389603bc6SNick Fitzgerald init: Option<&wasm_ref_t>,
446ef09359SAlex Crichton ) -> Option<Box<wasm_table_t>> {
45ff93bce0SNick Fitzgerald let tt = tt.ty().ty.clone();
46ff93bce0SNick Fitzgerald let init = option_wasm_ref_t_to_ref(init, &tt);
47ff93bce0SNick Fitzgerald let table = Table::new(store.store.context_mut(), tt, init).ok()?;
486ef09359SAlex Crichton Some(Box::new(wasm_table_t {
496ef09359SAlex Crichton ext: wasm_extern_t {
507a1b7cdfSAlex Crichton store: store.store.clone(),
51cca558cdSAlex Crichton which: table.into(),
526ef09359SAlex Crichton },
536ef09359SAlex Crichton }))
546ef09359SAlex Crichton }
556ef09359SAlex Crichton
56ae84e6edSAlex Crichton #[unsafe(no_mangle)]
wasm_table_type(t: &wasm_table_t) -> Box<wasm_tabletype_t>577a1b7cdfSAlex Crichton pub unsafe extern "C" fn wasm_table_type(t: &wasm_table_t) -> Box<wasm_tabletype_t> {
587a1b7cdfSAlex Crichton let table = t.table();
597a1b7cdfSAlex Crichton let store = t.ext.store.context();
607a1b7cdfSAlex Crichton Box::new(wasm_tabletype_t::new(table.ty(&store)))
611247f2b4SAlex Crichton }
621247f2b4SAlex Crichton
63ae84e6edSAlex Crichton #[unsafe(no_mangle)]
wasm_table_get( t: &mut wasm_table_t, index: wasm_table_size_t, ) -> Option<Box<wasm_ref_t>>647a1b7cdfSAlex Crichton pub unsafe extern "C" fn wasm_table_get(
657a1b7cdfSAlex Crichton t: &mut wasm_table_t,
66aaf4c941SNick Fitzgerald index: wasm_table_size_t,
67aaf4c941SNick Fitzgerald ) -> Option<Box<wasm_ref_t>> {
687a1b7cdfSAlex Crichton let table = t.table();
69df69b9a7SLinwei Shang let r = table.get(t.ext.store.context_mut(), u64::from(index))?;
70ff93bce0SNick Fitzgerald wasm_ref_t::new(r)
716ef09359SAlex Crichton }
726ef09359SAlex Crichton
73ae84e6edSAlex Crichton #[unsafe(no_mangle)]
wasm_table_set( t: &mut wasm_table_t, index: wasm_table_size_t, r: Option<&wasm_ref_t>, ) -> bool746ef09359SAlex Crichton pub unsafe extern "C" fn wasm_table_set(
757a1b7cdfSAlex Crichton t: &mut wasm_table_t,
766ef09359SAlex Crichton index: wasm_table_size_t,
7789603bc6SNick Fitzgerald r: Option<&wasm_ref_t>,
786ef09359SAlex Crichton ) -> bool {
797a1b7cdfSAlex Crichton let table = t.table();
80ff93bce0SNick Fitzgerald let val = option_wasm_ref_t_to_ref(r, &table.ty(t.ext.store.context()));
81df69b9a7SLinwei Shang table
82df69b9a7SLinwei Shang .set(t.ext.store.context_mut(), u64::from(index), val)
83df69b9a7SLinwei Shang .is_ok()
846ef09359SAlex Crichton }
856ef09359SAlex Crichton
86ae84e6edSAlex Crichton #[unsafe(no_mangle)]
wasm_table_size(t: &wasm_table_t) -> wasm_table_size_t877a1b7cdfSAlex Crichton pub unsafe extern "C" fn wasm_table_size(t: &wasm_table_t) -> wasm_table_size_t {
887a1b7cdfSAlex Crichton let table = t.table();
897a1b7cdfSAlex Crichton let store = t.ext.store.context();
90df69b9a7SLinwei Shang u32::try_from(table.size(&store)).unwrap()
916ef09359SAlex Crichton }
926ef09359SAlex Crichton
93ae84e6edSAlex Crichton #[unsafe(no_mangle)]
wasm_table_grow( t: &mut wasm_table_t, delta: wasm_table_size_t, init: Option<&wasm_ref_t>, ) -> bool946ef09359SAlex Crichton pub unsafe extern "C" fn wasm_table_grow(
957a1b7cdfSAlex Crichton t: &mut wasm_table_t,
966ef09359SAlex Crichton delta: wasm_table_size_t,
9789603bc6SNick Fitzgerald init: Option<&wasm_ref_t>,
986ef09359SAlex Crichton ) -> bool {
997a1b7cdfSAlex Crichton let table = t.table();
100ff93bce0SNick Fitzgerald let init = option_wasm_ref_t_to_ref(init, &table.ty(t.ext.store.context()));
101df69b9a7SLinwei Shang table
102df69b9a7SLinwei Shang .grow(t.ext.store.context_mut(), u64::from(delta), init)
103df69b9a7SLinwei Shang .is_ok()
1046ef09359SAlex Crichton }
1056ef09359SAlex Crichton
106ae84e6edSAlex Crichton #[unsafe(no_mangle)]
wasm_table_as_extern(t: &mut wasm_table_t) -> &mut wasm_extern_t1077a1b7cdfSAlex Crichton pub extern "C" fn wasm_table_as_extern(t: &mut wasm_table_t) -> &mut wasm_extern_t {
1087a1b7cdfSAlex Crichton &mut t.ext
1091247f2b4SAlex Crichton }
1101247f2b4SAlex Crichton
111ae84e6edSAlex Crichton #[unsafe(no_mangle)]
wasm_table_as_extern_const(t: &wasm_table_t) -> &wasm_extern_t1127a1b7cdfSAlex Crichton pub extern "C" fn wasm_table_as_extern_const(t: &wasm_table_t) -> &wasm_extern_t {
1136ef09359SAlex Crichton &t.ext
1146ef09359SAlex Crichton }
1157a1b7cdfSAlex Crichton
116ae84e6edSAlex Crichton #[unsafe(no_mangle)]
wasmtime_table_new( mut store: WasmtimeStoreContextMut<'_>, tt: &wasm_tabletype_t, init: &wasmtime_val_t, out: &mut Table, ) -> Option<Box<wasmtime_error_t>>1177a1b7cdfSAlex Crichton pub unsafe extern "C" fn wasmtime_table_new(
118420fc3d1SNick Fitzgerald mut store: WasmtimeStoreContextMut<'_>,
1197a1b7cdfSAlex Crichton tt: &wasm_tabletype_t,
1207a1b7cdfSAlex Crichton init: &wasmtime_val_t,
1217a1b7cdfSAlex Crichton out: &mut Table,
1227a1b7cdfSAlex Crichton ) -> Option<Box<wasmtime_error_t>> {
1239187f2d9SAlex Crichton let mut scope = RootScope::new(&mut store);
1247a1b7cdfSAlex Crichton handle_result(
1259187f2d9SAlex Crichton init.to_val(&mut scope)
126ff93bce0SNick Fitzgerald .ref_()
127*dc029724SNick Fitzgerald .ok_or_else(|| format_err!("wasmtime_table_new init value is not a reference"))
1289187f2d9SAlex Crichton .and_then(|init| Table::new(scope, tt.ty().ty.clone(), init)),
1297a1b7cdfSAlex Crichton |table| *out = table,
1307a1b7cdfSAlex Crichton )
1317a1b7cdfSAlex Crichton }
1327a1b7cdfSAlex Crichton
133ae84e6edSAlex Crichton #[unsafe(no_mangle)]
wasmtime_table_type( store: WasmtimeStoreContext<'_>, table: &Table, ) -> Box<wasm_tabletype_t>1347a1b7cdfSAlex Crichton pub unsafe extern "C" fn wasmtime_table_type(
135420fc3d1SNick Fitzgerald store: WasmtimeStoreContext<'_>,
1367a1b7cdfSAlex Crichton table: &Table,
1377a1b7cdfSAlex Crichton ) -> Box<wasm_tabletype_t> {
1387a1b7cdfSAlex Crichton Box::new(wasm_tabletype_t::new(table.ty(store)))
1397a1b7cdfSAlex Crichton }
1407a1b7cdfSAlex Crichton
141ae84e6edSAlex Crichton #[unsafe(no_mangle)]
wasmtime_table_get( store: WasmtimeStoreContextMut<'_>, table: &Table, index: u64, ret: &mut MaybeUninit<wasmtime_val_t>, ) -> bool1427a1b7cdfSAlex Crichton pub extern "C" fn wasmtime_table_get(
1439187f2d9SAlex Crichton store: WasmtimeStoreContextMut<'_>,
1447a1b7cdfSAlex Crichton table: &Table,
145df69b9a7SLinwei Shang index: u64,
1467a1b7cdfSAlex Crichton ret: &mut MaybeUninit<wasmtime_val_t>,
1477a1b7cdfSAlex Crichton ) -> bool {
1489187f2d9SAlex Crichton let mut scope = RootScope::new(store);
1499187f2d9SAlex Crichton match table.get(&mut scope, index) {
150ff93bce0SNick Fitzgerald Some(r) => {
1519187f2d9SAlex Crichton crate::initialize(ret, wasmtime_val_t::from_val(&mut scope, r.into()));
1527a1b7cdfSAlex Crichton true
1537a1b7cdfSAlex Crichton }
1547a1b7cdfSAlex Crichton None => false,
1557a1b7cdfSAlex Crichton }
1567a1b7cdfSAlex Crichton }
1577a1b7cdfSAlex Crichton
158ae84e6edSAlex Crichton #[unsafe(no_mangle)]
wasmtime_table_set( mut store: WasmtimeStoreContextMut<'_>, table: &Table, index: u64, val: &wasmtime_val_t, ) -> Option<Box<wasmtime_error_t>>1597a1b7cdfSAlex Crichton pub unsafe extern "C" fn wasmtime_table_set(
160420fc3d1SNick Fitzgerald mut store: WasmtimeStoreContextMut<'_>,
1617a1b7cdfSAlex Crichton table: &Table,
162df69b9a7SLinwei Shang index: u64,
1637a1b7cdfSAlex Crichton val: &wasmtime_val_t,
1647a1b7cdfSAlex Crichton ) -> Option<Box<wasmtime_error_t>> {
1659187f2d9SAlex Crichton let mut scope = RootScope::new(&mut store);
166ff93bce0SNick Fitzgerald handle_result(
1679187f2d9SAlex Crichton val.to_val(&mut scope)
168ff93bce0SNick Fitzgerald .ref_()
169*dc029724SNick Fitzgerald .ok_or_else(|| format_err!("wasmtime_table_set value is not a reference"))
1709187f2d9SAlex Crichton .and_then(|val| table.set(scope, index, val)),
171ff93bce0SNick Fitzgerald |()| {},
172ff93bce0SNick Fitzgerald )
1737a1b7cdfSAlex Crichton }
1747a1b7cdfSAlex Crichton
175ae84e6edSAlex Crichton #[unsafe(no_mangle)]
wasmtime_table_size(store: WasmtimeStoreContext<'_>, table: &Table) -> u64176df69b9a7SLinwei Shang pub extern "C" fn wasmtime_table_size(store: WasmtimeStoreContext<'_>, table: &Table) -> u64 {
1777a1b7cdfSAlex Crichton table.size(store)
1787a1b7cdfSAlex Crichton }
1797a1b7cdfSAlex Crichton
180ae84e6edSAlex Crichton #[unsafe(no_mangle)]
wasmtime_table_grow( mut store: WasmtimeStoreContextMut<'_>, table: &Table, delta: u64, val: &wasmtime_val_t, prev_size: &mut u64, ) -> Option<Box<wasmtime_error_t>>1817a1b7cdfSAlex Crichton pub unsafe extern "C" fn wasmtime_table_grow(
182420fc3d1SNick Fitzgerald mut store: WasmtimeStoreContextMut<'_>,
1837a1b7cdfSAlex Crichton table: &Table,
184df69b9a7SLinwei Shang delta: u64,
1857a1b7cdfSAlex Crichton val: &wasmtime_val_t,
186df69b9a7SLinwei Shang prev_size: &mut u64,
1877a1b7cdfSAlex Crichton ) -> Option<Box<wasmtime_error_t>> {
1889187f2d9SAlex Crichton let mut scope = RootScope::new(&mut store);
189ff93bce0SNick Fitzgerald handle_result(
1909187f2d9SAlex Crichton val.to_val(&mut scope)
191ff93bce0SNick Fitzgerald .ref_()
192*dc029724SNick Fitzgerald .ok_or_else(|| format_err!("wasmtime_table_grow value is not a reference"))
1939187f2d9SAlex Crichton .and_then(|val| table.grow(scope, delta, val)),
194ff93bce0SNick Fitzgerald |prev| *prev_size = prev,
195ff93bce0SNick Fitzgerald )
1967a1b7cdfSAlex Crichton }
197