wasmer_runtime_core_fl/
units.rs

1//! This module provides common WebAssembly units like [`Pages`] and conversion functions into
2//! other units.
3use crate::error::PageError;
4use std::{
5    fmt,
6    ops::{Add, Sub},
7};
8
9/// The page size in bytes of a wasm page.
10pub const WASM_PAGE_SIZE: usize = 65_536;
11/// The max number of wasm pages allowed.
12pub const WASM_MAX_PAGES: usize = 65_536;
13// From emscripten resize_heap implementation
14/// The minimum number of wasm pages allowed.
15pub const WASM_MIN_PAGES: usize = 256;
16
17/// Units of WebAssembly pages (as specified to be 65,536 bytes).
18#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
19pub struct Pages(pub u32);
20
21impl Pages {
22    /// Checked add of Pages to Pages.
23    pub fn checked_add(self, rhs: Pages) -> Result<Pages, PageError> {
24        let added = (self.0 as usize) + (rhs.0 as usize);
25        if added <= WASM_MAX_PAGES {
26            Ok(Pages(added as u32))
27        } else {
28            Err(PageError::ExceededMaxPages(
29                self.0 as usize,
30                rhs.0 as usize,
31                added,
32            ))
33        }
34    }
35
36    /// Calculate number of bytes from pages.
37    pub fn bytes(self) -> Bytes {
38        self.into()
39    }
40}
41
42impl fmt::Debug for Pages {
43    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
44        write!(f, "{} pages", self.0)
45    }
46}
47
48impl From<u32> for Pages {
49    fn from(other: u32) -> Self {
50        Pages(other)
51    }
52}
53
54/// Units of WebAssembly memory in terms of 8-bit bytes.
55#[derive(Serialize, Deserialize, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
56pub struct Bytes(pub usize);
57
58impl fmt::Debug for Bytes {
59    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
60        write!(f, "{} bytes", self.0)
61    }
62}
63
64impl From<Pages> for Bytes {
65    fn from(pages: Pages) -> Bytes {
66        Bytes((pages.0 as usize) * WASM_PAGE_SIZE)
67    }
68}
69
70impl From<usize> for Bytes {
71    fn from(other: usize) -> Self {
72        Bytes(other)
73    }
74}
75
76impl<T> Sub<T> for Pages
77where
78    T: Into<Pages>,
79{
80    type Output = Pages;
81    fn sub(self, rhs: T) -> Pages {
82        Pages(self.0 - rhs.into().0)
83    }
84}
85
86impl<T> Add<T> for Pages
87where
88    T: Into<Pages>,
89{
90    type Output = Pages;
91    fn add(self, rhs: T) -> Pages {
92        Pages(self.0 + rhs.into().0)
93    }
94}
95
96impl From<Bytes> for Pages {
97    fn from(bytes: Bytes) -> Pages {
98        Pages((bytes.0 / WASM_PAGE_SIZE) as u32)
99    }
100}
101
102impl<T> Sub<T> for Bytes
103where
104    T: Into<Bytes>,
105{
106    type Output = Bytes;
107    fn sub(self, rhs: T) -> Bytes {
108        Bytes(self.0 - rhs.into().0)
109    }
110}
111
112impl<T> Add<T> for Bytes
113where
114    T: Into<Bytes>,
115{
116    type Output = Bytes;
117    fn add(self, rhs: T) -> Bytes {
118        Bytes(self.0 + rhs.into().0)
119    }
120}