mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-09 14:18:20 +00:00
Merge branch 'master' into feature/multi-example-wasm-c-api
This commit is contained in:
@@ -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
|
* [#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
|
### Changed
|
||||||
|
* [#1944](https://github.com/wasmerio/wasmer/pull/1944) Require `WasmerEnv` to be `Send + Sync` even in dynamic functions.
|
||||||
|
|
||||||
### Fixed
|
### 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
|
## 1.0.0-beta2 - 2020-12-16
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
25
Makefile
25
Makefile
@@ -229,10 +229,13 @@ test-packages:
|
|||||||
cargo test -p wasmer-wasi --release
|
cargo test -p wasmer-wasi --release
|
||||||
cargo test -p wasmer-object --release
|
cargo test -p wasmer-object --release
|
||||||
cargo test -p wasmer-engine-native --release --no-default-features
|
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-cli --release
|
||||||
cargo test -p wasmer-cache --release
|
cargo test -p wasmer-cache --release
|
||||||
cargo test -p wasmer-engine --release
|
cargo test -p wasmer-engine --release
|
||||||
|
|
||||||
|
|
||||||
# The test-capi rules depend on the build-capi rules to build the .a files to
|
# 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
|
# 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))
|
test-capi: $(foreach compiler_engine,$(test_compilers_engines),test-capi-$(compiler_engine))
|
||||||
@@ -355,10 +358,26 @@ endif
|
|||||||
update-testsuite:
|
update-testsuite:
|
||||||
git subtree pull --prefix tests/wast/spec https://github.com/WebAssembly/testsuite.git master --squash
|
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`
|
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:
|
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
|
cargo fmt --all -- --check
|
||||||
RUSTFLAGS=${RUSTFLAGS} cargo clippy $(compiler_features)
|
|
||||||
|
lint: lint-formatting lint-packages
|
||||||
|
|
||||||
install-local: package
|
install-local: package
|
||||||
tar -C ~/.wasmer -zxvf wasmer.tar.gz
|
tar -C ~/.wasmer -zxvf wasmer.tar.gz
|
||||||
|
|||||||
187
lib/api/src/externals/function.rs
vendored
187
lib/api/src/externals/function.rs
vendored
@@ -67,6 +67,49 @@ pub struct Function {
|
|||||||
pub(crate) exported: ExportFunction,
|
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 {
|
impl Function {
|
||||||
/// Creates a new host `Function` (dynamic) with the provided signature.
|
/// 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
|
pub fn new<FT, F>(store: &Store, ty: FT, func: F) -> Self
|
||||||
where
|
where
|
||||||
FT: Into<FunctionType>,
|
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 ty: FunctionType = ty.into();
|
||||||
let dynamic_ctx: VMDynamicFunctionContext<DynamicFunctionWithoutEnv> =
|
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
|
pub fn new_with_env<FT, F, Env>(store: &Store, ty: FT, env: Env, func: F) -> Self
|
||||||
where
|
where
|
||||||
FT: Into<FunctionType>,
|
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,
|
Env: Sized + WasmerEnv + 'static,
|
||||||
{
|
{
|
||||||
let ty: FunctionType = ty.into();
|
let ty: FunctionType = ty.into();
|
||||||
@@ -220,58 +263,27 @@ impl Function {
|
|||||||
function_type: ty.clone(),
|
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.
|
// We don't yet have the address with the Wasm ABI signature.
|
||||||
// The engine linker will replace the address with one pointing to a
|
// The engine linker will replace the address with one pointing to a
|
||||||
// generated dynamic trampoline.
|
// generated dynamic trampoline.
|
||||||
let address = std::ptr::null() as *const VMFunctionBody;
|
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 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 {
|
Self {
|
||||||
store: store.clone(),
|
store: store.clone(),
|
||||||
definition: FunctionDefinition::Host(HostFunctionDefinition { has_env: true }),
|
definition: FunctionDefinition::Host(HostFunctionDefinition { has_env: true }),
|
||||||
exported: ExportFunction {
|
exported: ExportFunction {
|
||||||
metadata: Some(Arc::new(
|
metadata: Some(Arc::new(metadata)),
|
||||||
// # 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,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)),
|
|
||||||
vm_function: VMExportFunction {
|
vm_function: VMExportFunction {
|
||||||
address,
|
address,
|
||||||
kind: VMFunctionKind::Dynamic,
|
kind: VMFunctionKind::Dynamic,
|
||||||
@@ -374,50 +386,17 @@ impl Function {
|
|||||||
let function = inner::Function::<Args, Rets>::new(func);
|
let function = inner::Function::<Args, Rets>::new(func);
|
||||||
let address = function.address();
|
let address = function.address();
|
||||||
|
|
||||||
// TODO: We need to refactor the Function context.
|
let (host_env, metadata) =
|
||||||
// Right now is structured as it's always a `VMContext`. However, only
|
build_export_function_metadata::<Env>(env, Env::init_with_instance);
|
||||||
// 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) };
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: look into removing transmute by changing API type signatures
|
let vmctx = VMFunctionEnvironment { host_env };
|
||||||
let import_init_function_ptr = Some(unsafe {
|
|
||||||
std::mem::transmute::<fn(_, _) -> Result<(), _>, fn(_, _) -> Result<(), _>>(
|
|
||||||
Env::init_with_instance,
|
|
||||||
)
|
|
||||||
});
|
|
||||||
let signature = function.ty();
|
let signature = function.ty();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
store: store.clone(),
|
store: store.clone(),
|
||||||
definition: FunctionDefinition::Host(HostFunctionDefinition { has_env: true }),
|
definition: FunctionDefinition::Host(HostFunctionDefinition { has_env: true }),
|
||||||
exported: ExportFunction {
|
exported: ExportFunction {
|
||||||
metadata: Some(Arc::new(
|
metadata: Some(Arc::new(metadata)),
|
||||||
// # 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,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)),
|
|
||||||
vm_function: VMExportFunction {
|
vm_function: VMExportFunction {
|
||||||
address,
|
address,
|
||||||
kind: VMFunctionKind::Static,
|
kind: VMFunctionKind::Static,
|
||||||
@@ -455,43 +434,17 @@ impl Function {
|
|||||||
let function = inner::Function::<Args, Rets>::new(func);
|
let function = inner::Function::<Args, Rets>::new(func);
|
||||||
let address = function.address();
|
let address = function.address();
|
||||||
|
|
||||||
let box_env = Box::new(env);
|
let (host_env, metadata) =
|
||||||
let host_env = Box::into_raw(box_env) as *mut _;
|
build_export_function_metadata::<Env>(env, Env::init_with_instance);
|
||||||
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 vmctx = VMFunctionEnvironment { host_env };
|
||||||
let signature = function.ty();
|
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 {
|
Self {
|
||||||
store: store.clone(),
|
store: store.clone(),
|
||||||
definition: FunctionDefinition::Host(HostFunctionDefinition { has_env: true }),
|
definition: FunctionDefinition::Host(HostFunctionDefinition { has_env: true }),
|
||||||
exported: ExportFunction {
|
exported: ExportFunction {
|
||||||
metadata: Some(Arc::new(
|
metadata: Some(Arc::new(metadata)),
|
||||||
// # 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,
|
|
||||||
),
|
|
||||||
)),
|
|
||||||
vm_function: VMExportFunction {
|
vm_function: VMExportFunction {
|
||||||
address,
|
address,
|
||||||
kind: VMFunctionKind::Static,
|
kind: VMFunctionKind::Static,
|
||||||
@@ -855,7 +808,7 @@ impl fmt::Debug for Function {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// This trait is one that all dynamic functions must fulfill.
|
/// 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 call(&self, args: &[Val]) -> Result<Vec<Val>, RuntimeError>;
|
||||||
fn function_type(&self) -> &FunctionType;
|
fn function_type(&self) -> &FunctionType;
|
||||||
}
|
}
|
||||||
@@ -863,7 +816,7 @@ pub(crate) trait VMDynamicFunction {
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub(crate) struct DynamicFunctionWithoutEnv {
|
pub(crate) struct DynamicFunctionWithoutEnv {
|
||||||
#[allow(clippy::type_complexity)]
|
#[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,
|
function_type: FunctionType,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -878,15 +831,15 @@ impl VMDynamicFunction for DynamicFunctionWithoutEnv {
|
|||||||
|
|
||||||
pub(crate) struct DynamicFunctionWithEnv<Env>
|
pub(crate) struct DynamicFunctionWithEnv<Env>
|
||||||
where
|
where
|
||||||
Env: Sized + 'static,
|
Env: Sized + 'static + Send + Sync,
|
||||||
{
|
{
|
||||||
function_type: FunctionType,
|
function_type: FunctionType,
|
||||||
#[allow(clippy::type_complexity)]
|
#[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>,
|
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 {
|
fn clone(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
env: self.env.clone(),
|
env: self.env.clone(),
|
||||||
@@ -898,7 +851,7 @@ impl<Env: Sized + Clone + 'static> Clone for DynamicFunctionWithEnv<Env> {
|
|||||||
|
|
||||||
impl<Env> VMDynamicFunction for DynamicFunctionWithEnv<Env>
|
impl<Env> VMDynamicFunction for DynamicFunctionWithEnv<Env>
|
||||||
where
|
where
|
||||||
Env: Sized + 'static,
|
Env: Sized + 'static + Send + Sync,
|
||||||
{
|
{
|
||||||
fn call(&self, args: &[Val]) -> Result<Vec<Val>, RuntimeError> {
|
fn call(&self, args: &[Val]) -> Result<Vec<Val>, RuntimeError> {
|
||||||
(*self.func)(&*self.env, &args)
|
(*self.func)(&*self.env, &args)
|
||||||
|
|||||||
@@ -3,8 +3,31 @@
|
|||||||
macro_rules! wasm_declare_vec_inner {
|
macro_rules! wasm_declare_vec_inner {
|
||||||
($name:ident) => {
|
($name:ident) => {
|
||||||
paste::paste! {
|
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]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn [<wasm_ $name _vec_new_empty>](out: *mut [<wasm_ $name _vec_t>]) {
|
pub unsafe extern "C" fn [<wasm_ $name _vec_new_empty>](out: *mut [<wasm_ $name _vec_t>]) {
|
||||||
// TODO: actually implement this
|
// TODO: actually implement this
|
||||||
@@ -19,7 +42,37 @@ macro_rules! wasm_declare_vec_inner {
|
|||||||
macro_rules! wasm_declare_vec {
|
macro_rules! wasm_declare_vec {
|
||||||
($name:ident) => {
|
($name:ident) => {
|
||||||
paste::paste! {
|
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)]
|
#[derive(Debug)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct [<wasm_ $name _vec_t>] {
|
pub struct [<wasm_ $name _vec_t>] {
|
||||||
@@ -81,6 +134,7 @@ macro_rules! wasm_declare_vec {
|
|||||||
.into_boxed_slice();
|
.into_boxed_slice();
|
||||||
let data = copied_data.as_mut_ptr();
|
let data = copied_data.as_mut_ptr();
|
||||||
::std::mem::forget(copied_data);
|
::std::mem::forget(copied_data);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
size,
|
size,
|
||||||
data,
|
data,
|
||||||
@@ -111,27 +165,60 @@ macro_rules! wasm_declare_vec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: investigate possible memory leak on `init` (owned pointer)
|
// 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]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn [<wasm_ $name _vec_new>](out: *mut [<wasm_ $name _vec_t>], length: usize, init: *mut [<wasm_ $name _t>]) {
|
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);
|
let mut bytes: Vec<[<wasm_ $name _t>]> = Vec::with_capacity(length);
|
||||||
|
|
||||||
for i in 0..length {
|
for i in 0..length {
|
||||||
bytes.push(::std::ptr::read(init.add(i)));
|
bytes.push(::std::ptr::read(init.add(i)));
|
||||||
}
|
}
|
||||||
|
|
||||||
let pointer = bytes.as_mut_ptr();
|
let pointer = bytes.as_mut_ptr();
|
||||||
debug_assert!(bytes.len() == bytes.capacity());
|
debug_assert!(bytes.len() == bytes.capacity());
|
||||||
|
|
||||||
(*out).data = pointer;
|
(*out).data = pointer;
|
||||||
(*out).size = length;
|
(*out).size = length;
|
||||||
::std::mem::forget(bytes);
|
::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]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn [<wasm_ $name _vec_new_uninitialized>](out: *mut [<wasm_ $name _vec_t>], length: usize) {
|
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 mut bytes: Vec<[<wasm_ $name _t>]> = Vec::with_capacity(length);
|
||||||
let pointer = bytes.as_mut_ptr();
|
let pointer = bytes.as_mut_ptr();
|
||||||
|
|
||||||
(*out).data = pointer;
|
(*out).data = pointer;
|
||||||
(*out).size = length;
|
(*out).size = length;
|
||||||
|
|
||||||
::std::mem::forget(bytes);
|
::std::mem::forget(bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,7 +231,11 @@ macro_rules! wasm_declare_vec {
|
|||||||
*out_ptr = in_ptr.clone();
|
*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]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn [<wasm_ $name _vec_delete>](ptr: Option<&mut [<wasm_ $name _vec_t>]>) {
|
pub unsafe extern "C" fn [<wasm_ $name _vec_delete>](ptr: Option<&mut [<wasm_ $name _vec_t>]>) {
|
||||||
if let Some(vec) = ptr {
|
if let Some(vec) = ptr {
|
||||||
@@ -166,7 +257,9 @@ macro_rules! wasm_declare_vec {
|
|||||||
macro_rules! wasm_declare_boxed_vec {
|
macro_rules! wasm_declare_boxed_vec {
|
||||||
($name:ident) => {
|
($name:ident) => {
|
||||||
paste::paste! {
|
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)]
|
#[derive(Debug)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct [<wasm_ $name _vec_t>] {
|
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
|
// TODO: do this properly
|
||||||
impl [<wasm_ $name _vec_t>] {
|
impl [<wasm_ $name _vec_t>] {
|
||||||
pub unsafe fn into_slice(&self) -> Option<&[Box<[<wasm_ $name _t>]>]>{
|
pub unsafe fn into_slice(&self) -> Option<&[Box<[<wasm_ $name _t>]>]>{
|
||||||
@@ -235,23 +349,53 @@ macro_rules! wasm_declare_boxed_vec {
|
|||||||
#[no_mangle]
|
#[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>]) {
|
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);
|
let mut bytes: Vec<*mut [<wasm_ $name _t>]> = Vec::with_capacity(length);
|
||||||
|
|
||||||
for i in 0..length {
|
for i in 0..length {
|
||||||
bytes.push(*init.add(i));
|
bytes.push(*init.add(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut boxed_vec = bytes.into_boxed_slice();
|
let mut boxed_vec = bytes.into_boxed_slice();
|
||||||
let pointer = boxed_vec.as_mut_ptr();
|
let pointer = boxed_vec.as_mut_ptr();
|
||||||
|
|
||||||
(*out).data = pointer;
|
(*out).data = pointer;
|
||||||
(*out).size = length;
|
(*out).size = length;
|
||||||
|
|
||||||
::std::mem::forget(boxed_vec);
|
::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]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn [<wasm_ $name _vec_new_uninitialized>](out: *mut [<wasm_ $name _vec_t>], length: usize) {
|
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();
|
let pointer = bytes.as_mut_ptr();
|
||||||
|
|
||||||
(*out).data = pointer;
|
(*out).data = pointer;
|
||||||
(*out).size = length;
|
(*out).size = length;
|
||||||
|
|
||||||
::std::mem::forget(bytes);
|
::std::mem::forget(bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,11 +408,14 @@ macro_rules! wasm_declare_boxed_vec {
|
|||||||
*out_ptr = in_ptr.clone();
|
*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]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn [<wasm_ $name _vec_delete>](ptr: Option<&mut[<wasm_ $name _vec_t>]>) {
|
pub unsafe extern "C" fn [<wasm_ $name _vec_delete>](ptr: Option<&mut [<wasm_ $name _vec_t>]>) {
|
||||||
if let Some(vec) = ptr {
|
if let Some(vec) = ptr {
|
||||||
if !vec.data.is_null() {
|
if !vec.data.is_null() {
|
||||||
let ptr: *mut Option<Box<[<wasm_ $name _t>]>> = vec.data as _;
|
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);
|
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...
|
// TODO: finish this...
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,4 +48,4 @@ pub unsafe extern "C" fn wasm_frame_module_offset(frame: &wasm_frame_t) -> usize
|
|||||||
frame.info.module_offset()
|
frame.info.module_offset()
|
||||||
}
|
}
|
||||||
|
|
||||||
wasm_declare_vec!(frame);
|
wasm_declare_boxed_vec!(frame);
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
use super::{
|
use super::{wasm_externtype_t, wasm_valtype_vec_delete, wasm_valtype_vec_t, WasmExternType};
|
||||||
wasm_externtype_t, wasm_valtype_t, wasm_valtype_vec_delete, wasm_valtype_vec_t, WasmExternType,
|
|
||||||
};
|
|
||||||
use std::mem;
|
|
||||||
use wasmer::{ExternType, FunctionType, ValType};
|
use wasmer::{ExternType, FunctionType, ValType};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -13,44 +10,8 @@ pub(crate) struct WasmFunctionType {
|
|||||||
|
|
||||||
impl WasmFunctionType {
|
impl WasmFunctionType {
|
||||||
pub(crate) fn new(function_type: FunctionType) -> Self {
|
pub(crate) fn new(function_type: FunctionType) -> Self {
|
||||||
let params = {
|
let params: Box<wasm_valtype_vec_t> = Box::new(function_type.params().into());
|
||||||
let mut valtypes = function_type
|
let results: Box<wasm_valtype_vec_t> = Box::new(function_type.results().into());
|
||||||
.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
|
|
||||||
};
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
function_type,
|
function_type,
|
||||||
@@ -90,12 +51,12 @@ impl wasm_functype_t {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wasm_declare_vec!(functype);
|
wasm_declare_boxed_vec!(functype);
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn wasm_functype_new(
|
pub unsafe extern "C" fn wasm_functype_new(
|
||||||
params: Option<Box<wasm_valtype_vec_t>>,
|
params: Option<&mut wasm_valtype_vec_t>,
|
||||||
results: Option<Box<wasm_valtype_vec_t>>,
|
results: Option<&mut wasm_valtype_vec_t>,
|
||||||
) -> Option<Box<wasm_functype_t>> {
|
) -> Option<Box<wasm_functype_t>> {
|
||||||
let params = params?;
|
let params = params?;
|
||||||
let results = results?;
|
let results = results?;
|
||||||
@@ -111,8 +72,8 @@ pub unsafe extern "C" fn wasm_functype_new(
|
|||||||
.map(|val| val.as_ref().into())
|
.map(|val| val.as_ref().into())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
wasm_valtype_vec_delete(Some(&mut *Box::into_raw(params)));
|
wasm_valtype_vec_delete(Some(params));
|
||||||
wasm_valtype_vec_delete(Some(&mut *Box::into_raw(results)));
|
wasm_valtype_vec_delete(Some(results));
|
||||||
|
|
||||||
Some(Box::new(wasm_functype_t::new(FunctionType::new(
|
Some(Box::new(wasm_functype_t::new(FunctionType::new(
|
||||||
params_as_valtype,
|
params_as_valtype,
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ impl wasm_globaltype_t {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wasm_declare_vec!(globaltype);
|
wasm_declare_boxed_vec!(globaltype);
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn wasm_globaltype_new(
|
pub unsafe extern "C" fn wasm_globaltype_new(
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ impl wasm_memorytype_t {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wasm_declare_vec!(memorytype);
|
wasm_declare_boxed_vec!(memorytype);
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn wasm_memorytype_new(limits: &wasm_limits_t) -> Box<wasm_memorytype_t> {
|
pub unsafe extern "C" fn wasm_memorytype_new(limits: &wasm_limits_t) -> Box<wasm_memorytype_t> {
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ impl wasm_tabletype_t {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wasm_declare_vec!(tabletype);
|
wasm_declare_boxed_vec!(tabletype);
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn wasm_tabletype_new(
|
pub unsafe extern "C" fn wasm_tabletype_new(
|
||||||
|
|||||||
@@ -216,15 +216,15 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
|||||||
// destination block following the whole `if...end`. If we do end
|
// destination block following the whole `if...end`. If we do end
|
||||||
// up discovering an `else`, then we will allocate a block for it
|
// up discovering an `else`, then we will allocate a block for it
|
||||||
// and go back and patch the jump.
|
// 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 =
|
let branch_inst =
|
||||||
canonicalise_then_brz(builder, val, destination, state.peekn(params.len()));
|
canonicalise_then_brz(builder, val, destination, state.peekn(params.len()));
|
||||||
(destination, ElseData::NoElse { branch_inst })
|
(destination, ElseData::NoElse { branch_inst })
|
||||||
} else {
|
} else {
|
||||||
// The `if` type signature is not valid without an `else` block,
|
// The `if` type signature is not valid without an `else` block,
|
||||||
// so we eagerly allocate the `else` block here.
|
// so we eagerly allocate the `else` block here.
|
||||||
let destination = block_with_params(builder, results.clone(), environ)?;
|
let destination = block_with_params(builder, results, environ)?;
|
||||||
let else_block = block_with_params(builder, params.clone(), environ)?;
|
let else_block = block_with_params(builder, params, environ)?;
|
||||||
canonicalise_then_brz(builder, val, else_block, state.peekn(params.len()));
|
canonicalise_then_brz(builder, val, else_block, state.peekn(params.len()));
|
||||||
builder.seal_block(else_block);
|
builder.seal_block(else_block);
|
||||||
(destination, ElseData::WithElse { else_block })
|
(destination, ElseData::WithElse { else_block })
|
||||||
@@ -271,8 +271,7 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
|||||||
let (params, _results) =
|
let (params, _results) =
|
||||||
module_translation_state.blocktype_params_results(blocktype)?;
|
module_translation_state.blocktype_params_results(blocktype)?;
|
||||||
debug_assert_eq!(params.len(), num_return_values);
|
debug_assert_eq!(params.len(), num_return_values);
|
||||||
let else_block =
|
let else_block = block_with_params(builder, params, environ)?;
|
||||||
block_with_params(builder, params.clone(), environ)?;
|
|
||||||
canonicalise_then_jump(
|
canonicalise_then_jump(
|
||||||
builder,
|
builder,
|
||||||
destination,
|
destination,
|
||||||
|
|||||||
26
lib/deprecated/runtime-core/Cargo.lock
generated
26
lib/deprecated/runtime-core/Cargo.lock
generated
@@ -1158,7 +1158,7 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer"
|
name = "wasmer"
|
||||||
version = "1.0.0-beta1"
|
version = "1.0.0-beta2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 0.1.10",
|
"cfg-if 0.1.10",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
@@ -1181,7 +1181,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-cache"
|
name = "wasmer-cache"
|
||||||
version = "1.0.0-beta1"
|
version = "1.0.0-beta2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"blake3",
|
"blake3",
|
||||||
"hex",
|
"hex",
|
||||||
@@ -1191,7 +1191,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-compiler"
|
name = "wasmer-compiler"
|
||||||
version = "1.0.0-beta1"
|
version = "1.0.0-beta2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"enumset",
|
"enumset",
|
||||||
"raw-cpuid",
|
"raw-cpuid",
|
||||||
@@ -1207,7 +1207,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-compiler-cranelift"
|
name = "wasmer-compiler-cranelift"
|
||||||
version = "1.0.0-beta1"
|
version = "1.0.0-beta2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cranelift-codegen",
|
"cranelift-codegen",
|
||||||
"cranelift-frontend",
|
"cranelift-frontend",
|
||||||
@@ -1224,7 +1224,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-compiler-llvm"
|
name = "wasmer-compiler-llvm"
|
||||||
version = "1.0.0-beta1"
|
version = "1.0.0-beta2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"cc",
|
"cc",
|
||||||
@@ -1246,7 +1246,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-compiler-singlepass"
|
name = "wasmer-compiler-singlepass"
|
||||||
version = "1.0.0-beta1"
|
version = "1.0.0-beta2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"dynasm",
|
"dynasm",
|
||||||
@@ -1263,7 +1263,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-derive"
|
name = "wasmer-derive"
|
||||||
version = "1.0.0-beta1"
|
version = "1.0.0-beta2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro-error",
|
"proc-macro-error",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
@@ -1273,7 +1273,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-engine"
|
name = "wasmer-engine"
|
||||||
version = "1.0.0-beta1"
|
version = "1.0.0-beta2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"backtrace",
|
"backtrace",
|
||||||
"bincode",
|
"bincode",
|
||||||
@@ -1292,7 +1292,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-engine-jit"
|
name = "wasmer-engine-jit"
|
||||||
version = "1.0.0-beta1"
|
version = "1.0.0-beta2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"cfg-if 0.1.10",
|
"cfg-if 0.1.10",
|
||||||
@@ -1308,7 +1308,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-engine-native"
|
name = "wasmer-engine-native"
|
||||||
version = "1.0.0-beta1"
|
version = "1.0.0-beta2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"cfg-if 0.1.10",
|
"cfg-if 0.1.10",
|
||||||
@@ -1327,7 +1327,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-object"
|
name = "wasmer-object"
|
||||||
version = "1.0.0-beta1"
|
version = "1.0.0-beta2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"object 0.22.0",
|
"object 0.22.0",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
@@ -1355,7 +1355,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-types"
|
name = "wasmer-types"
|
||||||
version = "1.0.0-beta1"
|
version = "1.0.0-beta2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cranelift-entity",
|
"cranelift-entity",
|
||||||
"serde",
|
"serde",
|
||||||
@@ -1364,7 +1364,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-vm"
|
name = "wasmer-vm"
|
||||||
version = "1.0.0-beta1"
|
version = "1.0.0-beta2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"backtrace",
|
"backtrace",
|
||||||
"cc",
|
"cc",
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use new::wasmer::Export;
|
use new::wasmer::Export;
|
||||||
use std::{
|
use std::{
|
||||||
cell::RefCell,
|
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
convert::{AsRef, Infallible},
|
convert::{AsRef, Infallible},
|
||||||
ptr,
|
ptr,
|
||||||
|
sync::{Arc, Mutex},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use new::wasmer_types::{DataInitializer, ExportIndex, TableInitializer};
|
pub use new::wasmer_types::{DataInitializer, ExportIndex, TableInitializer};
|
||||||
@@ -126,20 +126,22 @@ impl Module {
|
|||||||
// is the same!
|
// is the same!
|
||||||
struct VMDynamicFunctionWithEnv<Env>
|
struct VMDynamicFunctionWithEnv<Env>
|
||||||
where
|
where
|
||||||
Env: Sized + 'static,
|
Env: Sized + 'static + Send + Sync,
|
||||||
{
|
{
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
function_type: FuncSig,
|
function_type: FuncSig,
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
func: Box<
|
func: Arc<
|
||||||
dyn Fn(
|
dyn Fn(
|
||||||
&mut Env,
|
&mut Env,
|
||||||
&[Value],
|
&[Value],
|
||||||
)
|
)
|
||||||
-> Result<Vec<Value>, RuntimeError>
|
-> Result<Vec<Value>, RuntimeError>
|
||||||
+ 'static,
|
+ 'static
|
||||||
|
+ Send
|
||||||
|
+ Sync,
|
||||||
>,
|
>,
|
||||||
env: RefCell<Env>,
|
env: Box<Mutex<Env>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get back the `vmctx` as it is
|
// Get back the `vmctx` as it is
|
||||||
@@ -154,7 +156,10 @@ impl Module {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Replace the environment by ours.
|
// 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…
|
// … without anyone noticing…
|
||||||
function.vm_function.vmctx.host_env = Box::into_raw(vmctx) as _;
|
function.vm_function.vmctx.host_env = Box::into_raw(vmctx) as _;
|
||||||
|
|||||||
26
lib/deprecated/runtime/Cargo.lock
generated
26
lib/deprecated/runtime/Cargo.lock
generated
@@ -1158,7 +1158,7 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer"
|
name = "wasmer"
|
||||||
version = "1.0.0-beta1"
|
version = "1.0.0-beta2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 0.1.10",
|
"cfg-if 0.1.10",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
@@ -1181,7 +1181,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-cache"
|
name = "wasmer-cache"
|
||||||
version = "1.0.0-beta1"
|
version = "1.0.0-beta2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"blake3",
|
"blake3",
|
||||||
"hex",
|
"hex",
|
||||||
@@ -1191,7 +1191,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-compiler"
|
name = "wasmer-compiler"
|
||||||
version = "1.0.0-beta1"
|
version = "1.0.0-beta2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"enumset",
|
"enumset",
|
||||||
"raw-cpuid",
|
"raw-cpuid",
|
||||||
@@ -1207,7 +1207,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-compiler-cranelift"
|
name = "wasmer-compiler-cranelift"
|
||||||
version = "1.0.0-beta1"
|
version = "1.0.0-beta2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cranelift-codegen",
|
"cranelift-codegen",
|
||||||
"cranelift-frontend",
|
"cranelift-frontend",
|
||||||
@@ -1224,7 +1224,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-compiler-llvm"
|
name = "wasmer-compiler-llvm"
|
||||||
version = "1.0.0-beta1"
|
version = "1.0.0-beta2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"cc",
|
"cc",
|
||||||
@@ -1246,7 +1246,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-compiler-singlepass"
|
name = "wasmer-compiler-singlepass"
|
||||||
version = "1.0.0-beta1"
|
version = "1.0.0-beta2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"dynasm",
|
"dynasm",
|
||||||
@@ -1263,7 +1263,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-derive"
|
name = "wasmer-derive"
|
||||||
version = "1.0.0-beta1"
|
version = "1.0.0-beta2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro-error",
|
"proc-macro-error",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
@@ -1273,7 +1273,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-engine"
|
name = "wasmer-engine"
|
||||||
version = "1.0.0-beta1"
|
version = "1.0.0-beta2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"backtrace",
|
"backtrace",
|
||||||
"bincode",
|
"bincode",
|
||||||
@@ -1292,7 +1292,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-engine-jit"
|
name = "wasmer-engine-jit"
|
||||||
version = "1.0.0-beta1"
|
version = "1.0.0-beta2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"cfg-if 0.1.10",
|
"cfg-if 0.1.10",
|
||||||
@@ -1308,7 +1308,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-engine-native"
|
name = "wasmer-engine-native"
|
||||||
version = "1.0.0-beta1"
|
version = "1.0.0-beta2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"cfg-if 0.1.10",
|
"cfg-if 0.1.10",
|
||||||
@@ -1327,7 +1327,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-object"
|
name = "wasmer-object"
|
||||||
version = "1.0.0-beta1"
|
version = "1.0.0-beta2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"object 0.22.0",
|
"object 0.22.0",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
@@ -1362,7 +1362,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-types"
|
name = "wasmer-types"
|
||||||
version = "1.0.0-beta1"
|
version = "1.0.0-beta2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cranelift-entity",
|
"cranelift-entity",
|
||||||
"serde",
|
"serde",
|
||||||
@@ -1371,7 +1371,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasmer-vm"
|
name = "wasmer-vm"
|
||||||
version = "1.0.0-beta1"
|
version = "1.0.0-beta2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"backtrace",
|
"backtrace",
|
||||||
"cc",
|
"cc",
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ mod test_vmfunction_import {
|
|||||||
/// containing the relevant context for running the function indicated
|
/// containing the relevant context for running the function indicated
|
||||||
/// in `address`.
|
/// in `address`.
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct VMDynamicFunctionContext<T: Sized> {
|
pub struct VMDynamicFunctionContext<T: Sized + Send + Sync> {
|
||||||
/// The address of the inner dynamic function.
|
/// The address of the inner dynamic function.
|
||||||
///
|
///
|
||||||
/// Note: The function must be on the form of
|
/// Note: The function must be on the form of
|
||||||
@@ -106,7 +106,14 @@ pub struct VMDynamicFunctionContext<T: Sized> {
|
|||||||
pub ctx: T,
|
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 {
|
fn clone(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
address: self.address,
|
address: self.address,
|
||||||
|
|||||||
Reference in New Issue
Block a user