xref: /wasmtime-44.0.1/crates/c-api/src/memory.rs (revision a7f592a0)
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