@@ -11,12 +11,12 @@ use crate::{
11
11
coroutine:: Coro ,
12
12
exceptions:: ExceptionCtor ,
13
13
function:: { FuncArgs , IntoPyResult } ,
14
- protocol:: { PyIter , PyIterReturn } ,
14
+ protocol:: { PyIter , PyIterReturn , PyMapping } ,
15
15
scope:: Scope ,
16
16
stdlib:: builtins,
17
17
types:: PyComparisonOp ,
18
- IdProtocol , ItemProtocol , PyMethod , PyObjectRef , PyRef , PyResult , PyValue , TryFromObject ,
19
- TypeProtocol , VirtualMachine ,
18
+ IdProtocol , ItemProtocol , PyMethod , PyObjectRef , PyObjectWrap , PyRef , PyResult , PyValue ,
19
+ TryFromObject , TypeProtocol , VirtualMachine ,
20
20
} ;
21
21
use indexmap:: IndexMap ;
22
22
use itertools:: Itertools ;
@@ -99,7 +99,7 @@ pub struct Frame {
99
99
100
100
pub fastlocals : PyMutex < Box < [ Option < PyObjectRef > ] > > ,
101
101
pub ( crate ) cells_frees : Box < [ PyCellRef ] > ,
102
- pub locals : PyObjectRef ,
102
+ pub locals : PyMapping ,
103
103
pub globals : PyDictRef ,
104
104
pub builtins : PyDictRef ,
105
105
@@ -179,7 +179,7 @@ impl FrameRef {
179
179
f ( exec)
180
180
}
181
181
182
- pub fn locals ( & self , vm : & VirtualMachine ) -> PyResult < PyObjectRef > {
182
+ pub fn locals ( & self , vm : & VirtualMachine ) -> PyResult < PyMapping > {
183
183
let locals = & self . locals ;
184
184
let code = & * * self . code ;
185
185
let map = & code. varnames ;
@@ -188,9 +188,9 @@ impl FrameRef {
188
188
let fastlocals = self . fastlocals . lock ( ) ;
189
189
for ( k, v) in itertools:: zip ( & map[ ..j] , & * * fastlocals) {
190
190
if let Some ( v) = v {
191
- locals. set_item ( k. clone ( ) , v. clone ( ) , vm) ?;
191
+ locals. as_object ( ) . set_item ( k. clone ( ) , v. clone ( ) , vm) ?;
192
192
} else {
193
- match locals. del_item ( k. clone ( ) , vm) {
193
+ match locals. as_object ( ) . del_item ( k. clone ( ) , vm) {
194
194
Ok ( ( ) ) => { }
195
195
Err ( e) if e. isinstance ( & vm. ctx . exceptions . key_error ) => { }
196
196
Err ( e) => return Err ( e) ,
@@ -202,9 +202,9 @@ impl FrameRef {
202
202
let map_to_dict = |keys : & [ PyStrRef ] , values : & [ PyCellRef ] | {
203
203
for ( k, v) in itertools:: zip ( keys, values) {
204
204
if let Some ( v) = v. get ( ) {
205
- locals. set_item ( k. clone ( ) , v, vm) ?;
205
+ locals. as_object ( ) . set_item ( k. clone ( ) , v, vm) ?;
206
206
} else {
207
- match locals. del_item ( k. clone ( ) , vm) {
207
+ match locals. as_object ( ) . del_item ( k. clone ( ) , vm) {
208
208
Ok ( ( ) ) => { }
209
209
Err ( e) if e. isinstance ( & vm. ctx . exceptions . key_error ) => { }
210
210
Err ( e) => return Err ( e) ,
@@ -275,7 +275,7 @@ struct ExecutingFrame<'a> {
275
275
code : & ' a PyRef < PyCode > ,
276
276
fastlocals : & ' a PyMutex < Box < [ Option < PyObjectRef > ] > > ,
277
277
cells_frees : & ' a [ PyCellRef ] ,
278
- locals : & ' a PyObjectRef ,
278
+ locals : & ' a PyMapping ,
279
279
globals : & ' a PyDictRef ,
280
280
builtins : & ' a PyDictRef ,
281
281
object : & ' a FrameRef ,
@@ -497,7 +497,12 @@ impl ExecutingFrame<'_> {
497
497
bytecode:: Instruction :: LoadNameAny ( idx) => {
498
498
let name = & self . code . names [ * idx as usize ] ;
499
499
// Try using locals as dict first, if not, fallback to generic method.
500
- let x = match self . locals . clone ( ) . downcast_exact :: < PyDict > ( vm) {
500
+ let x = match self
501
+ . locals
502
+ . clone ( )
503
+ . into_object ( )
504
+ . downcast_exact :: < PyDict > ( vm)
505
+ {
501
506
Ok ( d) => d. get_item_option ( name. clone ( ) , vm) ?,
502
507
Err ( o) => o. get_item ( name. clone ( ) , vm) . ok ( ) ,
503
508
} ;
@@ -525,7 +530,12 @@ impl ExecutingFrame<'_> {
525
530
let i = * i as usize ;
526
531
let name = self . code . freevars [ i - self . code . cellvars . len ( ) ] . clone ( ) ;
527
532
// Try using locals as dict first, if not, fallback to generic method.
528
- let value = match self . locals . clone ( ) . downcast_exact :: < PyDict > ( vm) {
533
+ let value = match self
534
+ . locals
535
+ . clone ( )
536
+ . into_object ( )
537
+ . downcast_exact :: < PyDict > ( vm)
538
+ {
529
539
Ok ( d) => d. get_item_option ( name, vm) ?,
530
540
Err ( o) => o. get_item ( name, vm) . ok ( ) ,
531
541
} ;
@@ -544,8 +554,11 @@ impl ExecutingFrame<'_> {
544
554
}
545
555
bytecode:: Instruction :: StoreLocal ( idx) => {
546
556
let value = self . pop_value ( ) ;
547
- self . locals
548
- . set_item ( self . code . names [ * idx as usize ] . clone ( ) , value, vm) ?;
557
+ self . locals . as_object ( ) . set_item (
558
+ self . code . names [ * idx as usize ] . clone ( ) ,
559
+ value,
560
+ vm,
561
+ ) ?;
549
562
Ok ( None )
550
563
}
551
564
bytecode:: Instruction :: StoreGlobal ( idx) => {
@@ -565,7 +578,7 @@ impl ExecutingFrame<'_> {
565
578
}
566
579
bytecode:: Instruction :: DeleteLocal ( idx) => {
567
580
let name = & self . code . names [ * idx as usize ] ;
568
- match self . locals . del_item ( name. clone ( ) , vm) {
581
+ match self . locals . clone ( ) . into_object ( ) . del_item ( name. clone ( ) , vm) {
569
582
Ok ( ( ) ) => { }
570
583
Err ( e) if e. isinstance ( & vm. ctx . exceptions . key_error ) => {
571
584
return Err ( vm. new_name_error ( format ! ( "name '{}' is not defined" , name) ) )
@@ -724,16 +737,24 @@ impl ExecutingFrame<'_> {
724
737
bytecode:: Instruction :: YieldFrom => self . execute_yield_from ( vm) ,
725
738
bytecode:: Instruction :: SetupAnnotation => {
726
739
// Try using locals as dict first, if not, fallback to generic method.
727
- let has_annotations = match self . locals . clone ( ) . downcast_exact :: < PyDict > ( vm) {
740
+ let has_annotations = match self
741
+ . locals
742
+ . clone ( )
743
+ . into_object ( )
744
+ . downcast_exact :: < PyDict > ( vm)
745
+ {
728
746
Ok ( d) => d. contains_key ( "__annotations__" , vm) ,
729
747
Err ( o) => {
730
748
let needle = vm. new_pyobj ( "__annotations__" ) ;
731
749
self . _in ( vm, needle, o) ?
732
750
}
733
751
} ;
734
752
if !has_annotations {
735
- self . locals
736
- . set_item ( "__annotations__" , vm. ctx . new_dict ( ) . into ( ) , vm) ?;
753
+ self . locals . as_object ( ) . set_item (
754
+ "__annotations__" ,
755
+ vm. ctx . new_dict ( ) . into ( ) ,
756
+ vm,
757
+ ) ?;
737
758
}
738
759
Ok ( None )
739
760
}
@@ -1146,7 +1167,7 @@ impl ExecutingFrame<'_> {
1146
1167
for ( k, v) in & dict {
1147
1168
let k = PyStrRef :: try_from_object ( vm, k) ?;
1148
1169
if filter_pred ( k. as_str ( ) ) {
1149
- self . locals . set_item ( k, v, vm) ?;
1170
+ self . locals . as_object ( ) . set_item ( k, v, vm) ?;
1150
1171
}
1151
1172
}
1152
1173
}
0 commit comments