Added support for native calls to dynamic functions

This commit is contained in:
Syrus
2020-06-12 20:50:24 -07:00
parent 21389f34ce
commit cd1138d520
10 changed files with 129 additions and 32 deletions

View File

@@ -9,7 +9,7 @@ use std::cmp::max;
use wasm_common::{HostFunction, WasmTypeList, WithEnv, WithoutEnv};
use wasmer_runtime::{
wasmer_call_trampoline, Export, ExportFunction, VMCallerCheckedAnyfunc, VMContext,
VMDynamicFunctionImportContext, VMFunctionBody, VMFunctionKind, VMTrampoline,
VMDynamicFunctionContext, VMFunctionBody, VMFunctionKind, VMTrampoline,
};
/// A function defined in the Wasm module
@@ -35,6 +35,7 @@ pub struct Function {
pub(crate) definition: FunctionDefinition,
// If the Function is owned by the Store, not the instance
pub(crate) owned_by_store: bool,
pub(crate) has_env: bool,
pub(crate) exported: ExportFunction,
}
@@ -58,6 +59,7 @@ impl Function {
store: store.clone(),
owned_by_store: true,
definition: FunctionDefinition::Host,
has_env: false,
exported: ExportFunction {
address,
vmctx,
@@ -72,17 +74,20 @@ impl Function {
where
F: Fn(&[Val]) -> Result<Vec<Val>, RuntimeError> + 'static,
{
let dynamic_ctx =
VMDynamicFunctionImportContext::from_context(VMDynamicFunctionWithoutEnv {
func: Box::new(func),
function_type: ty.clone(),
});
let dynamic_ctx = VMDynamicFunctionContext::from_context(VMDynamicFunctionWithoutEnv {
func: Box::new(func),
function_type: ty.clone(),
});
// 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 vmctx = Box::into_raw(Box::new(dynamic_ctx)) as *mut VMContext;
Self {
store: store.clone(),
owned_by_store: true,
definition: FunctionDefinition::Host,
has_env: false,
exported: ExportFunction {
address,
kind: VMFunctionKind::Dynamic,
@@ -98,17 +103,21 @@ impl Function {
F: Fn(&mut Env, &[Val]) -> Result<Vec<Val>, RuntimeError> + 'static,
Env: Sized,
{
let dynamic_ctx = VMDynamicFunctionImportContext::from_context(VMDynamicFunctionWithEnv {
let dynamic_ctx = VMDynamicFunctionContext::from_context(VMDynamicFunctionWithEnv {
env,
func: Box::new(func),
function_type: ty.clone(),
});
// 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 vmctx = Box::into_raw(Box::new(dynamic_ctx)) as *mut VMContext;
Self {
store: store.clone(),
owned_by_store: true,
definition: FunctionDefinition::Host,
has_env: true,
exported: ExportFunction {
address,
kind: VMFunctionKind::Dynamic,
@@ -143,6 +152,7 @@ impl Function {
store: store.clone(),
owned_by_store: true,
definition: FunctionDefinition::Host,
has_env: true,
exported: ExportFunction {
address,
kind: VMFunctionKind::Static,
@@ -269,6 +279,7 @@ impl Function {
Self {
store: store.clone(),
owned_by_store: false,
has_env: true,
definition: FunctionDefinition::Wasm(WasmFunctionDefinition { trampoline }),
exported: wasmer_export,
}
@@ -307,6 +318,7 @@ impl Function {
self.exported.vmctx,
self.exported.kind,
self.definition.clone(),
self.has_env,
))
}
}
@@ -330,12 +342,12 @@ impl std::fmt::Debug for Function {
}
/// This trait is one that all dynamic functions must fulfill.
trait VMDynamicFunction {
pub(crate) trait VMDynamicFunction {
fn call(&self, args: &[Val]) -> Result<Vec<Val>, RuntimeError>;
fn function_type(&self) -> &FunctionType;
}
struct VMDynamicFunctionWithoutEnv {
pub(crate) struct VMDynamicFunctionWithoutEnv {
#[allow(clippy::type_complexity)]
func: Box<dyn Fn(&[Val]) -> Result<Vec<Val>, RuntimeError> + 'static>,
function_type: FunctionType,
@@ -350,7 +362,7 @@ impl VMDynamicFunction for VMDynamicFunctionWithoutEnv {
}
}
struct VMDynamicFunctionWithEnv<Env>
pub(crate) struct VMDynamicFunctionWithEnv<Env>
where
Env: Sized,
{
@@ -372,13 +384,13 @@ where
}
}
trait VMDynamicFunctionImportCall<T: VMDynamicFunction> {
trait VMDynamicFunctionCall<T: VMDynamicFunction> {
fn from_context(ctx: T) -> Self;
fn address_ptr() -> *const VMFunctionBody;
unsafe fn func_wrapper(&self, values_vec: *mut i128);
}
impl<T: VMDynamicFunction> VMDynamicFunctionImportCall<T> for VMDynamicFunctionImportContext<T> {
impl<T: VMDynamicFunction> VMDynamicFunctionCall<T> for VMDynamicFunctionContext<T> {
fn from_context(ctx: T) -> Self {
Self {
address: Self::address_ptr(),
@@ -393,8 +405,8 @@ impl<T: VMDynamicFunction> VMDynamicFunctionImportCall<T> for VMDynamicFunctionI
// This function wraps our func, to make it compatible with the
// reverse trampoline signature
unsafe fn func_wrapper(
// Note: we use the trick that the first param to this function is the `VMDynamicFunctionImportContext`
// itself, so rather than doing `dynamic_ctx: &VMDynamicFunctionImportContext<T>`, we simplify it a bit
// Note: we use the trick that the first param to this function is the `VMDynamicFunctionContext`
// itself, so rather than doing `dynamic_ctx: &VMDynamicFunctionContext<T>`, we simplify it a bit
&self,
values_vec: *mut i128,
) {