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