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 #[unsafe(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(_) => panic!( 24 "Shared Memory no implemented for wasm_* types. Please use wasmtime_* types instead" 25 ), 26 } 27 } 28 29 #[unsafe(no_mangle)] 30 pub 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)] 37 pub 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)] 42 pub 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)] 47 pub 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)] 52 pub 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)] 57 pub 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)] 62 pub 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)] 67 pub 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)] 72 pub 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)] 77 pub struct wasmtime_extern_t { 78 pub kind: wasmtime_extern_kind_t, 79 pub of: wasmtime_extern_union, 80 } 81 82 pub type wasmtime_extern_kind_t = u8; 83 pub const WASMTIME_EXTERN_FUNC: wasmtime_extern_kind_t = 0; 84 pub const WASMTIME_EXTERN_GLOBAL: wasmtime_extern_kind_t = 1; 85 pub const WASMTIME_EXTERN_TABLE: wasmtime_extern_kind_t = 2; 86 pub const WASMTIME_EXTERN_MEMORY: wasmtime_extern_kind_t = 3; 87 pub const WASMTIME_EXTERN_SHAREDMEMORY: wasmtime_extern_kind_t = 4; 88 89 #[repr(C)] 90 pub 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 98 impl 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 108 impl 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 121 impl 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)] 151 pub unsafe extern "C" fn wasmtime_extern_delete(e: &mut ManuallyDrop<wasmtime_extern_t>) { 152 ManuallyDrop::drop(e); 153 } 154 155 #[unsafe(no_mangle)] 156 pub 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 } 162