Library restructure (#104)

* Move wasmer-runtime to wasmer-runtime-core

* Add the runtime library

* Fix issue with macros using wasmer_runtime, fmt

* Make default compiler dependency optional

* Add instantiate and validate functions
This commit is contained in:
Brandon Fish
2019-01-22 13:02:06 -06:00
committed by Lachlan Sneff
parent 62b8e7cc2d
commit 74875ed554
129 changed files with 218 additions and 130 deletions

View File

@ -0,0 +1,11 @@
#[cfg(unix)]
mod unix;
#[cfg(windows)]
mod windows;
#[cfg(unix)]
pub use self::unix::*;
#[cfg(windows)]
pub use self::windows::*;

View File

@ -0,0 +1,116 @@
use errno;
use nix::libc;
use page_size;
use std::ops::Range;
use std::{ptr, slice};
#[derive(Debug)]
pub struct Memory {
ptr: *mut u8,
size: usize,
}
impl Memory {
pub fn with_size(size: usize) -> Result<Self, String> {
if size == 0 {
return Ok(Self {
ptr: ptr::null_mut(),
size: 0,
});
}
let size = round_up_to_page_size(size, page_size::get());
let ptr = unsafe {
libc::mmap(
ptr::null_mut(),
size,
libc::PROT_NONE,
libc::MAP_PRIVATE | libc::MAP_ANON,
-1,
0,
)
};
if ptr == -1 as _ {
Err(errno::errno().to_string())
} else {
Ok(Self {
ptr: ptr as *mut u8,
size,
})
}
}
pub unsafe fn protect(&mut self, range: Range<usize>, protect: Protect) -> Result<(), String> {
let protect = protect.to_protect_const();
let page_size = page_size::get();
let start = self
.ptr
.add(round_down_to_page_size(range.start, page_size));
let size = round_up_to_page_size(range.end - range.start, page_size);
assert!(size <= self.size);
let success = libc::mprotect(start as _, size, protect as i32);
if success == -1 {
Err(errno::errno().to_string())
} else {
Ok(())
}
}
pub fn size(&self) -> usize {
self.size
}
pub unsafe fn as_slice(&self) -> &[u8] {
slice::from_raw_parts(self.ptr, self.size)
}
pub unsafe fn as_slice_mut(&mut self) -> &mut [u8] {
slice::from_raw_parts_mut(self.ptr, self.size)
}
pub fn as_ptr(&self) -> *mut u8 {
self.ptr
}
}
impl Drop for Memory {
fn drop(&mut self) {
if !self.ptr.is_null() {
let success = unsafe { libc::munmap(self.ptr as _, self.size) };
assert_eq!(success, 0, "failed to unmap memory: {}", errno::errno());
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[allow(dead_code)]
pub enum Protect {
None,
Read,
ReadWrite,
ReadExec,
}
impl Protect {
fn to_protect_const(self) -> u32 {
match self {
Protect::None => 0,
Protect::Read => 1,
Protect::ReadWrite => 1 | 2,
Protect::ReadExec => 1 | 4,
}
}
}
/// Round `size` up to the nearest multiple of `page_size`.
fn round_up_to_page_size(size: usize, page_size: usize) -> usize {
(size + (page_size - 1)) & !(page_size - 1)
}
/// Round `size` down to the nearest multiple of `page_size`.
fn round_down_to_page_size(size: usize, page_size: usize) -> usize {
size & !(page_size - 1)
}

View File

@ -0,0 +1,3 @@
mod memory;
pub use self::memory::{Memory, Protect};

View File

@ -0,0 +1,124 @@
use winapi::um::memoryapi::{
VirtualAlloc,
MEM_RESERVE, MEM_COMMIT,
PAGE_NOACCESS, PAGE_EXECUTE_READ, PAGE_READWRITE, PAGE_READONLY,
};
use page_size;
use std::ops::Range;
use std::{ptr, slice};
#[derive(Debug)]
pub struct Memory {
ptr: *mut u8,
size: usize,
}
impl Memory {
pub fn with_size(size: usize) -> Result<Self, String> {
if size == 0 {
return Ok(Self {
ptr: ptr::null_mut(),
size: 0,
});
}
let size = round_up_to_page_size(size, page_size::get());
let ptr = unsafe {
VirtualAlloc(
ptr::null_mut(),
size,
MEM_RESERVE,
PAGE_NOACCESS,
)
};
if ptr.is_null() {
Err("unable to allocate memory")
} else {
Ok(Self {
ptr: ptr as *mut u8,
size,
})
}
}
pub unsafe fn protect(&mut self, range: Range<usize>, protect: Protect) -> Result<(), String> {
let protect = protect.to_protect_const();
let page_size = page_size::get();
let start = self
.ptr
.add(round_down_to_page_size(range.start, page_size));
let size = round_up_to_page_size(range.end - range.start, page_size);
assert!(size <= self.size);
// Commit the virtual memory.
let ptr = VirtualAlloc(
start as _,
size,
MEM_COMMIT,
protect,
);
if ptr.is_null() {
Err("unable to protect memory")
} else {
Ok(())
}
}
pub fn size(&self) -> usize {
self.size
}
pub unsafe fn as_slice(&self) -> &[u8] {
slice::from_raw_parts(self.ptr, self.size)
}
pub unsafe fn as_slice_mut(&mut self) -> &mut [u8] {
slice::from_raw_parts_mut(self.ptr, self.size)
}
pub fn as_ptr(&self) -> *mut u8 {
self.ptr
}
}
impl Drop for Memory {
fn drop(&mut self) {
if !self.ptr.is_null() {
let success = unsafe { libc::munmap(self.ptr as _, self.size) };
assert_eq!(success, 0, "failed to unmap memory: {}", errno::errno());
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[allow(dead_code)]
pub enum Protect {
None,
Read,
ReadWrite,
ReadExec,
}
impl Protect {
fn to_protect_const(self) -> u32 {
match self {
Protect::None => PAGE_NOACCESS,
Protect::Read => PAGE_READONLY,
Protect::ReadWrite => PAGE_READWRITE,
Protect::ReadExec => PAGE_EXECUTE_READ,
}
}
}
/// Round `size` up to the nearest multiple of `page_size`.
fn round_up_to_page_size(size: usize, page_size: usize) -> usize {
(size + (page_size - 1)) & !(page_size - 1)
}
/// Round `size` down to the nearest multiple of `page_size`.
fn round_down_to_page_size(size: usize, page_size: usize) -> usize {
size & !(page_size - 1)
}

View File

@ -0,0 +1 @@
pub use self::memory::{Memory, Protect};