enable unification of streams to alias atoms (#1823)

This commit is contained in:
Mark
2023-06-27 12:23:40 -06:00
parent b593fffc7d
commit 16f281e3d1
2 changed files with 205 additions and 182 deletions

View File

@@ -281,24 +281,24 @@ pub struct HttpWriteStream {
impl Debug for HttpWriteStream { impl Debug for HttpWriteStream {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Http Write Stream") write!(f, "Http Write Stream")
} }
} }
impl Write for HttpWriteStream { impl Write for HttpWriteStream {
#[inline] #[inline]
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> { fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
let bytes = Bytes::copy_from_slice(buf); let bytes = Bytes::copy_from_slice(buf);
let len = bytes.len(); let len = bytes.len();
match self.body_writer.try_send_data(bytes) { match self.body_writer.try_send_data(bytes) {
Ok(()) => Ok(len), Ok(()) => Ok(len),
Err(_) => Err(std::io::Error::from(ErrorKind::Interrupted)) Err(_) => Err(std::io::Error::from(ErrorKind::Interrupted))
} }
} }
#[inline] #[inline]
fn flush(&mut self) -> std::io::Result<()> { fn flush(&mut self) -> std::io::Result<()> {
Ok(()) Ok(())
} }
} }
@@ -512,7 +512,7 @@ impl Stream {
ArenaHeaderTag::NamedTcpStream => Stream::NamedTcp(TypedArenaPtr::new(ptr as *mut _)), ArenaHeaderTag::NamedTcpStream => Stream::NamedTcp(TypedArenaPtr::new(ptr as *mut _)),
ArenaHeaderTag::NamedTlsStream => Stream::NamedTls(TypedArenaPtr::new(ptr as *mut _)), ArenaHeaderTag::NamedTlsStream => Stream::NamedTls(TypedArenaPtr::new(ptr as *mut _)),
ArenaHeaderTag::HttpReadStream => Stream::HttpRead(TypedArenaPtr::new(ptr as *mut _)), ArenaHeaderTag::HttpReadStream => Stream::HttpRead(TypedArenaPtr::new(ptr as *mut _)),
ArenaHeaderTag::HttpWriteStream => Stream::HttpWrite(TypedArenaPtr::new(ptr as *mut _)), ArenaHeaderTag::HttpWriteStream => Stream::HttpWrite(TypedArenaPtr::new(ptr as *mut _)),
ArenaHeaderTag::ReadlineStream => Stream::Readline(TypedArenaPtr::new(ptr as *mut _)), ArenaHeaderTag::ReadlineStream => Stream::Readline(TypedArenaPtr::new(ptr as *mut _)),
ArenaHeaderTag::StaticStringStream => { ArenaHeaderTag::StaticStringStream => {
Stream::StaticString(TypedArenaPtr::new(ptr as *mut _)) Stream::StaticString(TypedArenaPtr::new(ptr as *mut _))
@@ -566,7 +566,7 @@ impl Stream {
Stream::NamedTcp(ptr) => ptr.header_ptr(), Stream::NamedTcp(ptr) => ptr.header_ptr(),
Stream::NamedTls(ptr) => ptr.header_ptr(), Stream::NamedTls(ptr) => ptr.header_ptr(),
Stream::HttpRead(ptr) => ptr.header_ptr(), Stream::HttpRead(ptr) => ptr.header_ptr(),
Stream::HttpWrite(ptr) => ptr.header_ptr(), Stream::HttpWrite(ptr) => ptr.header_ptr(),
Stream::Null(_) => ptr::null(), Stream::Null(_) => ptr::null(),
Stream::Readline(ptr) => ptr.header_ptr(), Stream::Readline(ptr) => ptr.header_ptr(),
Stream::StandardOutput(ptr) => ptr.header_ptr(), Stream::StandardOutput(ptr) => ptr.header_ptr(),
@@ -583,7 +583,7 @@ impl Stream {
Stream::NamedTcp(ref ptr) => &ptr.options, Stream::NamedTcp(ref ptr) => &ptr.options,
Stream::NamedTls(ref ptr) => &ptr.options, Stream::NamedTls(ref ptr) => &ptr.options,
Stream::HttpRead(ref ptr) => &ptr.options, Stream::HttpRead(ref ptr) => &ptr.options,
Stream::HttpWrite(ref ptr) => &ptr.options, Stream::HttpWrite(ref ptr) => &ptr.options,
Stream::Null(ref options) => options, Stream::Null(ref options) => options,
Stream::Readline(ref ptr) => &ptr.options, Stream::Readline(ref ptr) => &ptr.options,
Stream::StandardOutput(ref ptr) => &ptr.options, Stream::StandardOutput(ref ptr) => &ptr.options,
@@ -600,7 +600,7 @@ impl Stream {
Stream::NamedTcp(ref mut ptr) => &mut ptr.options, Stream::NamedTcp(ref mut ptr) => &mut ptr.options,
Stream::NamedTls(ref mut ptr) => &mut ptr.options, Stream::NamedTls(ref mut ptr) => &mut ptr.options,
Stream::HttpRead(ref mut ptr) => &mut ptr.options, Stream::HttpRead(ref mut ptr) => &mut ptr.options,
Stream::HttpWrite(ref mut ptr) => &mut ptr.options, Stream::HttpWrite(ref mut ptr) => &mut ptr.options,
Stream::Null(ref mut options) => options, Stream::Null(ref mut options) => options,
Stream::Readline(ref mut ptr) => &mut ptr.options, Stream::Readline(ref mut ptr) => &mut ptr.options,
Stream::StandardOutput(ref mut ptr) => &mut ptr.options, Stream::StandardOutput(ref mut ptr) => &mut ptr.options,
@@ -618,7 +618,7 @@ impl Stream {
Stream::NamedTcp(ptr) => ptr.lines_read += incr_num_lines_read, Stream::NamedTcp(ptr) => ptr.lines_read += incr_num_lines_read,
Stream::NamedTls(ptr) => ptr.lines_read += incr_num_lines_read, Stream::NamedTls(ptr) => ptr.lines_read += incr_num_lines_read,
Stream::HttpRead(ptr) => ptr.lines_read += incr_num_lines_read, Stream::HttpRead(ptr) => ptr.lines_read += incr_num_lines_read,
Stream::HttpWrite(_) => {} Stream::HttpWrite(_) => {}
Stream::Null(_) => {} Stream::Null(_) => {}
Stream::Readline(ptr) => ptr.lines_read += incr_num_lines_read, Stream::Readline(ptr) => ptr.lines_read += incr_num_lines_read,
Stream::StandardOutput(ptr) => ptr.lines_read += incr_num_lines_read, Stream::StandardOutput(ptr) => ptr.lines_read += incr_num_lines_read,
@@ -636,7 +636,7 @@ impl Stream {
Stream::NamedTcp(ptr) => ptr.lines_read = value, Stream::NamedTcp(ptr) => ptr.lines_read = value,
Stream::NamedTls(ptr) => ptr.lines_read = value, Stream::NamedTls(ptr) => ptr.lines_read = value,
Stream::HttpRead(ptr) => ptr.lines_read = value, Stream::HttpRead(ptr) => ptr.lines_read = value,
Stream::HttpWrite(_) => {} Stream::HttpWrite(_) => {}
Stream::Null(_) => {} Stream::Null(_) => {}
Stream::Readline(ptr) => ptr.lines_read = value, Stream::Readline(ptr) => ptr.lines_read = value,
Stream::StandardOutput(ptr) => ptr.lines_read = value, Stream::StandardOutput(ptr) => ptr.lines_read = value,
@@ -654,7 +654,7 @@ impl Stream {
Stream::NamedTcp(ptr) => ptr.lines_read, Stream::NamedTcp(ptr) => ptr.lines_read,
Stream::NamedTls(ptr) => ptr.lines_read, Stream::NamedTls(ptr) => ptr.lines_read,
Stream::HttpRead(ptr) => ptr.lines_read, Stream::HttpRead(ptr) => ptr.lines_read,
Stream::HttpWrite(_) => 0, Stream::HttpWrite(_) => 0,
Stream::Null(_) => 0, Stream::Null(_) => 0,
Stream::Readline(ptr) => ptr.lines_read, Stream::Readline(ptr) => ptr.lines_read,
Stream::StandardOutput(ptr) => ptr.lines_read, Stream::StandardOutput(ptr) => ptr.lines_read,
@@ -676,7 +676,7 @@ impl CharRead for Stream {
Stream::OutputFile(_) | Stream::OutputFile(_) |
Stream::StandardError(_) | Stream::StandardError(_) |
Stream::StandardOutput(_) | Stream::StandardOutput(_) |
Stream::HttpWrite(_) | Stream::HttpWrite(_) |
Stream::Null(_) => Some(Err(std::io::Error::new( Stream::Null(_) => Some(Err(std::io::Error::new(
ErrorKind::PermissionDenied, ErrorKind::PermissionDenied,
StreamError::ReadFromOutputStream, StreamError::ReadFromOutputStream,
@@ -696,7 +696,7 @@ impl CharRead for Stream {
Stream::OutputFile(_) | Stream::OutputFile(_) |
Stream::StandardError(_) | Stream::StandardError(_) |
Stream::StandardOutput(_) | Stream::StandardOutput(_) |
Stream::HttpWrite(_) | Stream::HttpWrite(_) |
Stream::Null(_) => Some(Err(std::io::Error::new( Stream::Null(_) => Some(Err(std::io::Error::new(
ErrorKind::PermissionDenied, ErrorKind::PermissionDenied,
StreamError::ReadFromOutputStream, StreamError::ReadFromOutputStream,
@@ -716,7 +716,7 @@ impl CharRead for Stream {
Stream::OutputFile(_) | Stream::OutputFile(_) |
Stream::StandardError(_) | Stream::StandardError(_) |
Stream::StandardOutput(_) | Stream::StandardOutput(_) |
Stream::HttpWrite(_) | Stream::HttpWrite(_) |
Stream::Null(_) => {} Stream::Null(_) => {}
} }
} }
@@ -733,7 +733,7 @@ impl CharRead for Stream {
Stream::OutputFile(_) | Stream::OutputFile(_) |
Stream::StandardError(_) | Stream::StandardError(_) |
Stream::StandardOutput(_) | Stream::StandardOutput(_) |
Stream::HttpWrite(_) | Stream::HttpWrite(_) |
Stream::Null(_) => {} Stream::Null(_) => {}
} }
} }
@@ -751,13 +751,13 @@ impl Read for Stream {
Stream::StaticString(src) => (*src).read(buf), Stream::StaticString(src) => (*src).read(buf),
Stream::Byte(cursor) => (*cursor).read(buf), Stream::Byte(cursor) => (*cursor).read(buf),
Stream::OutputFile(_) Stream::OutputFile(_)
| Stream::StandardError(_) | Stream::StandardError(_)
| Stream::StandardOutput(_) | Stream::StandardOutput(_)
| Stream::HttpWrite(_) | Stream::HttpWrite(_)
| Stream::Null(_) => Err(std::io::Error::new( | Stream::Null(_) => Err(std::io::Error::new(
ErrorKind::PermissionDenied, ErrorKind::PermissionDenied,
StreamError::ReadFromOutputStream, StreamError::ReadFromOutputStream,
)), )),
}; };
bytes_read bytes_read
@@ -773,7 +773,7 @@ impl Write for Stream {
Stream::Byte(ref mut cursor) => cursor.get_mut().write(buf), Stream::Byte(ref mut cursor) => cursor.get_mut().write(buf),
Stream::StandardOutput(stream) => stream.write(buf), Stream::StandardOutput(stream) => stream.write(buf),
Stream::StandardError(stream) => stream.write(buf), Stream::StandardError(stream) => stream.write(buf),
Stream::HttpWrite(ref mut stream) => stream.get_mut().write(buf), Stream::HttpWrite(ref mut stream) => stream.get_mut().write(buf),
Stream::HttpRead(_) | Stream::HttpRead(_) |
Stream::StaticString(_) | Stream::StaticString(_) |
Stream::Readline(_) | Stream::Readline(_) |
@@ -793,7 +793,7 @@ impl Write for Stream {
Stream::Byte(ref mut cursor) => cursor.stream.get_mut().flush(), Stream::Byte(ref mut cursor) => cursor.stream.get_mut().flush(),
Stream::StandardError(stream) => stream.stream.flush(), Stream::StandardError(stream) => stream.stream.flush(),
Stream::StandardOutput(stream) => stream.stream.flush(), Stream::StandardOutput(stream) => stream.stream.flush(),
Stream::HttpWrite(ref mut stream) => stream.stream.get_mut().flush(), Stream::HttpWrite(ref mut stream) => stream.stream.get_mut().flush(),
Stream::HttpRead(_) | Stream::HttpRead(_) |
Stream::StaticString(_) | Stream::StaticString(_) |
Stream::Readline(_) | Stream::Readline(_) |
@@ -879,10 +879,10 @@ impl Stream {
file_stream.position() file_stream.position()
} }
Stream::NamedTcp(..) Stream::NamedTcp(..)
| Stream::NamedTls(..) | Stream::NamedTls(..)
| Stream::Readline(..) | Stream::Readline(..)
| Stream::StaticString(..) | Stream::StaticString(..)
| Stream::Byte(..) => Some(0), | Stream::Byte(..) => Some(0),
_ => None, _ => None,
}; };
@@ -920,7 +920,7 @@ impl Stream {
Stream::NamedTcp(stream) => stream.past_end_of_stream, Stream::NamedTcp(stream) => stream.past_end_of_stream,
Stream::NamedTls(stream) => stream.past_end_of_stream, Stream::NamedTls(stream) => stream.past_end_of_stream,
Stream::HttpRead(stream) => stream.past_end_of_stream, Stream::HttpRead(stream) => stream.past_end_of_stream,
Stream::HttpWrite(stream) => stream.past_end_of_stream, Stream::HttpWrite(stream) => stream.past_end_of_stream,
Stream::Null(_) => false, Stream::Null(_) => false,
Stream::Readline(stream) => stream.past_end_of_stream, Stream::Readline(stream) => stream.past_end_of_stream,
Stream::StandardOutput(stream) => stream.past_end_of_stream, Stream::StandardOutput(stream) => stream.past_end_of_stream,
@@ -943,7 +943,7 @@ impl Stream {
Stream::NamedTcp(stream) => stream.past_end_of_stream = value, Stream::NamedTcp(stream) => stream.past_end_of_stream = value,
Stream::NamedTls(stream) => stream.past_end_of_stream = value, Stream::NamedTls(stream) => stream.past_end_of_stream = value,
Stream::HttpRead(stream) => stream.past_end_of_stream = value, Stream::HttpRead(stream) => stream.past_end_of_stream = value,
Stream::HttpWrite(stream) => stream.past_end_of_stream = value, Stream::HttpWrite(stream) => stream.past_end_of_stream = value,
Stream::Null(_) => {} Stream::Null(_) => {}
Stream::Readline(stream) => stream.past_end_of_stream = value, Stream::Readline(stream) => stream.past_end_of_stream = value,
Stream::StandardOutput(stream) => stream.past_end_of_stream = value, Stream::StandardOutput(stream) => stream.past_end_of_stream = value,
@@ -1007,10 +1007,10 @@ impl Stream {
pub(crate) fn mode(&self) -> Atom { pub(crate) fn mode(&self) -> Atom {
match self { match self {
Stream::Byte(_) Stream::Byte(_)
| Stream::Readline(_) | Stream::Readline(_)
| Stream::StaticString(_) | Stream::StaticString(_)
| Stream::HttpRead(_) | Stream::HttpRead(_)
| Stream::InputFile(..) => atom!("read"), | Stream::InputFile(..) => atom!("read"),
Stream::NamedTcp(..) | Stream::NamedTls(..) => atom!("read_append"), Stream::NamedTcp(..) | Stream::NamedTls(..) => atom!("read_append"),
Stream::OutputFile(file) if file.is_append => atom!("append"), Stream::OutputFile(file) if file.is_append => atom!("append"),
Stream::OutputFile(_) | Stream::StandardError(_) | Stream::StandardOutput(_) | Stream::HttpWrite(_) => atom!("write"), Stream::OutputFile(_) | Stream::StandardError(_) | Stream::StandardOutput(_) | Stream::HttpWrite(_) => atom!("write"),
@@ -1084,15 +1084,15 @@ impl Stream {
#[inline] #[inline]
pub(crate) fn from_http_sender( pub(crate) fn from_http_sender(
body_writer: Sender, body_writer: Sender,
arena: &mut Arena, arena: &mut Arena,
) -> Self { ) -> Self {
Stream::HttpWrite(arena_alloc!( Stream::HttpWrite(arena_alloc!(
StreamLayout::new(CharReader::new(HttpWriteStream { StreamLayout::new(CharReader::new(HttpWriteStream {
body_writer body_writer
})), })),
arena arena
)) ))
} }
#[inline] #[inline]
@@ -1182,12 +1182,12 @@ impl Stream {
pub(crate) fn is_input_stream(&self) -> bool { pub(crate) fn is_input_stream(&self) -> bool {
match self { match self {
Stream::NamedTcp(..) Stream::NamedTcp(..)
| Stream::NamedTls(..) | Stream::NamedTls(..)
| Stream::HttpRead(..) | Stream::HttpRead(..)
| Stream::Byte(_) | Stream::Byte(_)
| Stream::Readline(_) | Stream::Readline(_)
| Stream::StaticString(_) | Stream::StaticString(_)
| Stream::InputFile(..) => true, | Stream::InputFile(..) => true,
_ => false, _ => false,
} }
} }
@@ -1196,12 +1196,12 @@ impl Stream {
pub(crate) fn is_output_stream(&self) -> bool { pub(crate) fn is_output_stream(&self) -> bool {
match self { match self {
Stream::StandardError(_) Stream::StandardError(_)
| Stream::StandardOutput(_) | Stream::StandardOutput(_)
| Stream::NamedTcp(..) | Stream::NamedTcp(..)
| Stream::NamedTls(..) | Stream::NamedTls(..)
| Stream::HttpWrite(..) | Stream::HttpWrite(..)
| Stream::Byte(_) | Stream::Byte(_)
| Stream::OutputFile(..) => true, | Stream::OutputFile(..) => true,
_ => false, _ => false,
} }
} }
@@ -1320,101 +1320,101 @@ impl MachineState {
stream_type: HeapCellValue, stream_type: HeapCellValue,
) -> StreamOptions { ) -> StreamOptions {
let alias = read_heap_cell!(self.store(MachineState::deref(self, alias)), let alias = read_heap_cell!(self.store(MachineState::deref(self, alias)),
(HeapCellValueTag::Atom, (name, arity)) => { (HeapCellValueTag::Atom, (name, arity)) => {
debug_assert_eq!(arity, 0); debug_assert_eq!(arity, 0);
if name != atom!("[]") { if name != atom!("[]") {
Some(name) Some(name)
} else { } else {
None None
} }
} }
(HeapCellValueTag::Str, s) => { (HeapCellValueTag::Str, s) => {
let (name, arity) = cell_as_atom_cell!(self.heap[s]) let (name, arity) = cell_as_atom_cell!(self.heap[s])
.get_name_and_arity(); .get_name_and_arity();
debug_assert_eq!(arity, 0); debug_assert_eq!(arity, 0);
if name != atom!("[]") { if name != atom!("[]") {
Some(name) Some(name)
} else { } else {
None None
} }
} }
_ => { _ => {
None None
} }
); );
let eof_action = read_heap_cell!(self.store(MachineState::deref(self, eof_action)), let eof_action = read_heap_cell!(self.store(MachineState::deref(self, eof_action)),
(HeapCellValueTag::Atom, (name, arity)) => { (HeapCellValueTag::Atom, (name, arity)) => {
debug_assert_eq!(arity, 0); debug_assert_eq!(arity, 0);
match name { match name {
atom!("eof_code") => EOFAction::EOFCode, atom!("eof_code") => EOFAction::EOFCode,
atom!("error") => EOFAction::Error, atom!("error") => EOFAction::Error,
atom!("reset") => EOFAction::Reset, atom!("reset") => EOFAction::Reset,
_ => unreachable!(), _ => unreachable!(),
} }
} }
(HeapCellValueTag::Str, s) => { (HeapCellValueTag::Str, s) => {
let (name, arity) = cell_as_atom_cell!(self.heap[s]) let (name, arity) = cell_as_atom_cell!(self.heap[s])
.get_name_and_arity(); .get_name_and_arity();
debug_assert_eq!(arity, 0); debug_assert_eq!(arity, 0);
match name { match name {
atom!("eof_code") => EOFAction::EOFCode, atom!("eof_code") => EOFAction::EOFCode,
atom!("error") => EOFAction::Error, atom!("error") => EOFAction::Error,
atom!("reset") => EOFAction::Reset, atom!("reset") => EOFAction::Reset,
_ => unreachable!(), _ => unreachable!(),
} }
} }
_ => { _ => {
unreachable!() unreachable!()
} }
); );
let reposition = read_heap_cell!(self.store(MachineState::deref(self, reposition)), let reposition = read_heap_cell!(self.store(MachineState::deref(self, reposition)),
(HeapCellValueTag::Atom, (name, arity)) => { (HeapCellValueTag::Atom, (name, arity)) => {
debug_assert_eq!(arity, 0); debug_assert_eq!(arity, 0);
name == atom!("true") name == atom!("true")
} }
(HeapCellValueTag::Str, s) => { (HeapCellValueTag::Str, s) => {
let (name, arity) = cell_as_atom_cell!(self.heap[s]) let (name, arity) = cell_as_atom_cell!(self.heap[s])
.get_name_and_arity(); .get_name_and_arity();
debug_assert_eq!(arity, 0); debug_assert_eq!(arity, 0);
name == atom!("true") name == atom!("true")
} }
_ => { _ => {
unreachable!() unreachable!()
} }
); );
let stream_type = read_heap_cell!(self.store(MachineState::deref(self, stream_type)), let stream_type = read_heap_cell!(self.store(MachineState::deref(self, stream_type)),
(HeapCellValueTag::Atom, (name, arity)) => { (HeapCellValueTag::Atom, (name, arity)) => {
debug_assert_eq!(arity, 0); debug_assert_eq!(arity, 0);
match name { match name {
atom!("text") => StreamType::Text, atom!("text") => StreamType::Text,
atom!("binary") => StreamType::Binary, atom!("binary") => StreamType::Binary,
_ => unreachable!(), _ => unreachable!(),
} }
} }
(HeapCellValueTag::Str, s) => { (HeapCellValueTag::Str, s) => {
let (name, arity) = cell_as_atom_cell!(self.heap[s]) let (name, arity) = cell_as_atom_cell!(self.heap[s])
.get_name_and_arity(); .get_name_and_arity();
debug_assert_eq!(arity, 0); debug_assert_eq!(arity, 0);
match name { match name {
atom!("text") => StreamType::Text, atom!("text") => StreamType::Text,
atom!("binary") => StreamType::Binary, atom!("binary") => StreamType::Binary,
_ => unreachable!(), _ => unreachable!(),
} }
} }
_ => { _ => {
unreachable!() unreachable!()
} }
); );
let mut options = StreamOptions::default(); let mut options = StreamOptions::default();
@@ -1437,60 +1437,60 @@ impl MachineState {
let addr = self.store(MachineState::deref(self, addr)); let addr = self.store(MachineState::deref(self, addr));
read_heap_cell!(addr, read_heap_cell!(addr,
(HeapCellValueTag::Atom, (name, arity)) => { (HeapCellValueTag::Atom, (name, arity)) => {
debug_assert_eq!(arity, 0); debug_assert_eq!(arity, 0);
return match stream_aliases.get(&name) { return match stream_aliases.get(&name) {
Some(stream) if !stream.is_null_stream() => Ok(*stream), Some(stream) if !stream.is_null_stream() => Ok(*stream),
_ => { _ => {
let stub = functor_stub(caller, arity); let stub = functor_stub(caller, arity);
let addr = atom_as_cell!(name); let addr = atom_as_cell!(name);
let existence_error = self.existence_error(ExistenceError::Stream(addr)); let existence_error = self.existence_error(ExistenceError::Stream(addr));
Err(self.error_form(existence_error, stub)) Err(self.error_form(existence_error, stub))
} }
}; };
} }
(HeapCellValueTag::Str, s) => { (HeapCellValueTag::Str, s) => {
let (name, arity) = cell_as_atom_cell!(self.heap[s]) let (name, arity) = cell_as_atom_cell!(self.heap[s])
.get_name_and_arity(); .get_name_and_arity();
debug_assert_eq!(arity, 0); debug_assert_eq!(arity, 0);
return match stream_aliases.get(&name) { return match stream_aliases.get(&name) {
Some(stream) if !stream.is_null_stream() => Ok(*stream), Some(stream) if !stream.is_null_stream() => Ok(*stream),
_ => { _ => {
let stub = functor_stub(caller, arity); let stub = functor_stub(caller, arity);
let addr = atom_as_cell!(name); let addr = atom_as_cell!(name);
let existence_error = self.existence_error(ExistenceError::Stream(addr)); let existence_error = self.existence_error(ExistenceError::Stream(addr));
Err(self.error_form(existence_error, stub)) Err(self.error_form(existence_error, stub))
} }
}; };
} }
(HeapCellValueTag::Cons, ptr) => { (HeapCellValueTag::Cons, ptr) => {
match_untyped_arena_ptr!(ptr, match_untyped_arena_ptr!(ptr,
(ArenaHeaderTag::Stream, stream) => { (ArenaHeaderTag::Stream, stream) => {
return if stream.is_null_stream() { return if stream.is_null_stream() {
Err(self.open_permission_error(stream_as_cell!(stream), caller, arity)) Err(self.open_permission_error(stream_as_cell!(stream), caller, arity))
} else { } else {
Ok(stream) Ok(stream)
}; };
} }
(ArenaHeaderTag::Dropped, _value) => { (ArenaHeaderTag::Dropped, _value) => {
let stub = functor_stub(caller, arity); let stub = functor_stub(caller, arity);
let err = self.existence_error(ExistenceError::Stream(addr)); let err = self.existence_error(ExistenceError::Stream(addr));
return Err(self.error_form(err, stub)); return Err(self.error_form(err, stub));
} }
_ => { _ => {
} }
); );
} }
_ => { _ => {
} }
); );
let stub = functor_stub(caller, arity); let stub = functor_stub(caller, arity);

View File

@@ -494,6 +494,29 @@ pub(crate) trait Unifier: DerefMut<Target = MachineState> {
(ArenaHeaderTag::Rational, rat_ptr) => { (ArenaHeaderTag::Rational, rat_ptr) => {
Self::unify_big_num(self, rat_ptr, value); Self::unify_big_num(self, rat_ptr, value);
} }
(ArenaHeaderTag::Stream, stream) => {
read_heap_cell!(value,
(HeapCellValueTag::AttrVar | HeapCellValueTag::Var) => {
Self::bind(self, value.as_var().unwrap(), untyped_arena_ptr_as_cell!(ptr));
}
(HeapCellValueTag::Atom, (name, arity)) => {
if arity > 0 {
self.fail = true;
} else {
let stream_options = stream.options();
if let Some(alias) = stream_options.get_alias() {
self.fail = name != alias;
} else {
self.fail = true;
}
}
}
_ => {
self.fail = true;
}
);
}
_ => { _ => {
if let Some(r) = value.as_var() { if let Some(r) = value.as_var() {
Self::bind(self, r, untyped_arena_ptr_as_cell!(ptr)); Self::bind(self, r, untyped_arena_ptr_as_cell!(ptr));