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