Skip to content

Commit

Permalink
Move the construction of HostFunc out of Config.
Browse files Browse the repository at this point in the history
This commit moves the implementation for constructing a host function into
`HostFunc::new` and `HostFunc::wrap` so that `Config` has minimal
implementation for creating host functions.
  • Loading branch information
peterhuene committed Feb 3, 2021
1 parent 454276b commit 4792401
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 25 deletions.
26 changes: 3 additions & 23 deletions crates/wasmtime/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use crate::memory::MemoryCreator;
use crate::trampoline::MemoryCreatorProxy;
use crate::{func::HostFunc, Caller, Func, FuncType, IntoFunc, Store, Trap, Val};
use crate::{func::HostFunc, Caller, FuncType, IntoFunc, Trap, Val};
use anyhow::{bail, Result};
use std::any::Any;
use std::cmp;
use std::collections::HashMap;
use std::convert::TryFrom;
Expand Down Expand Up @@ -781,25 +780,8 @@ impl Config {
ty: FuncType,
func: impl Fn(Caller<'_>, &[Val], &mut [Val]) -> Result<(), Trap> + Send + Sync + 'static,
) {
let ty_clone = ty.clone();

// Create a trampoline that converts raw u128 values to `Val`
let func = Box::new(move |caller_vmctx, values_vec: *mut u128| {
// Lookup the last registered store as host functions have no associated store
let store = wasmtime_runtime::with_last_info(|last| {
last.and_then(Any::downcast_ref::<Store>)
.cloned()
.expect("Host function called without thread state")
});

Func::invoke(&store, &ty_clone, caller_vmctx, values_vec, &func)
});

let (instance, trampoline) = crate::trampoline::create_function(&ty, func, &self, None)
.expect("failed to create host function");

self.host_funcs
.insert(module, name, HostFunc::new(ty, instance, trampoline));
.insert(module, name, HostFunc::new(self, ty, func));
}

/// Defines a host function for the [`Config`] from the given Rust closure.
Expand All @@ -816,9 +798,7 @@ impl Config {
name: &str,
func: impl IntoFunc<Params, Results> + Send + Sync,
) {
let (ty, instance, trampoline) = func.into_func(None);
self.host_funcs
.insert(module, name, HostFunc::new(ty, instance, trampoline));
self.host_funcs.insert(module, name, HostFunc::wrap(func));
}

pub(crate) fn get_host_func(&self, module: &str, name: &str) -> Option<&HostFunc> {
Expand Down
41 changes: 39 additions & 2 deletions crates/wasmtime/src/func.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::{sig_registry::SignatureRegistry, trampoline::StoreInstanceHandle};
use crate::{Extern, ExternRef, FuncType, Store, Trap, Val, ValType};
use crate::{Config, Extern, ExternRef, FuncType, Store, Trap, Val, ValType};
use anyhow::{bail, ensure, Context as _, Result};
use smallvec::{smallvec, SmallVec};
use std::any::Any;
Expand All @@ -25,7 +25,44 @@ pub(crate) struct HostFunc {
}

impl HostFunc {
pub fn new(ty: FuncType, instance: InstanceHandle, trampoline: VMTrampoline) -> Self {
/// Creates a new host function from a callback.
///
/// This is analogous to [`Func::new`].
pub fn new(
config: &Config,
ty: FuncType,
func: impl Fn(Caller<'_>, &[Val], &mut [Val]) -> Result<(), Trap> + Send + Sync + 'static,
) -> Self {
let ty_clone = ty.clone();

// Create a trampoline that converts raw u128 values to `Val`
let func = Box::new(move |caller_vmctx, values_vec: *mut u128| {
// Lookup the last registered store as host functions have no associated store
let store = wasmtime_runtime::with_last_info(|last| {
last.and_then(Any::downcast_ref::<Store>)
.cloned()
.expect("Host function called without thread state")
});

Func::invoke(&store, &ty_clone, caller_vmctx, values_vec, &func)
});

let (instance, trampoline) = crate::trampoline::create_function(&ty, func, config, None)
.expect("failed to create host function");

Self {
ty,
instance,
trampoline,
}
}

/// Creates a new host function from wrapping a closure.
///
/// This is analogous to [`Func::wrap`].
pub fn wrap<Params, Results>(func: impl IntoFunc<Params, Results> + Send + Sync) -> Self {
let (ty, instance, trampoline) = func.into_func(None);

Self {
ty,
instance,
Expand Down

0 comments on commit 4792401

Please sign in to comment.