wasmtime/runtime/vm/sys/
mod.rs

1//! OS-related abstractions required by Wasmtime.
2//!
3//! This module is intended to house all logic that's specific to either Unix
4//! or Windows, for example. The goal of this module is to be the "single
5//! module" to edit if Wasmtime is ported to a new platform. Ideally all that's
6//! needed is an extra block below and a new platform should be good to go after
7//! filling out the implementation.
8
9#![allow(clippy::cast_sign_loss)] // platforms too fiddly to worry about this
10
11use crate::runtime::vm::SendSyncPtr;
12use core::ptr::{self, NonNull};
13
14/// What happens to a mapping after it is decommitted?
15#[derive(Clone, Copy, PartialEq, Eq, Debug)]
16pub enum DecommitBehavior {
17    /// The mapping is zeroed.
18    Zero,
19    /// The original mapping is restored. If it was zero, then it is zero again;
20    /// if it was a CoW mapping, then the original CoW mapping is restored;
21    /// etc...
22    RestoreOriginalMapping,
23}
24
25fn empty_mmap() -> SendSyncPtr<[u8]> {
26    // Callers of this API assume that `.as_ptr()` below returns something
27    // page-aligned and non-null. This is because the pointer returned from
28    // that location is casted to other types which reside at a higher
29    // alignment than a byte for example. Despite the length being zero we
30    // still need to ensure that the pointer is suitably aligned.
31    //
32    // To handle that do a bit of trickery here to get the compiler to
33    // generate an empty array to a high-alignment type (here 4k which is
34    // the min page size we work with today). Then use this empty array as
35    // the source pointer for an empty byte slice. It's a bit wonky but this
36    // makes it such that the returned length is always zero (so this is
37    // safe) but the pointer is always 4096 or suitably aligned.
38    #[repr(C, align(4096))]
39    struct PageAligned;
40    let empty_page_alloc: &mut [PageAligned] = &mut [];
41    let empty = NonNull::new(ptr::slice_from_raw_parts_mut(
42        empty_page_alloc.as_mut_ptr().cast(),
43        0,
44    ))
45    .unwrap();
46    SendSyncPtr::from(empty)
47}
48
49cfg_if::cfg_if! {
50    if #[cfg(miri)] {
51        mod miri;
52        pub use miri::*;
53    } else if #[cfg(windows)] {
54        mod windows;
55        pub use windows::*;
56    } else if #[cfg(unix)] {
57        mod unix;
58        pub use unix::*;
59    } else {
60        mod custom;
61        pub use custom::*;
62    }
63}