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