Remove the need for HostRef<Module> (#778)

* Remove the need for `HostRef<Module>`

This commit continues previous work and also #708 by removing the need
to use `HostRef<Module>` in the API of the `wasmtime` crate. The API
changes performed here are:

* The `Module` type is now itself internally reference counted.
* The `Module::store` function now returns the `Store` that was used to
  create a `Module`
* Documentation for `Module` and its methods have been expanded.

* Fix compliation of test programs harness

* Fix the python extension

* Update `CodeMemory` to be `Send + Sync`

This commit updates the `CodeMemory` type in wasmtime to be both `Send`
and `Sync` by updating the implementation of `Mmap` to not store raw
pointers. This avoids the need for an `unsafe impl` and leaves the
unsafety as it is currently.

* Fix a typo
This commit is contained in:
Alex Crichton
2020-01-08 14:42:37 -06:00
committed by GitHub
parent c975a92a3a
commit 7b33f1c619
22 changed files with 221 additions and 130 deletions

View File

@@ -1,11 +1,8 @@
//! Low-level abstraction for allocating and managing zero-filled pages
//! of memory.
#[cfg(not(target_os = "windows"))]
use libc;
use more_asserts::assert_le;
use more_asserts::assert_lt;
use region;
use std::io;
use std::ptr;
use std::slice;
@@ -19,7 +16,7 @@ fn round_up_to_page_size(size: usize, page_size: usize) -> usize {
/// and initially-zeroed memory and a length.
#[derive(Debug)]
pub struct Mmap {
ptr: *mut u8,
offset: usize,
len: usize,
}
@@ -29,10 +26,8 @@ impl Mmap {
// Rust's slices require non-null pointers, even when empty. `Vec`
// contains code to create a non-null dangling pointer value when
// constructed empty, so we reuse that here.
Self {
ptr: Vec::new().as_mut_ptr(),
len: 0,
}
let empty = Vec::<u8>::new();
Self { offset: empty.as_ptr() as usize, len: 0 }
}
/// Create a new `Mmap` pointing to at least `size` bytes of page-aligned accessible memory.
@@ -78,7 +73,7 @@ impl Mmap {
}
Self {
ptr: ptr as *mut u8,
offset: ptr as usize,
len: mapping_size,
}
} else {
@@ -98,7 +93,7 @@ impl Mmap {
}
let mut result = Self {
ptr: ptr as *mut u8,
offset: ptr as usize,
len: mapping_size,
};
@@ -142,7 +137,7 @@ impl Mmap {
}
Self {
ptr: ptr as *mut u8,
offset: ptr as usize,
len: mapping_size,
}
} else {
@@ -154,7 +149,7 @@ impl Mmap {
}
let mut result = Self {
ptr: ptr as *mut u8,
offset: ptr as usize,
len: mapping_size,
};
@@ -179,7 +174,8 @@ impl Mmap {
assert_lt!(start, self.len - len);
// Commit the accessible size.
unsafe { region::protect(self.ptr.add(start), len, region::Protection::ReadWrite) }
let ptr = self.offset as *const u8;
unsafe { region::protect(ptr.add(start), len, region::Protection::ReadWrite) }
.map_err(|e| e.to_string())
}
@@ -198,9 +194,10 @@ impl Mmap {
assert_lt!(start, self.len - len);
// Commit the accessible size.
let ptr = self.offset as *const u8;
if unsafe {
VirtualAlloc(
self.ptr.add(start) as *mut c_void,
ptr.add(start) as *mut c_void,
len,
MEM_COMMIT,
PAGE_READWRITE,
@@ -216,22 +213,22 @@ impl Mmap {
/// Return the allocated memory as a slice of u8.
pub fn as_slice(&self) -> &[u8] {
unsafe { slice::from_raw_parts(self.ptr, self.len) }
unsafe { slice::from_raw_parts(self.offset as *const u8, self.len) }
}
/// Return the allocated memory as a mutable slice of u8.
pub fn as_mut_slice(&mut self) -> &mut [u8] {
unsafe { slice::from_raw_parts_mut(self.ptr, self.len) }
unsafe { slice::from_raw_parts_mut(self.offset as *mut u8, self.len) }
}
/// Return the allocated memory as a pointer to u8.
pub fn as_ptr(&self) -> *const u8 {
self.ptr
self.offset as *const u8
}
/// Return the allocated memory as a mutable pointer to u8.
pub fn as_mut_ptr(&mut self) -> *mut u8 {
self.ptr
self.offset as *mut u8
}
/// Return the length of the allocated memory.
@@ -249,7 +246,7 @@ impl Drop for Mmap {
#[cfg(not(target_os = "windows"))]
fn drop(&mut self) {
if self.len != 0 {
let r = unsafe { libc::munmap(self.ptr as *mut libc::c_void, self.len) };
let r = unsafe { libc::munmap(self.offset as *mut libc::c_void, self.len) };
assert_eq!(r, 0, "munmap failed: {}", io::Error::last_os_error());
}
}
@@ -260,12 +257,17 @@ impl Drop for Mmap {
use winapi::ctypes::c_void;
use winapi::um::memoryapi::VirtualFree;
use winapi::um::winnt::MEM_RELEASE;
let r = unsafe { VirtualFree(self.ptr as *mut c_void, 0, MEM_RELEASE) };
let r = unsafe { VirtualFree(self.offset as *mut c_void, 0, MEM_RELEASE) };
assert_ne!(r, 0);
}
}
}
fn _assert() {
fn _assert_send_sync<T: Send + Sync>() {}
_assert_send_sync::<Mmap>();
}
#[cfg(test)]
mod tests {
use super::*;