diff --git a/crates/vm2/src/tracing.rs b/crates/vm2/src/tracing.rs index 9a52382..727c6f9 100644 --- a/crates/vm2/src/tracing.rs +++ b/crates/vm2/src/tracing.rs @@ -49,11 +49,12 @@ impl StateInterface for VirtualMachine { for far_frame in std::iter::once(&mut self.state.current_frame) .chain(self.state.previous_frames.iter_mut().rev()) { - match n.cmp(&far_frame.near_calls.len()) { + let near_calls = far_frame.near_calls.len(); + match n.cmp(&near_calls) { Ordering::Less => { return CallframeWrapper { frame: far_frame, - near_call: Some(n), + near_call: Some(near_calls - 1 - n), } } Ordering::Equal => { @@ -62,7 +63,7 @@ impl StateInterface for VirtualMachine { near_call: None, } } - Ordering::Greater => n -= far_frame.near_calls.len() + 1, + Ordering::Greater => n -= near_calls + 1, } } panic!("Callframe index out of bounds") @@ -309,12 +310,16 @@ impl CallframeInterface for CallframeWrapper<'_, T, W> { } fn set_program_counter(&mut self, value: u16) { - self.frame.set_pc_from_u16(value); + if let Some(call) = self.near_call_on_top_mut() { + call.previous_frame_pc = value; + } else { + self.frame.set_pc_from_u16(value); + } } fn exception_handler(&self) -> u16 { if let Some(i) = self.near_call { - self.frame.near_calls[self.frame.near_calls.len() - i - 1].exception_handler + self.frame.near_calls[i].exception_handler } else { self.frame.exception_handler } @@ -322,8 +327,7 @@ impl CallframeInterface for CallframeWrapper<'_, T, W> { fn set_exception_handler(&mut self, value: u16) { if let Some(i) = self.near_call { - let idx = self.frame.near_calls.len() - i - 1; - self.frame.near_calls[idx].exception_handler = value; + self.frame.near_calls[i].exception_handler = value; } else { self.frame.exception_handler = value; } @@ -332,29 +336,13 @@ impl CallframeInterface for CallframeWrapper<'_, T, W> { impl CallframeWrapper<'_, T, W> { fn near_call_on_top(&self) -> Option<&NearCallFrame> { - if self.frame.near_calls.is_empty() || self.near_call == Some(0) { - None - } else { - let index = if let Some(i) = self.near_call { - i - 1 - } else { - self.frame.near_calls.len() - 1 - }; - Some(&self.frame.near_calls[index]) - } + let index = self.near_call.map_or(0, |i| i + 1); + self.frame.near_calls.get(index) } fn near_call_on_top_mut(&mut self) -> Option<&mut NearCallFrame> { - if self.frame.near_calls.is_empty() || self.near_call == Some(0) { - None - } else { - let index = if let Some(i) = self.near_call { - i - 1 - } else { - self.frame.near_calls.len() - 1 - }; - Some(&mut self.frame.near_calls[index]) - } + let index = self.near_call.map_or(0, |i| i + 1); + self.frame.near_calls.get_mut(index) } } @@ -391,26 +379,32 @@ mod test { }, ); + vm.state.current_frame.gas = 0; + vm.state.current_frame.exception_handler = 0; let mut frame_count = 1; let add_far_frame = |vm: &mut VirtualMachine<(), TestWorld<()>>, counter: &mut u16| { vm.push_frame::( H160::from_low_u64_be(1), program.clone(), - 0, + (*counter).into(), 0, *counter, false, HeapId::from_u32_unchecked(5), vm.world_diff.snapshot(), ); + assert_eq!(vm.current_frame().gas(), (*counter).into()); *counter += 1; }; let add_near_frame = |vm: &mut VirtualMachine<(), TestWorld<()>>, counter: &mut u16| { + let count_u32 = (*counter).into(); + vm.state.current_frame.gas += count_u32; vm.state .current_frame - .push_near_call(0, *counter, vm.world_diff.snapshot()); + .push_near_call(count_u32, *counter, vm.world_diff.snapshot()); + assert_eq!(vm.current_frame().gas(), (*counter).into()); *counter += 1; }; @@ -421,11 +415,9 @@ mod test { add_near_frame(&mut vm, &mut frame_count); add_near_frame(&mut vm, &mut frame_count); - for i in 0..frame_count { - assert_eq!( - vm.callframe(i as usize).exception_handler(), - frame_count - i - 1 - ); + for (fwd, rev) in (0..frame_count.into()).zip((0..frame_count).rev()) { + assert_eq!(vm.callframe(fwd).exception_handler(), rev); + assert_eq!(vm.callframe(fwd).gas(), rev.into()); } } }