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