mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-12 21:38:39 +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,
|
error::ExportError, export::Exportable, import::LikeNamespace, module::Module, new,
|
||||||
structures::TypedIndex, types::Value, vm,
|
structures::TypedIndex, types::Value, vm,
|
||||||
};
|
};
|
||||||
use std::error::Error;
|
use std::{
|
||||||
|
cell::{Ref, RefCell},
|
||||||
|
error::Error,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct PreInstance {
|
pub(crate) struct PreInstance {
|
||||||
pub(crate) vmctx: vm::Ctx,
|
pub(crate) vmctx: RefCell<vm::Ctx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PreInstance {
|
impl PreInstance {
|
||||||
pub(crate) fn new() -> Self {
|
pub(crate) fn new() -> Self {
|
||||||
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 {
|
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())
|
Module::new(self.new_instance.module().clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn context(&self) -> &vm::Ctx {
|
pub fn context(&self) -> Ref<vm::Ctx> {
|
||||||
&self.pre_instance.vmctx
|
self.pre_instance.vmctx.borrow()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn context_mut(&mut self) -> &mut vm::Ctx {
|
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 mod prelude {
|
||||||
pub use crate::import::{namespace, ImportObject, Namespace};
|
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};
|
pub use crate::types::{FuncIndex, GlobalIndex, MemoryIndex, TableIndex, Type, Value};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
cache::Artifact,
|
cache::Artifact,
|
||||||
error::InstantiationError,
|
error::{InstantiationError, RuntimeError},
|
||||||
import::{ImportObject, Namespace},
|
import::{ImportObject, Namespace},
|
||||||
instance::{Instance, PreInstance},
|
instance::{Instance, PreInstance},
|
||||||
new, vm,
|
new,
|
||||||
|
types::{FuncSig, Value},
|
||||||
|
vm,
|
||||||
};
|
};
|
||||||
use new::wasmer_runtime::Export;
|
use new::wasmer_runtime::Export;
|
||||||
use std::{
|
use std::{
|
||||||
|
cell::RefCell,
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
convert::{AsRef, Infallible},
|
convert::{AsRef, Infallible},
|
||||||
ptr,
|
ptr,
|
||||||
@@ -52,6 +55,10 @@ impl Module {
|
|||||||
Export::Function(mut function) => {
|
Export::Function(mut function) => {
|
||||||
// That's an ugly hack. Go your way :-].
|
// 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
|
// An empty `vm::Ctx` was created in
|
||||||
// `Func` as a host function
|
// `Func` as a host function
|
||||||
// environment. The internals of
|
// environment. The internals of
|
||||||
@@ -75,6 +82,48 @@ impl Module {
|
|||||||
// environment hack.
|
// environment hack.
|
||||||
function.vmctx = pre_instance.vmctx_ptr() as _;
|
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),
|
(namespace, name),
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use crate::{
|
|||||||
error::{ExportError, RuntimeError},
|
error::{ExportError, RuntimeError},
|
||||||
get_global_store,
|
get_global_store,
|
||||||
new::{self, wasm_common::NativeWasmType},
|
new::{self, wasm_common::NativeWasmType},
|
||||||
types::{FuncDescriptor, Type, Value},
|
types::{FuncDescriptor, FuncSig, Type, Value},
|
||||||
vm,
|
vm,
|
||||||
};
|
};
|
||||||
use std::marker::PhantomData;
|
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::memory::Memory;
|
||||||
pub use wasmer_runtime_core::module::Module;
|
pub use wasmer_runtime_core::module::Module;
|
||||||
pub use wasmer_runtime_core::table::Table;
|
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::types;
|
||||||
pub use wasmer_runtime_core::vm::Ctx;
|
pub use wasmer_runtime_core::vm::Ctx;
|
||||||
pub use wasmer_runtime_core::{
|
pub use wasmer_runtime_core::{
|
||||||
|
|||||||
Reference in New Issue
Block a user