wasmtime_c_api/
memory.rs

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}