Skip to content

Commit

Permalink
feat(runtime-core) Allow dynamic signature for polymorphic host funct…
Browse files Browse the repository at this point in the history
…ions.

This patch adds a new field in `Func`: `signature`. It contains the
signature of the host function.

For non-polymorphic host functions, the signature is computed from the
`Args` and `Rets` implementation parameters at compile-time.

For polymorphic host functions though, to be fully dynamic, the
signature given to `new_polymorphic` is used in `Func` as the correct
signature.
  • Loading branch information
Hywan committed Feb 17, 2020
1 parent ad20a00 commit 2ee1e80
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 5 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
25 changes: 21 additions & 4 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 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 2ee1e80

Please sign in to comment.