Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 4 additions & 13 deletions crates/api/examples/hello.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,8 @@
//! Translation of hello example

use anyhow::{ensure, Context as _, Result};
use std::rc::Rc;
use wasmtime::*;

struct HelloCallback;

impl Callable for HelloCallback {
fn call(&self, _params: &[Val], _results: &mut [Val]) -> Result<(), Trap> {
println!("Calling back...");
println!("> Hello World!");
Ok(())
}
}

fn main() -> Result<()> {
// Configure the initial compilation environment, creating the global
// `Store` structure. Note that you can also tweak configuration settings
Expand All @@ -34,8 +23,10 @@ fn main() -> Result<()> {
// Here we handle the imports of the module, which in this case is our
// `HelloCallback` type and its associated implementation of `Callback.
println!("Creating callback...");
let hello_type = FuncType::new(Box::new([]), Box::new([]));
let hello_func = Func::new(&store, hello_type, Rc::new(HelloCallback));
let hello_func = Func::wrap0(&store, || {
println!("Calling back...");
println!("> Hello World!");
});

// Once we've got that all set up we can then move to the instantiation
// phase, pairing together a compiled module as well as a set of imports.
Expand Down
122 changes: 2 additions & 120 deletions crates/api/src/externals.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
use crate::callable::{Callable, NativeCallable, WasmtimeFn, WrappedCallable};
use crate::runtime::Store;
use crate::trampoline::{generate_global_export, generate_memory_export, generate_table_export};
use crate::trap::Trap;
use crate::types::{ExternType, FuncType, GlobalType, MemoryType, TableType, ValType};
use crate::values::{from_checked_anyfunc, into_checked_anyfunc, Val};
use crate::Mutability;
use crate::{ExternType, GlobalType, MemoryType, TableType, ValType};
use crate::{Func, Store};
use anyhow::{anyhow, bail, Result};
use std::fmt;
use std::rc::Rc;
use std::slice;
use wasmtime_environ::wasm;
Expand Down Expand Up @@ -140,121 +137,6 @@ impl From<Table> for Extern {
}
}

/// A WebAssembly function which can be called.
///
/// This type can represent a number of callable items, such as:
///
/// * An exported function from a WebAssembly module.
/// * A user-defined function used to satisfy an import.
///
/// These types of callable items are all wrapped up in this `Func` and can be
/// used to both instantiate an [`Instance`](crate::Instance) as well as be
/// extracted from an [`Instance`](crate::Instance).
///
/// # `Func` and `Clone`
///
/// Functions are internally reference counted so you can `clone` a `Func`. The
/// cloning process only performs a shallow clone, so two cloned `Func`
/// instances are equivalent in their functionality.
#[derive(Clone)]
pub struct Func {
_store: Store,
callable: Rc<dyn WrappedCallable + 'static>,
ty: FuncType,
}

impl Func {
/// Creates a new `Func` with the given arguments, typically to create a
/// user-defined function to pass as an import to a module.
///
/// * `store` - a cache of data where information is stored, typically
/// shared with a [`Module`](crate::Module).
///
/// * `ty` - the signature of this function, used to indicate what the
/// inputs and outputs are, which must be WebAssembly types.
///
/// * `callable` - a type implementing the [`Callable`] trait which
/// is the implementation of this `Func` value.
///
/// Note that the implementation of `callable` must adhere to the `ty`
/// signature given, error or traps may occur if it does not respect the
/// `ty` signature.
pub fn new(store: &Store, ty: FuncType, callable: Rc<dyn Callable + 'static>) -> Self {
let callable = Rc::new(NativeCallable::new(callable, &ty, &store));
Func::from_wrapped(store, ty, callable)
}

fn from_wrapped(
store: &Store,
ty: FuncType,
callable: Rc<dyn WrappedCallable + 'static>,
) -> Func {
Func {
_store: store.clone(),
callable,
ty,
}
}

/// Returns the underlying wasm type that this `Func` has.
pub fn ty(&self) -> &FuncType {
&self.ty
}

/// Returns the number of parameters that this function takes.
pub fn param_arity(&self) -> usize {
self.ty.params().len()
}

/// Returns the number of results this function produces.
pub fn result_arity(&self) -> usize {
self.ty.results().len()
}

/// Invokes this function with the `params` given, returning the results and
/// any trap, if one occurs.
///
/// The `params` here must match the type signature of this `Func`, or a
/// trap will occur. If a trap occurs while executing this function, then a
/// trap will also be returned.
///
/// This function should not panic unless the underlying function itself
/// initiates a panic.
pub fn call(&self, params: &[Val]) -> Result<Box<[Val]>, Trap> {
let mut results = vec![Val::null(); self.result_arity()];
self.callable.call(params, &mut results)?;
Ok(results.into_boxed_slice())
}

pub(crate) fn wasmtime_export(&self) -> &wasmtime_runtime::Export {
self.callable.wasmtime_export()
}

pub(crate) fn from_wasmtime_function(
export: wasmtime_runtime::Export,
store: &Store,
instance_handle: InstanceHandle,
) -> Self {
// This is only called with `Export::Function`, and since it's coming
// from wasmtime_runtime itself we should support all the types coming
// out of it, so assert such here.
let ty = if let wasmtime_runtime::Export::Function { signature, .. } = &export {
FuncType::from_wasmtime_signature(signature.clone())
.expect("core wasm signature should be supported")
} else {
panic!("expected function export")
};
let callable = WasmtimeFn::new(store, instance_handle, export);
Func::from_wrapped(store, ty, Rc::new(callable))
}
}

impl fmt::Debug for Func {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Func")
}
}

/// A WebAssembly `global` value which can be read and written to.
///
/// A `global` in WebAssembly is sort of like a global variable within an
Expand Down
Loading