xref: /wasmtime-44.0.1/crates/c-api/src/ref.rs (revision 331b0dee)
1 use std::os::raw::c_void;
2 use wasmtime::{ExternRef, Func, Val};
3 
4 /// `*mut wasm_ref_t` is a reference type (`externref` or `funcref`), as seen by
5 /// the C API. Because we do not have a uniform representation for `funcref`s
6 /// and `externref`s, a `*mut wasm_ref_t` is morally a
7 /// `Option<Box<Either<ExternRef, Func>>>`.
8 ///
9 /// A null `*mut wasm_ref_t` is either a null `funcref` or a null `externref`
10 /// depending on context (e.g. the table's element type that it is going into or
11 /// coming out of).
12 ///
13 /// Note: this is not `#[repr(C)]` because it is an opaque type in the header,
14 /// and only ever referenced as `*mut wasm_ref_t`. This also lets us use a
15 /// regular, non-`repr(C)` `enum` to define `WasmRefInner`.
16 #[derive(Clone)]
17 pub struct wasm_ref_t {
18     pub(crate) r: WasmRefInner,
19 }
20 
21 #[derive(Clone)]
22 pub(crate) enum WasmRefInner {
23     ExternRef(ExternRef),
24     FuncRef(Func),
25 }
26 
27 wasmtime_c_api_macros::declare_own!(wasm_ref_t);
28 
29 pub(crate) fn ref_to_val(r: &wasm_ref_t) -> Val {
30     match &r.r {
31         WasmRefInner::ExternRef(x) => Val::ExternRef(Some(x.clone())),
32         WasmRefInner::FuncRef(f) => Val::FuncRef(Some(f.clone())),
33     }
34 }
35 
36 pub(crate) fn val_into_ref(val: Val) -> Option<Box<wasm_ref_t>> {
37     match val {
38         Val::ExternRef(Some(x)) => Some(Box::new(wasm_ref_t {
39             r: WasmRefInner::ExternRef(x),
40         })),
41         Val::FuncRef(Some(f)) => Some(Box::new(wasm_ref_t {
42             r: WasmRefInner::FuncRef(f),
43         })),
44         _ => None,
45     }
46 }
47 
48 #[no_mangle]
49 pub extern "C" fn wasm_ref_copy(r: Option<&wasm_ref_t>) -> Option<Box<wasm_ref_t>> {
50     r.map(|r| Box::new(r.clone()))
51 }
52 
53 fn abort(name: &str) -> ! {
54     eprintln!("`{}` is not implemented", name);
55     std::process::abort();
56 }
57 
58 #[no_mangle]
59 pub extern "C" fn wasm_ref_same(a: Option<&wasm_ref_t>, b: Option<&wasm_ref_t>) -> bool {
60     match (a.map(|a| &a.r), b.map(|b| &b.r)) {
61         (Some(WasmRefInner::ExternRef(a)), Some(WasmRefInner::ExternRef(b))) => a.ptr_eq(b),
62         (None, None) => true,
63         // Note: we don't support equality for `Func`, so we always return
64         // `false` for `funcref`s.
65         _ => false,
66     }
67 }
68 
69 #[no_mangle]
70 pub extern "C" fn wasm_ref_get_host_info(_ref: Option<&wasm_ref_t>) -> *mut c_void {
71     std::ptr::null_mut()
72 }
73 
74 #[no_mangle]
75 pub extern "C" fn wasm_ref_set_host_info(_ref: Option<&wasm_ref_t>, _info: *mut c_void) {
76     abort("wasm_ref_set_host_info")
77 }
78 
79 #[no_mangle]
80 pub extern "C" fn wasm_ref_set_host_info_with_finalizer(
81     _ref: Option<&wasm_ref_t>,
82     _info: *mut c_void,
83     _finalizer: Option<extern "C" fn(*mut c_void)>,
84 ) {
85     abort("wasm_ref_set_host_info_with_finalizer")
86 }
87 
88 #[no_mangle]
89 pub extern "C" fn wasm_ref_as_extern(_ref: Option<&wasm_ref_t>) -> Option<&crate::wasm_extern_t> {
90     abort("wasm_ref_as_extern")
91 }
92 
93 #[no_mangle]
94 pub extern "C" fn wasm_ref_as_extern_const(
95     _ref: Option<&wasm_ref_t>,
96 ) -> Option<&crate::wasm_extern_t> {
97     abort("wasm_ref_as_extern_const")
98 }
99 
100 #[no_mangle]
101 pub extern "C" fn wasm_ref_as_foreign(_ref: Option<&wasm_ref_t>) -> Option<&crate::wasm_foreign_t> {
102     abort("wasm_ref_as_foreign")
103 }
104 
105 #[no_mangle]
106 pub extern "C" fn wasm_ref_as_foreign_const(
107     _ref: Option<&wasm_ref_t>,
108 ) -> Option<&crate::wasm_foreign_t> {
109     abort("wasm_ref_as_foreign_const")
110 }
111 
112 #[no_mangle]
113 pub extern "C" fn wasm_ref_as_func(_ref: Option<&wasm_ref_t>) -> Option<&crate::wasm_func_t> {
114     abort("wasm_ref_as_func")
115 }
116 
117 #[no_mangle]
118 pub extern "C" fn wasm_ref_as_func_const(_ref: Option<&wasm_ref_t>) -> Option<&crate::wasm_func_t> {
119     abort("wasm_ref_as_func_const")
120 }
121 
122 #[no_mangle]
123 pub extern "C" fn wasm_ref_as_global(_ref: Option<&wasm_ref_t>) -> Option<&crate::wasm_global_t> {
124     abort("wasm_ref_as_global")
125 }
126 
127 #[no_mangle]
128 pub extern "C" fn wasm_ref_as_global_const(
129     _ref: Option<&wasm_ref_t>,
130 ) -> Option<&crate::wasm_global_t> {
131     abort("wasm_ref_as_global_const")
132 }
133 
134 #[no_mangle]
135 pub extern "C" fn wasm_ref_as_instance(
136     _ref: Option<&wasm_ref_t>,
137 ) -> Option<&crate::wasm_instance_t> {
138     abort("wasm_ref_as_instance")
139 }
140 
141 #[no_mangle]
142 pub extern "C" fn wasm_ref_as_instance_const(
143     _ref: Option<&wasm_ref_t>,
144 ) -> Option<&crate::wasm_instance_t> {
145     abort("wasm_ref_as_instance_const")
146 }
147 
148 #[no_mangle]
149 pub extern "C" fn wasm_ref_as_memory(_ref: Option<&wasm_ref_t>) -> Option<&crate::wasm_memory_t> {
150     abort("wasm_ref_as_memory")
151 }
152 
153 #[no_mangle]
154 pub extern "C" fn wasm_ref_as_memory_const(
155     _ref: Option<&wasm_ref_t>,
156 ) -> Option<&crate::wasm_memory_t> {
157     abort("wasm_ref_as_memory_const")
158 }
159 
160 #[no_mangle]
161 pub extern "C" fn wasm_ref_as_module(_ref: Option<&wasm_ref_t>) -> Option<&crate::wasm_module_t> {
162     abort("wasm_ref_as_module")
163 }
164 
165 #[no_mangle]
166 pub extern "C" fn wasm_ref_as_module_const(
167     _ref: Option<&wasm_ref_t>,
168 ) -> Option<&crate::wasm_module_t> {
169     abort("wasm_ref_as_module_const")
170 }
171 
172 #[no_mangle]
173 pub extern "C" fn wasm_ref_as_table(_ref: Option<&wasm_ref_t>) -> Option<&crate::wasm_table_t> {
174     abort("wasm_ref_as_table")
175 }
176 
177 #[no_mangle]
178 pub extern "C" fn wasm_ref_as_table_const(
179     _ref: Option<&wasm_ref_t>,
180 ) -> Option<&crate::wasm_table_t> {
181     abort("wasm_ref_as_table_const")
182 }
183 
184 #[no_mangle]
185 pub extern "C" fn wasm_ref_as_trap(_ref: Option<&wasm_ref_t>) -> Option<&crate::wasm_trap_t> {
186     abort("wasm_ref_as_trap")
187 }
188 
189 #[no_mangle]
190 pub extern "C" fn wasm_ref_as_trap_const(_ref: Option<&wasm_ref_t>) -> Option<&crate::wasm_trap_t> {
191     abort("wasm_ref_as_trap_const")
192 }
193 
194 #[derive(Clone)]
195 #[repr(C)]
196 pub struct wasm_foreign_t {}
197 
198 #[no_mangle]
199 pub extern "C" fn wasm_foreign_new(_store: &crate::wasm_store_t) -> Box<wasm_foreign_t> {
200     abort("wasm_foreign_new")
201 }
202 
203 #[no_mangle]
204 pub extern "C" fn wasm_foreign_delete(_foreign: Box<wasm_foreign_t>) {}
205 
206 #[no_mangle]
207 pub extern "C" fn wasm_foreign_copy(r: &wasm_foreign_t) -> Box<wasm_foreign_t> {
208     Box::new(r.clone())
209 }
210 
211 #[no_mangle]
212 pub extern "C" fn wasm_foreign_same(_a: &wasm_foreign_t, _b: &wasm_foreign_t) -> bool {
213     abort("wasm_foreign_same")
214 }
215 
216 #[no_mangle]
217 pub extern "C" fn wasm_foreign_get_host_info(_foreign: &wasm_foreign_t) -> *mut c_void {
218     std::ptr::null_mut()
219 }
220 
221 #[no_mangle]
222 pub extern "C" fn wasm_foreign_set_host_info(_foreign: &wasm_foreign_t, _info: *mut c_void) {
223     abort("wasm_foreign_set_host_info")
224 }
225 
226 #[no_mangle]
227 pub extern "C" fn wasm_foreign_set_host_info_with_finalizer(
228     _foreign: &wasm_foreign_t,
229     _info: *mut c_void,
230     _finalizer: Option<extern "C" fn(*mut c_void)>,
231 ) {
232     abort("wasm_foreign_set_host_info_with_finalizer")
233 }
234 
235 #[no_mangle]
236 pub extern "C" fn wasm_foreign_as_ref(_: &wasm_foreign_t) -> &wasm_ref_t {
237     abort("wasm_foreign_as_ref")
238 }
239 
240 #[no_mangle]
241 pub extern "C" fn wasm_foreign_as_ref_const(_: &wasm_foreign_t) -> Option<&wasm_ref_t> {
242     abort("wasm_foreign_as_ref_const")
243 }
244