mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-13 13:58:38 +00:00
feat(deprecated) Port DynamicFunc.
This commit is contained in:
@@ -2,22 +2,29 @@ use crate::{
|
||||
error::ExportError, export::Exportable, import::LikeNamespace, module::Module, new,
|
||||
structures::TypedIndex, types::Value, vm,
|
||||
};
|
||||
use std::error::Error;
|
||||
use std::{
|
||||
cell::{Ref, RefCell},
|
||||
error::Error,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct PreInstance {
|
||||
pub(crate) vmctx: vm::Ctx,
|
||||
pub(crate) vmctx: RefCell<vm::Ctx>,
|
||||
}
|
||||
|
||||
impl PreInstance {
|
||||
pub(crate) fn new() -> Self {
|
||||
Self {
|
||||
vmctx: vm::Ctx::new(),
|
||||
vmctx: RefCell::new(vm::Ctx::new()),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn vmctx(&self) -> RefCell<vm::Ctx> {
|
||||
self.vmctx.clone()
|
||||
}
|
||||
|
||||
pub(crate) fn vmctx_ptr(&self) -> *mut vm::Ctx {
|
||||
&self.vmctx as *const _ as *mut _
|
||||
self.vmctx.as_ptr()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,12 +78,12 @@ impl Instance {
|
||||
Module::new(self.new_instance.module().clone())
|
||||
}
|
||||
|
||||
pub fn context(&self) -> &vm::Ctx {
|
||||
&self.pre_instance.vmctx
|
||||
pub fn context(&self) -> Ref<vm::Ctx> {
|
||||
self.pre_instance.vmctx.borrow()
|
||||
}
|
||||
|
||||
pub fn context_mut(&mut self) -> &mut vm::Ctx {
|
||||
&mut self.pre_instance.vmctx
|
||||
self.pre_instance.vmctx.get_mut()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ pub use functional_api::{
|
||||
|
||||
pub mod prelude {
|
||||
pub use crate::import::{namespace, ImportObject, Namespace};
|
||||
pub use crate::typed_func::Func;
|
||||
pub use crate::typed_func::{DynamicFunc, Func};
|
||||
pub use crate::types::{FuncIndex, GlobalIndex, MemoryIndex, TableIndex, Type, Value};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
use crate::{
|
||||
cache::Artifact,
|
||||
error::InstantiationError,
|
||||
error::{InstantiationError, RuntimeError},
|
||||
import::{ImportObject, Namespace},
|
||||
instance::{Instance, PreInstance},
|
||||
new, vm,
|
||||
new,
|
||||
types::{FuncSig, Value},
|
||||
vm,
|
||||
};
|
||||
use new::wasmer_runtime::Export;
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
collections::HashMap,
|
||||
convert::{AsRef, Infallible},
|
||||
ptr,
|
||||
@@ -52,6 +55,10 @@ impl Module {
|
||||
Export::Function(mut function) => {
|
||||
// That's an ugly hack. Go your way :-].
|
||||
{
|
||||
// That's a static host function
|
||||
// constructed with
|
||||
// `new::wasmer::Function::new_env`.
|
||||
if !function.address.is_null() {
|
||||
// An empty `vm::Ctx` was created in
|
||||
// `Func` as a host function
|
||||
// environment. The internals of
|
||||
@@ -75,6 +82,48 @@ impl Module {
|
||||
// environment hack.
|
||||
function.vmctx = pre_instance.vmctx_ptr() as _;
|
||||
}
|
||||
// That's a dynamic host function
|
||||
// constructed with
|
||||
// `new::wasmer::Function::new_dynamic_env`.
|
||||
else {
|
||||
// `new::wasmer::VMDynamicFunctionWithEnv`
|
||||
// is private to `new::wasmer`. Let's
|
||||
// replicate it, and hope the layout
|
||||
// is the same!
|
||||
struct VMDynamicFunctionWithEnv<Env>
|
||||
where
|
||||
Env: Sized + 'static,
|
||||
{
|
||||
#[allow(unused)]
|
||||
function_type: FuncSig,
|
||||
#[allow(unused)]
|
||||
func: Box<
|
||||
dyn Fn(
|
||||
&mut Env,
|
||||
&[Value],
|
||||
)
|
||||
-> Result<Vec<Value>, RuntimeError>
|
||||
+ 'static,
|
||||
>,
|
||||
env: RefCell<Env>,
|
||||
}
|
||||
|
||||
// Get back the `vmctx` as it is
|
||||
// stored by
|
||||
// `new::wasmer::Function::new_dynamic_env`.
|
||||
let vmctx: Box<
|
||||
new::wasmer_runtime::VMDynamicFunctionContext<
|
||||
VMDynamicFunctionWithEnv<vm::Ctx>,
|
||||
>,
|
||||
> = unsafe { Box::from_raw(function.vmctx as *mut _) };
|
||||
|
||||
// Replace the environment by ours.
|
||||
vmctx.ctx.env.swap(&pre_instance.vmctx());
|
||||
|
||||
// … without anyone noticing…
|
||||
function.vmctx = Box::into_raw(vmctx) as _;
|
||||
}
|
||||
}
|
||||
|
||||
(
|
||||
(namespace, name),
|
||||
|
||||
@@ -2,7 +2,7 @@ use crate::{
|
||||
error::{ExportError, RuntimeError},
|
||||
get_global_store,
|
||||
new::{self, wasm_common::NativeWasmType},
|
||||
types::{FuncDescriptor, Type, Value},
|
||||
types::{FuncDescriptor, FuncSig, Type, Value},
|
||||
vm,
|
||||
};
|
||||
use std::marker::PhantomData;
|
||||
@@ -204,3 +204,73 @@ where
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct DynamicFunc {
|
||||
new_function: new::wasmer::Function,
|
||||
}
|
||||
|
||||
impl DynamicFunc {
|
||||
pub fn new<F>(signature: &FuncSig, func: F) -> Self
|
||||
where
|
||||
F: Fn(&mut vm::Ctx, &[Value]) -> Result<Vec<Value>, RuntimeError> + 'static,
|
||||
{
|
||||
// Create an empty `vm::Ctx`, that is going to be overwritten by `Instance::new`.
|
||||
let ctx = vm::Ctx::new();
|
||||
|
||||
Self {
|
||||
new_function: new::wasmer::Function::new_dynamic_env(
|
||||
get_global_store(),
|
||||
signature,
|
||||
ctx,
|
||||
func,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn signature(&self) -> &FuncDescriptor {
|
||||
self.new_function.ty()
|
||||
}
|
||||
|
||||
pub fn params(&self) -> &[Type] {
|
||||
self.signature().params()
|
||||
}
|
||||
|
||||
pub fn returns(&self) -> &[Type] {
|
||||
self.signature().results()
|
||||
}
|
||||
|
||||
pub fn dyn_call(&self, params: &[Value]) -> Result<Box<[Value]>, RuntimeError> {
|
||||
self.new_function.call(params)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<DynamicFunc> for new::wasmer::Extern {
|
||||
fn from(dynamic_func: DynamicFunc) -> Self {
|
||||
new::wasmer::Extern::Function(dynamic_func.new_function)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&new::wasmer::Function> for DynamicFunc {
|
||||
fn from(new_function: &new::wasmer::Function) -> Self {
|
||||
Self {
|
||||
new_function: new_function.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> new::wasmer::Exportable<'a> for DynamicFunc {
|
||||
fn to_export(&self) -> new::wasmer_runtime::Export {
|
||||
self.new_function.to_export()
|
||||
}
|
||||
|
||||
fn get_self_from_extern(r#extern: &'a new::wasmer::Extern) -> Result<&'a Self, ExportError> {
|
||||
match r#extern {
|
||||
new::wasmer::Extern::Function(dynamic_func) => Ok(
|
||||
// It's not ideal to call `Box::leak` here, but it would introduce too much changes in the `new::wasmer` API to support `Cow` or similar.
|
||||
Box::leak(Box::<DynamicFunc>::new(dynamic_func.into())),
|
||||
),
|
||||
_ => Err(ExportError::IncompatibleType),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ pub use wasmer_runtime_core::memory::ptr::{Array, Item, WasmPtr};
|
||||
pub use wasmer_runtime_core::memory::Memory;
|
||||
pub use wasmer_runtime_core::module::Module;
|
||||
pub use wasmer_runtime_core::table::Table;
|
||||
pub use wasmer_runtime_core::typed_func::Func;
|
||||
pub use wasmer_runtime_core::typed_func::{DynamicFunc, Func};
|
||||
pub use wasmer_runtime_core::types;
|
||||
pub use wasmer_runtime_core::vm::Ctx;
|
||||
pub use wasmer_runtime_core::{
|
||||
|
||||
Reference in New Issue
Block a user