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