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