wasmer/wasm_c_api/externals/
mod.rs

1mod function;
2mod global;
3mod memory;
4mod table;
5
6use super::store::StoreRef;
7// use super::types::{wasm_externkind_enum, wasm_externkind_t};
8pub use function::*;
9pub use global::*;
10pub use memory::*;
11pub use table::*;
12use wasmer_api::{Extern, ExternType, Function, Global, Memory, Table};
13
14#[allow(non_camel_case_types)]
15#[derive(Clone)]
16pub struct wasm_extern_t {
17    pub(crate) inner: Extern,
18    pub(crate) store: StoreRef,
19}
20
21impl wasm_extern_t {
22    pub(crate) fn new(store: StoreRef, inner: Extern) -> Self {
23        Self { inner, store }
24    }
25
26    pub(crate) fn global(&self) -> Global {
27        match &self.inner {
28            Extern::Global(g) => g.clone(),
29            _ => unsafe { std::hint::unreachable_unchecked() },
30        }
31    }
32
33    pub(crate) fn function(&self) -> Function {
34        match &self.inner {
35            Extern::Function(f) => f.clone(),
36            _ => unsafe { std::hint::unreachable_unchecked() },
37        }
38    }
39
40    pub(crate) fn table(&self) -> Table {
41        match &self.inner {
42            Extern::Table(t) => t.clone(),
43            _ => unsafe { std::hint::unreachable_unchecked() },
44        }
45    }
46
47    pub(crate) fn memory(&self) -> Memory {
48        match &self.inner {
49            Extern::Memory(m) => m.clone(),
50            _ => unsafe { std::hint::unreachable_unchecked() },
51        }
52    }
53}
54
55// #[no_mangle]
56// pub extern "C" fn wasm_extern_kind(e: &wasm_extern_t) -> wasm_externkind_t {
57//     (match e.inner {
58//         Extern::Function(_) => wasm_externkind_enum::WASM_EXTERN_FUNC,
59//         Extern::Table(_) => wasm_externkind_enum::WASM_EXTERN_TABLE,
60//         Extern::Global(_) => wasm_externkind_enum::WASM_EXTERN_GLOBAL,
61//         Extern::Memory(_) => wasm_externkind_enum::WASM_EXTERN_MEMORY,
62//     }) as wasm_externkind_t
63// }
64
65impl wasm_extern_t {
66    pub(crate) unsafe fn ty(&self) -> ExternType {
67        self.inner.ty(&self.store.store())
68    }
69}
70
71impl From<wasm_extern_t> for Extern {
72    fn from(other: wasm_extern_t) -> Self {
73        other.inner
74    }
75}
76
77wasm_declare_boxed_vec!(extern);
78
79/// Copy a `wasm_extern_t`.
80#[no_mangle]
81pub unsafe extern "C" fn wasm_extern_copy(r#extern: &wasm_extern_t) -> Box<wasm_extern_t> {
82    Box::new(r#extern.clone())
83}
84
85/// Delete an extern.
86#[no_mangle]
87pub unsafe extern "C" fn wasm_extern_delete(_extern: Option<Box<wasm_extern_t>>) {}
88
89#[no_mangle]
90pub extern "C" fn wasm_func_as_extern(func: Option<&wasm_func_t>) -> Option<&wasm_extern_t> {
91    Some(&func?.extern_)
92}
93
94#[no_mangle]
95pub extern "C" fn wasm_global_as_extern(global: Option<&wasm_global_t>) -> Option<&wasm_extern_t> {
96    Some(&global?.extern_)
97}
98
99#[no_mangle]
100pub extern "C" fn wasm_memory_as_extern(memory: Option<&wasm_memory_t>) -> Option<&wasm_extern_t> {
101    Some(&memory?.extern_)
102}
103
104#[no_mangle]
105pub extern "C" fn wasm_table_as_extern(table: Option<&wasm_table_t>) -> Option<&wasm_extern_t> {
106    Some(&table?.extern_)
107}
108
109#[no_mangle]
110pub extern "C" fn wasm_extern_as_func(r#extern: Option<&wasm_extern_t>) -> Option<&wasm_func_t> {
111    wasm_func_t::try_from(r#extern?)
112}
113
114#[no_mangle]
115pub extern "C" fn wasm_extern_as_global(
116    r#extern: Option<&wasm_extern_t>,
117) -> Option<&wasm_global_t> {
118    wasm_global_t::try_from(r#extern?)
119}
120
121#[no_mangle]
122pub extern "C" fn wasm_extern_as_memory(
123    r#extern: Option<&wasm_extern_t>,
124) -> Option<&wasm_memory_t> {
125    wasm_memory_t::try_from(r#extern?)
126}
127
128#[no_mangle]
129pub extern "C" fn wasm_extern_as_table(r#extern: Option<&wasm_extern_t>) -> Option<&wasm_table_t> {
130    wasm_table_t::try_from(r#extern?)
131}
132
133#[cfg(test)]
134mod tests {
135    #[cfg(not(target_os = "windows"))]
136    use inline_c::assert_c;
137    #[cfg(target_os = "windows")]
138    use wasmer_inline_c::assert_c;
139
140    #[cfg_attr(coverage, ignore)]
141    #[test]
142    fn test_extern_copy() {
143        (assert_c! {
144            #include "tests/wasmer.h"
145
146            int main() {
147                wasm_engine_t* engine = wasm_engine_new();
148                wasm_store_t* store = wasm_store_new(engine);
149
150                wasm_byte_vec_t wat;
151                wasmer_byte_vec_new_from_string(
152                    &wat,
153                    "(module\n"
154                    "  (func (export \"function\")))"
155                );
156                wasm_byte_vec_t wasm;
157                wat2wasm(&wat, &wasm);
158
159                wasm_module_t* module = wasm_module_new(store, &wasm);
160                assert(module);
161
162                wasm_extern_vec_t imports = WASM_EMPTY_VEC;
163                wasm_trap_t* trap = NULL;
164
165                wasm_instance_t* instance = wasm_instance_new(store, module, &imports, &trap);
166                assert(instance);
167
168                wasm_extern_vec_t exports;
169                wasm_instance_exports(instance, &exports);
170
171                assert(exports.size == 1);
172
173                wasm_extern_t* function = exports.data[0];
174                assert(wasm_extern_kind(function) == WASM_EXTERN_FUNC);
175
176                wasm_extern_t* function_copy = wasm_extern_copy(function);
177                assert(wasm_extern_kind(function_copy) == WASM_EXTERN_FUNC);
178
179                wasm_extern_delete(function_copy);
180                wasm_extern_vec_delete(&exports);
181                wasm_instance_delete(instance);
182                wasm_module_delete(module);
183                wasm_byte_vec_delete(&wasm);
184                wasm_byte_vec_delete(&wat);
185                wasm_store_delete(store);
186                wasm_engine_delete(engine);
187
188                return 0;
189            }
190        })
191        .success();
192    }
193}