Merge branch 'master' into feature/multi-example-wasm-c-api

This commit is contained in:
Mark McCaskey
2020-12-18 12:42:45 -08:00
committed by GitHub
14 changed files with 317 additions and 223 deletions

View File

@@ -12,9 +12,13 @@
* [#1894](https://github.com/wasmerio/wasmer/pull/1894) Added exports `wasmer::{CraneliftOptLevel, LLVMOptLevel}` to allow using `Cranelift::opt_level` and `LLVM::opt_level` directly via the `wasmer` crate
### Changed
* [#1944](https://github.com/wasmerio/wasmer/pull/1944) Require `WasmerEnv` to be `Send + Sync` even in dynamic functions.
### Fixed
- [#1949](https://github.com/wasmerio/wasmer/pull/1949) `wasm_<type>_vec_delete` functions no longer crash when the given vector is uninitialized, in the Wasmer C API
- [#1949](https://github.com/wasmerio/wasmer/pull/1949) The `wasm_frame_vec_t`, `wasm_functype_vec_t`, `wasm_globaltype_vec_t`, `wasm_memorytype_vec_t`, and `wasm_tabletype_vec_t` are now boxed vectors in the Wasmer C API
## 1.0.0-beta2 - 2020-12-16
### Added

View File

@@ -229,10 +229,13 @@ test-packages:
cargo test -p wasmer-wasi --release
cargo test -p wasmer-object --release
cargo test -p wasmer-engine-native --release --no-default-features
cargo test -p wasmer-engine-jit --release --no-default-features
cargo test -p wasmer-compiler --release
cargo test -p wasmer-cli --release
cargo test -p wasmer-cache --release
cargo test -p wasmer-engine --release
# The test-capi rules depend on the build-capi rules to build the .a files to
# link the tests against. cargo test doesn't know that the tests will be running
test-capi: $(foreach compiler_engine,$(test_compilers_engines),test-capi-$(compiler_engine))
@@ -355,10 +358,26 @@ endif
update-testsuite:
git subtree pull --prefix tests/wast/spec https://github.com/WebAssembly/testsuite.git master --squash
RUSTFLAGS := "-D dead-code -D nonstandard-style -D unused-imports -D unused-mut -D unused-variables -D unused-unsafe -D unreachable-patterns -D bad-style -D improper-ctypes -D unused-allocation -D unused-comparisons -D while-true -D unconditional-recursion -D bare-trait-objects -D function_item_references" # TODO: add `-D missing-docs`
lint:
RUSTFLAGS := "-D dead-code -D nonstandard-style -D unused-imports -D unused-mut -D unused-variables -D unused-unsafe -D unreachable-patterns -D bad-style -D improper-ctypes -D unused-allocation -D unused-comparisons -D while-true -D unconditional-recursion -D bare-trait-objects" # TODO: add `-D missing-docs` # TODO: add `-D function_item_references` (not available on Rust 1.47, try when upgrading)
lint-packages:
RUSTFLAGS=${RUSTFLAGS} cargo clippy -p wasmer
RUSTFLAGS=${RUSTFLAGS} cargo clippy -p wasmer-vm
RUSTFLAGS=${RUSTFLAGS} cargo clippy -p wasmer-types
RUSTFLAGS=${RUSTFLAGS} cargo clippy -p wasmer-wasi
RUSTFLAGS=${RUSTFLAGS} cargo clippy -p wasmer-object
RUSTFLAGS=${RUSTFLAGS} cargo clippy -p wasmer-engine-native
RUSTFLAGS=${RUSTFLAGS} cargo clippy -p wasmer-engine-jit
RUSTFLAGS=${RUSTFLAGS} cargo clippy -p wasmer-compiler
RUSTFLAGS=${RUSTFLAGS} cargo clippy -p wasmer-compiler-cranelift
RUSTFLAGS=${RUSTFLAGS} cargo clippy -p wasmer-compiler-singlepass
RUSTFLAGS=${RUSTFLAGS} cargo clippy -p wasmer-cli
RUSTFLAGS=${RUSTFLAGS} cargo clippy -p wasmer-cache
RUSTFLAGS=${RUSTFLAGS} cargo clippy -p wasmer-engine
lint-formatting:
cargo fmt --all -- --check
RUSTFLAGS=${RUSTFLAGS} cargo clippy $(compiler_features)
lint: lint-formatting lint-packages
install-local: package
tar -C ~/.wasmer -zxvf wasmer.tar.gz

View File

@@ -67,6 +67,49 @@ pub struct Function {
pub(crate) exported: ExportFunction,
}
fn build_export_function_metadata<Env>(
env: Env,
import_init_function_ptr: for<'a> fn(
&'a mut Env,
&'a crate::Instance,
) -> Result<(), crate::HostEnvInitError>,
) -> (*mut std::ffi::c_void, ExportFunctionMetadata)
where
Env: Clone + Sized + 'static + Send + Sync,
{
let import_init_function_ptr = Some(unsafe {
std::mem::transmute::<fn(_, _) -> Result<(), _>, fn(_, _) -> Result<(), _>>(
import_init_function_ptr,
)
});
let host_env_clone_fn: fn(*mut std::ffi::c_void) -> *mut std::ffi::c_void = |ptr| {
let env_ref: &Env = unsafe {
ptr.cast::<Env>()
.as_ref()
.expect("`ptr` to the environment is null when cloning it")
};
Box::into_raw(Box::new(env_ref.clone())) as _
};
let host_env_drop_fn: fn(*mut std::ffi::c_void) = |ptr| {
unsafe { Box::from_raw(ptr.cast::<Env>()) };
};
let env = Box::into_raw(Box::new(env)) as _;
// # Safety
// - All these functions work on all threads
// - The host env is `Send`.
let metadata = unsafe {
ExportFunctionMetadata::new(
env,
import_init_function_ptr,
host_env_clone_fn,
host_env_drop_fn,
)
};
(env, metadata)
}
impl Function {
/// Creates a new host `Function` (dynamic) with the provided signature.
///
@@ -104,7 +147,7 @@ impl Function {
pub fn new<FT, F>(store: &Store, ty: FT, func: F) -> Self
where
FT: Into<FunctionType>,
F: Fn(&[Val]) -> Result<Vec<Val>, RuntimeError> + 'static,
F: Fn(&[Val]) -> Result<Vec<Val>, RuntimeError> + 'static + Send + Sync,
{
let ty: FunctionType = ty.into();
let dynamic_ctx: VMDynamicFunctionContext<DynamicFunctionWithoutEnv> =
@@ -209,7 +252,7 @@ impl Function {
pub fn new_with_env<FT, F, Env>(store: &Store, ty: FT, env: Env, func: F) -> Self
where
FT: Into<FunctionType>,
F: Fn(&Env, &[Val]) -> Result<Vec<Val>, RuntimeError> + 'static,
F: Fn(&Env, &[Val]) -> Result<Vec<Val>, RuntimeError> + 'static + Send + Sync,
Env: Sized + WasmerEnv + 'static,
{
let ty: FunctionType = ty.into();
@@ -220,58 +263,27 @@ impl Function {
function_type: ty.clone(),
});
let import_init_function_ptr: for<'a> fn(&'a mut _, &'a _) -> Result<(), _> =
|env: &mut VMDynamicFunctionContext<DynamicFunctionWithEnv<Env>>,
instance: &crate::Instance| {
Env::init_with_instance(&mut *env.ctx.env, instance)
};
let (host_env, metadata) = build_export_function_metadata::<
VMDynamicFunctionContext<DynamicFunctionWithEnv<Env>>,
>(dynamic_ctx, import_init_function_ptr);
// We don't yet have the address with the Wasm ABI signature.
// The engine linker will replace the address with one pointing to a
// generated dynamic trampoline.
let address = std::ptr::null() as *const VMFunctionBody;
let host_env = Box::into_raw(Box::new(dynamic_ctx)) as *mut _;
let vmctx = VMFunctionEnvironment { host_env };
let import_init_function_ptr: fn(_, _) -> Result<(), _> =
|ptr: *mut std::ffi::c_void, instance: *const std::ffi::c_void| {
let ptr = ptr as *mut VMDynamicFunctionContext<DynamicFunctionWithEnv<Env>>;
unsafe {
let env = &mut *ptr;
let env: &mut Env = &mut *env.ctx.env;
let instance = &*(instance as *const crate::Instance);
Env::init_with_instance(env, instance)
}
};
let import_init_function_ptr = Some(unsafe {
std::mem::transmute::<fn(_, _) -> Result<(), _>, fn(_, _) -> Result<(), _>>(
import_init_function_ptr,
)
});
let host_env_clone_fn: fn(*mut std::ffi::c_void) -> *mut std::ffi::c_void = |ptr| {
let duped_env: VMDynamicFunctionContext<DynamicFunctionWithEnv<Env>> = unsafe {
let ptr: *mut VMDynamicFunctionContext<DynamicFunctionWithEnv<Env>> = ptr as _;
let item: &VMDynamicFunctionContext<DynamicFunctionWithEnv<Env>> = &*ptr;
item.clone()
};
Box::into_raw(Box::new(duped_env)) as _
};
let host_env_drop_fn: fn(*mut std::ffi::c_void) = |ptr: *mut std::ffi::c_void| {
unsafe {
Box::from_raw(ptr as *mut VMDynamicFunctionContext<DynamicFunctionWithEnv<Env>>)
};
};
Self {
store: store.clone(),
definition: FunctionDefinition::Host(HostFunctionDefinition { has_env: true }),
exported: ExportFunction {
metadata: Some(Arc::new(
// # Safety
// - All these functions work on all threads
// - The host env is `Send`.
unsafe {
ExportFunctionMetadata::new(
host_env,
import_init_function_ptr,
host_env_clone_fn,
host_env_drop_fn,
)
},
)),
metadata: Some(Arc::new(metadata)),
vm_function: VMExportFunction {
address,
kind: VMFunctionKind::Dynamic,
@@ -374,50 +386,17 @@ impl Function {
let function = inner::Function::<Args, Rets>::new(func);
let address = function.address();
// TODO: We need to refactor the Function context.
// Right now is structured as it's always a `VMContext`. However, only
// Wasm-defined functions have a `VMContext`.
// In the case of Host-defined functions `VMContext` is whatever environment
// the user want to attach to the function.
let host_env = Box::into_raw(Box::new(env)) as *mut _;
let vmctx = VMFunctionEnvironment { host_env };
let host_env_clone_fn: fn(*mut std::ffi::c_void) -> *mut std::ffi::c_void = |ptr| {
let duped_env = unsafe {
let ptr: *mut Env = ptr as _;
let item: &Env = &*ptr;
item.clone()
};
Box::into_raw(Box::new(duped_env)) as _
};
let host_env_drop_fn: fn(*mut std::ffi::c_void) = |ptr: *mut std::ffi::c_void| {
unsafe { Box::from_raw(ptr as *mut Env) };
};
let (host_env, metadata) =
build_export_function_metadata::<Env>(env, Env::init_with_instance);
// TODO: look into removing transmute by changing API type signatures
let import_init_function_ptr = Some(unsafe {
std::mem::transmute::<fn(_, _) -> Result<(), _>, fn(_, _) -> Result<(), _>>(
Env::init_with_instance,
)
});
let vmctx = VMFunctionEnvironment { host_env };
let signature = function.ty();
Self {
store: store.clone(),
definition: FunctionDefinition::Host(HostFunctionDefinition { has_env: true }),
exported: ExportFunction {
metadata: Some(Arc::new(
// # Safety
// - All these functions work on all threads
// - The host env is `Send`.
unsafe {
ExportFunctionMetadata::new(
host_env,
import_init_function_ptr,
host_env_clone_fn,
host_env_drop_fn,
)
},
)),
metadata: Some(Arc::new(metadata)),
vm_function: VMExportFunction {
address,
kind: VMFunctionKind::Static,
@@ -455,43 +434,17 @@ impl Function {
let function = inner::Function::<Args, Rets>::new(func);
let address = function.address();
let box_env = Box::new(env);
let host_env = Box::into_raw(box_env) as *mut _;
let vmctx = VMFunctionEnvironment { host_env };
let host_env_clone_fn: fn(*mut std::ffi::c_void) -> *mut std::ffi::c_void = |ptr| {
let duped_env: Env = {
let ptr: *mut Env = ptr as _;
let item: &Env = &*ptr;
item.clone()
};
Box::into_raw(Box::new(duped_env)) as _
};
let host_env_drop_fn: fn(*mut std::ffi::c_void) = |ptr: *mut std::ffi::c_void| {
Box::from_raw(ptr as *mut Env);
};
let (host_env, metadata) =
build_export_function_metadata::<Env>(env, Env::init_with_instance);
let vmctx = VMFunctionEnvironment { host_env };
let signature = function.ty();
// TODO: look into removing transmute by changing API type signatures
let import_init_function_ptr = Some(std::mem::transmute::<
fn(_, _) -> Result<(), _>,
fn(_, _) -> Result<(), _>,
>(Env::init_with_instance));
Self {
store: store.clone(),
definition: FunctionDefinition::Host(HostFunctionDefinition { has_env: true }),
exported: ExportFunction {
metadata: Some(Arc::new(
// # Safety
// - All these functions work on all threads
// - The host env is `Send`.
ExportFunctionMetadata::new(
host_env,
import_init_function_ptr,
host_env_clone_fn,
host_env_drop_fn,
),
)),
metadata: Some(Arc::new(metadata)),
vm_function: VMExportFunction {
address,
kind: VMFunctionKind::Static,
@@ -855,7 +808,7 @@ impl fmt::Debug for Function {
}
/// This trait is one that all dynamic functions must fulfill.
pub(crate) trait VMDynamicFunction {
pub(crate) trait VMDynamicFunction: Send + Sync {
fn call(&self, args: &[Val]) -> Result<Vec<Val>, RuntimeError>;
fn function_type(&self) -> &FunctionType;
}
@@ -863,7 +816,7 @@ pub(crate) trait VMDynamicFunction {
#[derive(Clone)]
pub(crate) struct DynamicFunctionWithoutEnv {
#[allow(clippy::type_complexity)]
func: Arc<dyn Fn(&[Val]) -> Result<Vec<Val>, RuntimeError> + 'static>,
func: Arc<dyn Fn(&[Val]) -> Result<Vec<Val>, RuntimeError> + 'static + Send + Sync>,
function_type: FunctionType,
}
@@ -878,15 +831,15 @@ impl VMDynamicFunction for DynamicFunctionWithoutEnv {
pub(crate) struct DynamicFunctionWithEnv<Env>
where
Env: Sized + 'static,
Env: Sized + 'static + Send + Sync,
{
function_type: FunctionType,
#[allow(clippy::type_complexity)]
func: Arc<dyn Fn(&Env, &[Val]) -> Result<Vec<Val>, RuntimeError> + 'static>,
func: Arc<dyn Fn(&Env, &[Val]) -> Result<Vec<Val>, RuntimeError> + 'static + Send + Sync>,
env: Box<Env>,
}
impl<Env: Sized + Clone + 'static> Clone for DynamicFunctionWithEnv<Env> {
impl<Env: Sized + Clone + 'static + Send + Sync> Clone for DynamicFunctionWithEnv<Env> {
fn clone(&self) -> Self {
Self {
env: self.env.clone(),
@@ -898,7 +851,7 @@ impl<Env: Sized + Clone + 'static> Clone for DynamicFunctionWithEnv<Env> {
impl<Env> VMDynamicFunction for DynamicFunctionWithEnv<Env>
where
Env: Sized + 'static,
Env: Sized + 'static + Send + Sync,
{
fn call(&self, args: &[Val]) -> Result<Vec<Val>, RuntimeError> {
(*self.func)(&*self.env, &args)

View File

@@ -3,8 +3,31 @@
macro_rules! wasm_declare_vec_inner {
($name:ident) => {
paste::paste! {
/// Creates an empty vector of
#[doc = "Creates an empty vector of [`wasm_" $name "_t`]."]
#[doc = "Creates an empty vector of [`wasm_" $name "_t`].
# Example
```rust
# use inline_c::assert_c;
# fn main() {
# (assert_c! {
# #include \"tests/wasmer_wasm.h\"
#
int main() {
// Creates an empty vector of `wasm_" $name "_t`.
wasm_" $name "_vec_t vector;
wasm_" $name "_vec_new_empty(&vector);
// Check that it is empty.
assert(vector.size == 0);
// Free it.
wasm_" $name "_vec_delete(&vector);
}
# })
# .success();
# }
```"]
#[no_mangle]
pub unsafe extern "C" fn [<wasm_ $name _vec_new_empty>](out: *mut [<wasm_ $name _vec_t>]) {
// TODO: actually implement this
@@ -19,7 +42,37 @@ macro_rules! wasm_declare_vec_inner {
macro_rules! wasm_declare_vec {
($name:ident) => {
paste::paste! {
#[doc = "Represents of a vector of [`wasm_" $name "_t`]."]
#[doc = "Represents a vector of `wasm_" $name "_t`.
Read the documentation of [`wasm_" $name "_t`] to see more concrete examples.
# Example
```rust
# use inline_c::assert_c;
# fn main() {
# (assert_c! {
# #include \"tests/wasmer_wasm.h\"
#
int main() {
// Create a vector of 2 `wasm_" $name "_t`.
wasm_" $name "_t x;
wasm_" $name "_t y;
wasm_" $name "_t* items[2] = {&x, &y};
wasm_" $name "_vec_t vector;
wasm_" $name "_vec_new(&vector, 2, (wasm_" $name "_t*) items);
// Check that it contains 2 items.
assert(vector.size == 2);
// Free it.
wasm_" $name "_vec_delete(&vector);
}
# })
# .success();
# }
```"]
#[derive(Debug)]
#[repr(C)]
pub struct [<wasm_ $name _vec_t>] {
@@ -81,6 +134,7 @@ macro_rules! wasm_declare_vec {
.into_boxed_slice();
let data = copied_data.as_mut_ptr();
::std::mem::forget(copied_data);
Self {
size,
data,
@@ -111,27 +165,60 @@ macro_rules! wasm_declare_vec {
}
// TODO: investigate possible memory leak on `init` (owned pointer)
#[doc = "Creates a new vector of [`wasm_" $name "_t`]."]
#[doc = "Creates a new vector of [`wasm_" $name "_t`].
# Example
See the [`wasm_" $name "_vec_t`] type to get an example."]
#[no_mangle]
pub unsafe extern "C" fn [<wasm_ $name _vec_new>](out: *mut [<wasm_ $name _vec_t>], length: usize, init: *mut [<wasm_ $name _t>]) {
let mut bytes: Vec<[<wasm_ $name _t>]> = Vec::with_capacity(length);
for i in 0..length {
bytes.push(::std::ptr::read(init.add(i)));
}
let pointer = bytes.as_mut_ptr();
debug_assert!(bytes.len() == bytes.capacity());
(*out).data = pointer;
(*out).size = length;
::std::mem::forget(bytes);
}
#[doc = "Creates a new uninitialized vector of [`wasm_" $name "_t`]."]
#[doc = "Creates a new uninitialized vector of [`wasm_" $name "_t`].
# Example
```rust
# use inline_c::assert_c;
# fn main() {
# (assert_c! {
# #include \"tests/wasmer_wasm.h\"
#
int main() {
// Creates an empty vector of `wasm_" $name "_t`.
wasm_" $name "_vec_t vector;
wasm_" $name "_vec_new_uninitialized(&vector, 3);
// Check that it contains 3 items.
assert(vector.size == 3);
// Free it.
wasm_" $name "_vec_delete(&vector);
}
# })
# .success();
# }
```"]
#[no_mangle]
pub unsafe extern "C" fn [<wasm_ $name _vec_new_uninitialized>](out: *mut [<wasm_ $name _vec_t>], length: usize) {
let mut bytes: Vec<[<wasm_ $name _t>]> = Vec::with_capacity(length);
let pointer = bytes.as_mut_ptr();
(*out).data = pointer;
(*out).size = length;
::std::mem::forget(bytes);
}
@@ -144,7 +231,11 @@ macro_rules! wasm_declare_vec {
*out_ptr = in_ptr.clone();
}
#[doc = "Deletes a vector of [`wasm_" $name "_t`]."]
#[doc = "Deletes a vector of [`wasm_" $name "_t`].
# Example
See the [`wasm_" $name "_vec_t`] type to get an example."]
#[no_mangle]
pub unsafe extern "C" fn [<wasm_ $name _vec_delete>](ptr: Option<&mut [<wasm_ $name _vec_t>]>) {
if let Some(vec) = ptr {
@@ -166,7 +257,9 @@ macro_rules! wasm_declare_vec {
macro_rules! wasm_declare_boxed_vec {
($name:ident) => {
paste::paste! {
#[doc = "Represents of a vector of [`wasm_" $name "_t`]."]
#[doc = "Represents a vector of `wasm_" $name "_t`.
Read the documentation of [`wasm_" $name "_t`] to see more concrete examples."]
#[derive(Debug)]
#[repr(C)]
pub struct [<wasm_ $name _vec_t>] {
@@ -217,6 +310,27 @@ macro_rules! wasm_declare_boxed_vec {
}
}
impl<'a, T: Into<[<wasm_ $name _t>]> + Clone> From<&'a [T]> for [<wasm_ $name _vec_t>] {
fn from(other: &'a [T]) -> Self {
let size = other.len();
let mut copied_data = other
.iter()
.cloned()
.map(Into::into)
.map(Box::new)
.map(Box::into_raw)
.collect::<Vec<*mut [<wasm_ $name _t>]>>()
.into_boxed_slice();
let data = copied_data.as_mut_ptr();
::std::mem::forget(copied_data);
Self {
size,
data,
}
}
}
// TODO: do this properly
impl [<wasm_ $name _vec_t>] {
pub unsafe fn into_slice(&self) -> Option<&[Box<[<wasm_ $name _t>]>]>{
@@ -235,23 +349,53 @@ macro_rules! wasm_declare_boxed_vec {
#[no_mangle]
pub unsafe extern "C" fn [<wasm_ $name _vec_new>](out: *mut [<wasm_ $name _vec_t>], length: usize, init: *const *mut [<wasm_ $name _t>]) {
let mut bytes: Vec<*mut [<wasm_ $name _t>]> = Vec::with_capacity(length);
for i in 0..length {
bytes.push(*init.add(i));
}
let mut boxed_vec = bytes.into_boxed_slice();
let pointer = boxed_vec.as_mut_ptr();
(*out).data = pointer;
(*out).size = length;
::std::mem::forget(boxed_vec);
}
#[doc = "Creates a new uninitialized vector of [`wasm_" $name "_t`]."]
#[doc = "Creates a new uninitialized vector of [`wasm_" $name "_t`].
# Example
```rust
# use inline_c::assert_c;
# fn main() {
# (assert_c! {
# #include \"tests/wasmer_wasm.h\"
#
int main() {
// Creates an empty vector of `wasm_" $name "_t`.
wasm_" $name "_vec_t vector;
wasm_" $name "_vec_new_uninitialized(&vector, 3);
// Check that it contains 3 items.
assert(vector.size == 3);
// Free it.
wasm_" $name "_vec_delete(&vector);
}
# })
# .success();
# }
```"]
#[no_mangle]
pub unsafe extern "C" fn [<wasm_ $name _vec_new_uninitialized>](out: *mut [<wasm_ $name _vec_t>], length: usize) {
let mut bytes: Vec<*mut [<wasm_ $name _t>]> = Vec::with_capacity(length);
let mut bytes: Vec<*mut [<wasm_ $name _t>]> = vec![::std::ptr::null_mut(); length];
let pointer = bytes.as_mut_ptr();
(*out).data = pointer;
(*out).size = length;
::std::mem::forget(bytes);
}
@@ -264,11 +408,14 @@ macro_rules! wasm_declare_boxed_vec {
*out_ptr = in_ptr.clone();
}
#[doc = "Deletes a vector of [`wasm_" $name "_t`].
#[doc = "Deletes a vector of [`wasm_" $name "_t`]."]
# Example
See the [`wasm_" $name "_vec_t`] type to get an example."]
#[no_mangle]
pub unsafe extern "C" fn [<wasm_ $name _vec_delete>](ptr: Option<&mut[<wasm_ $name _vec_t>]>) {
if let Some(vec) = ptr {
pub unsafe extern "C" fn [<wasm_ $name _vec_delete>](ptr: Option<&mut [<wasm_ $name _vec_t>]>) {
if let Some(vec) = ptr {
if !vec.data.is_null() {
let ptr: *mut Option<Box<[<wasm_ $name _t>]>> = vec.data as _;
let data: Vec<Option<Box<[<wasm_ $name _t>]>>> = Vec::from_raw_parts(ptr, vec.size, vec.size);
@@ -298,7 +445,6 @@ macro_rules! wasm_declare_ref_base {
}
// TODO: finish this...
}
};
}

View File

@@ -48,4 +48,4 @@ pub unsafe extern "C" fn wasm_frame_module_offset(frame: &wasm_frame_t) -> usize
frame.info.module_offset()
}
wasm_declare_vec!(frame);
wasm_declare_boxed_vec!(frame);

View File

@@ -1,7 +1,4 @@
use super::{
wasm_externtype_t, wasm_valtype_t, wasm_valtype_vec_delete, wasm_valtype_vec_t, WasmExternType,
};
use std::mem;
use super::{wasm_externtype_t, wasm_valtype_vec_delete, wasm_valtype_vec_t, WasmExternType};
use wasmer::{ExternType, FunctionType, ValType};
#[derive(Debug)]
@@ -13,44 +10,8 @@ pub(crate) struct WasmFunctionType {
impl WasmFunctionType {
pub(crate) fn new(function_type: FunctionType) -> Self {
let params = {
let mut valtypes = function_type
.params()
.iter()
.cloned()
.map(Into::into)
.map(Box::new)
.map(Box::into_raw)
.collect::<Vec<*mut wasm_valtype_t>>();
let valtypes_vec = Box::new(wasm_valtype_vec_t {
size: valtypes.len(),
data: valtypes.as_mut_ptr(),
});
mem::forget(valtypes);
valtypes_vec
};
let results = {
let mut valtypes = function_type
.results()
.iter()
.cloned()
.map(Into::into)
.map(Box::new)
.map(Box::into_raw)
.collect::<Vec<*mut wasm_valtype_t>>();
let valtypes_vec = Box::new(wasm_valtype_vec_t {
size: valtypes.len(),
data: valtypes.as_mut_ptr(),
});
mem::forget(valtypes);
valtypes_vec
};
let params: Box<wasm_valtype_vec_t> = Box::new(function_type.params().into());
let results: Box<wasm_valtype_vec_t> = Box::new(function_type.results().into());
Self {
function_type,
@@ -90,12 +51,12 @@ impl wasm_functype_t {
}
}
wasm_declare_vec!(functype);
wasm_declare_boxed_vec!(functype);
#[no_mangle]
pub unsafe extern "C" fn wasm_functype_new(
params: Option<Box<wasm_valtype_vec_t>>,
results: Option<Box<wasm_valtype_vec_t>>,
params: Option<&mut wasm_valtype_vec_t>,
results: Option<&mut wasm_valtype_vec_t>,
) -> Option<Box<wasm_functype_t>> {
let params = params?;
let results = results?;
@@ -111,8 +72,8 @@ pub unsafe extern "C" fn wasm_functype_new(
.map(|val| val.as_ref().into())
.collect::<Vec<_>>();
wasm_valtype_vec_delete(Some(&mut *Box::into_raw(params)));
wasm_valtype_vec_delete(Some(&mut *Box::into_raw(results)));
wasm_valtype_vec_delete(Some(params));
wasm_valtype_vec_delete(Some(results));
Some(Box::new(wasm_functype_t::new(FunctionType::new(
params_as_valtype,

View File

@@ -46,7 +46,7 @@ impl wasm_globaltype_t {
}
}
wasm_declare_vec!(globaltype);
wasm_declare_boxed_vec!(globaltype);
#[no_mangle]
pub unsafe extern "C" fn wasm_globaltype_new(

View File

@@ -48,7 +48,7 @@ impl wasm_memorytype_t {
}
}
wasm_declare_vec!(memorytype);
wasm_declare_boxed_vec!(memorytype);
#[no_mangle]
pub unsafe extern "C" fn wasm_memorytype_new(limits: &wasm_limits_t) -> Box<wasm_memorytype_t> {

View File

@@ -53,7 +53,7 @@ impl wasm_tabletype_t {
}
}
wasm_declare_vec!(tabletype);
wasm_declare_boxed_vec!(tabletype);
#[no_mangle]
pub unsafe extern "C" fn wasm_tabletype_new(

View File

@@ -216,15 +216,15 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
// destination block following the whole `if...end`. If we do end
// up discovering an `else`, then we will allocate a block for it
// and go back and patch the jump.
let destination = block_with_params(builder, results.clone(), environ)?;
let destination = block_with_params(builder, results, environ)?;
let branch_inst =
canonicalise_then_brz(builder, val, destination, state.peekn(params.len()));
(destination, ElseData::NoElse { branch_inst })
} else {
// The `if` type signature is not valid without an `else` block,
// so we eagerly allocate the `else` block here.
let destination = block_with_params(builder, results.clone(), environ)?;
let else_block = block_with_params(builder, params.clone(), environ)?;
let destination = block_with_params(builder, results, environ)?;
let else_block = block_with_params(builder, params, environ)?;
canonicalise_then_brz(builder, val, else_block, state.peekn(params.len()));
builder.seal_block(else_block);
(destination, ElseData::WithElse { else_block })
@@ -271,8 +271,7 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
let (params, _results) =
module_translation_state.blocktype_params_results(blocktype)?;
debug_assert_eq!(params.len(), num_return_values);
let else_block =
block_with_params(builder, params.clone(), environ)?;
let else_block = block_with_params(builder, params, environ)?;
canonicalise_then_jump(
builder,
destination,

View File

@@ -1158,7 +1158,7 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
[[package]]
name = "wasmer"
version = "1.0.0-beta1"
version = "1.0.0-beta2"
dependencies = [
"cfg-if 0.1.10",
"indexmap",
@@ -1181,7 +1181,7 @@ dependencies = [
[[package]]
name = "wasmer-cache"
version = "1.0.0-beta1"
version = "1.0.0-beta2"
dependencies = [
"blake3",
"hex",
@@ -1191,7 +1191,7 @@ dependencies = [
[[package]]
name = "wasmer-compiler"
version = "1.0.0-beta1"
version = "1.0.0-beta2"
dependencies = [
"enumset",
"raw-cpuid",
@@ -1207,7 +1207,7 @@ dependencies = [
[[package]]
name = "wasmer-compiler-cranelift"
version = "1.0.0-beta1"
version = "1.0.0-beta2"
dependencies = [
"cranelift-codegen",
"cranelift-frontend",
@@ -1224,7 +1224,7 @@ dependencies = [
[[package]]
name = "wasmer-compiler-llvm"
version = "1.0.0-beta1"
version = "1.0.0-beta2"
dependencies = [
"byteorder",
"cc",
@@ -1246,7 +1246,7 @@ dependencies = [
[[package]]
name = "wasmer-compiler-singlepass"
version = "1.0.0-beta1"
version = "1.0.0-beta2"
dependencies = [
"byteorder",
"dynasm",
@@ -1263,7 +1263,7 @@ dependencies = [
[[package]]
name = "wasmer-derive"
version = "1.0.0-beta1"
version = "1.0.0-beta2"
dependencies = [
"proc-macro-error",
"proc-macro2",
@@ -1273,7 +1273,7 @@ dependencies = [
[[package]]
name = "wasmer-engine"
version = "1.0.0-beta1"
version = "1.0.0-beta2"
dependencies = [
"backtrace",
"bincode",
@@ -1292,7 +1292,7 @@ dependencies = [
[[package]]
name = "wasmer-engine-jit"
version = "1.0.0-beta1"
version = "1.0.0-beta2"
dependencies = [
"bincode",
"cfg-if 0.1.10",
@@ -1308,7 +1308,7 @@ dependencies = [
[[package]]
name = "wasmer-engine-native"
version = "1.0.0-beta1"
version = "1.0.0-beta2"
dependencies = [
"bincode",
"cfg-if 0.1.10",
@@ -1327,7 +1327,7 @@ dependencies = [
[[package]]
name = "wasmer-object"
version = "1.0.0-beta1"
version = "1.0.0-beta2"
dependencies = [
"object 0.22.0",
"thiserror",
@@ -1355,7 +1355,7 @@ dependencies = [
[[package]]
name = "wasmer-types"
version = "1.0.0-beta1"
version = "1.0.0-beta2"
dependencies = [
"cranelift-entity",
"serde",
@@ -1364,7 +1364,7 @@ dependencies = [
[[package]]
name = "wasmer-vm"
version = "1.0.0-beta1"
version = "1.0.0-beta2"
dependencies = [
"backtrace",
"cc",

View File

@@ -10,10 +10,10 @@ use crate::{
};
use new::wasmer::Export;
use std::{
cell::RefCell,
collections::HashMap,
convert::{AsRef, Infallible},
ptr,
sync::{Arc, Mutex},
};
pub use new::wasmer_types::{DataInitializer, ExportIndex, TableInitializer};
@@ -126,20 +126,22 @@ impl Module {
// is the same!
struct VMDynamicFunctionWithEnv<Env>
where
Env: Sized + 'static,
Env: Sized + 'static + Send + Sync,
{
#[allow(unused)]
function_type: FuncSig,
#[allow(unused)]
func: Box<
func: Arc<
dyn Fn(
&mut Env,
&[Value],
)
-> Result<Vec<Value>, RuntimeError>
+ 'static,
+ 'static
+ Send
+ Sync,
>,
env: RefCell<Env>,
env: Box<Mutex<Env>>,
}
// Get back the `vmctx` as it is
@@ -154,7 +156,10 @@ impl Module {
};
// Replace the environment by ours.
vmctx.ctx.env.borrow_mut().vmctx = pre_instance.vmctx();
{
let mut guard = vmctx.ctx.env.lock().unwrap();
guard.vmctx = pre_instance.vmctx();
}
// … without anyone noticing…
function.vm_function.vmctx.host_env = Box::into_raw(vmctx) as _;

View File

@@ -1158,7 +1158,7 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
[[package]]
name = "wasmer"
version = "1.0.0-beta1"
version = "1.0.0-beta2"
dependencies = [
"cfg-if 0.1.10",
"indexmap",
@@ -1181,7 +1181,7 @@ dependencies = [
[[package]]
name = "wasmer-cache"
version = "1.0.0-beta1"
version = "1.0.0-beta2"
dependencies = [
"blake3",
"hex",
@@ -1191,7 +1191,7 @@ dependencies = [
[[package]]
name = "wasmer-compiler"
version = "1.0.0-beta1"
version = "1.0.0-beta2"
dependencies = [
"enumset",
"raw-cpuid",
@@ -1207,7 +1207,7 @@ dependencies = [
[[package]]
name = "wasmer-compiler-cranelift"
version = "1.0.0-beta1"
version = "1.0.0-beta2"
dependencies = [
"cranelift-codegen",
"cranelift-frontend",
@@ -1224,7 +1224,7 @@ dependencies = [
[[package]]
name = "wasmer-compiler-llvm"
version = "1.0.0-beta1"
version = "1.0.0-beta2"
dependencies = [
"byteorder",
"cc",
@@ -1246,7 +1246,7 @@ dependencies = [
[[package]]
name = "wasmer-compiler-singlepass"
version = "1.0.0-beta1"
version = "1.0.0-beta2"
dependencies = [
"byteorder",
"dynasm",
@@ -1263,7 +1263,7 @@ dependencies = [
[[package]]
name = "wasmer-derive"
version = "1.0.0-beta1"
version = "1.0.0-beta2"
dependencies = [
"proc-macro-error",
"proc-macro2",
@@ -1273,7 +1273,7 @@ dependencies = [
[[package]]
name = "wasmer-engine"
version = "1.0.0-beta1"
version = "1.0.0-beta2"
dependencies = [
"backtrace",
"bincode",
@@ -1292,7 +1292,7 @@ dependencies = [
[[package]]
name = "wasmer-engine-jit"
version = "1.0.0-beta1"
version = "1.0.0-beta2"
dependencies = [
"bincode",
"cfg-if 0.1.10",
@@ -1308,7 +1308,7 @@ dependencies = [
[[package]]
name = "wasmer-engine-native"
version = "1.0.0-beta1"
version = "1.0.0-beta2"
dependencies = [
"bincode",
"cfg-if 0.1.10",
@@ -1327,7 +1327,7 @@ dependencies = [
[[package]]
name = "wasmer-object"
version = "1.0.0-beta1"
version = "1.0.0-beta2"
dependencies = [
"object 0.22.0",
"thiserror",
@@ -1362,7 +1362,7 @@ dependencies = [
[[package]]
name = "wasmer-types"
version = "1.0.0-beta1"
version = "1.0.0-beta2"
dependencies = [
"cranelift-entity",
"serde",
@@ -1371,7 +1371,7 @@ dependencies = [
[[package]]
name = "wasmer-vm"
version = "1.0.0-beta1"
version = "1.0.0-beta2"
dependencies = [
"backtrace",
"cc",

View File

@@ -95,7 +95,7 @@ mod test_vmfunction_import {
/// containing the relevant context for running the function indicated
/// in `address`.
#[repr(C)]
pub struct VMDynamicFunctionContext<T: Sized> {
pub struct VMDynamicFunctionContext<T: Sized + Send + Sync> {
/// The address of the inner dynamic function.
///
/// Note: The function must be on the form of
@@ -106,7 +106,14 @@ pub struct VMDynamicFunctionContext<T: Sized> {
pub ctx: T,
}
impl<T: Sized + Clone> Clone for VMDynamicFunctionContext<T> {
// The `ctx` itself must be `Send`, `address` can be passed between
// threads because all usage is `unsafe` and synchronized.
unsafe impl<T: Sized + Send + Sync> Send for VMDynamicFunctionContext<T> {}
// The `ctx` itself must be `Sync`, `address` can be shared between
// threads because all usage is `unsafe` and synchronized.
unsafe impl<T: Sized + Send + Sync> Sync for VMDynamicFunctionContext<T> {}
impl<T: Sized + Clone + Send + Sync> Clone for VMDynamicFunctionContext<T> {
fn clone(&self) -> Self {
Self {
address: self.address,