From 4f3634c246431da5e1d78a2280d5ea597d4dc8d0 Mon Sep 17 00:00:00 2001 From: Taylor Whatley <32211852+1whatleytay@users.noreply.github.com> Date: Wed, 11 Sep 2024 12:47:01 -0400 Subject: [PATCH] Update titan to drop Recovery --- package.json | 3 ++- src-backend/Cargo.lock | 6 ++--- src-backend/src/execution.rs | 4 --- src-backend/src/syscall.rs | 47 +++++++++++++---------------------- src-tauri/Cargo.lock | 14 +++++------ src-wasm/Cargo.lock | 6 ++--- src-wasm/src/lib.rs | 33 ++++++++++++------------ src/utils/mips/wasm-worker.ts | 22 +++++++++++++--- 8 files changed, 68 insertions(+), 67 deletions(-) diff --git a/package.json b/package.json index 2eced70..11976c1 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,8 @@ "dev": "yarn wasm && vite", "build": "yarn wasm && vue-tsc --noEmit && vite build", "preview": "vite preview", - "tauri": "tauri" + "tauri": "tauri", + "cargo-bump": "cd src-backend && cargo update && cd ../src-tauri && cargo update && cd ../src-wasm && cargo update" }, "dependencies": { "@heroicons/vue": "^2.0.13", diff --git a/src-backend/Cargo.lock b/src-backend/Cargo.lock index 4d00a2c..aa19f7c 100644 --- a/src-backend/Cargo.lock +++ b/src-backend/Cargo.lock @@ -427,7 +427,7 @@ dependencies = [ [[package]] name = "titan" version = "0.1.0" -source = "git+https://github.com/1whatleytay/titan.git?branch=main#860de2c31408930d93215c7e5ffcca9a58ba3f93" +source = "git+https://github.com/1whatleytay/titan.git?branch=main#63a44dfd5aa9af2b7303b2e54278ba3f382ee53a" dependencies = [ "bitflags", "byteorder", @@ -447,9 +447,9 @@ checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "wasi" diff --git a/src-backend/src/execution.rs b/src-backend/src/execution.rs index af60b02..9077424 100644 --- a/src-backend/src/execution.rs +++ b/src-backend/src/execution.rs @@ -64,7 +64,6 @@ impl ResumeMode { fn from_executor(value: ExecutorMode, state: &State) -> Self { match value { ExecutorMode::Running => ResumeMode::Running, - ExecutorMode::Recovered => ResumeMode::Breakpoint, ExecutorMode::Invalid(error) => ResumeMode::Invalid { message: format_error(error, state) }, @@ -200,12 +199,9 @@ impl + Send> ExecutionDevice for Executi let state = self.delegate.clone(); let finished_pcs = self.finished_pcs.clone(); - log::info!("Resuming with batch options: {:?}", options.batch); - if let Some(breakpoints) = options.breakpoints { let breakpoints_set = HashSet::from_iter(breakpoints.iter().copied()); - log::info!("Overriding breakpoints: {:?}", breakpoints_set); debugger.set_breakpoints(breakpoints_set); } diff --git a/src-backend/src/syscall.rs b/src-backend/src/syscall.rs index b211f41..1992259 100644 --- a/src-backend/src/syscall.rs +++ b/src-backend/src/syscall.rs @@ -20,7 +20,7 @@ use titan::cpu::error::Error::{CpuSyscall, CpuTrap}; use titan::cpu::state::Registers; use titan::cpu::Memory; use titan::execution::executor::DebugFrame; -use titan::execution::executor::ExecutorMode::{Invalid, Recovered}; +use titan::execution::executor::ExecutorMode::{Invalid,}; use titan::execution::Executor; use titan::execution::trackers::Tracker; use futures::{FutureExt, select}; @@ -782,26 +782,23 @@ impl SyscallDelegate { &self, debugger: &Executor, frame: DebugFrame, - ) -> (Option, Option) { + ) -> (Option, Option, bool) { match frame.mode { Invalid(CpuSyscall) => { // $v0 let code = debugger.with_state(|s| s.registers.line[V0_REG]); let result = self.dispatch(debugger, code).await; - ( - match result { - Completed => { - debugger.syscall_handled(); - - None - } - _ => Some(frame), - }, - Some(result), - ) + match result { + Completed => { + debugger.syscall_handled(); + + (None, Some(result), true) + } + _ => (Some(frame), Some(result), false), + } } - _ => (Some(frame), None), + _ => (Some(frame), None, false), } } @@ -809,27 +806,20 @@ impl SyscallDelegate { pub async fn run_batch>( &self, debugger: &Executor, batch: usize, should_skip_first: bool, allow_interrupt: bool ) -> Option<(DebugFrame, Option)> { - log::info!("Running batch (size: {batch}, should_skip_first: {should_skip_first}, allow_interrupt: {allow_interrupt})"); - if !debugger.run_batched(batch, should_skip_first, allow_interrupt).interrupted { return None // no interruption, batch completed successfully } let frame_in = debugger.frame(); - let (frame, result) = self.handle_frame(debugger, frame_in).await; + let (frame, result, recovered) = self.handle_frame(debugger, frame_in).await; if let Some(frame) = frame { return Some((frame, result)); } - // Need to re-check. - let frame = debugger.frame(); - - log::info!("Resulting debugger frame handled with output mode: {:?}, result: {:?}", frame.mode, result); - - if frame.mode != Recovered { - return Some((frame, None)) + if !recovered { + return Some((debugger.frame(), None)) } None @@ -840,17 +830,14 @@ impl SyscallDelegate { ) -> (DebugFrame, Option) { loop { let frame = debugger.run(should_skip_first); - let (frame, result) = self.handle_frame(debugger, frame).await; + let (frame, result, recovered) = self.handle_frame(debugger, frame).await; if let Some(frame) = frame { return (frame, result); } - // Need to re-check. - let frame = debugger.frame(); - - if frame.mode != Recovered { - return (frame, None); + if !recovered { + return (debugger.frame(), None); } } } diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 8b74168..8dfff0c 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -961,9 +961,9 @@ dependencies = [ [[package]] name = "error-code" -version = "3.2.0" +version = "3.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0474425d51df81997e2f90a21591180b38eccf27292d755f3e30750225c175b" +checksum = "a5d9305ccc6942a704f4335694ecd3de2ea531b114ac2d51f5f843750787a92f" [[package]] name = "event-listener" @@ -2325,9 +2325,9 @@ dependencies = [ [[package]] name = "notify-rust" -version = "4.11.1" +version = "4.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26a1d03b6305ecefdd9c6c60150179bb8d9f0cd4e64bbcad1e41419e7bf5e414" +checksum = "5134a72dc570b178bff81b01e81ab14a6fcc015391ed4b3b14853090658cd3a3" dependencies = [ "log", "mac-notification-sys", @@ -4273,7 +4273,7 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "titan" version = "0.1.0" -source = "git+https://github.com/1whatleytay/titan.git?branch=main#860de2c31408930d93215c7e5ffcca9a58ba3f93" +source = "git+https://github.com/1whatleytay/titan.git?branch=main#63a44dfd5aa9af2b7303b2e54278ba3f382ee53a" dependencies = [ "bitflags 2.6.0", "byteorder", @@ -4521,9 +4521,9 @@ checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "unicode-normalization" diff --git a/src-wasm/Cargo.lock b/src-wasm/Cargo.lock index 709ccca..413c06c 100644 --- a/src-wasm/Cargo.lock +++ b/src-wasm/Cargo.lock @@ -526,7 +526,7 @@ dependencies = [ [[package]] name = "titan" version = "0.1.0" -source = "git+https://github.com/1whatleytay/titan.git?branch=main#860de2c31408930d93215c7e5ffcca9a58ba3f93" +source = "git+https://github.com/1whatleytay/titan.git?branch=main#63a44dfd5aa9af2b7303b2e54278ba3f382ee53a" dependencies = [ "bitflags", "byteorder", @@ -546,9 +546,9 @@ checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "wasi" diff --git a/src-wasm/src/lib.rs b/src-wasm/src/lib.rs index b62b0fd..32e5480 100644 --- a/src-wasm/src/lib.rs +++ b/src-wasm/src/lib.rs @@ -3,6 +3,7 @@ mod midi; mod time; mod events; +use std::cell::RefCell; use std::collections::HashSet; use std::io::Cursor; use std::rc::Rc; @@ -82,7 +83,7 @@ pub fn detailed_disassemble(bytes: Vec) -> Result { #[derive(Default)] pub struct Runner { display: FlushDisplayBody, - device: Option> + device: RefCell>> } impl Runner { @@ -142,8 +143,8 @@ impl Runner { Runner::default() } - pub fn set_breakpoints(&mut self, breakpoints: &[u32]) { - if let Some(device) = &mut self.device { + pub fn set_breakpoints(&self, breakpoints: &[u32]) { + if let Some(device) = self.device.borrow() { device.set_breakpoints(HashSet::::from_iter(breakpoints.iter().copied())) } } @@ -265,11 +266,11 @@ impl Runner { serde_wasm_bindgen::to_value(&result).unwrap() } - pub fn last_pc(&mut self) -> Option { + pub fn last_pc(&self) -> Option { self.device.as_ref().and_then(|device| device.last_pc()) } - pub fn read_bytes(&mut self, address: u32, count: u32) -> JsValue { + pub fn read_bytes(&self, address: u32, count: u32) -> JsValue { let result = self.device .as_ref() .and_then(|device| device.read_bytes(address, count)); @@ -277,14 +278,14 @@ impl Runner { serde_wasm_bindgen::to_value(&result).unwrap() } - pub fn write_bytes(&mut self, address: u32, bytes: Vec) { - if let Some(device) = &mut self.device { + pub fn write_bytes(&self, address: u32, bytes: Vec) { + if let Some(device) = &self.device { device.write_bytes(address, bytes) } } - pub fn set_register(&mut self, register: u32, value: u32) { - if let Some(device) = &mut self.device { + pub fn set_register(&self, register: u32, value: u32) { + if let Some(device) = &self.device { device.write_register(register, value) } } @@ -315,8 +316,8 @@ impl Runner { } } - pub async fn resume(&mut self, batch_size: usize, breakpoints: Option>, first_batch: bool, is_step: bool) -> JsValue { - let Some(device) = &mut self.device else { + pub async fn resume(&self, batch_size: usize, breakpoints: Option>, first_batch: bool, is_step: bool) -> JsValue { + let Some(device) = &self.device else { return JsValue::NULL }; @@ -334,16 +335,16 @@ impl Runner { serde_wasm_bindgen::to_value(&result.ok()).unwrap() } - pub fn pause(&mut self) { - let Some(device) = &mut self.device else { + pub fn pause(&self) { + let Some(device) = &self.device else { return }; device.pause() } - pub fn stop(&mut self) { - let Some(device) = &mut self.device else { + pub fn stop(&self) { + let Some(device) = &self.device else { return }; @@ -352,7 +353,7 @@ impl Runner { self.device = None } - pub fn rewind(&mut self, count: u32) -> JsValue { + pub fn rewind(&self, count: u32) -> JsValue { let Some(device) = &mut self.device else { return JsValue::NULL }; diff --git a/src/utils/mips/wasm-worker.ts b/src/utils/mips/wasm-worker.ts index 8739e7b..311c6e8 100644 --- a/src/utils/mips/wasm-worker.ts +++ b/src/utils/mips/wasm-worker.ts @@ -27,8 +27,10 @@ import { MessageResponse, PostInputData, PostKeyData, - ReadBytesData, ReadDisplayData, - ResumeData, RewindData, + ReadBytesData, + ReadDisplayData, + ResumeData, + RewindData, SetBreakpointsData, SetRegisterData, WriteBytesData @@ -87,6 +89,20 @@ function configureAsm({ text, timeTravel }: ConfigureAsmData): AssemblerResult { return runner.configure_asm(text, timeTravel) } +// Thanks to Milo +// https://github.com/facebook/react/blob/66cf2cfc8a8c4b09d2b783fd7302ae6b24150935/packages/scheduler/src/forks/Scheduler.js#L534-L540 +const channel = new MessageChannel() +const port = channel.port2 +let currentResolve: (() => void) | null = null +channel.port1.onmessage = () => currentResolve!() + +function awaitMacrotaskFast(): Promise { + return new Promise(resolve => { + currentResolve = resolve + port.postMessage(null) + }); +} + async function resume({ count, breakpoints }: ResumeData): Promise { const batchSize = 1200 // worth adjusting this batch size @@ -115,7 +131,7 @@ async function resume({ count, breakpoints }: ResumeData): Promise(resolve => setTimeout(resolve, 0)) + await awaitMacrotaskFast() } return result