wasmtime_c_api/
extern.rs

1use crate::{
2    wasm_externkind_t, wasm_externtype_t, wasm_func_t, wasm_global_t, wasm_memory_t, wasm_table_t,
3    WasmStoreRef, WasmtimeStoreContext,
4};
5use std::mem::ManuallyDrop;
6use wasmtime::{Extern, Func, Global, Memory, SharedMemory, Table};
7
8#[derive(Clone)]
9pub struct wasm_extern_t {
10    pub(crate) store: WasmStoreRef,
11    pub(crate) which: Extern,
12}
13
14wasmtime_c_api_macros::declare_ref!(wasm_extern_t);
15
16#[unsafe(no_mangle)]
17pub 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)]
30pub 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)]
37pub 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)]
42pub 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)]
47pub 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)]
52pub 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)]
57pub 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)]
62pub 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)]
67pub 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)]
72pub 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)]
77pub struct wasmtime_extern_t {
78    pub kind: wasmtime_extern_kind_t,
79    pub of: wasmtime_extern_union,
80}
81
82pub type wasmtime_extern_kind_t = u8;
83pub const WASMTIME_EXTERN_FUNC: wasmtime_extern_kind_t = 0;
84pub const WASMTIME_EXTERN_GLOBAL: wasmtime_extern_kind_t = 1;
85pub const WASMTIME_EXTERN_TABLE: wasmtime_extern_kind_t = 2;
86pub const WASMTIME_EXTERN_MEMORY: wasmtime_extern_kind_t = 3;
87pub const WASMTIME_EXTERN_SHAREDMEMORY: wasmtime_extern_kind_t = 4;
88
89#[repr(C)]
90pub 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
98impl 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
108impl 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
121impl 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)]
151pub unsafe extern "C" fn wasmtime_extern_delete(e: &mut ManuallyDrop<wasmtime_extern_t>) {
152    ManuallyDrop::drop(e);
153}
154
155#[unsafe(no_mangle)]
156pub 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}