@@ -2,8 +2,6 @@ use std::cell::RefCell;
2
2
use std:: fmt;
3
3
use std:: rc:: Rc ;
4
4
5
- use num_bigint:: BigInt ;
6
-
7
5
use rustpython_parser:: ast;
8
6
9
7
use crate :: builtins;
@@ -12,7 +10,6 @@ use crate::function::PyFuncArgs;
12
10
use crate :: obj:: objbool;
13
11
use crate :: obj:: objcode:: PyCodeRef ;
14
12
use crate :: obj:: objdict:: { PyDict , PyDictRef } ;
15
- use crate :: obj:: objint:: PyInt ;
16
13
use crate :: obj:: objiter;
17
14
use crate :: obj:: objlist;
18
15
use crate :: obj:: objslice:: PySlice ;
@@ -129,6 +126,7 @@ pub trait NameProtocol {
129
126
fn store_name ( & self , vm : & VirtualMachine , name : & str , value : PyObjectRef ) ;
130
127
fn delete_name ( & self , vm : & VirtualMachine , name : & str ) ;
131
128
fn load_cell ( & self , vm : & VirtualMachine , name : & str ) -> Option < PyObjectRef > ;
129
+ fn store_cell ( & self , vm : & VirtualMachine , name : & str , value : PyObjectRef ) ;
132
130
fn load_global ( & self , vm : & VirtualMachine , name : & str ) -> Option < PyObjectRef > ;
133
131
fn store_global ( & self , vm : & VirtualMachine , name : & str , value : PyObjectRef ) ;
134
132
}
@@ -157,6 +155,16 @@ impl NameProtocol for Scope {
157
155
None
158
156
}
159
157
158
+ fn store_cell ( & self , vm : & VirtualMachine , name : & str , value : PyObjectRef ) {
159
+ self . locals
160
+ . iter ( )
161
+ . skip ( 1 )
162
+ . next ( )
163
+ . expect ( "no outer scope for non-local" )
164
+ . set_item ( name, value, vm)
165
+ . unwrap ( ) ;
166
+ }
167
+
160
168
fn store_name ( & self , vm : & VirtualMachine , key : & str , value : PyObjectRef ) {
161
169
self . get_locals ( ) . set_item ( key, value, vm) . unwrap ( ) ;
162
170
}
@@ -435,26 +443,21 @@ impl Frame {
435
443
}
436
444
bytecode:: Instruction :: BuildSlice { size } => {
437
445
assert ! ( * size == 2 || * size == 3 ) ;
438
- let elements = self . pop_multiple ( * size) ;
439
446
440
- let mut out: Vec < Option < BigInt > > = elements
441
- . into_iter ( )
442
- . map ( |x| {
443
- if x. is ( & vm. ctx . none ( ) ) {
444
- None
445
- } else if let Some ( i) = x. payload :: < PyInt > ( ) {
446
- Some ( i. as_bigint ( ) . clone ( ) )
447
- } else {
448
- panic ! ( "Expect Int or None as BUILD_SLICE arguments" )
449
- }
450
- } )
451
- . collect ( ) ;
452
-
453
- let start = out[ 0 ] . take ( ) ;
454
- let stop = out[ 1 ] . take ( ) ;
455
- let step = if out. len ( ) == 3 { out[ 2 ] . take ( ) } else { None } ;
447
+ let step = if * size == 3 {
448
+ Some ( self . pop_value ( ) )
449
+ } else {
450
+ None
451
+ } ;
452
+ let stop = self . pop_value ( ) ;
453
+ let start = self . pop_value ( ) ;
456
454
457
- let obj = PySlice { start, stop, step } . into_ref ( vm) ;
455
+ let obj = PySlice {
456
+ start : Some ( start) ,
457
+ stop,
458
+ step,
459
+ }
460
+ . into_ref ( vm) ;
458
461
self . push_value ( obj. into_object ( ) ) ;
459
462
Ok ( None )
460
463
}
@@ -1037,8 +1040,11 @@ impl Frame {
1037
1040
bytecode:: NameScope :: Global => {
1038
1041
self . scope . store_global ( vm, name, obj) ;
1039
1042
}
1043
+ bytecode:: NameScope :: NonLocal => {
1044
+ self . scope . store_cell ( vm, name, obj) ;
1045
+ }
1040
1046
bytecode:: NameScope :: Local => {
1041
- self . scope . store_name ( & vm, name, obj) ;
1047
+ self . scope . store_name ( vm, name, obj) ;
1042
1048
}
1043
1049
}
1044
1050
Ok ( None )
@@ -1057,6 +1063,7 @@ impl Frame {
1057
1063
) -> FrameResult {
1058
1064
let optional_value = match name_scope {
1059
1065
bytecode:: NameScope :: Global => self . scope . load_global ( vm, name) ,
1066
+ bytecode:: NameScope :: NonLocal => self . scope . load_cell ( vm, name) ,
1060
1067
bytecode:: NameScope :: Local => self . scope . load_name ( & vm, name) ,
1061
1068
} ;
1062
1069
0 commit comments