Merge remote-tracking branch 'origin/master' into feature/unified-exceptions

This commit is contained in:
losfair
2020-01-21 01:10:40 +08:00
44 changed files with 552 additions and 290 deletions

View File

@ -76,9 +76,18 @@ impl Default for MemoryBoundCheckMode {
}
/// Controls which experimental features will be enabled.
/// Features usually have a corresponding [WebAssembly proposal][wasm-props].
///
/// [wasm-props]: https://github.com/WebAssembly/proposals
#[derive(Debug, Default)]
pub struct Features {
/// Whether support for the [SIMD proposal][simd-prop] is enabled.
///
/// [simd-prop]: https://github.com/webassembly/simd
pub simd: bool,
/// Whether support for the [threads proposal][threads-prop] is enabled.
///
/// [threads-prop]: https://github.com/webassembly/threads
pub threads: bool,
}

View File

@ -173,7 +173,7 @@ pub fn validate_and_report_errors_with_features(
}
}
/// Creates a new module from the given cache `Artifact` for the specified compiler backend
/// Creates a new module from the given cache [`Artifact`] for the specified compiler backend
pub unsafe fn load_cache_with(
cache: Artifact,
compiler: &dyn backend::Compiler,

View File

@ -627,9 +627,11 @@ pub mod x64 {
use crate::vm::Ctx;
use std::any::Any;
#[allow(clippy::cast_ptr_alignment)]
unsafe fn compute_vmctx_deref(vmctx: *const Ctx, seq: &[usize]) -> u64 {
let mut ptr = &vmctx as *const *const Ctx as *const u8;
for x in seq {
debug_assert!(ptr.align_offset(std::mem::align_of::<*const u8>()) == 0);
ptr = (*(ptr as *const *const u8)).offset(*x as isize);
}
ptr as usize as u64

View File

@ -1,85 +0,0 @@
#[derive(Debug, Clone)]
enum MonoVecInner<T> {
None,
Inline(T),
Heap(Vec<T>),
}
/// A type that can hold zero items,
/// one item, or many items.
#[derive(Debug, Clone)]
pub struct MonoVec<T> {
inner: MonoVecInner<T>,
}
impl<T> MonoVec<T> {
pub fn new() -> Self {
Self {
inner: MonoVecInner::None,
}
}
pub fn new_inline(item: T) -> Self {
Self {
inner: MonoVecInner::Inline(item),
}
}
pub fn with_capacity(capacity: usize) -> Self {
match capacity {
0 | 1 => Self::new(),
_ => Self {
inner: MonoVecInner::Heap(Vec::with_capacity(capacity)),
},
}
}
pub fn push(&mut self, item: T) {
let uninit = MonoVecInner::None;
let prev = mem::replace(&mut self.inner, uninit);
let next = match prev {
MonoVecInner::None => MonoVecInner::Inline(item),
MonoVecInner::Inline(previous_item) => MonoVecInner::Heap(vec![previous_item, item]),
MonoVecInner::Heap(mut v) => {
v.push(item);
MonoVecInner::Heap(v)
}
};
let uninit = mem::replace(&mut self.inner, next);
mem::forget(uninit);
}
pub fn pop(&mut self) -> Option<T> {
match self.inner {
MonoVecInner::None => None,
MonoVecInner::Inline(ref mut item) => {
let uninit = unsafe { mem::zeroed() };
let item = mem::replace(item, uninit);
let uninit = mem::replace(&mut self.inner, MonoVecInner::None);
mem::forget(uninit);
Some(item)
}
MonoVecInner::Heap(ref mut v) => v.pop(),
}
}
pub fn as_slice(&self) -> &[T] {
match self.inner {
MonoVecInner::None => unsafe {
slice::from_raw_parts(mem::align_of::<T>() as *const T, 0)
},
MonoVecInner::Inline(ref item) => slice::from_ref(item),
MonoVecInner::Heap(ref v) => &v[..],
}
}
pub fn as_slice_mut(&mut self) -> &mut [T] {
match self.inner {
MonoVecInner::None => unsafe {
slice::from_raw_parts_mut(mem::align_of::<T>() as *mut T, 0)
},
MonoVecInner::Inline(ref mut item) => slice::from_mut(item),
MonoVecInner::Heap(ref mut v) => &mut v[..],
}
}
}

View File

@ -1,4 +1,4 @@
//! The units module provides common WebAssembly units like `Pages` and conversion functions into
//! The units module provides common WebAssembly units like [`Pages`] and conversion functions into
//! other units.
use crate::error::PageError;
use std::{
@ -8,7 +8,7 @@ use std::{
/// The page size in bytes of a wasm page.
pub const WASM_PAGE_SIZE: usize = 65_536;
/// Tbe max number of wasm pages allowed.
/// The max number of wasm pages allowed.
pub const WASM_MAX_PAGES: usize = 65_536;
// From emscripten resize_heap implementation
/// The minimum number of wasm pages allowed.

View File

@ -54,11 +54,14 @@ pub struct Ctx {
/// This is intended to be user-supplied, per-instance
/// contextual data. There are currently some issue with it,
/// notably that it cannot be set before running the `start`
/// function in a WebAssembly module.
/// function in a WebAssembly module. Additionally, the `data`
/// field may be taken by another ABI implementation that the user
/// wishes to use in addition to their own, such as WASI. This issue is
/// being discussed at [#1111](https://github.com/wasmerio/wasmer/pull/1111).
///
/// [#219](https://github.com/wasmerio/wasmer/pull/219) fixes that
/// issue, as well as allowing the user to have *per-function*
/// context, instead of just per-instance.
/// Alternatively, per-function data can be used if the function in the
/// [`ImportObject`] is a closure. This cannot duplicate data though,
/// so if data may be shared if the [`ImportObject`] is reused.
pub data: *mut c_void,
/// If there's a function set in this field, it gets called
@ -567,6 +570,7 @@ pub struct FuncCtx {
impl FuncCtx {
/// Offset to the `vmctx` field.
#[allow(clippy::erasing_op)]
pub const fn offset_vmctx() -> u8 {
0 * (mem::size_of::<usize>() as u8)
}

View File

@ -1,3 +1,5 @@
//! Functions called from the generated code.
#![allow(clippy::cast_ptr_alignment)]
use crate::{
@ -12,6 +14,16 @@ use crate::{
// | LOCAL MEMORIES |
// +*****************************+
/// Increase the size of the static local memory with offset `memory_index` by
/// `delta` [`Pages`].
///
/// This function returns the number of pages before growing if successful, or
/// `-1` if the grow failed.
///
/// # Safety
///
/// The offset given by `memory_index` is not bounds-checked or typed-checked.
/// Thus, the offset should be in-bounds and point to a [`StaticMemory`].
pub unsafe extern "C" fn local_static_memory_grow(
ctx: &mut vm::Ctx,
memory_index: LocalMemoryIndex,
@ -31,16 +43,32 @@ pub unsafe extern "C" fn local_static_memory_grow(
ret
}
/// Get the size of a local [`StaticMemory`] in [`Pages`].
///
/// # Safety
///
/// The offset given by `memory_index` is not bounds-checked or typed-checked.
/// Thus, the offset should be in-bounds and point to a [`StaticMemory`].
pub unsafe extern "C" fn local_static_memory_size(
ctx: &vm::Ctx,
memory_index: LocalMemoryIndex,
) -> Pages {
let local_memory = *ctx.internal.memories.add(memory_index.index());
let memory = (*local_memory).memory as *mut StaticMemory;
let memory = (*local_memory).memory as *const StaticMemory;
(*memory).size()
}
/// Increase the size of the dynamic local memory with offset `memory_index` by
/// `delta` [`Pages`].
///
/// This function returns the number of pages before growing if successful, or
/// `-1` if the grow failed.
///
/// # Safety
///
/// The offset given by `memory_index` is not bounds-checked or typed-checked.
/// Thus, the offset should be in-bounds and point to a [`DynamicMemory`].
pub unsafe extern "C" fn local_dynamic_memory_grow(
ctx: &mut vm::Ctx,
memory_index: LocalMemoryIndex,
@ -60,12 +88,18 @@ pub unsafe extern "C" fn local_dynamic_memory_grow(
ret
}
/// Get the size of a local [`DynamicMemory`] in [`Pages`].
///
/// # Safety
///
/// The offset given by `memory_index` is not bounds-checked or typed-checked.
/// Thus, the offset should be in-bounds and point to a [`DynamicMemory`].
pub unsafe extern "C" fn local_dynamic_memory_size(
ctx: &vm::Ctx,
memory_index: LocalMemoryIndex,
) -> Pages {
let local_memory = *ctx.internal.memories.add(memory_index.index());
let memory = (*local_memory).memory as *mut DynamicMemory;
let memory = (*local_memory).memory as *const DynamicMemory;
(*memory).size()
}
@ -74,6 +108,16 @@ pub unsafe extern "C" fn local_dynamic_memory_size(
// | IMPORTED MEMORIES |
// +*****************************+
/// Increase the size of the static imported memory with offset `import_memory_index` by
/// `delta` [`Pages`].
///
/// This function returns the number of pages before growing if successful, or
/// `-1` if the grow failed.
///
/// # Safety
///
/// The offset given by `import_memory_index` is not bounds-checked or typed-checked.
/// Thus, the offset should be in-bounds and point to a [`StaticMemory`].
pub unsafe extern "C" fn imported_static_memory_grow(
ctx: &mut vm::Ctx,
import_memory_index: ImportedMemoryIndex,
@ -96,6 +140,12 @@ pub unsafe extern "C" fn imported_static_memory_grow(
ret
}
/// Get the size of an imported [`StaticMemory`] in [`Pages`].
///
/// # Safety
///
/// The offset given by `import_memory_index` is not bounds-checked or typed-checked.
/// Thus, the offset should be in-bounds and point to a [`StaticMemory`].
pub unsafe extern "C" fn imported_static_memory_size(
ctx: &vm::Ctx,
import_memory_index: ImportedMemoryIndex,
@ -104,11 +154,21 @@ pub unsafe extern "C" fn imported_static_memory_size(
.internal
.imported_memories
.add(import_memory_index.index());
let memory = (*local_memory).memory as *mut StaticMemory;
let memory = (*local_memory).memory as *const StaticMemory;
(*memory).size()
}
/// Increase the size of the dynamic imported memory with offset `memory_index` by
/// `delta` [`Pages`].
///
/// This function returns the number of pages before growing if successful, or
/// `-1` if the grow failed.
///
/// # Safety
///
/// The offset given by `memory_index` is not bounds-checked or typed-checked.
/// Thus, the offset should be in-bounds and point to a [`DynamicMemory`].
pub unsafe extern "C" fn imported_dynamic_memory_grow(
ctx: &mut vm::Ctx,
memory_index: ImportedMemoryIndex,
@ -128,12 +188,18 @@ pub unsafe extern "C" fn imported_dynamic_memory_grow(
ret
}
/// Get the size of an imported [`DynamicMemory`] in [`Pages`].
///
/// # Safety
///
/// The offset given by `memory_index` is not bounds-checked or typed-checked.
/// Thus, the offset should be in-bounds and point to a [`DynamicMemory`].
pub unsafe extern "C" fn imported_dynamic_memory_size(
ctx: &vm::Ctx,
memory_index: ImportedMemoryIndex,
) -> Pages {
let local_memory = *ctx.internal.imported_memories.add(memory_index.index());
let memory = (*local_memory).memory as *mut DynamicMemory;
let memory = (*local_memory).memory as *const DynamicMemory;
(*memory).size()
}