watt 0.4.2

Runtime for executing Rust procedural macros compiled as WebAssembly.
Documentation
use super::{HostFunc, Interpreter, Store, Value};

pub trait WasmArg: Sized {
    fn pop(interp: &mut Interpreter) -> Self;
}

pub trait WasmRet: Sized {
    fn push(interp: &mut Interpreter, val: Self);
}

impl WasmArg for u32 {
    fn pop(interp: &mut Interpreter) -> Self {
        match interp.pop().unwrap() {
            Value::I32(v) => v,
            _ => panic!("unexpected value on wasm stack"),
        }
    }
}

impl WasmRet for u32 {
    fn push(interp: &mut Interpreter, val: Self) {
        interp.push(Value::I32(val));
    }
}

impl WasmRet for () {
    fn push(interp: &mut Interpreter, val: Self) {
        let _ = interp;
        let _ = val;
    }
}

pub fn func1<A, R, F>(func: F, _store: &Store) -> HostFunc
where
    A: WasmArg,
    R: WasmRet,
    F: Fn(A) -> R + 'static,
{
    Box::new(move |interp| {
        let a = A::pop(interp);
        let ret = func(a);
        R::push(interp, ret);
        None
    })
}

pub fn mem_func2<A, B, R, F>(func: F, _store: &Store) -> HostFunc
where
    A: WasmArg,
    B: WasmArg,
    R: WasmRet,
    F: Fn(&mut [u8], A, B) -> R + 'static,
{
    Box::new(move |interp| {
        let b = B::pop(interp);
        let a = A::pop(interp);
        let mem = interp.get_memory_mut();
        let ret = func(mem, a, b);
        R::push(interp, ret);
        None
    })
}