@@ -45,14 +45,13 @@ enum BlockType {
4545} ,
4646}
4747
48- #[ derive( Clone ) ]
4948pub struct Frame {
5049pub code : bytecode:: CodeObject ,
5150// We need 1 stack per frame
5251stack : 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
5453pub 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 {
8079Frame {
8180code : objcode:: get_value ( & code) ,
8281stack : 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 > {
9291let 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 {
155154let instruction =self . fetch_instruction ( ) ;
156155{
157156trace ! ( "=======" ) ;
@@ -344,7 +343,7 @@ impl Frame {
344343match next_obj{
345344Some ( value) =>{
346345// Set back program counter:
347- self . lasti -=1 ;
346+ * self . lasti . borrow_mut ( ) -=1 ;
348347Ok ( Some ( ExecutionResult :: Yield ( value) ) )
349348}
350349None =>{
@@ -662,7 +661,7 @@ impl Frame {
662661}
663662
664663fn get_elements (
665- & mut self ,
664+ & self ,
666665vm : & mut VirtualMachine ,
667666size : usize ,
668667unpack : bool ,
@@ -683,7 +682,7 @@ impl Frame {
683682}
684683
685684fn import (
686- & mut self ,
685+ & self ,
687686vm : & mut VirtualMachine ,
688687module : & str ,
689688symbol : & Option < String > ,
@@ -701,7 +700,7 @@ impl Frame {
701700Ok ( 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 {
705704let current_path ={
706705let 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 > {
723722while let Some ( block) =self . pop_block ( ) {
724723match block. typ {
725724BlockType :: Loop { ..} =>{ }
@@ -743,9 +742,9 @@ impl Frame {
743742None
744743}
745744
746- fn unwind_loop ( & mut self , vm : & mut VirtualMachine ) ->Block {
745+ fn unwind_loop ( & self , vm : & mut VirtualMachine ) ->Block {
747746loop {
748- let block =self . current_block ( ) . cloned ( ) . expect ( "not in a loop" ) ;
747+ let block =self . current_block ( ) . expect ( "not in a loop" ) ;
749748match block. typ {
750749BlockType :: Loop { ..} =>break block,
751750BlockType :: 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:
774769while let Some ( block) =self . pop_block ( ) {
775770match 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 {
841836let obj =self . pop_value ( ) ;
842837 vm. ctx . set_attr ( & self . locals , name, obj) ;
843838Ok ( 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 {
847842let locals =match self . locals . payload {
848843PyObjectPayload :: Scope { ref scope} => scope. borrow ( ) . locals . clone ( ) ,
849844 _ =>panic ! ( "We really expect our scope to be a scope!" ) ,
@@ -855,7 +850,7 @@ impl Frame {
855850Ok ( 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!
860855let mut scope =self . locals . clone ( ) ;
861856loop {
@@ -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 {
882877let idx =self . pop_value ( ) ;
883878let obj =self . pop_value ( ) ;
884879let value =self . pop_value ( ) ;
885880 vm. call_method ( & obj, "__setitem__" , vec ! [ idx, value] ) ?;
886881Ok ( None )
887882}
888883
889- fn execute_delete_subscript ( & mut self , vm : & mut VirtualMachine ) ->FrameResult {
884+ fn execute_delete_subscript ( & self , vm : & mut VirtualMachine ) ->FrameResult {
890885let idx =self . pop_value ( ) ;
891886let obj =self . pop_value ( ) ;
892887 vm. call_method ( & obj, "__delitem__" , vec ! [ idx] ) ?;
893888Ok ( None )
894889}
895890
896- fn jump ( & mut self , label : bytecode:: Label ) {
891+ fn jump ( & self , label : bytecode:: Label ) {
897892let target_pc =self . code . label_map [ & label] ;
898893trace ! ( "program counter from {:?} to {:?}" , self . lasti, target_pc) ;
899- self . lasti = target_pc;
894+ * self . lasti . borrow_mut ( ) = target_pc;
900895}
901896
902897fn execute_binop (
903- & mut self ,
898+ & self ,
904899vm : & mut VirtualMachine ,
905900op : & bytecode:: BinaryOperator ,
906901inplace : bool ,
@@ -943,11 +938,7 @@ impl Frame {
943938Ok ( 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 {
951942let a =self . pop_value ( ) ;
952943let 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
970961fn _membership (
971- & mut self ,
962+ & self ,
972963vm : & mut VirtualMachine ,
973964needle : PyObjectRef ,
974965haystack : & 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 {
987973match self . _membership ( vm, needle, & haystack) {
988974Ok ( found) =>Ok ( found) ,
989975Err ( _) =>Err ( vm. new_type_error ( format ! (
@@ -994,7 +980,7 @@ impl Frame {
994980}
995981
996982fn _not_in (
997- & mut self ,
983+ & self ,
998984vm : & mut VirtualMachine ,
999985needle : PyObjectRef ,
1000986haystack : PyObjectRef ,
@@ -1020,7 +1006,7 @@ impl Frame {
10201006}
10211007
10221008fn execute_compare (
1023- & mut self ,
1009+ & self ,
10241010vm : & mut VirtualMachine ,
10251011op : & bytecode:: ComparisonOperator ,
10261012) ->FrameResult {
@@ -1043,47 +1029,47 @@ impl Frame {
10431029Ok ( 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 {
10471033let parent =self . pop_value ( ) ;
10481034let attr_name = vm. new_str ( attr_name. to_string ( ) ) ;
10491035let obj = vm. get_attribute ( parent, attr_name) ?;
10501036self . push_value ( obj) ;
10511037Ok ( 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 {
10551041let parent =self . pop_value ( ) ;
10561042let value =self . pop_value ( ) ;
10571043 vm. ctx . set_attr ( & parent, attr_name, value) ;
10581044Ok ( 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 {
10621048let parent =self . pop_value ( ) ;
10631049let name = vm. ctx . new_str ( attr_name. to_string ( ) ) ;
10641050 vm. del_attr ( & parent, name) ?;
10651051Ok ( None )
10661052}
10671053
10681054pub 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,
10751061level : 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 ( ) ?;
10811067self . stack . borrow_mut ( ) . truncate ( block. level ) ;
10821068Some ( 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
10891075pub fn push_value ( & self , obj : PyObjectRef ) {
@@ -1094,7 +1080,7 @@ impl Frame {
10941080self . 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 > {
10981084let mut objs: Vec < PyObjectRef > =Vec :: new ( ) ;
10991085for _xin 0 ..count{
11001086 objs. push ( self . pop_value ( ) ) ;
@@ -1123,6 +1109,7 @@ impl fmt::Debug for Frame {
11231109. join ( "" ) ;
11241110let block_str =self
11251111. blocks
1112+ . borrow ( )
11261113. iter ( )
11271114. map ( |elem|format ! ( "\n > {:?}" , elem) )
11281115. collect :: < Vec < _ > > ( )