1 use super::cvt; 2 use crate::runtime::vm::sys::capi; 3 use crate::runtime::vm::SendSyncPtr; 4 use crate::vm::sys::DecommitBehavior; 5 use anyhow::Result; 6 use core::ptr::{self, NonNull}; 7 #[cfg(feature = "std")] 8 use std::{fs::File, sync::Arc}; 9 10 pub unsafe fn expose_existing_mapping(ptr: *mut u8, len: usize) -> Result<()> { 11 cvt(capi::wasmtime_mprotect( 12 ptr.cast(), 13 len, 14 capi::PROT_READ | capi::PROT_WRITE, 15 )) 16 } 17 18 pub unsafe fn hide_existing_mapping(ptr: *mut u8, len: usize) -> Result<()> { 19 cvt(capi::wasmtime_mprotect(ptr.cast(), len, 0)) 20 } 21 22 pub unsafe fn erase_existing_mapping(ptr: *mut u8, len: usize) -> Result<()> { 23 cvt(capi::wasmtime_mmap_remap(ptr.cast(), len, 0)) 24 } 25 26 #[cfg(feature = "pooling-allocator")] 27 pub unsafe fn commit_pages(_addr: *mut u8, _len: usize) -> Result<()> { 28 // Pages are always READ | WRITE so there's nothing that needs to be 29 // done here. 30 Ok(()) 31 } 32 33 pub unsafe fn decommit_pages(addr: *mut u8, len: usize) -> Result<()> { 34 if len == 0 { 35 return Ok(()); 36 } 37 38 cvt(capi::wasmtime_mmap_remap( 39 addr, 40 len, 41 capi::PROT_READ | capi::PROT_WRITE, 42 )) 43 } 44 45 pub fn get_page_size() -> usize { 46 unsafe { capi::wasmtime_page_size() } 47 } 48 49 pub fn decommit_behavior() -> DecommitBehavior { 50 DecommitBehavior::Zero 51 } 52 53 #[derive(PartialEq, Debug)] 54 pub struct MemoryImageSource { 55 data: SendSyncPtr<capi::wasmtime_memory_image>, 56 } 57 58 impl MemoryImageSource { 59 #[cfg(feature = "std")] 60 pub fn from_file(_file: &Arc<File>) -> Option<MemoryImageSource> { 61 None 62 } 63 64 pub fn from_data(data: &[u8]) -> Result<Option<MemoryImageSource>> { 65 unsafe { 66 let mut ptr = ptr::null_mut(); 67 cvt(capi::wasmtime_memory_image_new( 68 data.as_ptr(), 69 data.len(), 70 &mut ptr, 71 ))?; 72 match NonNull::new(ptr) { 73 Some(ptr) => Ok(Some(MemoryImageSource { 74 data: SendSyncPtr::new(ptr), 75 })), 76 None => Ok(None), 77 } 78 } 79 } 80 81 pub unsafe fn map_at(&self, base: *mut u8, len: usize, offset: u64) -> Result<()> { 82 assert_eq!(offset, 0); 83 cvt(capi::wasmtime_memory_image_map_at( 84 self.data.as_ptr(), 85 base, 86 len, 87 )) 88 } 89 90 pub unsafe fn remap_as_zeros_at(&self, base: *mut u8, len: usize) -> Result<()> { 91 cvt(capi::wasmtime_mmap_remap( 92 base.cast(), 93 len, 94 capi::PROT_READ | capi::PROT_WRITE, 95 )) 96 } 97 } 98 99 impl Drop for MemoryImageSource { 100 fn drop(&mut self) { 101 unsafe { 102 capi::wasmtime_memory_image_free(self.data.as_ptr()); 103 } 104 } 105 } 106