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#[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(_) => todo!(),
24    }
25}
26
27#[no_mangle]
28pub 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]
35pub 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]
40pub 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]
45pub 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]
50pub 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]
55pub 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]
60pub 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]
65pub 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]
70pub 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)]
75pub struct wasmtime_extern_t {
76    pub kind: wasmtime_extern_kind_t,
77    pub of: wasmtime_extern_union,
78}
79
80pub type wasmtime_extern_kind_t = u8;
81pub const WASMTIME_EXTERN_FUNC: wasmtime_extern_kind_t = 0;
82pub const WASMTIME_EXTERN_GLOBAL: wasmtime_extern_kind_t = 1;
83pub const WASMTIME_EXTERN_TABLE: wasmtime_extern_kind_t = 2;
84pub const WASMTIME_EXTERN_MEMORY: wasmtime_extern_kind_t = 3;
85pub const WASMTIME_EXTERN_SHAREDMEMORY: wasmtime_extern_kind_t = 4;
86
87#[repr(C)]
88pub 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
96impl 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
106impl 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
119impl 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]
149pub unsafe extern "C" fn wasmtime_extern_delete(e: &mut ManuallyDrop<wasmtime_extern_t>) {
150    ManuallyDrop::drop(e);
151}
152
153#[no_mangle]
154pub 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}