diff --git a/src/vm/vm_core.rs b/src/vm/vm_core.rs index a87d100808..4fd450966d 100644 --- a/src/vm/vm_core.rs +++ b/src/vm/vm_core.rs @@ -986,6 +986,129 @@ impl VirtualMachine { } } +pub struct VirtualMachineBuilder { + pub(crate) run_context: RunContext, + pub(crate) builtin_runners: Vec<(&'static str, BuiltinRunner)>, + pub(crate) segments: MemorySegmentManager, + pub(crate) _program_base: Option, + pub(crate) accessed_addresses: Option>, + pub(crate) trace: Option>, + pub(crate) current_step: usize, + skip_instruction_execution: bool, + run_finished: bool, + #[cfg(feature = "hooks")] + pub(crate) hooks: crate::vm::hooks::Hooks, +} + +impl Default for VirtualMachineBuilder { + fn default() -> Self { + Self::new() + } +} + +impl VirtualMachineBuilder { + pub fn new() -> VirtualMachineBuilder { + let run_context = RunContext { + pc: Relocatable::from((0, 0)), + ap: 0, + fp: 0, + }; + + VirtualMachineBuilder { + run_context, + builtin_runners: Vec::new(), + _program_base: None, + accessed_addresses: Some(Vec::new()), + trace: None, + current_step: 0, + skip_instruction_execution: false, + segments: MemorySegmentManager::new(), + run_finished: false, + #[cfg(feature = "hooks")] + hooks: Default::default(), + } + } + + pub fn run_context(mut self, run_context: RunContext) -> VirtualMachineBuilder { + self.run_context = run_context; + self + } + + pub fn builtin_runners( + mut self, + builtin_runners: Vec<(&'static str, BuiltinRunner)>, + ) -> VirtualMachineBuilder { + self.builtin_runners = builtin_runners; + self + } + + pub fn segments(mut self, segments: MemorySegmentManager) -> VirtualMachineBuilder { + self.segments = segments; + self + } + + pub fn _program_base( + mut self, + _program_base: Option, + ) -> VirtualMachineBuilder { + self._program_base = _program_base; + self + } + + pub fn accessed_addresses( + mut self, + accessed_addresses: Option>, + ) -> VirtualMachineBuilder { + self.accessed_addresses = accessed_addresses; + self + } + + pub fn trace(mut self, trace: Option>) -> VirtualMachineBuilder { + self.trace = trace; + self + } + + pub fn current_step(mut self, current_step: usize) -> VirtualMachineBuilder { + self.current_step = current_step; + self + } + + pub fn skip_instruction_execution( + mut self, + skip_instruction_execution: bool, + ) -> VirtualMachineBuilder { + self.skip_instruction_execution = skip_instruction_execution; + self + } + + pub fn run_finished(mut self, run_finished: bool) -> VirtualMachineBuilder { + self.run_finished = run_finished; + self + } + + #[cfg(feature = "hooks")] + pub fn hooks(mut self, hooks: crate::vm::hooks::Hooks) -> VirtualMachineBuilder { + self.hooks = hooks; + self + } + + pub fn build(self) -> VirtualMachine { + VirtualMachine { + run_context: self.run_context, + builtin_runners: self.builtin_runners, + _program_base: self._program_base, + accessed_addresses: self.accessed_addresses, + trace: self.trace, + current_step: self.current_step, + skip_instruction_execution: self.skip_instruction_execution, + segments: self.segments, + run_finished: self.run_finished, + #[cfg(feature = "hooks")] + hooks: Default::default(), + } + } +} + #[cfg(test)] mod tests { use super::*; @@ -4015,4 +4138,40 @@ mod tests { let expected_traceback = vec![(Relocatable::from((1, 2)), Relocatable::from((0, 34)))]; assert_eq!(vm.get_traceback_entries(), expected_traceback); } + + #[test] + fn builder_test() { + let run_context = RunContext { + pc: Relocatable::from((0, 0)), + ap: 0, + fp: 0, + }; + + let virtual_machine = VirtualMachine { + run_context, + builtin_runners: Vec::new(), + _program_base: None, + accessed_addresses: Some(Vec::new()), + trace: None, + current_step: 12, + skip_instruction_execution: false, + segments: MemorySegmentManager::new(), + run_finished: true, + #[cfg(feature = "hooks")] + hooks: Default::default(), + }; + + let virtual_machine_from_builder: VirtualMachine = VirtualMachineBuilder::new() + .run_finished(true) + .current_step(12) + .build(); + assert_eq!( + virtual_machine.run_finished, + virtual_machine_from_builder.run_finished + ); + assert_eq!( + virtual_machine.current_step, + virtual_machine_from_builder.current_step + ); + } }