wasmer_c_api/wasm_c_api/externals/
mod.rs1mod function;
2mod global;
3mod memory;
4mod table;
5
6use super::store::StoreRef;
7pub 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
55impl wasm_extern_t {
66 pub(crate) unsafe fn ty(&self) -> ExternType {
67 let store_ref = unsafe { self.store.store() };
68 self.inner.ty(&store_ref)
69 }
70}
71
72impl From<wasm_extern_t> for Extern {
73 fn from(other: wasm_extern_t) -> Self {
74 other.inner
75 }
76}
77
78wasm_declare_boxed_vec!(extern);
79
80#[unsafe(no_mangle)]
82pub unsafe extern "C" fn wasm_extern_copy(r#extern: &wasm_extern_t) -> Box<wasm_extern_t> {
83 Box::new(r#extern.clone())
84}
85
86#[unsafe(no_mangle)]
88pub unsafe extern "C" fn wasm_extern_delete(_extern: Option<Box<wasm_extern_t>>) {}
89
90#[unsafe(no_mangle)]
91pub extern "C" fn wasm_func_as_extern(func: Option<&wasm_func_t>) -> Option<&wasm_extern_t> {
92 Some(&func?.extern_)
93}
94
95#[unsafe(no_mangle)]
96pub extern "C" fn wasm_global_as_extern(global: Option<&wasm_global_t>) -> Option<&wasm_extern_t> {
97 Some(&global?.extern_)
98}
99
100#[unsafe(no_mangle)]
101pub extern "C" fn wasm_memory_as_extern(memory: Option<&wasm_memory_t>) -> Option<&wasm_extern_t> {
102 Some(&memory?.extern_)
103}
104
105#[unsafe(no_mangle)]
106pub extern "C" fn wasm_table_as_extern(table: Option<&wasm_table_t>) -> Option<&wasm_extern_t> {
107 Some(&table?.extern_)
108}
109
110#[unsafe(no_mangle)]
111pub extern "C" fn wasm_extern_as_func(r#extern: Option<&wasm_extern_t>) -> Option<&wasm_func_t> {
112 wasm_func_t::try_from(r#extern?)
113}
114
115#[unsafe(no_mangle)]
116pub extern "C" fn wasm_extern_as_global(
117 r#extern: Option<&wasm_extern_t>,
118) -> Option<&wasm_global_t> {
119 wasm_global_t::try_from(r#extern?)
120}
121
122#[unsafe(no_mangle)]
123pub extern "C" fn wasm_extern_as_memory(
124 r#extern: Option<&wasm_extern_t>,
125) -> Option<&wasm_memory_t> {
126 wasm_memory_t::try_from(r#extern?)
127}
128
129#[unsafe(no_mangle)]
130pub extern "C" fn wasm_extern_as_table(r#extern: Option<&wasm_extern_t>) -> Option<&wasm_table_t> {
131 wasm_table_t::try_from(r#extern?)
132}
133
134#[cfg(test)]
135mod tests {
136 #[cfg(not(target_os = "windows"))]
137 use inline_c::assert_c;
138 #[cfg(target_os = "windows")]
139 use wasmer_inline_c::assert_c;
140
141 #[allow(
142 unexpected_cfgs,
143 reason = "tools like cargo-llvm-coverage pass --cfg coverage"
144 )]
145 #[cfg_attr(coverage_nightly, coverage(off))]
146 #[test]
147 fn test_extern_copy() {
148 (assert_c! {
149 #include "tests/wasmer.h"
150
151 int main() {
152 wasm_engine_t* engine = wasm_engine_new();
153 wasm_store_t* store = wasm_store_new(engine);
154
155 wasm_byte_vec_t wat;
156 wasmer_byte_vec_new_from_string(
157 &wat,
158 "(module\n"
159 " (func (export \"function\")))"
160 );
161 wasm_byte_vec_t wasm;
162 wat2wasm(&wat, &wasm);
163
164 wasm_module_t* module = wasm_module_new(store, &wasm);
165 assert(module);
166
167 wasm_extern_vec_t imports = WASM_EMPTY_VEC;
168 wasm_trap_t* trap = NULL;
169
170 wasm_instance_t* instance = wasm_instance_new(store, module, &imports, &trap);
171 assert(instance);
172
173 wasm_extern_vec_t exports;
174 wasm_instance_exports(instance, &exports);
175
176 assert(exports.size == 1);
177
178 wasm_extern_t* function = exports.data[0];
179 assert(wasm_extern_kind(function) == WASM_EXTERN_FUNC);
180
181 wasm_extern_t* function_copy = wasm_extern_copy(function);
182 assert(wasm_extern_kind(function_copy) == WASM_EXTERN_FUNC);
183
184 wasm_extern_delete(function_copy);
185 wasm_extern_vec_delete(&exports);
186 wasm_instance_delete(instance);
187 wasm_module_delete(module);
188 wasm_byte_vec_delete(&wasm);
189 wasm_byte_vec_delete(&wat);
190 wasm_store_delete(store);
191 wasm_engine_delete(engine);
192
193 return 0;
194 }
195 })
196 .success();
197 }
198}