diff --git a/Assets/dll/libwaterboxhost.so b/Assets/dll/libwaterboxhost.so index 8d78ea5ad6..4949ca778a 100644 Binary files a/Assets/dll/libwaterboxhost.so and b/Assets/dll/libwaterboxhost.so differ diff --git a/Assets/dll/waterboxhost.dll b/Assets/dll/waterboxhost.dll index 95569f3fd3..db2bf44449 100644 Binary files a/Assets/dll/waterboxhost.dll and b/Assets/dll/waterboxhost.dll differ diff --git a/waterbox/waterboxhost/src/lib.rs b/waterbox/waterboxhost/src/lib.rs index 52645961f4..455df6692e 100644 --- a/waterbox/waterboxhost/src/lib.rs +++ b/waterbox/waterboxhost/src/lib.rs @@ -1,6 +1,8 @@ #![crate_type = "cdylib"] -#![feature(try_trait)] +#![feature(try_trait_v2)] +#![feature(never_type)] +#![feature(control_flow_enum)] #![feature(core_intrinsics)] #![feature(asm)] #![feature(map_first_last)] diff --git a/waterbox/waterboxhost/src/syscall_defs.rs b/waterbox/waterboxhost/src/syscall_defs.rs index 9328ca5803..f42a1c9722 100644 --- a/waterbox/waterboxhost/src/syscall_defs.rs +++ b/waterbox/waterboxhost/src/syscall_defs.rs @@ -2,7 +2,7 @@ // There are various crates that contain these, but they're #[cfg]'ed to the HOST system. // We want exactly the ones that waterbox guest MUSL uses, exactly the way they're defined there -use std::{ops::Try, fmt}; +use std::{ops::Try, fmt, ops::ControlFlow, ops::FromResidual}; /// the result of a syscall in Rust-friendly form; OK or errno pub type SyscallResult = Result<(), SyscallError>; @@ -40,21 +40,37 @@ pub fn syscall_ok(result: usize) -> SyscallReturn { pub struct SyscallReturn(pub usize); impl SyscallReturn { pub const ERROR_THRESH: usize = -4096 as isize as usize; -} -impl Try for SyscallReturn { - type Ok = usize; - type Error = SyscallError; - fn into_result(self) -> Result { - if self.0 <= SyscallReturn::ERROR_THRESH { - Ok(self.0) - } else { - Err(SyscallError(-(self.0 as i32))) - } + pub fn from_ok(v: usize) -> Self { + Self::from_output(v) } - fn from_error(v: Self::Error) -> Self { + pub fn from_error(v: SyscallError) -> Self { + Self::from_residual(v) + } +} +impl FromResidual for SyscallReturn { + fn from_residual(v: SyscallError) -> Self { SyscallReturn(-v.0 as isize as usize) } - fn from_ok(v: Self::Ok) -> Self { +} +impl FromResidual> for SyscallReturn { + fn from_residual(v: Result) -> Self { + match v { + Ok(never) => match never {}, + Err(zz) => SyscallReturn(-zz.0 as isize as usize), + } + } +} +impl Try for SyscallReturn { + type Output = usize; + type Residual = SyscallError; + fn branch(self) -> ControlFlow { + if self.0 <= SyscallReturn::ERROR_THRESH { + ControlFlow::Continue(self.0) + } else { + ControlFlow::Break(SyscallError(-(self.0 as i32))) + } + } + fn from_output(v: Self::Output) -> Self { assert!(v <= SyscallReturn::ERROR_THRESH); SyscallReturn(v) }