* Use rsix to make system calls in Wasmtime. `rsix` is a system call wrapper crate that we use in `wasi-common`, which can provide the following advantages in the rest of Wasmtime: - It eliminates some `unsafe` blocks in Wasmtime's code. There's still an `unsafe` block in the library, but this way, the `unsafe` is factored out and clearly scoped. - And, it makes error handling more consistent, factoring out code for checking return values and `io::Error::last_os_error()`, and code that does `errno::set_errno(0)`. This doesn't cover *all* system calls; `rsix` doesn't implement signal-handling APIs, and this doesn't cover calls made through `std` or crates like `userfaultfd`, `rand`, and `region`.
64 lines
1.7 KiB
Rust
64 lines
1.7 KiB
Rust
use anyhow::{Context, Result};
|
|
|
|
fn decommit(addr: *mut u8, len: usize, protect: bool) -> Result<()> {
|
|
if len == 0 {
|
|
return Ok(());
|
|
}
|
|
|
|
// By creating a new mapping at the same location, this will discard the
|
|
// mapping for the pages in the given range.
|
|
// The new mapping will be to the CoW zero page, so this effectively
|
|
// zeroes the pages.
|
|
unsafe {
|
|
rsix::io::mmap_anonymous(
|
|
addr as _,
|
|
len,
|
|
if protect {
|
|
rsix::io::ProtFlags::NONE
|
|
} else {
|
|
rsix::io::ProtFlags::READ | rsix::io::ProtFlags::WRITE
|
|
},
|
|
rsix::io::MapFlags::PRIVATE | rsix::io::MapFlags::FIXED,
|
|
)
|
|
.context("mmap failed to remap pages: {}")?;
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub fn commit_memory_pages(addr: *mut u8, len: usize) -> Result<()> {
|
|
if len == 0 {
|
|
return Ok(());
|
|
}
|
|
|
|
// Just change the protection level to READ|WRITE
|
|
unsafe {
|
|
region::protect(addr, len, region::Protection::READ_WRITE)
|
|
.context("failed to make linear memory pages read/write")
|
|
}
|
|
}
|
|
|
|
pub fn decommit_memory_pages(addr: *mut u8, len: usize) -> Result<()> {
|
|
decommit(addr, len, true)
|
|
}
|
|
|
|
pub fn commit_table_pages(_addr: *mut u8, _len: usize) -> Result<()> {
|
|
// A no-op as table pages remain READ|WRITE
|
|
Ok(())
|
|
}
|
|
|
|
pub fn decommit_table_pages(addr: *mut u8, len: usize) -> Result<()> {
|
|
decommit(addr, len, false)
|
|
}
|
|
|
|
#[cfg(feature = "async")]
|
|
pub fn commit_stack_pages(_addr: *mut u8, _len: usize) -> Result<()> {
|
|
// A no-op as stack pages remain READ|WRITE
|
|
Ok(())
|
|
}
|
|
|
|
#[cfg(feature = "async")]
|
|
pub fn decommit_stack_pages(addr: *mut u8, len: usize) -> Result<()> {
|
|
decommit(addr, len, false)
|
|
}
|