mirror of
https://github.com/fluencelabs/wasmer
synced 2024-12-13 22:25:40 +00:00
Merge pull request #54 from wasmerio/feature/runtime-upgrade
Wasmer runtime upgrade - Phase 1 (libcalls & memory)
This commit is contained in:
commit
f51362be66
13
Cargo.lock
generated
13
Cargo.lock
generated
@ -373,15 +373,6 @@ dependencies = [
|
||||
"version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memmap"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.2.1"
|
||||
@ -876,11 +867,11 @@ dependencies = [
|
||||
"cranelift-native 0.23.0",
|
||||
"cranelift-wasm 0.23.0",
|
||||
"docopt 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"errno 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"indicatif 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.44 (git+https://github.com/rust-lang/libc)",
|
||||
"log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"nix 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rayon 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"region 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@ -891,6 +882,7 @@ dependencies = [
|
||||
"tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wabt 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasmparser 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -960,7 +952,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
"checksum log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fcce5fa49cc693c312001daf1d13411c4a5283796bac1084299ea3e567113f"
|
||||
"checksum mach 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2fd13ee2dd61cc82833ba05ade5a30bb3d63f7ced605ef827063c63078302de9"
|
||||
"checksum memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4b3629fe9fdbff6daa6c33b90f7c08355c1aca05a3d01fa8063b822fcf185f3b"
|
||||
"checksum memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2ffa2c986de11a9df78620c01eeaaf27d94d3ff02bf81bfcca953102dd0c6ff"
|
||||
"checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3"
|
||||
"checksum nix 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "921f61dc817b379d0834e45d5ec45beaacfae97082090a49c2cf30dcbc30206f"
|
||||
"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945"
|
||||
|
@ -33,11 +33,12 @@ serde = "1.0.55"
|
||||
serde_derive = "1.0.55"
|
||||
tempdir = "0.3.7"
|
||||
error-chain = "0.12.0"
|
||||
errno = "0.2.4"
|
||||
structopt = "0.2.11"
|
||||
wabt = "0.7.1"
|
||||
wasmparser = "0.20.0"
|
||||
winapi = "0.3.6"
|
||||
region = "0.3.0"
|
||||
memmap = "0.6.2"
|
||||
# spin = "0.4.10"
|
||||
log = "0.4.5"
|
||||
target-lexicon = "0.2.0"
|
||||
|
18
src/common/mmap/common.rs
Normal file
18
src/common/mmap/common.rs
Normal file
@ -0,0 +1,18 @@
|
||||
|
||||
/// Round `size` up to the nearest multiple of `page_size`.
|
||||
pub fn round_up_to_page_size(size: usize, page_size: usize) -> usize {
|
||||
(size + (page_size - 1)) & !(page_size - 1)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_round_up_to_page_size() {
|
||||
assert_eq!(round_up_to_page_size(0, 4096), 0);
|
||||
assert_eq!(round_up_to_page_size(1, 4096), 4096);
|
||||
assert_eq!(round_up_to_page_size(4096, 4096), 4096);
|
||||
assert_eq!(round_up_to_page_size(4097, 4096), 8192);
|
||||
}
|
||||
}
|
13
src/common/mmap/mod.rs
Normal file
13
src/common/mmap/mod.rs
Normal file
@ -0,0 +1,13 @@
|
||||
//! A cross-platform Rust API for memory mapped buffers.
|
||||
// TODO: Refactor this into it's own lib
|
||||
mod common;
|
||||
|
||||
#[cfg(windows)]
|
||||
mod windows;
|
||||
#[cfg(windows)]
|
||||
pub use self::windows::Mmap;
|
||||
|
||||
#[cfg(unix)]
|
||||
mod unix;
|
||||
#[cfg(unix)]
|
||||
pub use self::unix::Mmap;
|
96
src/common/mmap/unix.rs
Normal file
96
src/common/mmap/unix.rs
Normal file
@ -0,0 +1,96 @@
|
||||
//! Low-level abstraction for allocating and managing zero-filled pages
|
||||
//! of memory.
|
||||
|
||||
use errno;
|
||||
use libc;
|
||||
use region;
|
||||
use std::ptr;
|
||||
use std::slice;
|
||||
use std::string::String;
|
||||
|
||||
use super::common::round_up_to_page_size;
|
||||
|
||||
/// A simple struct consisting of a page-aligned pointer to page-aligned
|
||||
/// and initially-zeroed memory and a length.
|
||||
#[derive(Debug)]
|
||||
pub struct Mmap {
|
||||
ptr: *mut u8,
|
||||
len: usize,
|
||||
}
|
||||
|
||||
impl Mmap {
|
||||
/// Construct a new empty instance of `Mmap`.
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
ptr: ptr::null_mut(),
|
||||
len: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new `Mmap` pointing to at least `size` bytes of memory,
|
||||
/// suitably sized and aligned for memory protection.
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
pub fn with_size(size: usize) -> Result<Self, String> {
|
||||
// Mmap may return EINVAL if the size is zero, so just
|
||||
// special-case that.
|
||||
if size == 0 {
|
||||
return Ok(Self::new());
|
||||
}
|
||||
|
||||
let page_size = region::page::size();
|
||||
let alloc_size = round_up_to_page_size(size, page_size);
|
||||
let ptr = unsafe {
|
||||
libc::mmap(
|
||||
ptr::null_mut(),
|
||||
alloc_size,
|
||||
// libc::PROT_READ | libc::PROT_WRITE,
|
||||
libc::PROT_NONE,
|
||||
libc::MAP_PRIVATE | libc::MAP_ANON,
|
||||
-1,
|
||||
0,
|
||||
)
|
||||
};
|
||||
if ptr as isize == -1isize {
|
||||
Err(errno::errno().to_string())
|
||||
} else {
|
||||
Ok(Self {
|
||||
ptr: ptr as *mut u8,
|
||||
len: alloc_size,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the allocated memory as a slice of u8.
|
||||
pub fn as_slice(&self) -> &[u8] {
|
||||
unsafe { slice::from_raw_parts(self.ptr, 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) }
|
||||
}
|
||||
|
||||
/// Return the allocated memory as a pointer to u8.
|
||||
pub fn as_ptr(&self) -> *const u8 {
|
||||
self.ptr
|
||||
}
|
||||
|
||||
/// Return the allocated memory as a mutable pointer to u8.
|
||||
pub fn as_mut_ptr(&mut self) -> *mut u8 {
|
||||
self.ptr
|
||||
}
|
||||
|
||||
/// Return the lengthof the allocated memory.
|
||||
pub fn len(&self) -> usize {
|
||||
self.len
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Mmap {
|
||||
fn drop(&mut self) {
|
||||
if !self.ptr.is_null() {
|
||||
let r = unsafe { libc::munmap(self.ptr as *mut libc::c_void, self.len) };
|
||||
assert_eq!(r, 0, "munmap failed: {}", errno::errno());
|
||||
}
|
||||
}
|
||||
}
|
89
src/common/mmap/windows.rs
Normal file
89
src/common/mmap/windows.rs
Normal file
@ -0,0 +1,89 @@
|
||||
//! Low-level abstraction for allocating and managing zero-filled pages
|
||||
//! of memory.
|
||||
|
||||
use errno;
|
||||
use region;
|
||||
use std::ptr;
|
||||
use std::slice;
|
||||
use std::string::String;
|
||||
use winapi::um::memoryapi::{VirtualAlloc, VirtualFree};
|
||||
use winapi::um::winnt::{MEM_COMMIT, MEM_RESERVE, PAGE_READWRITE, MEM_RELEASE};
|
||||
|
||||
use super::common::round_up_to_page_size;
|
||||
|
||||
|
||||
/// A simple struct consisting of a page-aligned pointer to page-aligned
|
||||
/// and initially-zeroed memory and a length.
|
||||
#[derive(Debug)]
|
||||
pub struct Mmap {
|
||||
ptr: *mut u8,
|
||||
len: usize,
|
||||
}
|
||||
|
||||
impl Mmap {
|
||||
/// Construct a new empty instance of `Mmap`.
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
ptr: ptr::null_mut(),
|
||||
len: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new `Mmap` pointing to at least `size` bytes of memory,
|
||||
/// suitably sized and aligned for memory protection.
|
||||
pub fn with_size(size: usize) -> Result<Self, String> {
|
||||
let page_size = region::page::size();
|
||||
|
||||
// VirtualAlloc always rounds up to the next multiple of the page size
|
||||
let ptr = unsafe {
|
||||
VirtualAlloc(
|
||||
ptr::null_mut(),
|
||||
size,
|
||||
MEM_COMMIT | MEM_RESERVE,
|
||||
PAGE_READWRITE,
|
||||
)
|
||||
};
|
||||
if !ptr.is_null() {
|
||||
Ok(Self {
|
||||
ptr: ptr as *mut u8,
|
||||
len: round_up_to_page_size(size, page_size),
|
||||
})
|
||||
} else {
|
||||
Err(errno::errno().to_string())
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the allocated memory as a slice of u8.
|
||||
pub fn as_slice(&self) -> &[u8] {
|
||||
unsafe { slice::from_raw_parts(self.ptr, 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) }
|
||||
}
|
||||
|
||||
/// Return the allocated memory as a pointer to u8.
|
||||
pub fn as_ptr(&self) -> *const u8 {
|
||||
self.ptr
|
||||
}
|
||||
|
||||
/// Return the allocated memory as a mutable pointer to u8.
|
||||
pub fn as_mut_ptr(&mut self) -> *mut u8 {
|
||||
self.ptr
|
||||
}
|
||||
|
||||
/// Return the lengthof the allocated memory.
|
||||
pub fn len(&self) -> usize {
|
||||
self.len
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Mmap {
|
||||
fn drop(&mut self) {
|
||||
if !self.ptr.is_null() {
|
||||
let r = unsafe { VirtualFree(self.ptr, self.len, MEM_RELEASE) };
|
||||
assert_eq!(r, 0);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,2 +1,3 @@
|
||||
pub mod slice;
|
||||
pub mod stdio;
|
||||
pub mod mmap;
|
||||
|
@ -5,7 +5,6 @@ extern crate cranelift_entity;
|
||||
extern crate cranelift_native;
|
||||
extern crate cranelift_wasm;
|
||||
extern crate libc;
|
||||
extern crate memmap;
|
||||
extern crate region;
|
||||
extern crate structopt;
|
||||
extern crate wabt;
|
||||
@ -17,6 +16,8 @@ pub extern crate nix; // re-exported for usage in macros
|
||||
extern crate rayon;
|
||||
extern crate indicatif;
|
||||
extern crate console;
|
||||
#[cfg(windows)]
|
||||
extern crate winapi;
|
||||
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
|
@ -26,7 +26,7 @@ use std::{fmt, mem, slice};
|
||||
use super::super::common::slice::{BoundedSlice, UncheckedSlice};
|
||||
use super::errors::ErrorKind;
|
||||
use super::import_object::{ImportObject, ImportValue};
|
||||
use super::math_intrinsics;
|
||||
use super::libcalls;
|
||||
use super::memory::LinearMemory;
|
||||
use super::module::{Export, ImportableExportable, Module};
|
||||
use super::relocation::{Reloc, RelocSink, RelocationType};
|
||||
@ -311,35 +311,21 @@ impl Instance {
|
||||
RelocationType::GrowMemory => {
|
||||
grow_memory as isize
|
||||
},
|
||||
RelocationType::LibCall(LibCall::CeilF32) => {
|
||||
math_intrinsics::ceilf32 as isize
|
||||
},
|
||||
RelocationType::LibCall(LibCall::FloorF32) => {
|
||||
math_intrinsics::floorf32 as isize
|
||||
},
|
||||
RelocationType::LibCall(LibCall::TruncF32) => {
|
||||
math_intrinsics::truncf32 as isize
|
||||
},
|
||||
RelocationType::LibCall(LibCall::NearestF32) => {
|
||||
math_intrinsics::nearbyintf32 as isize
|
||||
},
|
||||
RelocationType::LibCall(LibCall::CeilF64) => {
|
||||
math_intrinsics::ceilf64 as isize
|
||||
},
|
||||
RelocationType::LibCall(LibCall::FloorF64) => {
|
||||
math_intrinsics::floorf64 as isize
|
||||
},
|
||||
RelocationType::LibCall(LibCall::TruncF64) => {
|
||||
math_intrinsics::truncf64 as isize
|
||||
},
|
||||
RelocationType::LibCall(LibCall::NearestF64) => {
|
||||
math_intrinsics::nearbyintf64 as isize
|
||||
},
|
||||
RelocationType::LibCall(LibCall::Probestack) => {
|
||||
__rust_probestack as isize
|
||||
},
|
||||
RelocationType::LibCall(call) => {
|
||||
panic!("Unexpected libcall {}", call);
|
||||
RelocationType::LibCall(libcall) => {
|
||||
match libcall {
|
||||
LibCall::CeilF32 => libcalls::ceilf32 as isize,
|
||||
LibCall::FloorF32 => libcalls::floorf32 as isize,
|
||||
LibCall::TruncF32 => libcalls::truncf32 as isize,
|
||||
LibCall::NearestF32 => libcalls::nearbyintf32 as isize,
|
||||
LibCall::CeilF64 => libcalls::ceilf64 as isize,
|
||||
LibCall::FloorF64 => libcalls::floorf64 as isize,
|
||||
LibCall::TruncF64 => libcalls::truncf64 as isize,
|
||||
LibCall::NearestF64 => libcalls::nearbyintf64 as isize,
|
||||
LibCall::Probestack => libcalls::__rust_probestack as isize,
|
||||
_ => {
|
||||
panic!("Unexpected libcall {}", libcall);
|
||||
}
|
||||
}
|
||||
},
|
||||
RelocationType::Intrinsic(ref name) => {
|
||||
panic!("Unexpected intrinsic {}", name);
|
||||
@ -690,9 +676,3 @@ extern "C" fn current_memory(memory_index: u32, instance: &mut Instance) -> u32
|
||||
let memory = &instance.memories[memory_index as usize];
|
||||
memory.current_pages() as u32
|
||||
}
|
||||
|
||||
/// A declaration for the stack probe function in Rust's standard library, for
|
||||
/// catching callstack overflow.
|
||||
extern "C" {
|
||||
pub fn __rust_probestack();
|
||||
}
|
||||
|
@ -39,3 +39,10 @@ pub extern "C" fn truncf64(x: f64) -> f64 {
|
||||
pub extern "C" fn nearbyintf64(x: f64) -> f64 {
|
||||
x.round()
|
||||
}
|
||||
|
||||
|
||||
/// A declaration for the stack probe function in Rust's standard library, for
|
||||
/// catching callstack overflow.
|
||||
extern "C" {
|
||||
pub fn __rust_probestack();
|
||||
}
|
@ -3,17 +3,21 @@
|
||||
//! webassembly::Instance.
|
||||
//! A memory created by Rust or in WebAssembly code will be accessible and
|
||||
//! mutable from both Rust and WebAssembly.
|
||||
use nix::libc::{c_void, mprotect, PROT_READ, PROT_WRITE};
|
||||
use nix::sys::mman::{mmap, MapFlags, ProtFlags};
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::slice;
|
||||
use region;
|
||||
|
||||
use crate::common::mmap::Mmap;
|
||||
|
||||
/// A linear memory instance.
|
||||
//
|
||||
#[derive(Debug)]
|
||||
pub struct LinearMemory {
|
||||
base: *mut c_void, // The size will always be `LinearMemory::DEFAULT_SIZE`
|
||||
current: u32, // current number of wasm pages
|
||||
// The mmap allocation
|
||||
mmap: Mmap,
|
||||
|
||||
// current number of wasm pages
|
||||
current: u32,
|
||||
|
||||
// The maximum size the WebAssembly Memory is allowed to grow
|
||||
// to, in units of WebAssembly pages. When present, the maximum
|
||||
// parameter acts as a hint to the engine to reserve memory up
|
||||
@ -21,6 +25,10 @@ pub struct LinearMemory {
|
||||
// request. In general, most WebAssembly modules shouldn't need
|
||||
// to set a maximum.
|
||||
maximum: Option<u32>,
|
||||
|
||||
// The size of the extra guard pages after the end.
|
||||
// Is used to optimize loads and stores with constant offsets.
|
||||
offset_guard_size: usize,
|
||||
}
|
||||
|
||||
/// It holds the raw bytes of memory accessed by a WebAssembly Instance
|
||||
@ -42,46 +50,38 @@ impl LinearMemory {
|
||||
"Instantiate LinearMemory(initial={:?}, maximum={:?})",
|
||||
initial, maximum
|
||||
);
|
||||
|
||||
let offset_guard_size = LinearMemory::DEFAULT_SIZE as usize;
|
||||
let mut mmap = Mmap::with_size(offset_guard_size).expect("Can't create mmap");
|
||||
|
||||
// TODO: Investigate if memory is zeroed out
|
||||
let base = unsafe {
|
||||
mmap(
|
||||
0 as _,
|
||||
LinearMemory::DEFAULT_SIZE,
|
||||
ProtFlags::PROT_NONE,
|
||||
MapFlags::MAP_ANON | MapFlags::MAP_PRIVATE,
|
||||
-1,
|
||||
0,
|
||||
).unwrap()
|
||||
};
|
||||
let base = mmap.as_mut_ptr();
|
||||
|
||||
if initial > 0 {
|
||||
assert_eq!(
|
||||
unsafe {
|
||||
mprotect(
|
||||
base,
|
||||
initial as usize * Self::PAGE_SIZE as usize,
|
||||
// Self::DEFAULT_HEAP_SIZE,
|
||||
PROT_READ | PROT_WRITE,
|
||||
)
|
||||
},
|
||||
0
|
||||
);
|
||||
if initial != 0 {
|
||||
unsafe {
|
||||
region::protect(
|
||||
base as _,
|
||||
initial as usize * Self::PAGE_SIZE as usize,
|
||||
region::Protection::Read | region::Protection::Write,
|
||||
// region::Protection::None,
|
||||
)
|
||||
}
|
||||
.expect("unable to make memory inaccessible");
|
||||
}
|
||||
|
||||
debug!("LinearMemory instantiated");
|
||||
debug!(" - usable: {:#x}..{:#x}", base as usize, (base as usize) + LinearMemory::DEFAULT_HEAP_SIZE);
|
||||
debug!(" - guard: {:#x}..{:#x}", (base as usize) + LinearMemory::DEFAULT_HEAP_SIZE, (base as usize) + LinearMemory::DEFAULT_SIZE);
|
||||
Self {
|
||||
base,
|
||||
mmap,
|
||||
current: initial,
|
||||
offset_guard_size,
|
||||
maximum,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns an base address of this linear memory.
|
||||
pub fn base_addr(&mut self) -> *mut u8 {
|
||||
self.base as _
|
||||
pub fn base(&mut self) -> *mut u8 {
|
||||
self.mmap.as_mut_ptr() as _
|
||||
}
|
||||
|
||||
/// Returns a number of allocated wasm pages.
|
||||
@ -95,7 +95,7 @@ impl LinearMemory {
|
||||
|
||||
/// Returns the maximum number of wasm pages allowed.
|
||||
pub fn maximum_size(&self) -> u32 {
|
||||
self.maximum.unwrap_or(65536)
|
||||
self.maximum.unwrap_or(Self::MAX_PAGES)
|
||||
}
|
||||
|
||||
/// Grow memory by the specified amount of pages.
|
||||
@ -130,32 +130,43 @@ impl LinearMemory {
|
||||
let new_bytes = (new_pages * Self::PAGE_SIZE) as usize;
|
||||
|
||||
unsafe {
|
||||
assert_eq!(
|
||||
mprotect(
|
||||
self.base.add(prev_bytes),
|
||||
new_bytes - prev_bytes,
|
||||
PROT_READ | PROT_WRITE,
|
||||
),
|
||||
0
|
||||
);
|
||||
region::protect(
|
||||
self.mmap.as_mut_ptr().add(prev_bytes) as _,
|
||||
new_bytes - prev_bytes,
|
||||
region::Protection::Read | region::Protection::Write,
|
||||
// region::Protection::None,
|
||||
)
|
||||
}
|
||||
.expect("unable to make memory inaccessible");
|
||||
// if new_bytes > self.mmap.len() - self.offset_guard_size {
|
||||
// // If we have no maximum, this is a "dynamic" heap, and it's allowed to move.
|
||||
// assert!(self.maximum.is_none());
|
||||
// let guard_bytes = self.offset_guard_size;
|
||||
// let request_bytes = new_bytes.checked_add(guard_bytes)?;
|
||||
|
||||
// let mut new_mmap = Mmap::with_size(request_bytes).ok()?;
|
||||
|
||||
// // Make the offset-guard pages inaccessible.
|
||||
// unsafe {
|
||||
// region::protect(
|
||||
// new_mmap.as_ptr().add(new_bytes),
|
||||
// guard_bytes,
|
||||
// region::Protection::Read | region::Protection::Write,
|
||||
// // region::Protection::None,
|
||||
// )
|
||||
// }
|
||||
// .expect("unable to make memory inaccessible");
|
||||
|
||||
// let copy_len = self.mmap.len() - self.offset_guard_size;
|
||||
// new_mmap.as_mut_slice()[..copy_len].copy_from_slice(&self.mmap.as_slice()[..copy_len]);
|
||||
|
||||
// self.mmap = new_mmap;
|
||||
// }
|
||||
|
||||
self.current = new_pages;
|
||||
|
||||
Some(prev_pages as i32)
|
||||
}
|
||||
|
||||
pub fn carve_slice(&self, offset: u32, size: u32) -> Option<&[u8]> {
|
||||
let start = offset as usize;
|
||||
let end = start + size as usize;
|
||||
let slice: &[u8] = &*self;
|
||||
|
||||
if end <= self.current_size() as usize {
|
||||
Some(&slice[start..end])
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Not comparing based on memory content. That would be inefficient.
|
||||
@ -168,12 +179,12 @@ impl PartialEq for LinearMemory {
|
||||
impl Deref for LinearMemory {
|
||||
type Target = [u8];
|
||||
fn deref(&self) -> &[u8] {
|
||||
unsafe { slice::from_raw_parts(self.base as _, self.current as usize * Self::PAGE_SIZE as usize) }
|
||||
unsafe { slice::from_raw_parts(self.mmap.as_ptr() as _, self.current as usize * Self::PAGE_SIZE as usize) }
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for LinearMemory {
|
||||
fn deref_mut(&mut self) -> &mut [u8] {
|
||||
unsafe { slice::from_raw_parts_mut(self.base as _, self.current as usize * Self::PAGE_SIZE as usize) }
|
||||
unsafe { slice::from_raw_parts_mut(self.mmap.as_mut_ptr() as _, self.current as usize * Self::PAGE_SIZE as usize) }
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
pub mod errors;
|
||||
pub mod import_object;
|
||||
pub mod instance;
|
||||
pub mod math_intrinsics;
|
||||
pub mod libcalls;
|
||||
pub mod memory;
|
||||
pub mod module;
|
||||
pub mod relocation;
|
||||
|
Loading…
Reference in New Issue
Block a user