diff --git a/lib/singlepass-backend/src/emitter_x64.rs b/lib/singlepass-backend/src/emitter_x64.rs index 3476bd289..328fcef26 100644 --- a/lib/singlepass-backend/src/emitter_x64.rs +++ b/lib/singlepass-backend/src/emitter_x64.rs @@ -635,18 +635,14 @@ impl Emitter for Assembler { match (sz, src) { (Size::S64, Location::Imm32(src)) => dynasm!(self ; push src as i32), (Size::S64, Location::GPR(src)) => dynasm!(self ; push Rq(src as u8)), - (Size::S64, Location::Memory(src, disp)) => { - dynasm!(self ; push QWORD [Rq(src as u8) + disp]) - } + (Size::S64, Location::Memory(src, disp)) => dynasm!(self ; push QWORD [Rq(src as u8) + disp]), _ => panic!("push {:?} {:?}", sz, src), } } fn emit_pop(&mut self, sz: Size, dst: Location) { match (sz, dst) { (Size::S64, Location::GPR(dst)) => dynasm!(self ; pop Rq(dst as u8)), - (Size::S64, Location::Memory(dst, disp)) => { - dynasm!(self ; pop QWORD [Rq(dst as u8) + disp]) - } + (Size::S64, Location::Memory(dst, disp)) => dynasm!(self ; pop QWORD [Rq(dst as u8) + disp]), _ => panic!("pop {:?} {:?}", sz, dst), } } @@ -851,54 +847,42 @@ impl Emitter for Assembler { fn emit_ucomiss(&mut self, src: XMMOrMemory, dst: XMM) { match src { XMMOrMemory::XMM(x) => dynasm!(self ; ucomiss Rx(dst as u8), Rx(x as u8)), - XMMOrMemory::Memory(base, disp) => { - dynasm!(self ; ucomiss Rx(dst as u8), [Rq(base as u8) + disp]) - } + XMMOrMemory::Memory(base, disp) => dynasm!(self ; ucomiss Rx(dst as u8), [Rq(base as u8) + disp]), } } fn emit_ucomisd(&mut self, src: XMMOrMemory, dst: XMM) { match src { XMMOrMemory::XMM(x) => dynasm!(self ; ucomisd Rx(dst as u8), Rx(x as u8)), - XMMOrMemory::Memory(base, disp) => { - dynasm!(self ; ucomisd Rx(dst as u8), [Rq(base as u8) + disp]) - } + XMMOrMemory::Memory(base, disp) => dynasm!(self ; ucomisd Rx(dst as u8), [Rq(base as u8) + disp]), } } fn emit_cvttss2si_32(&mut self, src: XMMOrMemory, dst: GPR) { match src { XMMOrMemory::XMM(x) => dynasm!(self ; cvttss2si Rd(dst as u8), Rx(x as u8)), - XMMOrMemory::Memory(base, disp) => { - dynasm!(self ; cvttss2si Rd(dst as u8), [Rq(base as u8) + disp]) - } + XMMOrMemory::Memory(base, disp) => dynasm!(self ; cvttss2si Rd(dst as u8), [Rq(base as u8) + disp]), } } fn emit_cvttss2si_64(&mut self, src: XMMOrMemory, dst: GPR) { match src { XMMOrMemory::XMM(x) => dynasm!(self ; cvttss2si Rq(dst as u8), Rx(x as u8)), - XMMOrMemory::Memory(base, disp) => { - dynasm!(self ; cvttss2si Rq(dst as u8), [Rq(base as u8) + disp]) - } + XMMOrMemory::Memory(base, disp) => dynasm!(self ; cvttss2si Rq(dst as u8), [Rq(base as u8) + disp]), } } fn emit_cvttsd2si_32(&mut self, src: XMMOrMemory, dst: GPR) { match src { XMMOrMemory::XMM(x) => dynasm!(self ; cvttsd2si Rd(dst as u8), Rx(x as u8)), - XMMOrMemory::Memory(base, disp) => { - dynasm!(self ; cvttsd2si Rd(dst as u8), [Rq(base as u8) + disp]) - } + XMMOrMemory::Memory(base, disp) => dynasm!(self ; cvttsd2si Rd(dst as u8), [Rq(base as u8) + disp]), } } fn emit_cvttsd2si_64(&mut self, src: XMMOrMemory, dst: GPR) { match src { XMMOrMemory::XMM(x) => dynasm!(self ; cvttsd2si Rq(dst as u8), Rx(x as u8)), - XMMOrMemory::Memory(base, disp) => { - dynasm!(self ; cvttsd2si Rq(dst as u8), [Rq(base as u8) + disp]) - } + XMMOrMemory::Memory(base, disp) => dynasm!(self ; cvttsd2si Rq(dst as u8), [Rq(base as u8) + disp]), } } diff --git a/lib/wasi-tests/build/wasitests.rs b/lib/wasi-tests/build/wasitests.rs index 3ad628654..aefab31ed 100644 --- a/lib/wasi-tests/build/wasitests.rs +++ b/lib/wasi-tests/build/wasitests.rs @@ -63,6 +63,22 @@ pub fn compile(file: &str, ignores: &HashSet) -> Option { std::fs::remove_file(&normalized_name).expect("could not delete executable"); let wasm_out_name = format!("{}.wasm", &normalized_name); + let mut file_contents = String::new(); + { + let mut file = std::fs::File::open(file).unwrap(); + file.read_to_string(&mut file_contents).unwrap(); + } + { + let mut actual_file = std::fs::OpenOptions::new() + .write(true) + .truncate(true) + .open(file) + .unwrap(); + actual_file + .write_all(format!("#![feature(wasi_ext)]\n{}", &file_contents).as_bytes()) + .unwrap(); + } + let wasm_compilation_out = Command::new("rustc") .arg("+nightly") .arg("--target=wasm32-wasi") @@ -74,6 +90,14 @@ pub fn compile(file: &str, ignores: &HashSet) -> Option { .output() .expect("Failed to compile program to native code"); print_info_on_error(&wasm_compilation_out, "WASM COMPILATION"); + { + let mut actual_file = std::fs::OpenOptions::new() + .write(true) + .truncate(true) + .open(file) + .unwrap(); + actual_file.write_all(file_contents.as_bytes()).unwrap(); + } // to prevent commiting huge binary blobs forever let wasm_strip_out = Command::new("wasm-strip") diff --git a/lib/wasi-tests/tests/wasitests/fd_pread.rs b/lib/wasi-tests/tests/wasitests/fd_pread.rs new file mode 100644 index 000000000..cfd8f2ac5 --- /dev/null +++ b/lib/wasi-tests/tests/wasitests/fd_pread.rs @@ -0,0 +1,14 @@ +#[test] +fn test_fd_pread() { + assert_wasi_output!( + "../../wasitests/fd_pread.wasm", + "fd_pread", + vec![], + vec![( + ".".to_string(), + ::std::path::PathBuf::from("wasitests/test_fs/hamlet") + ),], + vec![], + "../../wasitests/fd_pread.out" + ); +} diff --git a/lib/wasi-tests/tests/wasitests/mod.rs b/lib/wasi-tests/tests/wasitests/mod.rs index a7d06db06..262592b00 100644 --- a/lib/wasi-tests/tests/wasitests/mod.rs +++ b/lib/wasi-tests/tests/wasitests/mod.rs @@ -7,6 +7,7 @@ mod _common; mod create_dir; mod envvar; +mod fd_pread; mod file_metadata; mod fs_sandbox_test; mod fseek; diff --git a/lib/wasi-tests/wasitests/create_dir.wasm b/lib/wasi-tests/wasitests/create_dir.wasm index 9847f3bec..2fa023792 100755 Binary files a/lib/wasi-tests/wasitests/create_dir.wasm and b/lib/wasi-tests/wasitests/create_dir.wasm differ diff --git a/lib/wasi-tests/wasitests/envvar.wasm b/lib/wasi-tests/wasitests/envvar.wasm index a952a6c04..ef539e6a5 100755 Binary files a/lib/wasi-tests/wasitests/envvar.wasm and b/lib/wasi-tests/wasitests/envvar.wasm differ diff --git a/lib/wasi-tests/wasitests/fd_pread.out b/lib/wasi-tests/wasitests/fd_pread.out new file mode 100644 index 000000000..a83632aea --- /dev/null +++ b/lib/wasi-tests/wasitests/fd_pread.out @@ -0,0 +1,9 @@ + POLONIUS + + He will come straight. Look you lay home to him: + + POLONIUS + + He will come straight. Look you lay home to him: + +Read the same data? true \ No newline at end of file diff --git a/lib/wasi-tests/wasitests/fd_pread.rs b/lib/wasi-tests/wasitests/fd_pread.rs new file mode 100644 index 000000000..72addfdfe --- /dev/null +++ b/lib/wasi-tests/wasitests/fd_pread.rs @@ -0,0 +1,87 @@ +// Args: +// mapdir: .:wasitests/test_fs/hamlet + +use std::fs; +#[cfg(target_os = "wasi")] +use std::os::wasi::prelude::AsRawFd; +use std::path::PathBuf; + +#[cfg(target_os = "wasi")] +#[repr(C)] +struct WasiIovec { + pub buf: u32, + pub buf_len: u32, +} + +#[cfg(target_os = "wasi")] +#[link(wasm_import_module = "wasi_unstable")] +extern "C" { + fn fd_pread(fd: u32, iovs: u32, iovs_len: u32, offset: u64, nread: u32) -> u16; +} + +#[cfg(target_os = "wasi")] +fn pread(fd: u32, iovs: &[&mut [u8]], offset: u64) -> u32 { + let mut nread = 0; + let mut processed_iovs = vec![]; + + for iov in iovs { + processed_iovs.push(WasiIovec { + buf: iov.as_ptr() as usize as u32, + buf_len: iov.len() as u32, + }) + } + + unsafe { + fd_pread( + fd, + processed_iovs.as_ptr() as usize as u32, + processed_iovs.len() as u32, + offset, + &mut nread as *mut u32 as usize as u32, + ); + } + nread +} + +fn main() { + #[cfg(not(target_os = "wasi"))] + let mut base = PathBuf::from("wasitests/test_fs/hamlet"); + #[cfg(target_os = "wasi")] + let mut base = PathBuf::from("."); + + base.push("act3/scene4.txt"); + let mut file = fs::File::open(&base).expect("Could not open file"); + let mut buffer = [0u8; 64]; + + #[cfg(target_os = "wasi")] + { + let raw_fd = file.as_raw_fd(); + assert_eq!(pread(raw_fd, &[&mut buffer], 75), 64); + let str_val = std::str::from_utf8(&buffer[..]).unwrap().to_string(); + println!("{}", &str_val); + for i in 0..buffer.len() { + buffer[i] = 0; + } + assert_eq!(pread(raw_fd, &[&mut buffer], 75), 64); + let str_val2 = std::str::from_utf8(&buffer[..]).unwrap().to_string(); + println!("{}", &str_val2); + + println!("Read the same data? {}", str_val == str_val2); + } + + #[cfg(not(target_os = "wasi"))] + { + // eh, just print the output directly + print!( + " POLONIUS + + He will come straight. Look you lay home to him: + + POLONIUS + + He will come straight. Look you lay home to him: + +Read the same data? true" + ); + } +} diff --git a/lib/wasi-tests/wasitests/fd_pread.wasm b/lib/wasi-tests/wasitests/fd_pread.wasm new file mode 100755 index 000000000..a6fdb0c33 Binary files /dev/null and b/lib/wasi-tests/wasitests/fd_pread.wasm differ diff --git a/lib/wasi-tests/wasitests/file_metadata.wasm b/lib/wasi-tests/wasitests/file_metadata.wasm index fd9b2ba97..986362c58 100755 Binary files a/lib/wasi-tests/wasitests/file_metadata.wasm and b/lib/wasi-tests/wasitests/file_metadata.wasm differ diff --git a/lib/wasi-tests/wasitests/fs_sandbox_test.wasm b/lib/wasi-tests/wasitests/fs_sandbox_test.wasm index 901bdaf16..255287806 100755 Binary files a/lib/wasi-tests/wasitests/fs_sandbox_test.wasm and b/lib/wasi-tests/wasitests/fs_sandbox_test.wasm differ diff --git a/lib/wasi-tests/wasitests/fseek.wasm b/lib/wasi-tests/wasitests/fseek.wasm index 20b51e1f6..f50045437 100755 Binary files a/lib/wasi-tests/wasitests/fseek.wasm and b/lib/wasi-tests/wasitests/fseek.wasm differ diff --git a/lib/wasi-tests/wasitests/hello.wasm b/lib/wasi-tests/wasitests/hello.wasm index 3e2cfc436..758a14bd1 100755 Binary files a/lib/wasi-tests/wasitests/hello.wasm and b/lib/wasi-tests/wasitests/hello.wasm differ diff --git a/lib/wasi-tests/wasitests/mapdir.wasm b/lib/wasi-tests/wasitests/mapdir.wasm index ae0eba16b..c6e594991 100755 Binary files a/lib/wasi-tests/wasitests/mapdir.wasm and b/lib/wasi-tests/wasitests/mapdir.wasm differ diff --git a/lib/wasi-tests/wasitests/quine.wasm b/lib/wasi-tests/wasitests/quine.wasm index 086f19844..fc6361b5c 100755 Binary files a/lib/wasi-tests/wasitests/quine.wasm and b/lib/wasi-tests/wasitests/quine.wasm differ diff --git a/lib/wasi-tests/wasitests/readlink.wasm b/lib/wasi-tests/wasitests/readlink.wasm index c04abb75d..67ada4404 100755 Binary files a/lib/wasi-tests/wasitests/readlink.wasm and b/lib/wasi-tests/wasitests/readlink.wasm differ diff --git a/lib/wasi-tests/wasitests/wasi_sees_virtual_root.wasm b/lib/wasi-tests/wasitests/wasi_sees_virtual_root.wasm index 6d0b3cd3a..4c819b4cc 100755 Binary files a/lib/wasi-tests/wasitests/wasi_sees_virtual_root.wasm and b/lib/wasi-tests/wasitests/wasi_sees_virtual_root.wasm differ diff --git a/lib/wasi-tests/wasitests/writing.wasm b/lib/wasi-tests/wasitests/writing.wasm index eae2eb97b..148add04d 100755 Binary files a/lib/wasi-tests/wasitests/writing.wasm and b/lib/wasi-tests/wasitests/writing.wasm differ