diff --git a/src/apis/emscripten/mod.rs b/src/apis/emscripten/mod.rs index 54c8a0a24..14c0b67b1 100644 --- a/src/apis/emscripten/mod.rs +++ b/src/apis/emscripten/mod.rs @@ -7,6 +7,7 @@ mod memory; mod process; mod syscalls; mod utils; +mod varargs; // SYSCALLS pub use self::utils::is_emscripten_module; diff --git a/src/apis/emscripten/syscalls.rs b/src/apis/emscripten/syscalls.rs index 62c40bf6a..976232e58 100644 --- a/src/apis/emscripten/syscalls.rs +++ b/src/apis/emscripten/syscalls.rs @@ -3,59 +3,47 @@ use libc::{c_int, c_void, ssize_t, write}; use crate::webassembly::Instance; - -// A macro to retrieve variadic arguments given a varargs offset -macro_rules! vararg { - ($name:ident, $type:ident, $instance:ident, $varargs:ident) => ( - let ($name, $varargs) = unsafe { - use std::ptr; - let ptr = $instance.memory_offset_addr(0, $varargs as usize); - let ret = ptr::read(ptr as *const $type); - (ret, $varargs + 4) - }; - ) -} +use super::varargs::VarArgs; /// sys_read -pub extern "C" fn ___syscall3(_which: c_int, _varargs: c_int, _instance: &mut Instance) -> ssize_t { +pub extern "C" fn ___syscall3(_which: c_int, mut _varargs: VarArgs, _instance: &mut Instance) -> ssize_t { debug!("emscripten::___syscall3"); 0 } /// sys_write -pub extern "C" fn ___syscall4(_which: c_int, varargs: c_int, instance: &mut Instance) -> c_int { - debug!("emscripten::___syscall4"); - vararg!(fd, i32, instance, varargs); - vararg!(buf_ptr, u32, instance, varargs); - vararg!(count, u32, instance, varargs); +pub extern "C" fn ___syscall4(_which: c_int, mut varargs: VarArgs, instance: &mut Instance) -> c_int { + let fd: i32 = varargs.get(instance); + let buf_ptr: u32 = varargs.get(instance); + let count: u32 = varargs.get(instance); debug!("fd: {}, buf_ptr: {}, count: {}", fd, buf_ptr, count); let buf = instance.memory_offset_addr(0, buf_ptr as usize) as *const c_void; unsafe { write(fd, buf, count as usize) as i32 } } /// sys_open -pub extern "C" fn ___syscall5(_which: c_int, varargs: c_int, instance: &mut Instance) -> c_int { +pub extern "C" fn ___syscall5(_which: c_int, mut varargs: VarArgs, instance: &mut Instance) -> c_int { debug!("emscripten::___syscall5"); - vararg!(pathname, u32, instance, varargs); - vararg!(flags, u32, instance, varargs); - vararg!(mode, u32, instance, varargs); + let pathname: u32 = varargs.get(instance); + let flags: u32 = varargs.get(instance); + let mode: u32 = varargs.get(instance); debug!("pathname: {}, flags: {}, mode: {}", pathname, flags, mode); -2 } // sys_ioctl -pub extern "C" fn ___syscall54(_which: c_int, varargs: c_int, instance: &mut Instance) -> c_int { +pub extern "C" fn ___syscall54(_which: c_int, mut varargs: VarArgs, instance: &mut Instance) -> c_int { debug!("emscripten::___syscall54"); - vararg!(stream, u32, instance, varargs); - vararg!(op, u32, instance, varargs); + let stream: u32 = varargs.get(instance); + let op: u32 = varargs.get(instance); debug!("stream: {}, op: {}", stream, op); 0 } // sys_newuname -pub extern "C" fn ___syscall122(_which: c_int, varargs: c_int, instance: &mut Instance) -> c_int { +pub extern "C" fn ___syscall122(_which: c_int, mut varargs: VarArgs, instance: &mut Instance) -> c_int { debug!("emscripten::___syscall122"); - vararg!(buf, u32, instance, varargs); + let buf: u32 = varargs.get(instance); debug!("buf: {}", buf); 0 } diff --git a/src/apis/emscripten/varargs.rs b/src/apis/emscripten/varargs.rs new file mode 100644 index 000000000..7f5cf3577 --- /dev/null +++ b/src/apis/emscripten/varargs.rs @@ -0,0 +1,15 @@ +use crate::webassembly::Instance; +use std::mem; + +#[repr(transparent)] +pub struct VarArgs { + pointer: u32, // assuming 32bit wasm +} + +impl VarArgs { + pub fn get(&mut self, instance: &mut Instance) -> T { + let ptr = instance.memory_offset_addr(0, self.pointer as usize); + self.pointer += mem::size_of::() as u32; + unsafe { (ptr as *const T).read() } + } +} \ No newline at end of file