@@ -45,14 +45,13 @@ enum BlockType {
4545 } ,
4646}
4747
48- #[ derive( Clone ) ]
4948pub struct Frame {
5049 pub code : bytecode:: CodeObject ,
5150 // We need 1 stack per frame
5251 stack : RefCell < Vec < PyObjectRef > > , // The main data frame of the stack machine
53- blocks : Vec < Block > , // Block frames, for controlling loops and exceptions
52+ blocks : RefCell < Vec < Block > > , // Block frames, for controlling loops and exceptions
5453 pub locals : PyObjectRef , // Variables
55- pub lasti : usize , // index of last instruction ran
54+ pub lasti : RefCell < usize > , // index of last instruction ran
5655}
5756
5857// Running a frame can result in one of the below:
@@ -80,15 +79,15 @@ impl Frame {
8079 Frame {
8180 code : objcode:: get_value ( & code) ,
8281 stack : RefCell :: new ( vec ! [ ] ) ,
83- blocks : vec ! [ ] ,
82+ blocks : RefCell :: new ( vec ! [ ] ) ,
8483 // save the callargs as locals
8584 // globals: locals.clone(),
8685 locals,
87- lasti : 0 ,
86+ lasti : RefCell :: new ( 0 ) ,
8887 }
8988 }
9089
91- pub fn run ( & mut self , vm : & mut VirtualMachine ) -> Result < ExecutionResult , PyObjectRef > {
90+ pub fn run ( & self , vm : & mut VirtualMachine ) -> Result < ExecutionResult , PyObjectRef > {
9291 let filename = & self . code . source_path . to_string ( ) ;
9392
9493 // This is the name of the object being run:
@@ -142,16 +141,16 @@ impl Frame {
142141 value
143142 }
144143
145- pub fn fetch_instruction ( & mut self ) -> bytecode:: Instruction {
144+ pub fn fetch_instruction ( & self ) -> bytecode:: Instruction {
146145 // TODO: an immutable reference is enough, we should not
147146 // clone the instruction.
148- let ins2 = self . code . instructions [ self . lasti ] . clone ( ) ;
149- self . lasti += 1 ;
147+ let ins2 = self . code . instructions [ * self . lasti . borrow ( ) ] . clone ( ) ;
148+ * self . lasti . borrow_mut ( ) += 1 ;
150149 ins2
151150 }
152151
153152 // Execute a single instruction:
154- fn execute_instruction ( & mut self , vm : & mut VirtualMachine ) -> FrameResult {
153+ fn execute_instruction ( & self , vm : & mut VirtualMachine ) -> FrameResult {
155154 let instruction = self . fetch_instruction ( ) ;
156155 {
157156 trace ! ( "=======" ) ;
@@ -344,7 +343,7 @@ impl Frame {
344343 match next_obj {
345344 Some ( value) => {
346345 // Set back program counter:
347- self . lasti -= 1 ;
346+ * self . lasti . borrow_mut ( ) -= 1 ;
348347 Ok ( Some ( ExecutionResult :: Yield ( value) ) )
349348 }
350349 None => {
@@ -662,7 +661,7 @@ impl Frame {
662661 }
663662
664663 fn get_elements (
665- & mut self ,
664+ & self ,
666665 vm : & mut VirtualMachine ,
667666 size : usize ,
668667 unpack : bool ,
@@ -683,7 +682,7 @@ impl Frame {
683682 }
684683
685684 fn import (
686- & mut self ,
685+ & self ,
687686 vm : & mut VirtualMachine ,
688687 module : & str ,
689688 symbol : & Option < String > ,
@@ -701,7 +700,7 @@ impl Frame {
701700 Ok ( None )
702701 }
703702
704- fn import_star ( & mut self , vm : & mut VirtualMachine , module : & str ) -> FrameResult {
703+ fn import_star ( & self , vm : & mut VirtualMachine , module : & str ) -> FrameResult {
705704 let current_path = {
706705 let mut source_pathbuf = PathBuf :: from ( & self . code . source_path ) ;
707706 source_pathbuf. pop ( ) ;
@@ -719,7 +718,7 @@ impl Frame {
719718 }
720719
721720 // Unwind all blocks:
722- fn unwind_blocks ( & mut self , vm : & mut VirtualMachine ) -> Option < PyObjectRef > {
721+ fn unwind_blocks ( & self , vm : & mut VirtualMachine ) -> Option < PyObjectRef > {
723722 while let Some ( block) = self . pop_block ( ) {
724723 match block. typ {
725724 BlockType :: Loop { .. } => { }
@@ -743,9 +742,9 @@ impl Frame {
743742 None
744743 }
745744
746- fn unwind_loop ( & mut self , vm : & mut VirtualMachine ) -> Block {
745+ fn unwind_loop ( & self , vm : & mut VirtualMachine ) -> Block {
747746 loop {
748- let block = self . current_block ( ) . cloned ( ) . expect ( "not in a loop" ) ;
747+ let block = self . current_block ( ) . expect ( "not in a loop" ) ;
749748 match block. typ {
750749 BlockType :: Loop { .. } => break block,
751750 BlockType :: TryExcept { .. } => {
@@ -765,11 +764,7 @@ impl Frame {
765764 }
766765 }
767766
768- fn unwind_exception (
769- & mut self ,
770- vm : & mut VirtualMachine ,
771- exc : PyObjectRef ,
772- ) -> Option < PyObjectRef > {
767+ fn unwind_exception ( & self , vm : & mut VirtualMachine , exc : PyObjectRef ) -> Option < PyObjectRef > {
773768 // unwind block stack on exception and find any handlers:
774769 while let Some ( block) = self . pop_block ( ) {
775770 match block. typ {
@@ -837,13 +832,13 @@ impl Frame {
837832 vm. call_method ( context_manager, "__exit__" , args)
838833 }
839834
840- fn store_name ( & mut self , vm : & mut VirtualMachine , name : & str ) -> FrameResult {
835+ fn store_name ( & self , vm : & mut VirtualMachine , name : & str ) -> FrameResult {
841836 let obj = self . pop_value ( ) ;
842837 vm. ctx . set_attr ( & self . locals , name, obj) ;
843838 Ok ( None )
844839 }
845840
846- fn delete_name ( & mut self , vm : & mut VirtualMachine , name : & str ) -> FrameResult {
841+ fn delete_name ( & self , vm : & mut VirtualMachine , name : & str ) -> FrameResult {
847842 let locals = match self . locals . payload {
848843 PyObjectPayload :: Scope { ref scope } => scope. borrow ( ) . locals . clone ( ) ,
849844 _ => panic ! ( "We really expect our scope to be a scope!" ) ,
@@ -855,7 +850,7 @@ impl Frame {
855850 Ok ( None )
856851 }
857852
858- fn load_name ( & mut self , vm : & mut VirtualMachine , name : & str ) -> FrameResult {
853+ fn load_name ( & self , vm : & mut VirtualMachine , name : & str ) -> FrameResult {
859854 // Lookup name in scope and put it onto the stack!
860855 let mut scope = self . locals . clone ( ) ;
861856 loop {
@@ -874,33 +869,33 @@ impl Frame {
874869 }
875870 }
876871
877- fn subscript ( & mut self , vm : & mut VirtualMachine , a : PyObjectRef , b : PyObjectRef ) -> PyResult {
872+ fn subscript ( & self , vm : & mut VirtualMachine , a : PyObjectRef , b : PyObjectRef ) -> PyResult {
878873 vm. call_method ( & a, "__getitem__" , vec ! [ b] )
879874 }
880875
881- fn execute_store_subscript ( & mut self , vm : & mut VirtualMachine ) -> FrameResult {
876+ fn execute_store_subscript ( & self , vm : & mut VirtualMachine ) -> FrameResult {
882877 let idx = self . pop_value ( ) ;
883878 let obj = self . pop_value ( ) ;
884879 let value = self . pop_value ( ) ;
885880 vm. call_method ( & obj, "__setitem__" , vec ! [ idx, value] ) ?;
886881 Ok ( None )
887882 }
888883
889- fn execute_delete_subscript ( & mut self , vm : & mut VirtualMachine ) -> FrameResult {
884+ fn execute_delete_subscript ( & self , vm : & mut VirtualMachine ) -> FrameResult {
890885 let idx = self . pop_value ( ) ;
891886 let obj = self . pop_value ( ) ;
892887 vm. call_method ( & obj, "__delitem__" , vec ! [ idx] ) ?;
893888 Ok ( None )
894889 }
895890
896- fn jump ( & mut self , label : bytecode:: Label ) {
891+ fn jump ( & self , label : bytecode:: Label ) {
897892 let target_pc = self . code . label_map [ & label] ;
898893 trace ! ( "program counter from {:?} to {:?}" , self . lasti, target_pc) ;
899- self . lasti = target_pc;
894+ * self . lasti . borrow_mut ( ) = target_pc;
900895 }
901896
902897 fn execute_binop (
903- & mut self ,
898+ & self ,
904899 vm : & mut VirtualMachine ,
905900 op : & bytecode:: BinaryOperator ,
906901 inplace : bool ,
@@ -943,11 +938,7 @@ impl Frame {
943938 Ok ( None )
944939 }
945940
946- fn execute_unop (
947- & mut self ,
948- vm : & mut VirtualMachine ,
949- op : & bytecode:: UnaryOperator ,
950- ) -> FrameResult {
941+ fn execute_unop ( & self , vm : & mut VirtualMachine , op : & bytecode:: UnaryOperator ) -> FrameResult {
951942 let a = self . pop_value ( ) ;
952943 let value = match * op {
953944 bytecode:: UnaryOperator :: Minus => vm. call_method ( & a, "__neg__" , vec ! [ ] ) ?,
@@ -968,7 +959,7 @@ impl Frame {
968959
969960 // https://docs.python.org/3/reference/expressions.html#membership-test-operations
970961 fn _membership (
971- & mut self ,
962+ & self ,
972963 vm : & mut VirtualMachine ,
973964 needle : PyObjectRef ,
974965 haystack : & PyObjectRef ,
@@ -978,12 +969,7 @@ impl Frame {
978969 // not implemented.
979970 }
980971
981- fn _in (
982- & mut self ,
983- vm : & mut VirtualMachine ,
984- needle : PyObjectRef ,
985- haystack : PyObjectRef ,
986- ) -> PyResult {
972+ fn _in ( & self , vm : & mut VirtualMachine , needle : PyObjectRef , haystack : PyObjectRef ) -> PyResult {
987973 match self . _membership ( vm, needle, & haystack) {
988974 Ok ( found) => Ok ( found) ,
989975 Err ( _) => Err ( vm. new_type_error ( format ! (
@@ -994,7 +980,7 @@ impl Frame {
994980 }
995981
996982 fn _not_in (
997- & mut self ,
983+ & self ,
998984 vm : & mut VirtualMachine ,
999985 needle : PyObjectRef ,
1000986 haystack : PyObjectRef ,
@@ -1020,7 +1006,7 @@ impl Frame {
10201006 }
10211007
10221008 fn execute_compare (
1023- & mut self ,
1009+ & self ,
10241010 vm : & mut VirtualMachine ,
10251011 op : & bytecode:: ComparisonOperator ,
10261012 ) -> FrameResult {
@@ -1043,47 +1029,47 @@ impl Frame {
10431029 Ok ( None )
10441030 }
10451031
1046- fn load_attr ( & mut self , vm : & mut VirtualMachine , attr_name : & str ) -> FrameResult {
1032+ fn load_attr ( & self , vm : & mut VirtualMachine , attr_name : & str ) -> FrameResult {
10471033 let parent = self . pop_value ( ) ;
10481034 let attr_name = vm. new_str ( attr_name. to_string ( ) ) ;
10491035 let obj = vm. get_attribute ( parent, attr_name) ?;
10501036 self . push_value ( obj) ;
10511037 Ok ( None )
10521038 }
10531039
1054- fn store_attr ( & mut self , vm : & mut VirtualMachine , attr_name : & str ) -> FrameResult {
1040+ fn store_attr ( & self , vm : & mut VirtualMachine , attr_name : & str ) -> FrameResult {
10551041 let parent = self . pop_value ( ) ;
10561042 let value = self . pop_value ( ) ;
10571043 vm. ctx . set_attr ( & parent, attr_name, value) ;
10581044 Ok ( None )
10591045 }
10601046
1061- fn delete_attr ( & mut self , vm : & mut VirtualMachine , attr_name : & str ) -> FrameResult {
1047+ fn delete_attr ( & self , vm : & mut VirtualMachine , attr_name : & str ) -> FrameResult {
10621048 let parent = self . pop_value ( ) ;
10631049 let name = vm. ctx . new_str ( attr_name. to_string ( ) ) ;
10641050 vm. del_attr ( & parent, name) ?;
10651051 Ok ( None )
10661052 }
10671053
10681054 pub fn get_lineno ( & self ) -> ast:: Location {
1069- self . code . locations [ self . lasti ] . clone ( )
1055+ self . code . locations [ * self . lasti . borrow ( ) ] . clone ( )
10701056 }
10711057
1072- fn push_block ( & mut self , typ : BlockType ) {
1073- self . blocks . push ( Block {
1058+ fn push_block ( & self , typ : BlockType ) {
1059+ self . blocks . borrow_mut ( ) . push ( Block {
10741060 typ,
10751061 level : self . stack . borrow ( ) . len ( ) ,
10761062 } ) ;
10771063 }
10781064
1079- fn pop_block ( & mut self ) -> Option < Block > {
1080- let block = self . blocks . pop ( ) ?;
1065+ fn pop_block ( & self ) -> Option < Block > {
1066+ let block = self . blocks . borrow_mut ( ) . pop ( ) ?;
10811067 self . stack . borrow_mut ( ) . truncate ( block. level ) ;
10821068 Some ( block)
10831069 }
10841070
1085- fn current_block ( & self ) -> Option < & Block > {
1086- self . blocks . last ( )
1071+ fn current_block ( & self ) -> Option < Block > {
1072+ self . blocks . borrow ( ) . last ( ) . cloned ( )
10871073 }
10881074
10891075 pub fn push_value ( & self , obj : PyObjectRef ) {
@@ -1094,7 +1080,7 @@ impl Frame {
10941080 self . stack . borrow_mut ( ) . pop ( ) . unwrap ( )
10951081 }
10961082
1097- fn pop_multiple ( & mut self , count : usize ) -> Vec < PyObjectRef > {
1083+ fn pop_multiple ( & self , count : usize ) -> Vec < PyObjectRef > {
10981084 let mut objs: Vec < PyObjectRef > = Vec :: new ( ) ;
10991085 for _x in 0 ..count {
11001086 objs. push ( self . pop_value ( ) ) ;
@@ -1123,6 +1109,7 @@ impl fmt::Debug for Frame {
11231109 . join ( "" ) ;
11241110 let block_str = self
11251111 . blocks
1112+ . borrow ( )
11261113 . iter ( )
11271114 . map ( |elem| format ! ( "\n > {:?}" , elem) )
11281115 . collect :: < Vec < _ > > ( )
0 commit comments