refactor(tvix/eval): use CodeIdx wrapper for instruction pointer
As suggested by sterni in cl/6453. Change-Id: I3cf80d97c11fd7d085ab510f6be4b5f937c791ec Reviewed-on: https://cl.tvl.fyi/c/depot/+/6562 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
This commit is contained in:
		
							parent
							
								
									a9914a79a0
								
							
						
					
					
						commit
						d5ee893fb1
					
				
					 3 changed files with 34 additions and 9 deletions
				
			
		|  | @ -53,7 +53,7 @@ pub trait Observer { | ||||||
| 
 | 
 | ||||||
|     /// Called when the runtime *begins* executing an instruction. The
 |     /// Called when the runtime *begins* executing an instruction. The
 | ||||||
|     /// provided stack is the state at the beginning of the operation.
 |     /// provided stack is the state at the beginning of the operation.
 | ||||||
|     fn observe_execute_op(&mut self, _ip: usize, _: &OpCode, _: &[Value]) {} |     fn observe_execute_op(&mut self, _ip: CodeIdx, _: &OpCode, _: &[Value]) {} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Default)] | #[derive(Default)] | ||||||
|  | @ -162,8 +162,8 @@ impl<W: Write> Observer for TracingObserver<W> { | ||||||
|         ); |         ); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn observe_execute_op(&mut self, ip: usize, op: &OpCode, stack: &[Value]) { |     fn observe_execute_op(&mut self, ip: CodeIdx, op: &OpCode, stack: &[Value]) { | ||||||
|         let _ = write!(&mut self.writer, "{:04} {:?}\t[ ", ip, op); |         let _ = write!(&mut self.writer, "{:04} {:?}\t[ ", ip.0, op); | ||||||
| 
 | 
 | ||||||
|         for val in stack { |         for val in stack { | ||||||
|             let _ = write!(&mut self.writer, "{} ", val); |             let _ = write!(&mut self.writer, "{} ", val); | ||||||
|  |  | ||||||
|  | @ -1,6 +1,8 @@ | ||||||
| //! This module implements the instruction set running on the abstract
 | //! This module implements the instruction set running on the abstract
 | ||||||
| //! machine implemented by tvix.
 | //! machine implemented by tvix.
 | ||||||
| 
 | 
 | ||||||
|  | use std::ops::{AddAssign, Sub}; | ||||||
|  | 
 | ||||||
| /// Index of a constant in the current code chunk.
 | /// Index of a constant in the current code chunk.
 | ||||||
| #[repr(transparent)] | #[repr(transparent)] | ||||||
| #[derive(Clone, Copy, Debug)] | #[derive(Clone, Copy, Debug)] | ||||||
|  | @ -11,6 +13,20 @@ pub struct ConstantIdx(pub usize); | ||||||
| #[derive(Clone, Copy, Debug)] | #[derive(Clone, Copy, Debug)] | ||||||
| pub struct CodeIdx(pub usize); | pub struct CodeIdx(pub usize); | ||||||
| 
 | 
 | ||||||
|  | impl AddAssign<usize> for CodeIdx { | ||||||
|  |     fn add_assign(&mut self, rhs: usize) { | ||||||
|  |         *self = CodeIdx(self.0 + rhs) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Sub<usize> for CodeIdx { | ||||||
|  |     type Output = Self; | ||||||
|  | 
 | ||||||
|  |     fn sub(self, rhs: usize) -> Self::Output { | ||||||
|  |         CodeIdx(self.0 - rhs) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /// Index of a value in the runtime stack.
 | /// Index of a value in the runtime stack.
 | ||||||
| #[repr(transparent)] | #[repr(transparent)] | ||||||
| #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd)] | #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd)] | ||||||
|  |  | ||||||
|  | @ -13,9 +13,18 @@ use crate::{ | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct CallFrame { | struct CallFrame { | ||||||
|  |     /// The lambda currently being executed.
 | ||||||
|     lambda: Rc<Lambda>, |     lambda: Rc<Lambda>, | ||||||
|  | 
 | ||||||
|  |     /// Optional captured upvalues of this frame (if a thunk or
 | ||||||
|  |     /// closure if being evaluated).
 | ||||||
|     upvalues: Upvalues, |     upvalues: Upvalues, | ||||||
|     ip: usize, | 
 | ||||||
|  |     /// Instruction pointer to the instruction currently being
 | ||||||
|  |     /// executed.
 | ||||||
|  |     ip: CodeIdx, | ||||||
|  | 
 | ||||||
|  |     /// Stack offset, i.e. the frames "view" into the VM's full stack.
 | ||||||
|     stack_offset: usize, |     stack_offset: usize, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -134,7 +143,7 @@ impl<'o> VM<'o> { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn inc_ip(&mut self) -> OpCode { |     fn inc_ip(&mut self) -> OpCode { | ||||||
|         let op = self.chunk().code[self.frame().ip]; |         let op = self.chunk()[self.frame().ip]; | ||||||
|         self.frame_mut().ip += 1; |         self.frame_mut().ip += 1; | ||||||
|         op |         op | ||||||
|     } |     } | ||||||
|  | @ -154,7 +163,7 @@ impl<'o> VM<'o> { | ||||||
|     /// Returns the source span of the instruction currently being
 |     /// Returns the source span of the instruction currently being
 | ||||||
|     /// executed.
 |     /// executed.
 | ||||||
|     fn current_span(&self) -> codemap::Span { |     fn current_span(&self) -> codemap::Span { | ||||||
|         self.chunk().get_span(CodeIdx(self.frame().ip - 1)) |         self.chunk().get_span(self.frame().ip - 1) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /// Construct an error from the given ErrorKind and the source
 |     /// Construct an error from the given ErrorKind and the source
 | ||||||
|  | @ -181,7 +190,7 @@ impl<'o> VM<'o> { | ||||||
|         let frame = CallFrame { |         let frame = CallFrame { | ||||||
|             lambda, |             lambda, | ||||||
|             upvalues, |             upvalues, | ||||||
|             ip: 0, |             ip: CodeIdx(0), | ||||||
|             stack_offset: self.stack.len() - arg_count, |             stack_offset: self.stack.len() - arg_count, | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|  | @ -200,7 +209,7 @@ impl<'o> VM<'o> { | ||||||
|             // Break the loop if this call frame has already run to
 |             // Break the loop if this call frame has already run to
 | ||||||
|             // completion, pop it off, and return the value to the
 |             // completion, pop it off, and return the value to the
 | ||||||
|             // caller.
 |             // caller.
 | ||||||
|             if self.frame().ip == self.chunk().code.len() { |             if self.frame().ip.0 == self.chunk().code.len() { | ||||||
|                 self.frames.pop(); |                 self.frames.pop(); | ||||||
|                 return Ok(self.pop()); |                 return Ok(self.pop()); | ||||||
|             } |             } | ||||||
|  | @ -465,7 +474,7 @@ impl<'o> VM<'o> { | ||||||
|                             let mut frame = self.frame_mut(); |                             let mut frame = self.frame_mut(); | ||||||
|                             frame.lambda = lambda; |                             frame.lambda = lambda; | ||||||
|                             frame.upvalues = closure.upvalues().clone(); |                             frame.upvalues = closure.upvalues().clone(); | ||||||
|                             frame.ip = 0; // reset instruction pointer to beginning
 |                             frame.ip = CodeIdx(0); // reset instruction pointer to beginning
 | ||||||
|                         } |                         } | ||||||
| 
 | 
 | ||||||
|                         _ => return Err(self.error(ErrorKind::NotCallable)), |                         _ => return Err(self.error(ErrorKind::NotCallable)), | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue