xref: /wasmtime-44.0.1/crates/c-api/src/extern.rs (revision b81ef46c)
1 use crate::{
2     wasm_externkind_t, wasm_externtype_t, wasm_func_t, wasm_global_t, wasm_memory_t, wasm_table_t,
3     WasmStoreRef, WasmtimeStoreContext,
4 };
5 use std::mem::ManuallyDrop;
6 use wasmtime::{Extern, Func, Global, Memory, SharedMemory, Table};
7 
8 #[derive(Clone)]
9 pub struct wasm_extern_t {
10     pub(crate) store: WasmStoreRef,
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         Extern::SharedMemory(_) => todo!(),
24     }
25 }
26 
27 #[no_mangle]
28 pub unsafe extern "C" fn wasm_extern_type(e: &wasm_extern_t) -> Box<wasm_externtype_t> {
29     Box::new(wasm_externtype_t::from_extern_type(
30         e.which.ty(&e.store.context()),
31     ))
32 }
33 
34 #[no_mangle]
35 pub extern "C" fn wasm_extern_as_func(e: &wasm_extern_t) -> Option<&wasm_func_t> {
36     wasm_func_t::try_from(e)
37 }
38 
39 #[no_mangle]
40 pub extern "C" fn wasm_extern_as_func_const(e: &wasm_extern_t) -> Option<&wasm_func_t> {
41     wasm_extern_as_func(e)
42 }
43 
44 #[no_mangle]
45 pub extern "C" fn wasm_extern_as_global(e: &wasm_extern_t) -> Option<&wasm_global_t> {
46     wasm_global_t::try_from(e)
47 }
48 
49 #[no_mangle]
50 pub extern "C" fn wasm_extern_as_global_const(e: &wasm_extern_t) -> Option<&wasm_global_t> {
51     wasm_extern_as_global(e)
52 }
53 
54 #[no_mangle]
55 pub extern "C" fn wasm_extern_as_table(e: &wasm_extern_t) -> Option<&wasm_table_t> {
56     wasm_table_t::try_from(e)
57 }
58 
59 #[no_mangle]
60 pub extern "C" fn wasm_extern_as_table_const(e: &wasm_extern_t) -> Option<&wasm_table_t> {
61     wasm_extern_as_table(e)
62 }
63 
64 #[no_mangle]
65 pub extern "C" fn wasm_extern_as_memory(e: &wasm_extern_t) -> Option<&wasm_memory_t> {
66     wasm_memory_t::try_from(e)
67 }
68 
69 #[no_mangle]
70 pub extern "C" fn wasm_extern_as_memory_const(e: &wasm_extern_t) -> Option<&wasm_memory_t> {
71     wasm_extern_as_memory(e)
72 }
73 
74 #[repr(C)]
75 pub struct wasmtime_extern_t {
76     pub kind: wasmtime_extern_kind_t,
77     pub of: wasmtime_extern_union,
78 }
79 
80 pub type wasmtime_extern_kind_t = u8;
81 pub const WASMTIME_EXTERN_FUNC: wasmtime_extern_kind_t = 0;
82 pub const WASMTIME_EXTERN_GLOBAL: wasmtime_extern_kind_t = 1;
83 pub const WASMTIME_EXTERN_TABLE: wasmtime_extern_kind_t = 2;
84 pub const WASMTIME_EXTERN_MEMORY: wasmtime_extern_kind_t = 3;
85 pub const WASMTIME_EXTERN_SHAREDMEMORY: wasmtime_extern_kind_t = 4;
86 
87 #[repr(C)]
88 pub union wasmtime_extern_union {
89     pub func: Func,
90     pub table: Table,
91     pub global: Global,
92     pub memory: Memory,
93     pub sharedmemory: ManuallyDrop<Box<SharedMemory>>,
94 }
95 
96 impl Drop for wasmtime_extern_t {
97     fn drop(&mut self) {
98         if self.kind == WASMTIME_EXTERN_SHAREDMEMORY {
99             unsafe {
100                 ManuallyDrop::drop(&mut self.of.sharedmemory);
101             }
102         }
103     }
104 }
105 
106 impl wasmtime_extern_t {
107     pub unsafe fn to_extern(&self) -> Extern {
108         match self.kind {
109             WASMTIME_EXTERN_FUNC => Extern::Func(self.of.func),
110             WASMTIME_EXTERN_GLOBAL => Extern::Global(self.of.global),
111             WASMTIME_EXTERN_TABLE => Extern::Table(self.of.table),
112             WASMTIME_EXTERN_MEMORY => Extern::Memory(self.of.memory),
113             WASMTIME_EXTERN_SHAREDMEMORY => Extern::SharedMemory((**self.of.sharedmemory).clone()),
114             other => panic!("unknown wasmtime_extern_kind_t: {other}"),
115         }
116     }
117 }
118 
119 impl From<Extern> for wasmtime_extern_t {
120     fn from(item: Extern) -> wasmtime_extern_t {
121         match item {
122             Extern::Func(func) => wasmtime_extern_t {
123                 kind: WASMTIME_EXTERN_FUNC,
124                 of: wasmtime_extern_union { func },
125             },
126             Extern::Global(global) => wasmtime_extern_t {
127                 kind: WASMTIME_EXTERN_GLOBAL,
128                 of: wasmtime_extern_union { global },
129             },
130             Extern::Table(table) => wasmtime_extern_t {
131                 kind: WASMTIME_EXTERN_TABLE,
132                 of: wasmtime_extern_union { table },
133             },
134             Extern::Memory(memory) => wasmtime_extern_t {
135                 kind: WASMTIME_EXTERN_MEMORY,
136                 of: wasmtime_extern_union { memory },
137             },
138             Extern::SharedMemory(sharedmemory) => wasmtime_extern_t {
139                 kind: WASMTIME_EXTERN_SHAREDMEMORY,
140                 of: wasmtime_extern_union {
141                     sharedmemory: ManuallyDrop::new(Box::new(sharedmemory)),
142                 },
143             },
144         }
145     }
146 }
147 
148 #[no_mangle]
149 pub unsafe extern "C" fn wasmtime_extern_delete(e: &mut ManuallyDrop<wasmtime_extern_t>) {
150     ManuallyDrop::drop(e);
151 }
152 
153 #[no_mangle]
154 pub unsafe extern "C" fn wasmtime_extern_type(
155     store: WasmtimeStoreContext<'_>,
156     e: &wasmtime_extern_t,
157 ) -> Box<wasm_externtype_t> {
158     Box::new(wasm_externtype_t::from_extern_type(e.to_extern().ty(store)))
159 }
160