@@ -16,8 +16,8 @@ use crate::obj::objlist;
1616use crate :: obj:: objstr;
1717use crate :: obj:: objtype;
1818use crate :: pyobject:: {
19- DictProtocol , IdProtocol , ParentProtocol , PyFuncArgs , PyObject , PyObjectPayload , PyObjectRef ,
20- PyResult , TypeProtocol ,
19+ DictProtocol , IdProtocol , PyFuncArgs , PyObject , PyObjectPayload , PyObjectRef , PyResult ,
20+ ScopeRef , TypeProtocol ,
2121} ;
2222use crate :: vm:: VirtualMachine ;
2323use num_bigint:: BigInt ;
@@ -50,7 +50,7 @@ pub struct Frame {
5050 // We need 1 stack per frame
5151 stack : RefCell < Vec < PyObjectRef > > , // The main data frame of the stack machine
5252 blocks : RefCell < Vec < Block > > , // Block frames, for controlling loops and exceptions
53- pub locals : PyObjectRef , // Variables
53+ pub scope : ScopeRef , // Variables
5454 pub lasti : RefCell < usize > , // index of last instruction ran
5555}
5656
@@ -64,7 +64,7 @@ pub enum ExecutionResult {
6464pub type FrameResult = Result < Option < ExecutionResult > , PyObjectRef > ;
6565
6666impl Frame {
67- pub fn new ( code : PyObjectRef , globals : PyObjectRef ) -> Frame {
67+ pub fn new ( code : PyObjectRef , scope : ScopeRef ) -> Frame {
6868 //populate the globals and locals
6969 //TODO: This is wrong, check https://github.com/nedbat/byterun/blob/31e6c4a8212c35b5157919abff43a7daa0f377c6/byterun/pyvm2.py#L95
7070 /*
@@ -73,7 +73,7 @@ impl Frame {
7373 None => HashMap::new(),
7474 };
7575 */
76- let locals = globals;
76+ // let locals = globals;
7777 // locals.extend(callargs);
7878
7979 Frame {
@@ -82,7 +82,7 @@ impl Frame {
8282 blocks : RefCell :: new ( vec ! [ ] ) ,
8383 // save the callargs as locals
8484 // globals: locals.clone(),
85- locals ,
85+ scope ,
8686 lasti : RefCell :: new ( 0 ) ,
8787 }
8888 }
@@ -436,7 +436,7 @@ impl Frame {
436436 } ;
437437 // pop argc arguments
438438 // argument: name, args, globals
439- let scope = self . locals . clone ( ) ;
439+ let scope = self . scope . clone ( ) ;
440440 let obj = vm. ctx . new_function ( code_obj, scope, defaults) ;
441441 self . push_value ( obj) ;
442442 Ok ( None )
@@ -582,16 +582,6 @@ impl Frame {
582582 self . push_value ( rustfunc) ;
583583 Ok ( None )
584584 }
585- bytecode:: Instruction :: StoreLocals => {
586- let locals = self . pop_value ( ) ;
587- match self . locals . payload {
588- PyObjectPayload :: Scope { ref scope } => {
589- ( * scope. borrow_mut ( ) ) . locals = locals;
590- }
591- _ => panic ! ( "We really expect our scope to be a scope!" ) ,
592- }
593- Ok ( None )
594- }
595585 bytecode:: Instruction :: UnpackSequence { size } => {
596586 let value = self . pop_value ( ) ;
597587 let elements = vm. extract_elements ( & value) ?;
@@ -715,8 +705,10 @@ impl Frame {
715705 let obj = import_module ( vm, current_path, module) ?;
716706
717707 for ( k, v) in obj. get_key_value_pairs ( ) . iter ( ) {
718- vm. ctx
719- . set_attr ( & self . locals , & objstr:: get_value ( k) , v. clone ( ) ) ;
708+ & self
709+ . scope
710+ . locals
711+ . set_item ( & vm. ctx , & objstr:: get_value ( k) , v. clone ( ) ) ;
720712 }
721713 Ok ( None )
722714 }
@@ -838,37 +830,35 @@ impl Frame {
838830
839831 fn store_name ( & self , vm : & mut VirtualMachine , name : & str ) -> FrameResult {
840832 let obj = self . pop_value ( ) ;
841- vm . ctx . set_attr ( & self . locals , name, obj) ;
833+ self . scope . locals . set_item ( & vm . ctx , name, obj) ;
842834 Ok ( None )
843835 }
844836
845837 fn delete_name ( & self , vm : & mut VirtualMachine , name : & str ) -> FrameResult {
846- let locals = match self . locals . payload {
847- PyObjectPayload :: Scope { ref scope } => scope. borrow ( ) . locals . clone ( ) ,
848- _ => panic ! ( "We really expect our scope to be a scope!" ) ,
849- } ;
850-
851- // Assume here that locals is a dict
852838 let name = vm. ctx . new_str ( name. to_string ( ) ) ;
853- vm. call_method ( & locals, "__delitem__" , vec ! [ name] ) ?;
839+ vm. call_method ( & self . scope . locals , "__delitem__" , vec ! [ name] ) ?;
854840 Ok ( None )
855841 }
856842
857843 fn load_name ( & self , vm : & mut VirtualMachine , name : & str ) -> FrameResult {
858844 // Lookup name in scope and put it onto the stack!
859- let mut scope = self . locals . clone ( ) ;
845+ let mut scope = self . scope . clone ( ) ;
860846 loop {
861- if scope. contains_key ( name) {
862- let obj = scope. get_item ( name) . unwrap ( ) ;
847+ if scope. locals . contains_key ( name) {
848+ let obj = scope. locals . get_item ( name) . unwrap ( ) ;
863849 self . push_value ( obj) ;
864- break Ok ( None ) ;
865- } else if scope. has_parent ( ) {
866- scope = scope. get_parent ( ) ;
867- } else {
868- let name_error_type = vm. ctx . exceptions . name_error . clone ( ) ;
869- let msg = format ! ( "name '{}' is not defined" , name) ;
870- let name_error = vm. new_exception ( name_error_type, msg) ;
871- break Err ( name_error) ;
850+ return Ok ( None ) ;
851+ }
852+ match & scope. parent {
853+ Some ( parent_scope) => {
854+ scope = parent_scope. clone ( ) ;
855+ }
856+ None => {
857+ let name_error_type = vm. ctx . exceptions . name_error . clone ( ) ;
858+ let msg = format ! ( "name '{}' is not defined" , name) ;
859+ let name_error = vm. new_exception ( name_error_type, msg) ;
860+ return Err ( name_error) ;
861+ }
872862 }
873863 }
874864 }
@@ -1119,21 +1109,18 @@ impl fmt::Debug for Frame {
11191109 . map ( |elem| format ! ( "\n > {:?}" , elem) )
11201110 . collect :: < Vec < _ > > ( )
11211111 . join ( "" ) ;
1122- let local_str = match self . locals . payload {
1123- PyObjectPayload :: Scope { ref scope } => match scope. borrow ( ) . locals . payload {
1124- PyObjectPayload :: Dict { ref elements } => {
1125- objdict:: get_key_value_pairs_from_content ( & elements. borrow ( ) )
1126- . iter ( )
1127- . map ( |elem| format ! ( "\n {:?} = {:?}" , elem. 0 , elem. 1 ) )
1128- . collect :: < Vec < _ > > ( )
1129- . join ( "" )
1130- }
1131- ref unexpected => panic ! (
1132- "locals unexpectedly not wrapping a dict! instead: {:?}" ,
1133- unexpected
1134- ) ,
1135- } ,
1136- ref unexpected => panic ! ( "locals unexpectedly not a scope! instead: {:?}" , unexpected) ,
1112+ let local_str = match self . scope . locals . payload {
1113+ PyObjectPayload :: Dict { ref elements } => {
1114+ objdict:: get_key_value_pairs_from_content ( & elements. borrow ( ) )
1115+ . iter ( )
1116+ . map ( |elem| format ! ( "\n {:?} = {:?}" , elem. 0 , elem. 1 ) )
1117+ . collect :: < Vec < _ > > ( )
1118+ . join ( "" )
1119+ }
1120+ ref unexpected => panic ! (
1121+ "locals unexpectedly not wrapping a dict! instead: {:?}" ,
1122+ unexpected
1123+ ) ,
11371124 } ;
11381125 write ! (
11391126 f,
0 commit comments