wasmtime_c_api/types/
memory.rs1use 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}