Skip to content

Commit

Permalink
Merge pull request #1225 from Hywan/feature/polymorphic-v2.1
Browse files Browse the repository at this point in the history
feat(runtime-core) Allow dynamic signature for polymorphic host functions
  • Loading branch information
losfair authored Feb 24, 2020
2 parents 7b0f7ee + 2ee1e80 commit 644755f
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 6 deletions.
2 changes: 1 addition & 1 deletion lib/runtime-core-tests/tests/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ fn imported_functions_forms(test: &dyn Fn(&Instance)) {
Ok(n + 1)
}),

"callback_closure_polymorphic" => Func::<i32, i32, _>::new_polymorphic(
"callback_closure_polymorphic" => Func::new_polymorphic(
Arc::new(FuncSig::new(vec![Type::I32], vec![Type::I32])),
|_, params| -> Vec<Value> {
match params[0] {
Expand Down
27 changes: 22 additions & 5 deletions lib/runtime-core/src/typed_func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,9 +189,21 @@ where
/// Represents a function that can be used by WebAssembly.
pub struct Func<'a, Args = (), Rets = (), Inner: Kind = Wasm> {
inner: Inner,

/// The function pointer.
func: NonNull<vm::Func>,

/// The function environment.
func_env: Option<NonNull<vm::FuncEnv>>,

/// The famous `vm::Ctx`.
vmctx: *mut vm::Ctx,

/// The signature is usually infered from `Args` and `Rets`. In
/// case of polymorphic function, the signature is only known at
/// runtime.
signature: Arc<FuncSig>,

_phantom: PhantomData<(&'a (), Args, Rets)>,
}

Expand All @@ -214,6 +226,7 @@ where
func,
func_env,
vmctx,
signature: Arc::new(FuncSig::new(Args::types(), Rets::types())),
_phantom: PhantomData,
}
}
Expand All @@ -225,7 +238,7 @@ where
Rets: WasmTypeList,
{
/// Creates a new `Func`.
pub fn new<F, Kind>(func: F) -> Func<'a, Args, Rets, Host>
pub fn new<F, Kind>(func: F) -> Self
where
Kind: ExternalFunctionKind,
F: ExternalFunction<Kind, Args, Rets>,
Expand All @@ -237,14 +250,17 @@ where
func,
func_env,
vmctx: ptr::null_mut(),
signature: Arc::new(FuncSig::new(Args::types(), Rets::types())),
_phantom: PhantomData,
}
}
}

impl<'a> Func<'a, (), (), Host> {
/// Creates a polymorphic function.
#[allow(unused_variables)]
#[cfg(all(unix, target_arch = "x86_64"))]
pub fn new_polymorphic<F>(signature: Arc<FuncSig>, func: F) -> Func<'a, Args, Rets, Host>
pub fn new_polymorphic<F>(signature: Arc<FuncSig>, func: F) -> Self
where
F: Fn(&mut vm::Ctx, &[crate::types::Value]) -> Vec<crate::types::Value> + 'static,
{
Expand All @@ -254,7 +270,7 @@ where

struct PolymorphicContext {
arg_types: Vec<Type>,
func: Box<Fn(&mut vm::Ctx, &[Value]) -> Vec<Value>>,
func: Box<dyn Fn(&mut vm::Ctx, &[Value]) -> Vec<Value>>,
}
unsafe extern "C" fn enter_host_polymorphic(
ctx: *const CallContext,
Expand Down Expand Up @@ -305,11 +321,13 @@ where
let ptr = builder
.append_global()
.expect("cannot bump-allocate global trampoline memory");

Func {
inner: Host(()),
func: ptr.cast::<vm::Func>(),
func_env: None,
vmctx: ptr::null_mut(),
signature,
_phantom: PhantomData,
}
}
Expand Down Expand Up @@ -751,12 +769,11 @@ where
func_env @ Some(_) => Context::ExternalWithEnv(self.vmctx, func_env),
None => Context::Internal,
};
let signature = Arc::new(FuncSig::new(Args::types(), Rets::types()));

Export::Function {
func,
ctx,
signature,
signature: self.signature.clone(),
}
}
}
Expand Down

0 comments on commit 644755f

Please sign in to comment.