From 39cf60bc05236d304cdec233ea0c84d1a1e78bcf Mon Sep 17 00:00:00 2001 From: Peter Mikkelsen Date: Fri, 22 Aug 2025 11:02:59 +0200 Subject: [PATCH 1/3] Don't use "readline" input functionality for the following builtins: * peek_byte * peek_char * peek_code * get_byte * get_char * get_code * get_n_chars --- src/machine/system_calls.rs | 7 ++++++ src/read.rs | 45 ++++++++++++++++++++++++++++++++++--- 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/src/machine/system_calls.rs b/src/machine/system_calls.rs index 60a4a515..06bf481e 100644 --- a/src/machine/system_calls.rs +++ b/src/machine/system_calls.rs @@ -2600,6 +2600,7 @@ impl Machine { #[inline(always)] pub(crate) fn peek_byte(&mut self) -> CallResult { + let _guard = RawReadGuard::new(); let stub_gen = || functor_stub(atom!("peek_byte"), 2); let mut stream = self.machine_st.get_stream_or_alias( @@ -2690,6 +2691,7 @@ impl Machine { #[inline(always)] pub(crate) fn peek_char(&mut self) -> CallResult { + let _guard = RawReadGuard::new(); let stub_gen = || functor_stub(atom!("peek_char"), 2); let mut stream = self.machine_st.get_stream_or_alias( @@ -2784,6 +2786,7 @@ impl Machine { #[inline(always)] pub(crate) fn peek_code(&mut self) -> CallResult { + let _guard = RawReadGuard::new(); let stub_gen = || functor_stub(atom!("peek_code"), 2); let mut stream = self.machine_st.get_stream_or_alias( @@ -3437,6 +3440,7 @@ impl Machine { #[inline(always)] pub(crate) fn get_byte(&mut self) -> CallResult { + let _guard = RawReadGuard::new(); let mut stream = self.machine_st.get_stream_or_alias( self.machine_st.registers[1], &self.indices, @@ -3521,6 +3525,7 @@ impl Machine { #[inline(always)] pub(crate) fn get_char(&mut self) -> CallResult { + let _guard = RawReadGuard::new(); let mut stream = self.machine_st.get_stream_or_alias( self.machine_st.registers[1], &self.indices, @@ -3616,6 +3621,7 @@ impl Machine { #[inline(always)] pub(crate) fn get_n_chars(&mut self) -> CallResult { + let _guard = RawReadGuard::new(); let stream = self.machine_st.get_stream_or_alias( self.machine_st.registers[1], &self.indices, @@ -3688,6 +3694,7 @@ impl Machine { #[inline(always)] pub(crate) fn get_code(&mut self) -> CallResult { + let _guard = RawReadGuard::new(); let mut stream = self.machine_st.get_stream_or_alias( self.machine_st.registers[1], &self.indices, diff --git a/src/read.rs b/src/read.rs index 4c6b033c..636a6f49 100644 --- a/src/read.rs +++ b/src/read.rs @@ -107,6 +107,30 @@ fn get_prompt() -> &'static str { } } +static mut RAW_READ: bool = false; + +pub struct RawReadGuard; + +impl RawReadGuard { + pub fn new() -> RawReadGuard { + unsafe { + if RAW_READ { + panic!("Nested RawReadGuards"); + } + RAW_READ = true; + } + RawReadGuard + } +} + +impl Drop for RawReadGuard { + fn drop(&mut self) { + unsafe { + RAW_READ = false; + } + } +} + #[derive(Debug)] pub struct ReadlineStream { #[cfg(feature = "repl")] @@ -172,7 +196,23 @@ impl ReadlineStream { #[cfg(feature = "repl")] fn call_readline(&mut self) -> std::io::Result { - match self.rl.readline(get_prompt()) { + let raw = unsafe { RAW_READ }; + let text = if raw { + let mut buffer = String::new(); + let stdin = std::io::stdin(); + match stdin.read_line(&mut buffer) { + Ok(_) => Ok(buffer), + Err(e) => Err(e), + } + } else { + match self.rl.readline(get_prompt()) { + Ok(text) => Ok(text), + Err(ReadlineError::Eof) => Err(Error::from(ErrorKind::UnexpectedEof)), + Err(e) => Err(Error::new(ErrorKind::InvalidInput, e)), + } + }; + + match text { Ok(text) => { self.pending_input.reset_buffer(); @@ -195,8 +235,7 @@ impl ReadlineStream { Ok(self.pending_input.get_ref().get_ref().len()) } - Err(ReadlineError::Eof) => Err(Error::from(ErrorKind::UnexpectedEof)), - Err(e) => Err(Error::new(ErrorKind::InvalidInput, e)), + Err(e) => Err(e) } } From 90e6e843128dfa1c1d3fa46e3229be39d4b88d7c Mon Sep 17 00:00:00 2001 From: Peter Mikkelsen Date: Sun, 24 Aug 2025 14:17:41 +0200 Subject: [PATCH 2/3] Update src/read.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bennet Bleßmann <3877590+Skgland@users.noreply.github.com> --- src/read.rs | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/read.rs b/src/read.rs index 636a6f49..586ab738 100644 --- a/src/read.rs +++ b/src/read.rs @@ -107,27 +107,25 @@ fn get_prompt() -> &'static str { } } -static mut RAW_READ: bool = false; +thread_local! { + static RAW_READ: std::cell::Cell = const { std::cell::Cell::new(false) }; +} pub struct RawReadGuard; impl RawReadGuard { pub fn new() -> RawReadGuard { - unsafe { - if RAW_READ { - panic!("Nested RawReadGuards"); - } - RAW_READ = true; + if RAW_READ.get() { + panic!("Nested RawReadGuards"); } + RAW_READ.set(true); RawReadGuard } } impl Drop for RawReadGuard { fn drop(&mut self) { - unsafe { - RAW_READ = false; - } + RAW_READ.set(false); } } @@ -196,8 +194,7 @@ impl ReadlineStream { #[cfg(feature = "repl")] fn call_readline(&mut self) -> std::io::Result { - let raw = unsafe { RAW_READ }; - let text = if raw { + let text = if RAW_READ.get() { let mut buffer = String::new(); let stdin = std::io::stdin(); match stdin.read_line(&mut buffer) { From eb91b3c1fb3967f29e3b8da4d65c0952e4f611a0 Mon Sep 17 00:00:00 2001 From: Peter Mikkelsen Date: Mon, 25 Aug 2025 20:47:29 +0200 Subject: [PATCH 3/3] Style tweak --- src/read.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/read.rs b/src/read.rs index 586ab738..e9603522 100644 --- a/src/read.rs +++ b/src/read.rs @@ -232,7 +232,7 @@ impl ReadlineStream { Ok(self.pending_input.get_ref().get_ref().len()) } - Err(e) => Err(e) + Err(e) => Err(e), } }