diff --git a/vm/Cargo.toml b/vm/Cargo.toml index 60dfa0b282..2f24f0c46e 100644 --- a/vm/Cargo.toml +++ b/vm/Cargo.toml @@ -97,13 +97,15 @@ crc32fast = "1.2.0" adler32 = "1.0.3" gethostname = "0.2.0" subprocess = "0.2.2" -num_cpus = "1" socket2 = { version = "0.3", features = ["unix"] } rustyline = "6.0" openssl = { version = "0.10", features = ["vendored"] } openssl-sys = "0.9" openssl-probe = "0.1" +[target.'cfg(any(not(target_arch = "wasm32"), target_os = "wasi"))'.dependencies] +num_cpus = "1" + [target.'cfg(not(any(target_arch = "wasm32", target_os = "redox")))'.dependencies] dns-lookup = "1.0" flate2 = { version = "1.0", features = ["zlib"], default-features = false } diff --git a/vm/src/stdlib/io.rs b/vm/src/stdlib/io.rs index fc1c8ea4af..836bfa9e86 100644 --- a/vm/src/stdlib/io.rs +++ b/vm/src/stdlib/io.rs @@ -516,7 +516,7 @@ fn buffered_reader_close(instance: PyObjectRef, vm: &VirtualMachine) -> PyResult } // disable FileIO on WASM -#[cfg(not(target_arch = "wasm32"))] +#[cfg(any(not(target_arch = "wasm32"), target_os = "wasi"))] mod fileio { use super::super::os; use super::*; @@ -658,23 +658,9 @@ mod fileio { Ok(len) } - #[cfg(windows)] fn file_io_close(instance: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { let raw_handle = i64::try_from_object(vm, vm.get_attribute(instance.clone(), "__fileno")?)?; - unsafe { - winapi::um::handleapi::CloseHandle(raw_handle as _); - } - vm.set_attr(&instance, "closefd", vm.new_bool(true))?; - vm.set_attr(&instance, "__closed", vm.new_bool(true))?; - Ok(()) - } - - #[cfg(unix)] - fn file_io_close(instance: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { - let raw_fd = i64::try_from_object(vm, vm.get_attribute(instance.clone(), "__fileno")?)?; - unsafe { - libc::close(raw_fd as _); - } + drop(os::rust_file(raw_handle)); vm.set_attr(&instance, "closefd", vm.new_bool(true))?; vm.set_attr(&instance, "__closed", vm.new_bool(true))?; Ok(()) @@ -1051,7 +1037,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef { "DEFAULT_BUFFER_SIZE" => ctx.new_int(8 * 1024), }); - #[cfg(not(target_arch = "wasm32"))] + #[cfg(any(not(target_arch = "wasm32"), target_os = "wasi"))] extend_module!(vm, module, { "FileIO" => fileio::make_fileio(ctx, raw_io_base), }); diff --git a/vm/src/stdlib/mod.rs b/vm/src/stdlib/mod.rs index d1c5bfb8a7..0758d6447d 100644 --- a/vm/src/stdlib/mod.rs +++ b/vm/src/stdlib/mod.rs @@ -37,7 +37,7 @@ mod unicodedata; mod warnings; mod weakref; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(any(not(target_arch = "wasm32"), target_os = "wasi"))] #[macro_use] mod os; @@ -112,10 +112,12 @@ pub fn get_module_inits() -> HashMap { modules.insert("symtable".to_owned(), Box::new(symtable::make_module)); } + #[cfg(any(unix, windows, target_os = "wasi"))] + modules.insert(os::MODULE_NAME.to_owned(), Box::new(os::make_module)); + // disable some modules on WASM #[cfg(not(target_arch = "wasm32"))] { - modules.insert(os::MODULE_NAME.to_owned(), Box::new(os::make_module)); modules.insert("_socket".to_owned(), Box::new(socket::make_module)); modules.insert( "_multiprocessing".to_owned(), diff --git a/vm/src/stdlib/os.rs b/vm/src/stdlib/os.rs index 0224c0e40c..2d73790ac8 100644 --- a/vm/src/stdlib/os.rs +++ b/vm/src/stdlib/os.rs @@ -85,12 +85,24 @@ pub fn rust_file(raw_fileno: i64) -> File { unsafe { File::from_raw_handle(raw_fileno) } } -#[cfg(all(not(unix), not(windows)))] +#[cfg(target_os = "wasi")] +pub fn raw_file_number(handle: File) -> i64 { + // This should be safe, since the wasi api is pretty well defined, but once + // `wasi_ext` get's stabilized, we should use that instead. + unsafe { std::mem::transmute::<_, u32>(handle).into() } +} + +#[cfg(target_os = "wasi")] +pub fn rust_file(raw_fileno: i64) -> File { + unsafe { std::mem::transmute(raw_fileno as u32) } +} + +#[cfg(not(any(unix, windows, target_os = "wasi")))] pub fn rust_file(raw_fileno: i64) -> File { unimplemented!(); } -#[cfg(all(not(unix), not(windows)))] +#[cfg(not(any(unix, windows, target_os = "wasi")))] pub fn raw_file_number(handle: File) -> i64 { unimplemented!(); } @@ -168,8 +180,10 @@ fn os_close(fileno: i64) { type OpenFlags = i32; #[cfg(windows)] type OpenFlags = u32; +#[cfg(target_os = "wasi")] +type OpenFlags = u16; -#[cfg(any(unix, windows))] +#[cfg(any(unix, windows, target_os = "wasi"))] pub fn os_open( name: PyStringRef, flags: OpenFlags, @@ -213,6 +227,7 @@ pub fn os_open( #[cfg(windows)] let flags = flags & !(libc::O_WRONLY as u32); + #[cfg(not(target_os = "wasi"))] options.custom_flags(flags); let handle = options .open(fname) @@ -221,7 +236,7 @@ pub fn os_open( Ok(raw_file_number(handle)) } -#[cfg(all(not(unix), not(windows)))] +#[cfg(not(any(unix, windows, target_os = "wasi")))] pub fn os_open(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult { unimplemented!() } @@ -490,7 +505,7 @@ fn bytes_as_osstr<'a>(b: &'a [u8], vm: &VirtualMachine) -> PyResult<&'a ffi::OsS use std::os::unix::ffi::OsStrExt; Some(ffi::OsStr::from_bytes(b)) } - #[cfg(windows)] + #[cfg(not(unix))] { std::str::from_utf8(b).ok().map(|s| s.as_ref()) } @@ -889,9 +904,10 @@ fn os_stat( windows )))] fn os_stat( - _file: Either, + file: Either, _dir_fd: DirFd, - _follow_symlinks: FollowSymlinks, + follow_symlinks: FollowSymlinks, + vm: &VirtualMachine, ) -> PyResult { unimplemented!(); } @@ -978,6 +994,10 @@ fn os_get_inheritable(fd: RawFd, vm: &VirtualMachine) -> PyResult { } fn os_set_inheritable(fd: i64, inheritable: bool, vm: &VirtualMachine) -> PyResult<()> { + #[cfg(not(any(unix, windows)))] + { + unimplemented!() + } #[cfg(unix)] { let fd = fd as RawFd; @@ -1523,11 +1543,13 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef { "supports_follow_symlinks" => supports_follow_symlinks.into_object(), }); - extend_module_platform_specific(&vm, module) + extend_module_platform_specific(&vm, &module); + + module } #[cfg(unix)] -fn extend_module_platform_specific(vm: &VirtualMachine, module: PyObjectRef) -> PyObjectRef { +fn extend_module_platform_specific(vm: &VirtualMachine, module: &PyObjectRef) { let ctx = &vm.ctx; let uname_result = UnameResult::make_class(ctx); @@ -1611,16 +1633,15 @@ fn extend_module_platform_specific(vm: &VirtualMachine, module: PyObjectRef) -> extend_module!(vm, module, { "pipe2" => ctx.new_function(os_pipe2), }); - - module } #[cfg(windows)] -fn extend_module_platform_specific(vm: &VirtualMachine, module: PyObjectRef) -> PyObjectRef { +fn extend_module_platform_specific(vm: &VirtualMachine, module: &PyObjectRef) { let ctx = &vm.ctx; extend_module!(vm, module, { "O_BINARY" => ctx.new_int(libc::O_BINARY), }); - - module } + +#[cfg(not(any(unix, windows)))] +fn extend_module_platform_specific(_vm: &VirtualMachine, _module: &PyObjectRef) {} diff --git a/vm/src/vm.rs b/vm/src/vm.rs index d8d2e7b0c7..330842e1c3 100644 --- a/vm/src/vm.rs +++ b/vm/src/vm.rs @@ -239,7 +239,7 @@ impl VirtualMachine { import::init_importlib(self, initialize_parameter)?; - #[cfg(not(target_arch = "wasm32"))] + #[cfg(any(not(target_arch = "wasm32"), target_os = "wasi"))] { let io = self.import("io", &[], 0)?; let io_open = self.get_attribute(io.clone(), "open")?;