From 2bc6a1b27ba23e4cc84452840ffd64c50ee1453f Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Wed, 17 Apr 2024 15:47:45 -0700 Subject: [PATCH] fix reborrow panic fixes #21 --- ic10emu/src/interpreter.rs | 38 +++++++++++++++++++++++++++++--------- ic10emu/src/lib.rs | 10 +++++++--- 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/ic10emu/src/interpreter.rs b/ic10emu/src/interpreter.rs index 79041dd..1020fa5 100644 --- a/ic10emu/src/interpreter.rs +++ b/ic10emu/src/interpreter.rs @@ -111,7 +111,7 @@ pub enum ICError { #[error("bad network Id '{0}'")] BadNetworkId(u32), #[error("channel index out of range '{0}'")] - ChannelIndexOutOfRange(usize) + ChannelIndexOutOfRange(usize), } impl ICError { @@ -2046,8 +2046,14 @@ impl IC { Some(device) => match device.borrow().ic.as_ref() { Some(ic_id) => { let addr = addr.as_value(this, inst, 3)?; - let ic = vm.ics.get(ic_id).unwrap().borrow(); - let val = ic.peek_addr(addr)?; + let val = { + if ic_id == &this.id { + this.peek_addr(addr) + } else { + let ic = vm.ics.get(ic_id).unwrap().borrow(); + ic.peek_addr(addr) + } + }?; this.set_register(indirection, target, val)?; Ok(()) } @@ -2073,8 +2079,14 @@ impl IC { Some(device) => match device.borrow().ic.as_ref() { Some(ic_id) => { let addr = addr.as_value(this, inst, 3)?; - let ic = vm.ics.get(ic_id).unwrap().borrow(); - let val = ic.peek_addr(addr)?; + let val = { + if ic_id == &this.id { + this.peek_addr(addr) + } else { + let ic = vm.ics.get(ic_id).unwrap().borrow(); + ic.peek_addr(addr) + } + }?; this.set_register(indirection, target, val)?; Ok(()) } @@ -2097,8 +2109,12 @@ impl IC { Some(ic_id) => { let addr = addr.as_value(this, inst, 2)?; let val = val.as_value(this, inst, 3)?; - let mut ic = vm.ics.get(ic_id).unwrap().borrow_mut(); - ic.poke(addr, val)?; + if ic_id == &this.id { + this.poke(addr, val)?; + } else { + let mut ic = vm.ics.get(ic_id).unwrap().borrow_mut(); + ic.poke(addr, val)?; + } vm.set_modified(device_id); Ok(()) } @@ -2121,8 +2137,12 @@ impl IC { Some(ic_id) => { let addr = addr.as_value(this, inst, 2)?; let val = val.as_value(this, inst, 3)?; - let mut ic = vm.ics.get(ic_id).unwrap().borrow_mut(); - ic.poke(addr, val)?; + if ic_id == &this.id { + this.poke(addr, val)?; + } else { + let mut ic = vm.ics.get(ic_id).unwrap().borrow_mut(); + ic.poke(addr, val)?; + } vm.set_modified(device_id as u32); Ok(()) } diff --git a/ic10emu/src/lib.rs b/ic10emu/src/lib.rs index 6ea4495..8b9238c 100644 --- a/ic10emu/src/lib.rs +++ b/ic10emu/src/lib.rs @@ -14,7 +14,7 @@ use grammar::{BatchMode, LogicType, ReagentMode, SlotLogicType}; use interpreter::{ICError, LineError}; use itertools::Itertools; use serde::{Deserialize, Serialize}; -use strum_macros::{EnumIter, EnumString, AsRefStr}; +use strum_macros::{AsRefStr, EnumIter, EnumString}; use thiserror::Error; use crate::interpreter::ICState; @@ -1276,8 +1276,12 @@ impl VM { pub fn step_ic(&self, id: u32, advance_ip_on_err: bool) -> Result { self.operation_modified.borrow_mut().clear(); - let device = self.devices.get(&id).ok_or(VMError::UnknownId(id))?.clone(); - let ic_id = *device.borrow().ic.as_ref().ok_or(VMError::NoIC(id))?; + let ic_id = { + let device = self.devices.get(&id).ok_or(VMError::UnknownId(id))?; + let device_ref = device.borrow(); + let ic_id = device_ref.ic.as_ref().ok_or(VMError::NoIC(id))?; + *ic_id + }; self.set_modified(id); let ic = self .ics