@@ -10,10 +10,14 @@ use crate::{
1010 prelude:: * ,
1111 rc:: Rc ,
1212 } ,
13- types:: { builtin_name:: BuiltinName , layout:: CairoLayoutParams , layout_name:: LayoutName } ,
13+ types:: {
14+ builtin_name:: BuiltinName , instruction:: Instruction , layout:: CairoLayoutParams ,
15+ layout_name:: LayoutName ,
16+ } ,
1417 vm:: {
1518 runners:: builtin_runner:: SegmentArenaBuiltinRunner ,
1619 trace:: trace_entry:: { relocate_trace_register, RelocatedTraceEntry , TraceEntry } ,
20+ vm_core:: VirtualMachineBuilder ,
1721 vm_memory:: memory_segments:: MemorySegmentManager ,
1822 } ,
1923 Felt252 ,
@@ -162,8 +166,8 @@ pub struct CairoRunnerBuilder {
162166 loaded_program : bool ,
163167 // Set after compiling hints.
164168 hints : Option < Vec < Rc < Box < dyn Any > > > > ,
165- // TODO: Set after loading instruction cache.
166- // instructions: Vec<Option<Instruction>>,
169+ // Set after loading instruction cache.
170+ instructions : Vec < Option < Instruction > > ,
167171}
168172
169173impl CairoRunnerBuilder {
@@ -207,6 +211,7 @@ impl CairoRunnerBuilder {
207211 memory : MemorySegmentManager :: new ( ) ,
208212 loaded_program : false ,
209213 hints : None ,
214+ instructions : Vec :: new ( ) ,
210215 } )
211216 }
212217
@@ -229,8 +234,15 @@ impl CairoRunnerBuilder {
229234 self . memory . add ( )
230235 }
231236
232- // TODO: Cloning the builder after calling this function leads to bad
233- // behaviour (transactions revert). Why?
237+ /// *Initializes* all the builtin supported by the current layout, but only
238+ /// *includes* the builtins required by the program.
239+ ///
240+ /// Note that *initializing* a builtin implies creating a runner for it,
241+ /// and *including* a builtin refers to enabling the builtin runner flag:
242+ /// `included`.
243+ ///
244+ /// TODO: Cloning the builder after calling this function leads to bad
245+ /// behaviour (transactions revert). Why?
234246 pub fn initialize_builtin_runners_for_layout ( & mut self ) -> Result < ( ) , RunnerError > {
235247 let builtin_ordered_list = vec ! [
236248 BuiltinName :: output,
@@ -363,21 +375,49 @@ impl CairoRunnerBuilder {
363375 self . execution_base = Some ( self . add_memory_segment ( ) ) ;
364376 }
365377
378+ /// Initializing the builtin segments.
379+ ///
380+ /// Depends on:
381+ /// - [initialize_base_segments](Self::initialize_base_segments)
382+ /// - [initialize_builtin_runners_for_layout](Self::initialize_builtin_runners_for_layout)
366383 pub fn initialize_builtin_segments ( & mut self ) {
367384 for builtin_runner in self . builtin_runners . iter_mut ( ) {
368385 builtin_runner. initialize_segments ( & mut self . memory ) ;
369386 }
370387 }
371388
389+ /// Loads the program into the program segment.
390+ ///
391+ /// If this function is not called, the program will be loaded
392+ /// automataically when initializing the entrypoint.
372393 pub fn load_program ( & mut self ) -> Result < ( ) , RunnerError > {
373394 let program_base = self . program_base . ok_or ( RunnerError :: NoProgBase ) ?;
395+ let program_data = & self . program . shared_program_data . data ;
374396 self . memory
375- . load_data ( program_base, & self . program . shared_program_data . data )
397+ . load_data ( program_base, program_data )
376398 . map_err ( RunnerError :: MemoryInitializationError ) ?;
377399 for i in 0 ..self . program . shared_program_data . data . len ( ) {
378400 self . memory . memory . mark_as_accessed ( ( program_base + i) ?) ;
379401 }
380402 self . loaded_program = true ;
403+ self . instructions . resize ( program_data. len ( ) , None ) ;
404+ Ok ( ( ) )
405+ }
406+
407+ /// Predecodes the program's instructions.
408+ ///
409+ /// # Safety
410+ ///
411+ /// The decoded instructions must belong the the associated program. To
412+ /// obtain them, call [VirtualMachine::take_instruction_cache] at the end of
413+ /// the execution.
414+ ///
415+ /// [VirtualMachine::take_instruction_cache]: crate::vm::vm_core::VirtualMachine::take_instruction_cache
416+ pub fn load_cached_instructions (
417+ & mut self ,
418+ instructions : Vec < Option < Instruction > > ,
419+ ) -> Result < ( ) , RunnerError > {
420+ self . instructions = instructions;
381421 Ok ( ( ) )
382422 }
383423
@@ -423,10 +463,11 @@ impl CairoRunnerBuilder {
423463 }
424464
425465 pub fn build ( self ) -> Result < CairoRunner , RunnerError > {
426- let mut vm = VirtualMachine :: new ( self . enable_trace , self . disable_trace_padding ) ;
427-
428- vm. builtin_runners = self . builtin_runners ;
429- vm. segments = self . memory ;
466+ let vm = VirtualMachineBuilder :: default ( )
467+ . builtin_runners ( self . builtin_runners )
468+ . segments ( self . memory )
469+ . instruction_cache ( self . instructions )
470+ . build ( ) ;
430471
431472 Ok ( CairoRunner {
432473 vm,
0 commit comments