1use crate::{
2 handle_result, wasm_extern_t, wasm_memorytype_t, wasm_store_t, wasmtime_error_t,
3 WasmtimeStoreContext, WasmtimeStoreContextMut,
4};
5use std::convert::TryFrom;
6use wasmtime::{Extern, Memory};
7
8#[derive(Clone)]
9#[repr(transparent)]
10pub struct wasm_memory_t {
11 ext: wasm_extern_t,
12}
13
14wasmtime_c_api_macros::declare_ref!(wasm_memory_t);
15
16pub type wasm_memory_pages_t = u32;
17
18impl 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)]
35pub 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)]
49pub 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)]
54pub extern "C" fn wasm_memory_as_extern_const(m: &wasm_memory_t) -> &wasm_extern_t {
55 &m.ext
56}
57
58#[unsafe(no_mangle)]
59pub 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)]
65pub 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)]
70pub 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)]
75pub 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)]
80pub 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)]
90pub 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)]
99pub 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)]
107pub extern "C" fn wasmtime_memory_data(store: WasmtimeStoreContext<'_>, mem: &Memory) -> *const u8 {
108 mem.data(store).as_ptr()
109}
110
111#[unsafe(no_mangle)]
112pub 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)]
120pub extern "C" fn wasmtime_memory_size(store: WasmtimeStoreContext<'_>, mem: &Memory) -> u64 {
121 mem.size(store)
122}
123
124#[unsafe(no_mangle)]
125pub 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}