@@ -162,7 +162,7 @@ pub struct CairoRunnerBuilder {
162162 // Set after loading instruction cache.
163163 // instructions: Vec<Option<Instruction>>,
164164 // Set after compiling hints.
165- // hints: Vec<Rc<dyn Any>>,
165+ hints : Option < Vec < Rc < Box < dyn Any > > > > ,
166166}
167167
168168impl CairoRunnerBuilder {
@@ -203,6 +203,7 @@ impl CairoRunnerBuilder {
203203 execution_base : None ,
204204 memory : MemorySegmentManager :: new ( ) ,
205205 loaded_program : false ,
206+ hints : None ,
206207 } )
207208 }
208209
@@ -221,7 +222,7 @@ impl CairoRunnerBuilder {
221222 || self . runner_mode == RunnerMode :: ProofModeCairo1
222223 }
223224
224- fn add_memory_segment ( & mut self ) -> Relocatable {
225+ pub fn add_memory_segment ( & mut self ) -> Relocatable {
225226 self . memory . add ( )
226227 }
227228
@@ -352,9 +353,12 @@ impl CairoRunnerBuilder {
352353 Ok ( ( ) )
353354 }
354355
355- pub fn initialize_segments ( & mut self ) {
356+ pub fn initialize_base_segments ( & mut self ) {
356357 self . program_base = Some ( self . add_memory_segment ( ) ) ;
357358 self . execution_base = Some ( self . add_memory_segment ( ) ) ;
359+ }
360+
361+ pub fn initialize_builtin_segments ( & mut self ) {
358362 for builtin_runner in self . builtin_runners . iter_mut ( ) {
359363 builtin_runner. initialize_segments ( & mut self . memory ) ;
360364 }
@@ -372,6 +376,33 @@ impl CairoRunnerBuilder {
372376 Ok ( ( ) )
373377 }
374378
379+ pub fn compile_hints (
380+ & mut self ,
381+ hint_processor : & mut dyn HintProcessor ,
382+ ) -> Result < ( ) , VirtualMachineError > {
383+ let constants = Rc :: new ( self . program . constants . clone ( ) ) ;
384+ let references = & self . program . shared_program_data . reference_manager ;
385+ let compiled_hints = self
386+ . program
387+ . shared_program_data
388+ . hints_collection
389+ . iter_hints ( )
390+ . map ( |hint| {
391+ let hint = hint_processor. compile_hint (
392+ & hint. code ,
393+ & hint. flow_tracking_data . ap_tracking ,
394+ & hint. flow_tracking_data . reference_ids ,
395+ references,
396+ constants. clone ( ) ,
397+ ) ?;
398+
399+ Ok ( Rc :: new ( hint) )
400+ } )
401+ . collect :: < Result < Vec < Rc < Box < dyn Any > > > , VirtualMachineError > > ( ) ?;
402+ self . hints = Some ( compiled_hints) ;
403+ Ok ( ( ) )
404+ }
405+
375406 pub fn build ( self ) -> Result < CairoRunner , RunnerError > {
376407 let mut vm = VirtualMachine :: new ( self . enable_trace , self . disable_trace_padding ) ;
377408
@@ -401,6 +432,7 @@ impl CairoRunnerBuilder {
401432 relocated_trace : None ,
402433 program : self . program ,
403434 loaded_program : self . loaded_program ,
435+ hints : self . hints ,
404436 } )
405437 }
406438}
@@ -424,6 +456,7 @@ pub struct CairoRunner {
424456 pub exec_scopes : ExecutionScopes ,
425457 pub relocated_trace : Option < Vec < RelocatedTraceEntry > > ,
426458 loaded_program : bool ,
459+ hints : Option < Vec < Rc < Box < dyn Any > > > > ,
427460}
428461
429462#[ derive( Clone , Debug , PartialEq ) ]
@@ -486,6 +519,7 @@ impl CairoRunner {
486519 } ,
487520 relocated_trace : None ,
488521 loaded_program : false ,
522+ hints : None ,
489523 } )
490524 }
491525
@@ -991,6 +1025,57 @@ impl CairoRunner {
9911025 Ok ( ( ) )
9921026 }
9931027
1028+ pub fn run_until_pc_v2 (
1029+ & mut self ,
1030+ address : Relocatable ,
1031+ hint_processor : & mut dyn HintProcessor ,
1032+ ) -> Result < ( ) , VirtualMachineError > {
1033+ let references = & self . program . shared_program_data . reference_manager ;
1034+ #[ cfg_attr( not( feature = "extensive_hints" ) , allow( unused_mut) ) ]
1035+ let mut hint_data = if let Some ( hints) = self . hints . take ( ) {
1036+ hints
1037+ } else {
1038+ self . get_hint_data ( references, hint_processor) ?
1039+ . into_iter ( )
1040+ . map ( Rc :: new)
1041+ . collect ( )
1042+ } ;
1043+ #[ cfg( feature = "extensive_hints" ) ]
1044+ let mut hint_ranges = self
1045+ . program
1046+ . shared_program_data
1047+ . hints_collection
1048+ . hints_ranges
1049+ . clone ( ) ;
1050+ while self . vm . get_pc ( ) != address && !hint_processor. consumed ( ) {
1051+ self . vm . step_v2 (
1052+ hint_processor,
1053+ & mut self . exec_scopes ,
1054+ #[ cfg( feature = "extensive_hints" ) ]
1055+ & mut hint_data,
1056+ #[ cfg( not( feature = "extensive_hints" ) ) ]
1057+ self . program
1058+ . shared_program_data
1059+ . hints_collection
1060+ . get_hint_range_for_pc ( self . vm . get_pc ( ) . offset )
1061+ . and_then ( |range| {
1062+ range. and_then ( |( start, length) | hint_data. get ( start..start + length. get ( ) ) )
1063+ } )
1064+ . unwrap_or ( & [ ] ) ,
1065+ #[ cfg( feature = "extensive_hints" ) ]
1066+ & mut hint_ranges,
1067+ ) ?;
1068+
1069+ hint_processor. consume_step ( ) ;
1070+ }
1071+
1072+ if self . vm . get_pc ( ) != address {
1073+ return Err ( VirtualMachineError :: UnfinishedExecution ) ;
1074+ }
1075+
1076+ Ok ( ( ) )
1077+ }
1078+
9941079 /// Execute an exact number of steps on the program from the actual position.
9951080 pub fn run_for_steps (
9961081 & mut self ,
0 commit comments