11extern crate rustpython_parser;
22
33use self :: rustpython_parser:: ast;
4+ use std:: cell:: RefCell ;
45use std:: fmt;
5- use std:: mem;
66use std:: path:: PathBuf ;
77
88use crate :: builtins;
@@ -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
52- stack : Vec < PyObjectRef > , // The main data frame of the stack machine
53- blocks : Vec < Block > , // Block frames, for controlling loops and exceptions
54- pub locals : PyObjectRef , // Variables
55- pub lasti : usize , // index of last instruction ran
51+ stack : RefCell < Vec < PyObjectRef > > , // The main data frame of the stack machine
52+ blocks : RefCell < Vec < Block > > , // Block frames, for controlling loops and exceptions
53+ pub locals : PyObjectRef , // Variables
54+ pub lasti : RefCell < usize > , // index of last instruction ran
5655}
5756
5857// Running a frame can result in one of the below:
@@ -79,27 +78,18 @@ impl Frame {
7978
8079 Frame {
8180 code : objcode:: get_value ( & code) ,
82- stack : vec ! [ ] ,
83- blocks : vec ! [ ] ,
81+ stack : RefCell :: new ( 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_frame_full ( & mut self , vm : & mut VirtualMachine ) -> PyResult {
92- match self . run_frame ( vm) ? {
93- ExecutionResult :: Return ( value) => Ok ( value) ,
94- _ => panic ! ( "Got unexpected result from function" ) ,
95- }
96- }
97-
98- pub fn run_frame ( & mut self , vm : & mut VirtualMachine ) -> Result < ExecutionResult , PyObjectRef > {
90+ pub fn run ( & self , vm : & mut VirtualMachine ) -> Result < ExecutionResult , PyObjectRef > {
9991 let filename = & self . code . source_path . to_string ( ) ;
10092
101- let prev_frame = mem:: replace ( & mut vm. current_frame , Some ( vm. ctx . new_frame ( self . clone ( ) ) ) ) ;
102-
10393 // This is the name of the object being run:
10494 let run_obj_name = & self . code . obj_name . to_string ( ) ;
10595
@@ -148,20 +138,19 @@ impl Frame {
148138 }
149139 } ;
150140
151- vm. current_frame = prev_frame;
152141 value
153142 }
154143
155- pub fn fetch_instruction ( & mut self ) -> bytecode:: Instruction {
144+ pub fn fetch_instruction ( & self ) -> bytecode:: Instruction {
156145 // TODO: an immutable reference is enough, we should not
157146 // clone the instruction.
158- let ins2 = self . code . instructions [ self . lasti ] . clone ( ) ;
159- self . lasti += 1 ;
147+ let ins2 = self . code . instructions [ * self . lasti . borrow ( ) ] . clone ( ) ;
148+ * self . lasti . borrow_mut ( ) += 1 ;
160149 ins2
161150 }
162151
163152 // Execute a single instruction:
164- fn execute_instruction ( & mut self , vm : & mut VirtualMachine ) -> FrameResult {
153+ fn execute_instruction ( & self , vm : & mut VirtualMachine ) -> FrameResult {
165154 let instruction = self . fetch_instruction ( ) ;
166155 {
167156 trace ! ( "=======" ) ;
@@ -354,7 +343,7 @@ impl Frame {
354343 match next_obj {
355344 Some ( value) => {
356345 // Set back program counter:
357- self . lasti -= 1 ;
346+ * self . lasti . borrow_mut ( ) -= 1 ;
358347 Ok ( Some ( ExecutionResult :: Yield ( value) ) )
359348 }
360349 None => {
@@ -672,7 +661,7 @@ impl Frame {
672661 }
673662
674663 fn get_elements (
675- & mut self ,
664+ & self ,
676665 vm : & mut VirtualMachine ,
677666 size : usize ,
678667 unpack : bool ,
@@ -693,7 +682,7 @@ impl Frame {
693682 }
694683
695684 fn import (
696- & mut self ,
685+ & self ,
697686 vm : & mut VirtualMachine ,
698687 module : & str ,
699688 symbol : & Option < String > ,
@@ -711,7 +700,7 @@ impl Frame {
711700 Ok ( None )
712701 }
713702
714- fn import_star ( & mut self , vm : & mut VirtualMachine , module : & str ) -> FrameResult {
703+ fn import_star ( & self , vm : & mut VirtualMachine , module : & str ) -> FrameResult {
715704 let current_path = {
716705 let mut source_pathbuf = PathBuf :: from ( & self . code . source_path ) ;
717706 source_pathbuf. pop ( ) ;
@@ -729,7 +718,7 @@ impl Frame {
729718 }
730719
731720 // Unwind all blocks:
732- fn unwind_blocks ( & mut self , vm : & mut VirtualMachine ) -> Option < PyObjectRef > {
721+ fn unwind_blocks ( & self , vm : & mut VirtualMachine ) -> Option < PyObjectRef > {
733722 while let Some ( block) = self . pop_block ( ) {
734723 match block. typ {
735724 BlockType :: Loop { .. } => { }
@@ -753,9 +742,9 @@ impl Frame {
753742 None
754743 }
755744
756- fn unwind_loop ( & mut self , vm : & mut VirtualMachine ) -> Block {
745+ fn unwind_loop ( & self , vm : & mut VirtualMachine ) -> Block {
757746 loop {
758- let block = self . current_block ( ) . cloned ( ) . expect ( "not in a loop" ) ;
747+ let block = self . current_block ( ) . expect ( "not in a loop" ) ;
759748 match block. typ {
760749 BlockType :: Loop { .. } => break block,
761750 BlockType :: TryExcept { .. } => {
@@ -775,11 +764,7 @@ impl Frame {
775764 }
776765 }
777766
778- fn unwind_exception (
779- & mut self ,
780- vm : & mut VirtualMachine ,
781- exc : PyObjectRef ,
782- ) -> Option < PyObjectRef > {
767+ fn unwind_exception ( & self , vm : & mut VirtualMachine , exc : PyObjectRef ) -> Option < PyObjectRef > {
783768 // unwind block stack on exception and find any handlers:
784769 while let Some ( block) = self . pop_block ( ) {
785770 match block. typ {
@@ -847,13 +832,13 @@ impl Frame {
847832 vm. call_method ( context_manager, "__exit__" , args)
848833 }
849834
850- fn store_name ( & mut self , vm : & mut VirtualMachine , name : & str ) -> FrameResult {
835+ fn store_name ( & self , vm : & mut VirtualMachine , name : & str ) -> FrameResult {
851836 let obj = self . pop_value ( ) ;
852837 vm. ctx . set_attr ( & self . locals , name, obj) ;
853838 Ok ( None )
854839 }
855840
856- fn delete_name ( & mut self , vm : & mut VirtualMachine , name : & str ) -> FrameResult {
841+ fn delete_name ( & self , vm : & mut VirtualMachine , name : & str ) -> FrameResult {
857842 let locals = match self . locals . payload {
858843 PyObjectPayload :: Scope { ref scope } => scope. borrow ( ) . locals . clone ( ) ,
859844 _ => panic ! ( "We really expect our scope to be a scope!" ) ,
@@ -865,7 +850,7 @@ impl Frame {
865850 Ok ( None )
866851 }
867852
868- fn load_name ( & mut self , vm : & mut VirtualMachine , name : & str ) -> FrameResult {
853+ fn load_name ( & self , vm : & mut VirtualMachine , name : & str ) -> FrameResult {
869854 // Lookup name in scope and put it onto the stack!
870855 let mut scope = self . locals . clone ( ) ;
871856 loop {
@@ -884,33 +869,33 @@ impl Frame {
884869 }
885870 }
886871
887- fn subscript ( & mut self , vm : & mut VirtualMachine , a : PyObjectRef , b : PyObjectRef ) -> PyResult {
872+ fn subscript ( & self , vm : & mut VirtualMachine , a : PyObjectRef , b : PyObjectRef ) -> PyResult {
888873 vm. call_method ( & a, "__getitem__" , vec ! [ b] )
889874 }
890875
891- fn execute_store_subscript ( & mut self , vm : & mut VirtualMachine ) -> FrameResult {
876+ fn execute_store_subscript ( & self , vm : & mut VirtualMachine ) -> FrameResult {
892877 let idx = self . pop_value ( ) ;
893878 let obj = self . pop_value ( ) ;
894879 let value = self . pop_value ( ) ;
895880 vm. call_method ( & obj, "__setitem__" , vec ! [ idx, value] ) ?;
896881 Ok ( None )
897882 }
898883
899- fn execute_delete_subscript ( & mut self , vm : & mut VirtualMachine ) -> FrameResult {
884+ fn execute_delete_subscript ( & self , vm : & mut VirtualMachine ) -> FrameResult {
900885 let idx = self . pop_value ( ) ;
901886 let obj = self . pop_value ( ) ;
902887 vm. call_method ( & obj, "__delitem__" , vec ! [ idx] ) ?;
903888 Ok ( None )
904889 }
905890
906- fn jump ( & mut self , label : bytecode:: Label ) {
891+ fn jump ( & self , label : bytecode:: Label ) {
907892 let target_pc = self . code . label_map [ & label] ;
908893 trace ! ( "program counter from {:?} to {:?}" , self . lasti, target_pc) ;
909- self . lasti = target_pc;
894+ * self . lasti . borrow_mut ( ) = target_pc;
910895 }
911896
912897 fn execute_binop (
913- & mut self ,
898+ & self ,
914899 vm : & mut VirtualMachine ,
915900 op : & bytecode:: BinaryOperator ,
916901 inplace : bool ,
@@ -953,11 +938,7 @@ impl Frame {
953938 Ok ( None )
954939 }
955940
956- fn execute_unop (
957- & mut self ,
958- vm : & mut VirtualMachine ,
959- op : & bytecode:: UnaryOperator ,
960- ) -> FrameResult {
941+ fn execute_unop ( & self , vm : & mut VirtualMachine , op : & bytecode:: UnaryOperator ) -> FrameResult {
961942 let a = self . pop_value ( ) ;
962943 let value = match * op {
963944 bytecode:: UnaryOperator :: Minus => vm. call_method ( & a, "__neg__" , vec ! [ ] ) ?,
@@ -978,7 +959,7 @@ impl Frame {
978959
979960 // https://docs.python.org/3/reference/expressions.html#membership-test-operations
980961 fn _membership (
981- & mut self ,
962+ & self ,
982963 vm : & mut VirtualMachine ,
983964 needle : PyObjectRef ,
984965 haystack : & PyObjectRef ,
@@ -988,12 +969,7 @@ impl Frame {
988969 // not implemented.
989970 }
990971
991- fn _in (
992- & mut self ,
993- vm : & mut VirtualMachine ,
994- needle : PyObjectRef ,
995- haystack : PyObjectRef ,
996- ) -> PyResult {
972+ fn _in ( & self , vm : & mut VirtualMachine , needle : PyObjectRef , haystack : PyObjectRef ) -> PyResult {
997973 match self . _membership ( vm, needle, & haystack) {
998974 Ok ( found) => Ok ( found) ,
999975 Err ( _) => Err ( vm. new_type_error ( format ! (
@@ -1004,7 +980,7 @@ impl Frame {
1004980 }
1005981
1006982 fn _not_in (
1007- & mut self ,
983+ & self ,
1008984 vm : & mut VirtualMachine ,
1009985 needle : PyObjectRef ,
1010986 haystack : PyObjectRef ,
@@ -1030,7 +1006,7 @@ impl Frame {
10301006 }
10311007
10321008 fn execute_compare (
1033- & mut self ,
1009+ & self ,
10341010 vm : & mut VirtualMachine ,
10351011 op : & bytecode:: ComparisonOperator ,
10361012 ) -> FrameResult {
@@ -1053,85 +1029,88 @@ impl Frame {
10531029 Ok ( None )
10541030 }
10551031
1056- fn load_attr ( & mut self , vm : & mut VirtualMachine , attr_name : & str ) -> FrameResult {
1032+ fn load_attr ( & self , vm : & mut VirtualMachine , attr_name : & str ) -> FrameResult {
10571033 let parent = self . pop_value ( ) ;
10581034 let attr_name = vm. new_str ( attr_name. to_string ( ) ) ;
10591035 let obj = vm. get_attribute ( parent, attr_name) ?;
10601036 self . push_value ( obj) ;
10611037 Ok ( None )
10621038 }
10631039
1064- fn store_attr ( & mut self , vm : & mut VirtualMachine , attr_name : & str ) -> FrameResult {
1040+ fn store_attr ( & self , vm : & mut VirtualMachine , attr_name : & str ) -> FrameResult {
10651041 let parent = self . pop_value ( ) ;
10661042 let value = self . pop_value ( ) ;
10671043 vm. ctx . set_attr ( & parent, attr_name, value) ;
10681044 Ok ( None )
10691045 }
10701046
1071- fn delete_attr ( & mut self , vm : & mut VirtualMachine , attr_name : & str ) -> FrameResult {
1047+ fn delete_attr ( & self , vm : & mut VirtualMachine , attr_name : & str ) -> FrameResult {
10721048 let parent = self . pop_value ( ) ;
10731049 let name = vm. ctx . new_str ( attr_name. to_string ( ) ) ;
10741050 vm. del_attr ( & parent, name) ?;
10751051 Ok ( None )
10761052 }
10771053
10781054 pub fn get_lineno ( & self ) -> ast:: Location {
1079- self . code . locations [ self . lasti ] . clone ( )
1055+ self . code . locations [ * self . lasti . borrow ( ) ] . clone ( )
10801056 }
10811057
1082- fn push_block ( & mut self , typ : BlockType ) {
1083- self . blocks . push ( Block {
1058+ fn push_block ( & self , typ : BlockType ) {
1059+ self . blocks . borrow_mut ( ) . push ( Block {
10841060 typ,
1085- level : self . stack . len ( ) ,
1061+ level : self . stack . borrow ( ) . len ( ) ,
10861062 } ) ;
10871063 }
10881064
1089- fn pop_block ( & mut self ) -> Option < Block > {
1090- let block = self . blocks . pop ( ) ?;
1091- self . stack . truncate ( block. level ) ;
1065+ fn pop_block ( & self ) -> Option < Block > {
1066+ let block = self . blocks . borrow_mut ( ) . pop ( ) ?;
1067+ self . stack . borrow_mut ( ) . truncate ( block. level ) ;
10921068 Some ( block)
10931069 }
10941070
1095- fn current_block ( & self ) -> Option < & Block > {
1096- self . blocks . last ( )
1071+ fn current_block ( & self ) -> Option < Block > {
1072+ self . blocks . borrow ( ) . last ( ) . cloned ( )
10971073 }
10981074
1099- pub fn push_value ( & mut self , obj : PyObjectRef ) {
1100- self . stack . push ( obj) ;
1075+ pub fn push_value ( & self , obj : PyObjectRef ) {
1076+ self . stack . borrow_mut ( ) . push ( obj) ;
11011077 }
11021078
1103- fn pop_value ( & mut self ) -> PyObjectRef {
1104- self . stack . pop ( ) . unwrap ( )
1079+ fn pop_value ( & self ) -> PyObjectRef {
1080+ self . stack . borrow_mut ( ) . pop ( ) . unwrap ( )
11051081 }
11061082
1107- fn pop_multiple ( & mut self , count : usize ) -> Vec < PyObjectRef > {
1083+ fn pop_multiple ( & self , count : usize ) -> Vec < PyObjectRef > {
11081084 let mut objs: Vec < PyObjectRef > = Vec :: new ( ) ;
11091085 for _x in 0 ..count {
1110- objs. push ( self . stack . pop ( ) . unwrap ( ) ) ;
1086+ objs. push ( self . pop_value ( ) ) ;
11111087 }
11121088 objs. reverse ( ) ;
11131089 objs
11141090 }
11151091
11161092 fn last_value ( & self ) -> PyObjectRef {
1117- self . stack . last ( ) . unwrap ( ) . clone ( )
1093+ self . stack . borrow ( ) . last ( ) . unwrap ( ) . clone ( )
11181094 }
11191095
11201096 fn nth_value ( & self , depth : usize ) -> PyObjectRef {
1121- self . stack [ self . stack . len ( ) - depth - 1 ] . clone ( )
1097+ let stack = self . stack . borrow_mut ( ) ;
1098+ stack[ stack. len ( ) - depth - 1 ] . clone ( )
11221099 }
11231100}
11241101
11251102impl fmt:: Debug for Frame {
11261103 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
11271104 let stack_str = self
11281105 . stack
1106+ . borrow ( )
11291107 . iter ( )
11301108 . map ( |elem| format ! ( "\n > {:?}" , elem) )
11311109 . collect :: < Vec < _ > > ( )
11321110 . join ( "" ) ;
11331111 let block_str = self
11341112 . blocks
1113+ . borrow ( )
11351114 . iter ( )
11361115 . map ( |elem| format ! ( "\n > {:?}" , elem) )
11371116 . collect :: < Vec < _ > > ( )
0 commit comments