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