xref: /wasmtime-44.0.1/crates/c-api/src/extern.rs (revision c8daf0b8)
1 use crate::{
2     wasm_externkind_t, wasm_externtype_t, wasm_func_t, wasm_global_t, wasm_memory_t, wasm_table_t,
3     CStoreContext, StoreRef,
4 };
5 use std::mem::ManuallyDrop;
6 use wasmtime::{Extern, Func, Global, Memory, Table};
7 
8 #[derive(Clone)]
9 pub struct wasm_extern_t {
10     pub(crate) store: StoreRef,
11     pub(crate) which: Extern,
12 }
13 
14 wasmtime_c_api_macros::declare_ref!(wasm_extern_t);
15 
16 #[no_mangle]
17 pub extern "C" fn wasm_extern_kind(e: &wasm_extern_t) -> wasm_externkind_t {
18     match e.which {
19         Extern::Func(_) => crate::WASM_EXTERN_FUNC,
20         Extern::Global(_) => crate::WASM_EXTERN_GLOBAL,
21         Extern::Table(_) => crate::WASM_EXTERN_TABLE,
22         Extern::Memory(_) => crate::WASM_EXTERN_MEMORY,
23     }
24 }
25 
26 #[no_mangle]
27 pub unsafe extern "C" fn wasm_extern_type(e: &wasm_extern_t) -> Box<wasm_externtype_t> {
28     Box::new(wasm_externtype_t::new(e.which.ty(&e.store.context())))
29 }
30 
31 #[no_mangle]
32 pub extern "C" fn wasm_extern_as_func(e: &wasm_extern_t) -> Option<&wasm_func_t> {
33     wasm_func_t::try_from(e)
34 }
35 
36 #[no_mangle]
37 pub extern "C" fn wasm_extern_as_func_const(e: &wasm_extern_t) -> Option<&wasm_func_t> {
38     wasm_extern_as_func(e)
39 }
40 
41 #[no_mangle]
42 pub extern "C" fn wasm_extern_as_global(e: &wasm_extern_t) -> Option<&wasm_global_t> {
43     wasm_global_t::try_from(e)
44 }
45 
46 #[no_mangle]
47 pub extern "C" fn wasm_extern_as_global_const(e: &wasm_extern_t) -> Option<&wasm_global_t> {
48     wasm_extern_as_global(e)
49 }
50 
51 #[no_mangle]
52 pub extern "C" fn wasm_extern_as_table(e: &wasm_extern_t) -> Option<&wasm_table_t> {
53     wasm_table_t::try_from(e)
54 }
55 
56 #[no_mangle]
57 pub extern "C" fn wasm_extern_as_table_const(e: &wasm_extern_t) -> Option<&wasm_table_t> {
58     wasm_extern_as_table(e)
59 }
60 
61 #[no_mangle]
62 pub extern "C" fn wasm_extern_as_memory(e: &wasm_extern_t) -> Option<&wasm_memory_t> {
63     wasm_memory_t::try_from(e)
64 }
65 
66 #[no_mangle]
67 pub extern "C" fn wasm_extern_as_memory_const(e: &wasm_extern_t) -> Option<&wasm_memory_t> {
68     wasm_extern_as_memory(e)
69 }
70 
71 #[repr(C)]
72 pub struct wasmtime_extern_t {
73     pub kind: wasmtime_extern_kind_t,
74     pub of: wasmtime_extern_union,
75 }
76 
77 pub type wasmtime_extern_kind_t = u8;
78 pub const WASMTIME_EXTERN_FUNC: wasmtime_extern_kind_t = 0;
79 pub const WASMTIME_EXTERN_GLOBAL: wasmtime_extern_kind_t = 1;
80 pub const WASMTIME_EXTERN_TABLE: wasmtime_extern_kind_t = 2;
81 pub const WASMTIME_EXTERN_MEMORY: wasmtime_extern_kind_t = 3;
82 
83 #[repr(C)]
84 pub union wasmtime_extern_union {
85     pub func: Func,
86     pub table: Table,
87     pub global: Global,
88     pub memory: Memory,
89 }
90 
91 impl wasmtime_extern_t {
92     pub unsafe fn to_extern(&self) -> Extern {
93         match self.kind {
94             WASMTIME_EXTERN_FUNC => Extern::Func(self.of.func),
95             WASMTIME_EXTERN_GLOBAL => Extern::Global(self.of.global),
96             WASMTIME_EXTERN_TABLE => Extern::Table(self.of.table),
97             WASMTIME_EXTERN_MEMORY => Extern::Memory(self.of.memory),
98             other => panic!("unknown wasm_extern_kind_t: {}", other),
99         }
100     }
101 }
102 
103 impl From<Extern> for wasmtime_extern_t {
104     fn from(item: Extern) -> wasmtime_extern_t {
105         match item {
106             Extern::Func(func) => wasmtime_extern_t {
107                 kind: WASMTIME_EXTERN_FUNC,
108                 of: wasmtime_extern_union { func },
109             },
110             Extern::Global(global) => wasmtime_extern_t {
111                 kind: WASMTIME_EXTERN_GLOBAL,
112                 of: wasmtime_extern_union { global },
113             },
114             Extern::Table(table) => wasmtime_extern_t {
115                 kind: WASMTIME_EXTERN_TABLE,
116                 of: wasmtime_extern_union { table },
117             },
118             Extern::Memory(memory) => wasmtime_extern_t {
119                 kind: WASMTIME_EXTERN_MEMORY,
120                 of: wasmtime_extern_union { memory },
121             },
122         }
123     }
124 }
125 
126 #[no_mangle]
127 pub unsafe extern "C" fn wasmtime_extern_delete(e: &mut ManuallyDrop<wasmtime_extern_t>) {
128     ManuallyDrop::drop(e);
129 }
130 
131 #[no_mangle]
132 pub unsafe extern "C" fn wasmtime_extern_type(
133     store: CStoreContext<'_>,
134     e: &wasmtime_extern_t,
135 ) -> Box<wasm_externtype_t> {
136     Box::new(wasm_externtype_t::new(e.to_extern().ty(store)))
137 }
138