wasmer_c_api/wasm_c_api/externals/
table.rs1use crate::error::update_last_error;
2
3use super::super::store::{StoreRef, wasm_store_t};
4use super::super::types::{wasm_ref_t, wasm_table_size_t, wasm_tabletype_t};
5use super::wasm_extern_t;
6use wasmer_api::{Extern, Table, Type, Value};
7
8#[allow(non_camel_case_types)]
9#[repr(C)]
10#[derive(Clone)]
11pub struct wasm_table_t {
12 pub(crate) extern_: wasm_extern_t,
13}
14
15impl wasm_table_t {
16 pub(crate) fn try_from(e: &wasm_extern_t) -> Option<&wasm_table_t> {
17 match &e.inner {
18 Extern::Table(_) => Some(unsafe { &*(e as *const _ as *const _) }),
19 _ => None,
20 }
21 }
22}
23
24fn init_value(init: *const wasm_ref_t, element_ty: Type) -> Value {
28 if init.is_null() {
29 match element_ty {
30 Type::FuncRef => Value::FuncRef(None),
31 _ => Value::ExternRef(None),
32 }
33 } else {
34 unsafe { &*init }.inner.clone()
36 }
37}
38
39#[unsafe(no_mangle)]
40pub unsafe extern "C" fn wasm_table_new(
41 store: Option<&mut wasm_store_t>,
42 table_type: Option<&wasm_tabletype_t>,
43 init: *const wasm_ref_t,
44) -> Option<Box<wasm_table_t>> {
45 let store = store?;
46 let table_type = table_type?;
47 let table_type = table_type.inner()._table_type;
48 let init_val = init_value(init, table_type.ty);
49
50 let table = {
51 let mut store_mut = unsafe { store.inner.store_mut() };
52 c_try!(Table::new(&mut store_mut, table_type, init_val))
53 };
54
55 Some(Box::new(wasm_table_t {
56 extern_: wasm_extern_t::new(store.inner.clone(), table.into()),
57 }))
58}
59
60#[unsafe(no_mangle)]
61pub unsafe extern "C" fn wasm_table_delete(_table: Option<Box<wasm_table_t>>) {}
62
63#[unsafe(no_mangle)]
64pub unsafe extern "C" fn wasm_table_copy(
65 table: Option<&wasm_table_t>,
66) -> Option<Box<wasm_table_t>> {
67 table.cloned().map(Box::new)
68}
69
70#[unsafe(no_mangle)]
71pub unsafe extern "C" fn wasm_table_size(table: Option<&wasm_table_t>) -> usize {
72 let Some(table) = table else {
73 update_last_error("table pointer is null");
74 return 0;
75 };
76 let store_ref = unsafe { table.extern_.store.store() };
77 table.extern_.table().size(&store_ref) as _
78}
79
80#[unsafe(no_mangle)]
81pub unsafe extern "C" fn wasm_table_type(
82 table: Option<&wasm_table_t>,
83) -> Option<Box<wasm_tabletype_t>> {
84 let Some(table) = table else {
85 update_last_error("table pointer is null");
86 return None;
87 };
88 let store_ref = unsafe { table.extern_.store.store() };
89 Some(Box::new(wasm_tabletype_t::new(
90 table.extern_.table().ty(&store_ref),
91 )))
92}
93
94#[unsafe(no_mangle)]
95pub unsafe extern "C" fn wasm_table_same(
96 wasm_table1: &wasm_table_t,
97 wasm_table2: &wasm_table_t,
98) -> bool {
99 wasm_table1.extern_.table() == wasm_table2.extern_.table()
100}
101
102#[unsafe(no_mangle)]
103pub unsafe extern "C" fn wasm_table_get(
104 table: Option<&wasm_table_t>,
105 index: wasm_table_size_t,
106) -> Option<Box<wasm_ref_t>> {
107 let Some(table) = table else {
108 update_last_error("table pointer is null");
109 return None;
110 };
111 let table_obj = table.extern_.table();
112 let mut store: StoreRef = table.extern_.store.clone();
113 let value = {
117 let mut store_mut = unsafe { store.store_mut() };
118 match table_obj.get(&mut store_mut, index) {
119 Some(value) => value,
120 None => {
121 update_last_error("table index out of bounds");
122 return None;
123 }
124 }
125 };
126 wasm_ref_t::new(table.extern_.store.clone(), value)
127}
128
129#[unsafe(no_mangle)]
130pub unsafe extern "C" fn wasm_table_set(
131 table: Option<&mut wasm_table_t>,
132 index: wasm_table_size_t,
133 r: *mut wasm_ref_t,
134) -> bool {
135 let Some(table) = table else {
136 update_last_error("table pointer is null");
137 return false;
138 };
139 let table_obj = table.extern_.table();
140 let mut store: StoreRef = table.extern_.store.clone();
141 let mut store_mut = unsafe { store.store_mut() };
142 let element_ty = table_obj.ty(&store_mut).ty;
143 let value = init_value(r, element_ty);
144 match table_obj.set(&mut store_mut, index, value) {
145 Ok(()) => true,
146 Err(e) => {
147 update_last_error(e);
148 false
149 }
150 }
151}
152
153#[unsafe(no_mangle)]
154pub unsafe extern "C" fn wasm_table_grow(
155 table: &mut wasm_table_t,
156 delta: wasm_table_size_t,
157 init: *mut wasm_ref_t,
158) -> bool {
159 let table_obj = table.extern_.table();
160 let mut store: StoreRef = table.extern_.store.clone();
161 let mut store_mut = unsafe { store.store_mut() };
162 let element_ty = table_obj.ty(&store_mut).ty;
163 let init_val = init_value(init, element_ty);
164 match table_obj.grow(&mut store_mut, delta, init_val) {
165 Ok(_) => true,
166 Err(e) => {
167 update_last_error(e);
168 false
169 }
170 }
171}