From 1ff926068488c7eb3222d57e67798fad4c1c5d00 Mon Sep 17 00:00:00 2001 From: TurcFort07 Date: Sat, 4 Feb 2023 18:37:01 +0100 Subject: [PATCH] feat: Builder pattern for VirtualMachine --- src/vm/vm_core.rs | 154 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) diff --git a/src/vm/vm_core.rs b/src/vm/vm_core.rs index e6e2a545ea..1b303231de 100644 --- a/src/vm/vm_core.rs +++ b/src/vm/vm_core.rs @@ -996,6 +996,125 @@ impl VirtualMachine { } } +pub struct VirtualMachineBuilder { + pub(crate) run_context: RunContext, + pub(crate) builtin_runners: Vec<(String, BuiltinRunner)>, + pub(crate) segments: MemorySegmentManager, + pub(crate) _program_base: Option, + pub(crate) memory: Memory, + pub(crate) accessed_addresses: Option>, + pub(crate) trace: Option>, + pub(crate) current_step: usize, + skip_instruction_execution: bool, + run_finished: bool, +} + +impl VirtualMachineBuilder { + pub fn new(trace_enabled: bool) -> VirtualMachineBuilder { + let run_context = RunContext { + pc: Relocatable::from((0, 0)), + ap: 0, + fp: 0, + }; + + let trace = if trace_enabled { + Some(Vec::::new()) + } else { + None + }; + + VirtualMachineBuilder { + run_context, + builtin_runners: Vec::new(), + _program_base: None, + memory: Memory::new(), + accessed_addresses: Some(Vec::new()), + trace, + current_step: 0, + skip_instruction_execution: false, + segments: MemorySegmentManager::new(), + run_finished: false, + } + } + + 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<(String, 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 memory(mut self, memory: Memory) -> VirtualMachineBuilder { + self.memory = memory; + 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 + } + + pub fn build(self) -> VirtualMachine { + VirtualMachine { + run_context: self.run_context, + builtin_runners: self.builtin_runners, + _program_base: self._program_base, + memory: self.memory, + 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(test)] mod tests { use super::*; @@ -3921,4 +4040,39 @@ 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, + memory: Memory::new(), + accessed_addresses: Some(Vec::new()), + trace: None, + current_step: 0, + skip_instruction_execution: false, + segments: MemorySegmentManager::new(), + run_finished: true, + }; + + let virtual_machine_from_builder: VirtualMachine = VirtualMachineBuilder::new(false) + .run_finished(true) + .segments(MemorySegmentManager::new()) + .build(); + assert_eq!( + virtual_machine.run_finished, + virtual_machine_from_builder.run_finished + ); + assert_eq!( + virtual_machine.segments, + virtual_machine_from_builder.segments + ); + } }