use crate::{ wasm_externkind_t, wasm_externtype_t, wasm_func_t, wasm_global_t, wasm_memory_t, wasm_table_t, CStoreContext, StoreRef, }; use std::mem::ManuallyDrop; use wasmtime::{Extern, Func, Global, Memory, Table}; #[derive(Clone)] pub struct wasm_extern_t { pub(crate) store: StoreRef, pub(crate) which: Extern, } wasmtime_c_api_macros::declare_ref!(wasm_extern_t); #[no_mangle] pub extern "C" fn wasm_extern_kind(e: &wasm_extern_t) -> wasm_externkind_t { match e.which { Extern::Func(_) => crate::WASM_EXTERN_FUNC, Extern::Global(_) => crate::WASM_EXTERN_GLOBAL, Extern::Table(_) => crate::WASM_EXTERN_TABLE, Extern::Memory(_) => crate::WASM_EXTERN_MEMORY, Extern::SharedMemory(_) => todo!(), } } #[no_mangle] pub unsafe extern "C" fn wasm_extern_type(e: &wasm_extern_t) -> Box { Box::new(wasm_externtype_t::new(e.which.ty(&e.store.context()))) } #[no_mangle] pub extern "C" fn wasm_extern_as_func(e: &wasm_extern_t) -> Option<&wasm_func_t> { wasm_func_t::try_from(e) } #[no_mangle] pub extern "C" fn wasm_extern_as_func_const(e: &wasm_extern_t) -> Option<&wasm_func_t> { wasm_extern_as_func(e) } #[no_mangle] pub extern "C" fn wasm_extern_as_global(e: &wasm_extern_t) -> Option<&wasm_global_t> { wasm_global_t::try_from(e) } #[no_mangle] pub extern "C" fn wasm_extern_as_global_const(e: &wasm_extern_t) -> Option<&wasm_global_t> { wasm_extern_as_global(e) } #[no_mangle] pub extern "C" fn wasm_extern_as_table(e: &wasm_extern_t) -> Option<&wasm_table_t> { wasm_table_t::try_from(e) } #[no_mangle] pub extern "C" fn wasm_extern_as_table_const(e: &wasm_extern_t) -> Option<&wasm_table_t> { wasm_extern_as_table(e) } #[no_mangle] pub extern "C" fn wasm_extern_as_memory(e: &wasm_extern_t) -> Option<&wasm_memory_t> { wasm_memory_t::try_from(e) } #[no_mangle] pub extern "C" fn wasm_extern_as_memory_const(e: &wasm_extern_t) -> Option<&wasm_memory_t> { wasm_extern_as_memory(e) } #[repr(C)] pub struct wasmtime_extern_t { pub kind: wasmtime_extern_kind_t, pub of: wasmtime_extern_union, } pub type wasmtime_extern_kind_t = u8; pub const WASMTIME_EXTERN_FUNC: wasmtime_extern_kind_t = 0; pub const WASMTIME_EXTERN_GLOBAL: wasmtime_extern_kind_t = 1; pub const WASMTIME_EXTERN_TABLE: wasmtime_extern_kind_t = 2; pub const WASMTIME_EXTERN_MEMORY: wasmtime_extern_kind_t = 3; #[repr(C)] pub union wasmtime_extern_union { pub func: Func, pub table: Table, pub global: Global, pub memory: Memory, } impl wasmtime_extern_t { pub unsafe fn to_extern(&self) -> Extern { match self.kind { WASMTIME_EXTERN_FUNC => Extern::Func(self.of.func), WASMTIME_EXTERN_GLOBAL => Extern::Global(self.of.global), WASMTIME_EXTERN_TABLE => Extern::Table(self.of.table), WASMTIME_EXTERN_MEMORY => Extern::Memory(self.of.memory), other => panic!("unknown wasm_extern_kind_t: {}", other), } } } impl From for wasmtime_extern_t { fn from(item: Extern) -> wasmtime_extern_t { match item { Extern::Func(func) => wasmtime_extern_t { kind: WASMTIME_EXTERN_FUNC, of: wasmtime_extern_union { func }, }, Extern::Global(global) => wasmtime_extern_t { kind: WASMTIME_EXTERN_GLOBAL, of: wasmtime_extern_union { global }, }, Extern::Table(table) => wasmtime_extern_t { kind: WASMTIME_EXTERN_TABLE, of: wasmtime_extern_union { table }, }, Extern::Memory(memory) => wasmtime_extern_t { kind: WASMTIME_EXTERN_MEMORY, of: wasmtime_extern_union { memory }, }, Extern::SharedMemory(_memory) => todo!(), } } } #[no_mangle] pub unsafe extern "C" fn wasmtime_extern_delete(e: &mut ManuallyDrop) { ManuallyDrop::drop(e); } #[no_mangle] pub unsafe extern "C" fn wasmtime_extern_type( store: CStoreContext<'_>, e: &wasmtime_extern_t, ) -> Box { Box::new(wasm_externtype_t::new(e.to_extern().ty(store))) }