From 870f1bb5229200b47fa76431630330e5bb51c1e8 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Thu, 25 Apr 2024 01:10:17 +0900 Subject: [PATCH 1/2] popblock debug --- vm/src/frame.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/vm/src/frame.rs b/vm/src/frame.rs index d62e538051..ff5e2d723d 100644 --- a/vm/src/frame.rs +++ b/vm/src/frame.rs @@ -1911,8 +1911,18 @@ impl ExecutingFrame<'_> { }); } + #[track_caller] fn pop_block(&mut self) -> Block { let block = self.state.blocks.pop().expect("No more blocks to pop!"); + #[cfg(debug_assertions)] + if self.state.stack.len() < block.level { + dbg!(&self); + panic!( + "stack size reversion: current size({}) < truncates target({}).", + self.state.stack.len(), + block.level + ); + } self.state.stack.truncate(block.level); block } @@ -1945,7 +1955,7 @@ impl ExecutingFrame<'_> { } #[inline] - #[track_caller] // not a real track_caller but pop_value is not very useful + #[track_caller] // not a real track_caller but top_value is not very useful fn top_value(&self) -> &PyObject { match &*self.state.stack { [.., last] => last, From 8b1b1e4a27c5148f817351b25c466251999891e6 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Thu, 25 Apr 2024 14:46:44 +0900 Subject: [PATCH 2/2] Fix with __exit__ error handling --- vm/src/frame.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/vm/src/frame.rs b/vm/src/frame.rs index ff5e2d723d..80f848fc94 100644 --- a/vm/src/frame.rs +++ b/vm/src/frame.rs @@ -925,7 +925,7 @@ impl ExecutingFrame<'_> { _ => None, }; - let exit = self.pop_value(); + let exit = self.top_value(); let args = if let Some(exc) = exc { vm.split_exception(exc) @@ -933,7 +933,7 @@ impl ExecutingFrame<'_> { (vm.ctx.none(), vm.ctx.none(), vm.ctx.none()) }; let exit_res = exit.call(args, vm)?; - self.push_value(exit_res); + self.replace_top(exit_res); Ok(None) } @@ -994,7 +994,7 @@ impl ExecutingFrame<'_> { } bytecode::Instruction::GetANext => { let aiter = self.top_value(); - let awaitable = vm.call_special_method(&aiter, identifier!(vm, __anext__), ())?; + let awaitable = vm.call_special_method(aiter, identifier!(vm, __anext__), ())?; let awaitable = if awaitable.payload_is::() { awaitable } else { @@ -1954,6 +1954,13 @@ impl ExecutingFrame<'_> { self.state.stack.drain(stack_len - count..) } + #[inline] + fn replace_top(&mut self, mut top: PyObjectRef) -> PyObjectRef { + let last = self.state.stack.last_mut().unwrap(); + std::mem::swap(&mut top, last); + top + } + #[inline] #[track_caller] // not a real track_caller but top_value is not very useful fn top_value(&self) -> &PyObject {