Skip to content

Commit

Permalink
Merge branch 'master' into metering-manager
Browse files Browse the repository at this point in the history
  • Loading branch information
syrusakbary authored Dec 20, 2020
2 parents 44fb48e + d966208 commit 8b6c7e5
Show file tree
Hide file tree
Showing 29 changed files with 371 additions and 267 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,7 @@ jobs:
override: true
components: rustfmt, clippy
- run: make lint
- name: Assert no files have changed
run: |
git status
! [[ $(git status -s) ]]
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,15 @@

### Changed

- [#1941](https://github.com/wasmerio/wasmer/pull/1941) Turn `get_remaining_points`/`set_remaining_points` of the `Metering` middleware into free functions to allow using them in an ahead-of-time compilation setup
* [#1941](https://github.com/wasmerio/wasmer/pull/1941) Turn `get_remaining_points`/`set_remaining_points` of the `Metering` middleware into free functions to allow using them in an ahead-of-time compilation setup
* [#1955](https://github.com/wasmerio/wasmer/pull/1955) Set `jit` as a default feature of the `wasmer-wasm-c-api` crate
* [#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
Expand Down
26 changes: 23 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down Expand Up @@ -355,10 +358,27 @@ 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-c-api
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
Expand Down
187 changes: 70 additions & 117 deletions lib/api/src/externals/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
///
Expand Down Expand Up @@ -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> =
Expand Down Expand Up @@ -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();
Expand All @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -855,15 +808,15 @@ 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;
}

#[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,
}

Expand All @@ -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(),
Expand All @@ -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)
Expand Down
5 changes: 2 additions & 3 deletions lib/api/src/externals/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,8 @@ pub struct Memory {
impl Memory {
/// Creates a new host `Memory` from the provided [`MemoryType`].
///
/// This function will construct the `Memory` using the store [`Tunables`].
///
/// [`Tunables`]: crate::tunables::Tunables
/// This function will construct the `Memory` using the store
/// [`BaseTunables`][crate::tunables::BaseTunables].
///
/// # Example
///
Expand Down
5 changes: 2 additions & 3 deletions lib/api/src/externals/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,8 @@ impl Table {
///
/// All the elements in the table will be set to the `init` value.
///
/// This function will construct the `Table` using the store [`Tunables`].
///
/// [`Tunables`]: crate::tunables::Tunables
/// This function will construct the `Table` using the store
/// [`BaseTunables`][crate::tunables::BaseTunables].
pub fn new(store: &Store, ty: TableType, init: Val) -> Result<Self, RuntimeError> {
let item = init.into_checked_anyfunc(store)?;
let tunables = store.tunables();
Expand Down
1 change: 1 addition & 0 deletions lib/c-api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ default = [
"deprecated",
"wat",
"cranelift",
"jit",
"wasi",
]
wat = ["wasmer/wat"]
Expand Down
Loading

0 comments on commit 8b6c7e5

Please sign in to comment.