mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-08 13:48:26 +00:00
Added support for native calls to dynamic functions
This commit is contained in:
40
lib/api/src/externals/function.rs
vendored
40
lib/api/src/externals/function.rs
vendored
@@ -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,
|
||||
) {
|
||||
|
||||
Reference in New Issue
Block a user