@@ -51,6 +51,7 @@ const GLOBAL_NAMES: [&str; 18] = [
5151#[ pyclass( unsendable) ]
5252pub struct PyVM {
5353 pub ( crate ) vm : Rc < RefCell < VirtualMachine > > ,
54+ pub ( crate ) failed_hint_index : Option < usize > ,
5455}
5556
5657#[ pymethods]
@@ -74,6 +75,7 @@ impl PyVM {
7475 trace_enabled,
7576 error_message_attributes,
7677 ) ) ) ,
78+ failed_hint_index : None ,
7779 }
7880 }
7981
@@ -82,7 +84,7 @@ impl PyVM {
8284 }
8385
8486 pub ( crate ) fn execute_hint (
85- & self ,
87+ & mut self ,
8688 hint_data : & HintProcessorData ,
8789 hint_locals : & mut HashMap < String , PyObject > ,
8890 exec_scopes : & mut ExecutionScopes ,
@@ -164,7 +166,7 @@ impl PyVM {
164166
165167 #[ allow( clippy:: too_many_arguments) ]
166168 pub ( crate ) fn step_hint (
167- & self ,
169+ & mut self ,
168170 hint_executor : & mut dyn HintProcessor ,
169171 hint_locals : & mut HashMap < String , PyObject > ,
170172 exec_scopes : & mut ExecutionScopes ,
@@ -176,7 +178,7 @@ impl PyVM {
176178 let pc_offset = ( * self . vm ) . borrow ( ) . get_pc ( ) . offset ;
177179
178180 if let Some ( hint_list) = hint_data_dictionary. get ( & pc_offset) {
179- for hint_data in hint_list. iter ( ) {
181+ for ( hint_index , hint_data) in hint_list. iter ( ) . enumerate ( ) {
180182 if self
181183 . should_run_py_hint ( hint_executor, exec_scopes, hint_data, constants)
182184 . map_err ( to_py_error) ?
@@ -186,14 +188,17 @@ impl PyVM {
186188 . ok_or ( VirtualMachineError :: WrongHintData )
187189 . map_err ( to_py_error) ?;
188190
189- self . execute_hint (
191+ if let Err ( hint_error ) = self . execute_hint (
190192 hint_data,
191193 hint_locals,
192194 exec_scopes,
193195 constants,
194196 Rc :: clone ( & struct_types) ,
195197 static_locals,
196- ) ?;
198+ ) {
199+ self . failed_hint_index = Some ( hint_index) ;
200+ return Err ( hint_error) ;
201+ }
197202 }
198203 }
199204 }
@@ -203,7 +208,7 @@ impl PyVM {
203208
204209 #[ allow( clippy:: too_many_arguments) ]
205210 pub ( crate ) fn step (
206- & self ,
211+ & mut self ,
207212 hint_executor : & mut dyn HintProcessor ,
208213 hint_locals : & mut HashMap < String , PyObject > ,
209214 exec_scopes : & mut ExecutionScopes ,
@@ -296,7 +301,7 @@ mod test {
296301
297302 #[ test]
298303 fn execute_print_hint ( ) {
299- let vm = PyVM :: new (
304+ let mut vm = PyVM :: new (
300305 BigInt :: new ( Sign :: Plus , vec ! [ 1 , 0 , 0 , 0 , 0 , 0 , 17 , 134217728 ] ) ,
301306 false ,
302307 Vec :: new ( ) ,
@@ -317,7 +322,7 @@ mod test {
317322
318323 #[ test]
319324 fn set_memory_item_hint ( ) {
320- let vm = PyVM :: new (
325+ let mut vm = PyVM :: new (
321326 BigInt :: new ( Sign :: Plus , vec ! [ 1 , 0 , 0 , 0 , 0 , 0 , 17 , 134217728 ] ) ,
322327 false ,
323328 Vec :: new ( ) ,
@@ -338,7 +343,7 @@ mod test {
338343
339344 #[ test]
340345 fn ids_hint ( ) {
341- let vm = PyVM :: new (
346+ let mut vm = PyVM :: new (
342347 BigInt :: new ( Sign :: Plus , vec ! [ 1 , 0 , 0 , 0 , 0 , 0 , 17 , 134217728 ] ) ,
343348 false ,
344349 Vec :: new ( ) ,
@@ -378,7 +383,7 @@ mod test {
378383 #[ test]
379384 // Test the availability of cairo constants in ids
380385 fn const_ids ( ) {
381- let vm = PyVM :: new (
386+ let mut vm = PyVM :: new (
382387 BigInt :: new ( Sign :: Plus , vec ! [ 1 , 0 , 0 , 0 , 0 , 0 , 17 , 134217728 ] ) ,
383388 false ,
384389 Vec :: new ( ) ,
@@ -419,7 +424,7 @@ mod test {
419424 #[ test]
420425 // This test is analogous to the `test_step_for_preset_memory` unit test in the cairo-rs crate.
421426 fn test_step_with_no_hint ( ) {
422- let vm = PyVM :: new (
427+ let mut vm = PyVM :: new (
423428 BigInt :: new ( Sign :: Plus , vec ! [ 1 , 0 , 0 , 0 , 0 , 0 , 17 , 134217728 ] ) ,
424429 false ,
425430 Vec :: new ( ) ,
@@ -463,7 +468,7 @@ mod test {
463468
464469 #[ test]
465470 fn test_step_with_print_hint ( ) {
466- let vm = PyVM :: new (
471+ let mut vm = PyVM :: new (
467472 BigInt :: new ( Sign :: Plus , vec ! [ 1 , 0 , 0 , 0 , 0 , 0 , 17 , 134217728 ] ) ,
468473 false ,
469474 Vec :: new ( ) ,
@@ -513,7 +518,7 @@ mod test {
513518
514519 #[ test]
515520 fn scopes_hint ( ) {
516- let vm = PyVM :: new (
521+ let mut vm = PyVM :: new (
517522 BigInt :: new ( Sign :: Plus , vec ! [ 1 , 0 , 0 , 0 , 0 , 0 , 17 , 134217728 ] ) ,
518523 false ,
519524 Vec :: new ( ) ,
@@ -552,7 +557,7 @@ mod test {
552557
553558 #[ test]
554559 fn scopes_hint_modify ( ) {
555- let vm = PyVM :: new (
560+ let mut vm = PyVM :: new (
556561 BigInt :: new ( Sign :: Plus , vec ! [ 1 , 0 , 0 , 0 , 0 , 0 , 17 , 134217728 ] ) ,
557562 false ,
558563 Vec :: new ( ) ,
@@ -614,7 +619,7 @@ mod test {
614619
615620 #[ test]
616621 fn modify_hint_locals ( ) {
617- let vm = PyVM :: new (
622+ let mut vm = PyVM :: new (
618623 BigInt :: new ( Sign :: Plus , vec ! [ 1 , 0 , 0 , 0 , 0 , 0 , 17 , 134217728 ] ) ,
619624 false ,
620625 Vec :: new ( ) ,
@@ -646,7 +651,7 @@ print(word)";
646651
647652 #[ test]
648653 fn exit_main_scope_hint ( ) {
649- let vm = PyVM :: new (
654+ let mut vm = PyVM :: new (
650655 BigInt :: new ( Sign :: Plus , vec ! [ 1 , 0 , 0 , 0 , 0 , 0 , 17 , 134217728 ] ) ,
651656 false ,
652657 Vec :: new ( ) ,
@@ -667,7 +672,7 @@ print(word)";
667672
668673 #[ test]
669674 fn enter_scope_empty_hint ( ) {
670- let vm = PyVM :: new (
675+ let mut vm = PyVM :: new (
671676 BigInt :: new ( Sign :: Plus , vec ! [ 1 , 0 , 0 , 0 , 0 , 0 , 17 , 134217728 ] ) ,
672677 false ,
673678 Vec :: new ( ) ,
@@ -690,7 +695,7 @@ print(word)";
690695
691696 #[ test]
692697 fn enter_exit_scope_same_hint ( ) {
693- let vm = PyVM :: new (
698+ let mut vm = PyVM :: new (
694699 BigInt :: new ( Sign :: Plus , vec ! [ 1 , 0 , 0 , 0 , 0 , 0 , 17 , 134217728 ] ) ,
695700 false ,
696701 Vec :: new ( ) ,
@@ -714,7 +719,7 @@ vm_exit_scope()";
714719
715720 #[ test]
716721 fn enter_exit_scope_separate_hints ( ) {
717- let vm = PyVM :: new (
722+ let mut vm = PyVM :: new (
718723 BigInt :: new ( Sign :: Plus , vec ! [ 1 , 0 , 0 , 0 , 0 , 0 , 17 , 134217728 ] ) ,
719724 false ,
720725 Vec :: new ( ) ,
@@ -750,7 +755,7 @@ vm_exit_scope()";
750755
751756 #[ test]
752757 fn enter_exit_enter_scope_same_hint ( ) {
753- let vm = PyVM :: new (
758+ let mut vm = PyVM :: new (
754759 BigInt :: new ( Sign :: Plus , vec ! [ 1 , 0 , 0 , 0 , 0 , 0 , 17 , 134217728 ] ) ,
755760 false ,
756761 Vec :: new ( ) ,
@@ -775,7 +780,7 @@ vm_enter_scope()";
775780
776781 #[ test]
777782 fn list_comprehension ( ) {
778- let vm = PyVM :: new (
783+ let mut vm = PyVM :: new (
779784 BigInt :: new ( Sign :: Plus , vec ! [ 1 , 0 , 0 , 0 , 0 , 0 , 17 , 134217728 ] ) ,
780785 false ,
781786 Vec :: new ( ) ,
@@ -798,7 +803,7 @@ lista_b = [lista_a[k] for k in range(2)]";
798803
799804 #[ test]
800805 fn enter_scope_non_empty_hint ( ) {
801- let vm = PyVM :: new (
806+ let mut vm = PyVM :: new (
802807 BigInt :: new ( Sign :: Plus , vec ! [ 1 , 0 , 0 , 0 , 0 , 0 , 17 , 134217728 ] ) ,
803808 false ,
804809 Vec :: new ( ) ,
@@ -834,7 +839,7 @@ lista_b = [lista_a[k] for k in range(2)]";
834839
835840 #[ test]
836841 fn access_relocatable_segment_index ( ) {
837- let vm = PyVM :: new (
842+ let mut vm = PyVM :: new (
838843 BigInt :: new ( Sign :: Plus , vec ! [ 1 , 0 , 0 , 0 , 0 , 0 , 17 , 134217728 ] ) ,
839844 false ,
840845 Vec :: new ( ) ,
@@ -856,7 +861,7 @@ lista_b = [lista_a[k] for k in range(2)]";
856861
857862 #[ test]
858863 fn to_felt_or_relocatable_number ( ) {
859- let vm = PyVM :: new (
864+ let mut vm = PyVM :: new (
860865 BigInt :: new ( Sign :: Plus , vec ! [ 1 , 0 , 0 , 0 , 0 , 0 , 17 , 134217728 ] ) ,
861866 false ,
862867 Vec :: new ( ) ,
@@ -890,7 +895,7 @@ lista_b = [lista_a[k] for k in range(2)]";
890895
891896 #[ test]
892897 fn to_felt_or_relocatable_list_should_fail ( ) {
893- let vm = PyVM :: new (
898+ let mut vm = PyVM :: new (
894899 BigInt :: new ( Sign :: Plus , vec ! [ 1 , 0 , 0 , 0 , 0 , 0 , 17 , 134217728 ] ) ,
895900 false ,
896901 Vec :: new ( ) ,
@@ -912,7 +917,7 @@ lista_b = [lista_a[k] for k in range(2)]";
912917
913918 #[ test]
914919 fn to_felt_or_relocatable_relocatable ( ) {
915- let vm = PyVM :: new (
920+ let mut vm = PyVM :: new (
916921 BigInt :: new ( Sign :: Plus , vec ! [ 1 , 0 , 0 , 0 , 0 , 0 , 17 , 134217728 ] ) ,
917922 false ,
918923 Vec :: new ( ) ,
@@ -953,7 +958,7 @@ lista_b = [lista_a[k] for k in range(2)]";
953958
954959 #[ test]
955960 fn test_get_range ( ) {
956- let pyvm = PyVM :: new (
961+ let mut pyvm = PyVM :: new (
957962 BigInt :: new ( Sign :: Plus , vec ! [ 1 , 0 , 0 , 0 , 0 , 0 , 17 , 134217728 ] ) ,
958963 false ,
959964 Vec :: new ( ) ,
@@ -1002,7 +1007,7 @@ lista_b = [lista_a[k] for k in range(2)]";
10021007
10031008 #[ test]
10041009 fn test_segments_memory_get_range ( ) {
1005- let pyvm = PyVM :: new (
1010+ let mut pyvm = PyVM :: new (
10061011 BigInt :: new ( Sign :: Plus , vec ! [ 1 , 0 , 0 , 0 , 0 , 0 , 17 , 134217728 ] ) ,
10071012 false ,
10081013 Vec :: new ( ) ,
@@ -1045,7 +1050,7 @@ lista_b = [lista_a[k] for k in range(2)]";
10451050
10461051 #[ test]
10471052 fn run_hint_with_static_locals ( ) {
1048- let vm = PyVM :: new (
1053+ let mut vm = PyVM :: new (
10491054 BigInt :: new ( Sign :: Plus , vec ! [ 1 , 0 , 0 , 0 , 0 , 0 , 17 , 134217728 ] ) ,
10501055 false ,
10511056 Vec :: new ( ) ,
@@ -1081,7 +1086,7 @@ lista_b = [lista_a[k] for k in range(2)]";
10811086
10821087 #[ test]
10831088 fn run_hint_with_static_locals_shouldnt_change_its_value ( ) {
1084- let vm = PyVM :: new (
1089+ let mut vm = PyVM :: new (
10851090 BigInt :: new ( Sign :: Plus , vec ! [ 1 , 0 , 0 , 0 , 0 , 0 , 17 , 134217728 ] ) ,
10861091 false ,
10871092 Vec :: new ( ) ,
@@ -1115,7 +1120,7 @@ lista_b = [lista_a[k] for k in range(2)]";
11151120
11161121 #[ test]
11171122 fn run_hint_with_static_locals_shouldnt_affect_scope_or_hint_locals ( ) {
1118- let vm = PyVM :: new (
1123+ let mut vm = PyVM :: new (
11191124 BigInt :: new ( Sign :: Plus , vec ! [ 1 , 0 , 0 , 0 , 0 , 0 , 17 , 134217728 ] ) ,
11201125 false ,
11211126 Vec :: new ( ) ,
0 commit comments