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