@@ -16,8 +16,8 @@ use crate::obj::objlist;
16
16
use crate :: obj:: objstr;
17
17
use crate :: obj:: objtype;
18
18
use crate :: pyobject:: {
19
- DictProtocol , IdProtocol , ParentProtocol , PyFuncArgs , PyObject , PyObjectPayload , PyObjectRef ,
20
- PyResult , TypeProtocol ,
19
+ DictProtocol , IdProtocol , PyFuncArgs , PyObject , PyObjectPayload , PyObjectRef , PyResult ,
20
+ ScopeRef , TypeProtocol ,
21
21
} ;
22
22
use crate :: vm:: VirtualMachine ;
23
23
use num_bigint:: BigInt ;
@@ -50,7 +50,7 @@ pub struct Frame {
50
50
// We need 1 stack per frame
51
51
stack : RefCell < Vec < PyObjectRef > > , // The main data frame of the stack machine
52
52
blocks : RefCell < Vec < Block > > , // Block frames, for controlling loops and exceptions
53
- pub locals : PyObjectRef , // Variables
53
+ pub scope : ScopeRef , // Variables
54
54
pub lasti : RefCell < usize > , // index of last instruction ran
55
55
}
56
56
@@ -64,7 +64,7 @@ pub enum ExecutionResult {
64
64
pub type FrameResult = Result < Option < ExecutionResult > , PyObjectRef > ;
65
65
66
66
impl Frame {
67
- pub fn new ( code : PyObjectRef , globals : PyObjectRef ) -> Frame {
67
+ pub fn new ( code : PyObjectRef , scope : ScopeRef ) -> Frame {
68
68
//populate the globals and locals
69
69
//TODO: This is wrong, check https://github.com/nedbat/byterun/blob/31e6c4a8212c35b5157919abff43a7daa0f377c6/byterun/pyvm2.py#L95
70
70
/*
@@ -73,7 +73,7 @@ impl Frame {
73
73
None => HashMap::new(),
74
74
};
75
75
*/
76
- let locals = globals;
76
+ // let locals = globals;
77
77
// locals.extend(callargs);
78
78
79
79
Frame {
@@ -82,7 +82,7 @@ impl Frame {
82
82
blocks : RefCell :: new ( vec ! [ ] ) ,
83
83
// save the callargs as locals
84
84
// globals: locals.clone(),
85
- locals ,
85
+ scope ,
86
86
lasti : RefCell :: new ( 0 ) ,
87
87
}
88
88
}
@@ -436,7 +436,7 @@ impl Frame {
436
436
} ;
437
437
// pop argc arguments
438
438
// argument: name, args, globals
439
- let scope = self . locals . clone ( ) ;
439
+ let scope = self . scope . clone ( ) ;
440
440
let obj = vm. ctx . new_function ( code_obj, scope, defaults) ;
441
441
self . push_value ( obj) ;
442
442
Ok ( None )
@@ -582,16 +582,6 @@ impl Frame {
582
582
self . push_value ( rustfunc) ;
583
583
Ok ( None )
584
584
}
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
- }
595
585
bytecode:: Instruction :: UnpackSequence { size } => {
596
586
let value = self . pop_value ( ) ;
597
587
let elements = vm. extract_elements ( & value) ?;
@@ -715,8 +705,10 @@ impl Frame {
715
705
let obj = import_module ( vm, current_path, module) ?;
716
706
717
707
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 ( ) ) ;
720
712
}
721
713
Ok ( None )
722
714
}
@@ -838,37 +830,35 @@ impl Frame {
838
830
839
831
fn store_name ( & self , vm : & mut VirtualMachine , name : & str ) -> FrameResult {
840
832
let obj = self . pop_value ( ) ;
841
- vm . ctx . set_attr ( & self . locals , name, obj) ;
833
+ self . scope . locals . set_item ( & vm . ctx , name, obj) ;
842
834
Ok ( None )
843
835
}
844
836
845
837
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
852
838
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] ) ?;
854
840
Ok ( None )
855
841
}
856
842
857
843
fn load_name ( & self , vm : & mut VirtualMachine , name : & str ) -> FrameResult {
858
844
// Lookup name in scope and put it onto the stack!
859
- let mut scope = self . locals . clone ( ) ;
845
+ let mut scope = self . scope . clone ( ) ;
860
846
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 ( ) ;
863
849
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
+ }
872
862
}
873
863
}
874
864
}
@@ -1119,21 +1109,18 @@ impl fmt::Debug for Frame {
1119
1109
. map ( |elem| format ! ( "\n > {:?}" , elem) )
1120
1110
. collect :: < Vec < _ > > ( )
1121
1111
. 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
+ ) ,
1137
1124
} ;
1138
1125
write ! (
1139
1126
f,
0 commit comments