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