1 use crate::{ 2 handle_result, wasm_extern_t, wasm_memorytype_t, wasm_store_t, wasmtime_error_t, CStoreContext, 3 CStoreContextMut, 4 }; 5 use wasmtime::{Extern, Memory}; 6 7 #[derive(Clone)] 8 #[repr(transparent)] 9 pub struct wasm_memory_t { 10 ext: wasm_extern_t, 11 } 12 13 wasmtime_c_api_macros::declare_ref!(wasm_memory_t); 14 15 pub type wasm_memory_pages_t = u32; 16 17 impl wasm_memory_t { 18 pub(crate) fn try_from(e: &wasm_extern_t) -> Option<&wasm_memory_t> { 19 match &e.which { 20 Extern::Memory(_) => Some(unsafe { &*(e as *const _ as *const _) }), 21 _ => None, 22 } 23 } 24 25 fn memory(&self) -> Memory { 26 match self.ext.which { 27 Extern::Memory(m) => m, 28 _ => unsafe { std::hint::unreachable_unchecked() }, 29 } 30 } 31 } 32 33 #[no_mangle] 34 pub unsafe extern "C" fn wasm_memory_new( 35 store: &mut wasm_store_t, 36 mt: &wasm_memorytype_t, 37 ) -> Option<Box<wasm_memory_t>> { 38 let memory = Memory::new(store.store.context_mut(), mt.ty().ty.clone()).ok()?; 39 Some(Box::new(wasm_memory_t { 40 ext: wasm_extern_t { 41 store: store.store.clone(), 42 which: memory.into(), 43 }, 44 })) 45 } 46 47 #[no_mangle] 48 pub extern "C" fn wasm_memory_as_extern(m: &mut wasm_memory_t) -> &mut wasm_extern_t { 49 &mut m.ext 50 } 51 52 #[no_mangle] 53 pub extern "C" fn wasm_memory_as_extern_const(m: &wasm_memory_t) -> &wasm_extern_t { 54 &m.ext 55 } 56 57 #[no_mangle] 58 pub unsafe extern "C" fn wasm_memory_type(m: &wasm_memory_t) -> Box<wasm_memorytype_t> { 59 let ty = m.memory().ty(m.ext.store.context()); 60 Box::new(wasm_memorytype_t::new(ty)) 61 } 62 63 #[no_mangle] 64 pub unsafe extern "C" fn wasm_memory_data(m: &wasm_memory_t) -> *mut u8 { 65 m.memory().data_ptr(m.ext.store.context()) 66 } 67 68 #[no_mangle] 69 pub unsafe extern "C" fn wasm_memory_data_size(m: &wasm_memory_t) -> usize { 70 m.memory().data_size(m.ext.store.context()) 71 } 72 73 #[no_mangle] 74 pub unsafe extern "C" fn wasm_memory_size(m: &wasm_memory_t) -> wasm_memory_pages_t { 75 m.memory().size(m.ext.store.context()) 76 } 77 78 #[no_mangle] 79 pub unsafe extern "C" fn wasm_memory_grow( 80 m: &mut wasm_memory_t, 81 delta: wasm_memory_pages_t, 82 ) -> bool { 83 let memory = m.memory(); 84 let mut store = m.ext.store.context_mut(); 85 memory.grow(&mut store, delta).is_ok() 86 } 87 88 #[no_mangle] 89 pub extern "C" fn wasmtime_memory_new( 90 store: CStoreContextMut<'_>, 91 ty: &wasm_memorytype_t, 92 ret: &mut Memory, 93 ) -> Option<Box<wasmtime_error_t>> { 94 handle_result(Memory::new(store, ty.ty().ty.clone()), |mem| *ret = mem) 95 } 96 97 #[no_mangle] 98 pub extern "C" fn wasmtime_memory_type( 99 store: CStoreContext<'_>, 100 mem: &Memory, 101 ) -> Box<wasm_memorytype_t> { 102 Box::new(wasm_memorytype_t::new(mem.ty(store))) 103 } 104 105 #[no_mangle] 106 pub extern "C" fn wasmtime_memory_data(store: CStoreContext<'_>, mem: &Memory) -> *const u8 { 107 mem.data(store).as_ptr() 108 } 109 110 #[no_mangle] 111 pub extern "C" fn wasmtime_memory_data_size(store: CStoreContext<'_>, mem: &Memory) -> usize { 112 mem.data(store).len() 113 } 114 115 #[no_mangle] 116 pub extern "C" fn wasmtime_memory_size(store: CStoreContext<'_>, mem: &Memory) -> u32 { 117 mem.size(store) 118 } 119 120 #[no_mangle] 121 pub extern "C" fn wasmtime_memory_grow( 122 store: CStoreContextMut<'_>, 123 mem: &Memory, 124 delta: u32, 125 prev_size: &mut u32, 126 ) -> Option<Box<wasmtime_error_t>> { 127 handle_result(mem.grow(store, delta), |prev| *prev_size = prev) 128 } 129