Skip to content

Commit

Permalink
Add experimental function wrapper macro for linking
Browse files Browse the repository at this point in the history
  • Loading branch information
Veykril committed Jan 27, 2020
1 parent 1cf95dc commit 7915db9
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 13 deletions.
12 changes: 4 additions & 8 deletions examples/wasm_link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ fn main() {

let mut module = rt.load_module(module).map_err(|(_, e)| e).unwrap();
module
.link_function::<(), u64>("time", "millis", Some(millis))
.link_function::<(), u64>("time", "millis", millis_wrap)
.unwrap();
let func = module.find_function::<(), u64>("seconds").unwrap();
println!("{}ms in seconds is {:?}s.", MILLIS, func.call());
Expand All @@ -21,11 +21,7 @@ fn main() {

const MILLIS: u64 = 500_000;

unsafe extern "C" fn millis(
_rt: ffi::IM3Runtime,
sp: *mut u64,
_mem: *mut std::ffi::c_void,
) -> *const std::ffi::c_void {
*sp = MILLIS;
ffi::m3Err_none as _
wasm3::make_func_wrapper!(millis_wrap: millis() -> u64);
fn millis() -> u64 {
MILLIS
}
7 changes: 7 additions & 0 deletions src/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ use crate::error::{Error, Result};
use crate::runtime::Runtime;
use crate::{WasmArgs, WasmType};

// redefine of ffi::RawCall without the Option<T> around it
pub type RawCall = unsafe extern "C" fn(
runtime: ffi::IM3Runtime,
_sp: *mut u64,
_mem: *mut libc::c_void,
) -> *const libc::c_void;

#[derive(Debug)]
pub struct Function<'env, 'rt, ARGS, RET> {
raw: ffi::IM3Function,
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ pub mod module;
pub mod runtime;
mod ty;
pub use self::ty::{WasmArg, WasmArgs, WasmType};
mod macros;
pub use self::macros::*;

#[inline]
pub fn print_m3_info() {
Expand Down
66 changes: 66 additions & 0 deletions src/macros.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
//! Public macros

#[macro_export]
macro_rules! make_func_wrapper {
// ptype is an ident because we still want to match on it later -- \/ rtype too -- \/
( $wrapper_name:ident: $original:ident( $( $pname:ident: $ptype:ident ),* $( , )? ) $( -> $rtype:ident )?) => {
unsafe extern "C" fn $wrapper_name(
_rt: ffi::IM3Runtime,
_sp: *mut u64,
_mem: *mut std::ffi::c_void,
) -> *const std::ffi::c_void {
let ssp = _sp;
$(
let $pname = $crate::read_stack_param!(_sp -> $ptype);
let _sp = _sp.add(1);
)*
let ret = $original( $( $pname ),* );
$(
$crate::put_stack_return!(ssp <- ret as $rtype);
)?
ffi::m3Err_none as _
}
};
}

#[doc(hidden)]
#[macro_export]
macro_rules! read_stack_param {
($sp:ident -> u64) => {
*$sp
};
($sp:ident -> u32) => {
(*$sp & 0xFFFF_FFFF) as u32;
};
($sp:ident -> f64) => {
f64::from_ne_bytes((*$sp).to_ne_bytes())
};
($sp:ident -> f32) => {
f64::from_ne_bytes($crate::read_stack_param!($sp -> u32).to_ne_bytes())
};
($sp:ident -> $type:ty) => {
compile_error!(concat!("unknown function argument type ", stringify!($type)))
};
}

#[doc(hidden)]
#[macro_export]
macro_rules! put_stack_return {
($sp:ident <- $ident:ident as u64) => {
*$sp = $ident;
};
($sp:ident -> u32) => {
*$sp = $ident as u64;
};
($sp:ident -> f64) => {
*$sp = u64::from_ne_bytes($ident.to_ne_bytes());
};
($sp:ident -> f32) => {
f64::from_ne_bytes($crate::read_stack_param!($sp -> u32).to_ne_bytes())
*$sp = u32::from_ne_bytes($ident.to_ne_bytes()) as u64;
};
($sp:ident -> ()) => {};
($sp:ident -> $type:ty) => {
compile_error!(concat!("unknown function argument type ", stringify!($type)))
};
}
8 changes: 4 additions & 4 deletions src/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use core::slice;

use crate::environment::Environment;
use crate::error::{Error, Result};
use crate::function::Function;
use crate::function::{Function, RawCall};
use crate::runtime::Runtime;

pub struct ParsedModule<'env> {
Expand Down Expand Up @@ -61,7 +61,7 @@ impl<'env, 'rt> Module<'env, 'rt> {
&mut self,
module_name: &str,
function_name: &str,
f: ffi::M3RawCall,
f: RawCall,
) -> Result<()>
where
ARGS: crate::WasmArgs,
Expand All @@ -76,15 +76,15 @@ impl<'env, 'rt> Module<'env, 'rt> {
}
}

unsafe fn link_func_impl(&self, m3_func: ffi::IM3Function, func: ffi::M3RawCall) {
unsafe fn link_func_impl(&self, m3_func: ffi::IM3Function, func: RawCall) {
let page = ffi::AcquireCodePageWithCapacity(self.rt.as_ptr(), 2);
if page.is_null() {
panic!("oom")
} else {
(*m3_func).compiled = ffi::GetPagePC(page);
(*m3_func).module = self.raw;
ffi::EmitWord_impl(page, ffi::op_CallRawFunction as _);
ffi::EmitWord_impl(page, func.map(|f| f as _).unwrap_or_else(ptr::null_mut));
ffi::EmitWord_impl(page, func as _);

ffi::ReleaseCodePage(self.rt.as_ptr(), page);
}
Expand Down
2 changes: 1 addition & 1 deletion src/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ impl<'env> Runtime<'env> {
module: ParsedModule<'env>,
) -> core::result::Result<Module<'env, 'rt>, (ParsedModule<'env>, Error)> {
if let Err(err) =
unsafe { Error::from_ffi_res(ffi::m3_LoadModule(self.raw, module.as_ptr())) }
Error::from_ffi_res(unsafe { ffi::m3_LoadModule(self.raw, module.as_ptr()) })
{
Err((module, err))
} else {
Expand Down

0 comments on commit 7915db9

Please sign in to comment.