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