Skip to main content

wasmtime_c_api/types/
memory.rs

1use crate::{CExternType, handle_result, wasm_externtype_t, wasm_limits_t, wasmtime_error_t};
2use std::convert::TryFrom;
3use std::{mem::MaybeUninit, sync::OnceLock};
4use wasmtime::{MemoryType, MemoryTypeBuilder};
5
6#[repr(transparent)]
7#[derive(Clone)]
8pub struct wasm_memorytype_t {
9    ext: wasm_externtype_t,
10}
11
12wasmtime_c_api_macros::declare_ty!(wasm_memorytype_t);
13
14#[derive(Clone)]
15pub(crate) struct CMemoryType {
16    pub(crate) ty: MemoryType,
17    limits_cache: OnceLock<wasm_limits_t>,
18}
19
20impl wasm_memorytype_t {
21    pub(crate) fn new(ty: MemoryType) -> wasm_memorytype_t {
22        wasm_memorytype_t {
23            ext: wasm_externtype_t::from_extern_type(ty.into()),
24        }
25    }
26
27    pub(crate) fn try_from(e: &wasm_externtype_t) -> Option<&wasm_memorytype_t> {
28        match &e.which {
29            CExternType::Memory(_) => Some(unsafe { &*(e as *const _ as *const _) }),
30            _ => None,
31        }
32    }
33
34    pub(crate) fn ty(&self) -> &CMemoryType {
35        match &self.ext.which {
36            CExternType::Memory(f) => &f,
37            _ => unsafe { std::hint::unreachable_unchecked() },
38        }
39    }
40}
41
42impl CMemoryType {
43    pub(crate) fn new(ty: MemoryType) -> CMemoryType {
44        CMemoryType {
45            ty,
46            limits_cache: OnceLock::new(),
47        }
48    }
49}
50
51#[unsafe(no_mangle)]
52pub extern "C" fn wasm_memorytype_new(limits: &wasm_limits_t) -> Option<Box<wasm_memorytype_t>> {
53    let ty = MemoryType::new(limits.min, limits.max()).ok()?;
54    Some(Box::new(wasm_memorytype_t::new(ty)))
55}
56
57#[unsafe(no_mangle)]
58pub extern "C" fn wasm_memorytype_limits(mt: &wasm_memorytype_t) -> &wasm_limits_t {
59    let mt = mt.ty();
60    mt.limits_cache.get_or_init(|| wasm_limits_t {
61        min: u32::try_from(mt.ty.minimum()).unwrap(),
62        max: u32::try_from(mt.ty.maximum().unwrap_or(u64::from(u32::MAX))).unwrap(),
63    })
64}
65
66#[unsafe(no_mangle)]
67pub extern "C" fn wasmtime_memorytype_new(
68    minimum: u64,
69    maximum_specified: bool,
70    maximum: u64,
71    memory64: bool,
72    shared: bool,
73    page_size_log2: u8,
74    ret: &mut MaybeUninit<Box<wasm_memorytype_t>>,
75) -> Option<Box<wasmtime_error_t>> {
76    let maximum = if maximum_specified {
77        Some(maximum)
78    } else {
79        None
80    };
81
82    handle_result(
83        MemoryTypeBuilder::default()
84            .min(minimum)
85            .max(maximum)
86            .memory64(memory64)
87            .shared(shared)
88            .page_size_log2(page_size_log2)
89            .build(),
90        |ty| {
91            ret.write(Box::new(wasm_memorytype_t::new(ty)));
92        },
93    )
94}
95
96#[unsafe(no_mangle)]
97pub extern "C" fn wasmtime_memorytype_minimum(mt: &wasm_memorytype_t) -> u64 {
98    mt.ty().ty.minimum()
99}
100
101#[unsafe(no_mangle)]
102pub extern "C" fn wasmtime_memorytype_maximum(mt: &wasm_memorytype_t, out: &mut u64) -> bool {
103    match mt.ty().ty.maximum() {
104        Some(max) => {
105            *out = max;
106            true
107        }
108        None => false,
109    }
110}
111
112#[unsafe(no_mangle)]
113pub extern "C" fn wasmtime_memorytype_is64(mt: &wasm_memorytype_t) -> bool {
114    mt.ty().ty.is_64()
115}
116
117#[unsafe(no_mangle)]
118pub extern "C" fn wasmtime_memorytype_isshared(mt: &wasm_memorytype_t) -> bool {
119    mt.ty().ty.is_shared()
120}
121
122#[unsafe(no_mangle)]
123pub extern "C" fn wasmtime_memorytype_page_size(mt: &wasm_memorytype_t) -> u64 {
124    mt.ty().ty.page_size()
125}
126
127#[unsafe(no_mangle)]
128pub extern "C" fn wasmtime_memorytype_page_size_log2(mt: &wasm_memorytype_t) -> u8 {
129    mt.ty().ty.page_size_log2()
130}
131
132#[unsafe(no_mangle)]
133pub extern "C" fn wasm_memorytype_as_externtype(ty: &wasm_memorytype_t) -> &wasm_externtype_t {
134    &ty.ext
135}
136
137#[unsafe(no_mangle)]
138pub extern "C" fn wasm_memorytype_as_externtype_const(
139    ty: &wasm_memorytype_t,
140) -> &wasm_externtype_t {
141    &ty.ext
142}