diff --git a/src/vm.rs b/src/vm.rs index 2e38b33..94f6b04 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -340,7 +340,7 @@ impl VM { &mut self.memory } - fn push(&mut self, val: Value) -> VMResult<()> { + pub(crate) fn push(&mut self, val: Value) -> VMResult<()> { if self.value_stack.len() >= VALUE_STACK_LIMIT { return Err(Trap::ValueStackOverflow); } @@ -348,7 +348,7 @@ impl VM { Ok(()) } - fn pop(&mut self) -> VMResult { + pub(crate) fn pop(&mut self) -> VMResult { self.value_stack.pop().ok_or(Trap::PopFromEmptyStack) } @@ -651,7 +651,17 @@ impl VM { let func = self.module.get_func(self.ip.func_index).unwrap(); if func.is_imported() { if let Some(wasi_func) = func.wasi_function() { - return wasi_func.handle(self); + wasi_func.handle(self)?; + loop { + if let Some(Label::Return) = self.label_stack.pop() { + if !self.label_stack.is_empty() { + let frame = self.function_stack.pop().unwrap(); + self.ip = frame.ret_addr; + } + break; + } + } + return Ok(()); } return Err(Trap::UnsupportedCallToImportedFunction(self.ip.func_index)); } diff --git a/src/wasi.rs b/src/wasi.rs index da19534..264aa07 100644 --- a/src/wasi.rs +++ b/src/wasi.rs @@ -26,7 +26,7 @@ impl WasiFunction { // "fd_prestat_dir_name" => WasiFunction::FdPrestatDirName, // "fd_seek" => WasiFunction::FdSeek, // "fd_read" => WasiFunction::FdRead, - // "fd_write" => WasiFunction::FdWrite, + "fd_write" => WasiFunction::FdWrite, // "fd_close" => WasiFunction::FdClose, // "path_open" => WasiFunction::PathOpen, "proc_exit" => WasiFunction::ProcExit, @@ -46,7 +46,29 @@ impl WasiFunction { WasiFunction::FdPrestatDirName => (), WasiFunction::FdSeek => (), WasiFunction::FdRead => (), - WasiFunction::FdWrite => (), + WasiFunction::FdWrite => { + let fd = vm.locals()?[0].to::().unwrap(); + let iovs = vm.locals()?[1].to::().unwrap(); + let iovs_len = vm.locals()?[2].to::().unwrap(); + let nwritten_out = vm.locals()?[3].to::().unwrap(); + let mut nwritten = 0; + if fd != 1 { + panic!("wasi.fd_write call with fd != stdout"); + } + for i in 0..iovs_len { + let iov = iovs + i * 8; + let str_addr: u32 = vm.memory().load(iov)?; + let len: u32 = vm.memory().load(iov + 4)?; + let start = str_addr as usize; + let end = (str_addr + len) as usize; + let s = &vm.memory().data()[start..end]; + print!("{}", String::from_utf8(s.to_vec()).unwrap()); + nwritten += len; + } + let errno: u32 = 0; + vm.push(errno.into())?; + vm.memory_mut().store(nwritten_out, nwritten)?; + } WasiFunction::FdClose => (), WasiFunction::PathOpen => (), WasiFunction::ProcExit => return Err(Trap::WasiExit(vm.pop_as()?)),