1
1
use std:: fmt;
2
- use std:: rc:: Rc ;
3
2
4
3
use crate :: obj:: objdict:: PyDictRef ;
5
4
use crate :: pyobject:: { ItemProtocol , PyContext , PyObjectRef , PyResult } ;
@@ -9,58 +8,9 @@ use crate::vm::VirtualMachine;
9
8
* So a scope is a linked list of scopes.
10
9
* When a name is looked up, it is check in its scope.
11
10
*/
12
- #[ derive( Debug ) ]
13
- struct RcListNode < T > {
14
- elem : T ,
15
- next : Option < Rc < RcListNode < T > > > ,
16
- }
17
-
18
- #[ derive( Debug , Clone ) ]
19
- struct RcList < T > {
20
- head : Option < Rc < RcListNode < T > > > ,
21
- }
22
-
23
- struct Iter < ' a , T : ' a > {
24
- next : Option < & ' a RcListNode < T > > ,
25
- }
26
-
27
- impl < T > RcList < T > {
28
- pub fn new ( ) -> Self {
29
- RcList { head : None }
30
- }
31
-
32
- pub fn insert ( self , elem : T ) -> Self {
33
- RcList {
34
- head : Some ( Rc :: new ( RcListNode {
35
- elem,
36
- next : self . head ,
37
- } ) ) ,
38
- }
39
- }
40
-
41
- #[ cfg_attr( feature = "flame-it" , flame( "RcList" ) ) ]
42
- pub fn iter ( & self ) -> Iter < T > {
43
- Iter {
44
- next : self . head . as_ref ( ) . map ( |node| & * * node) ,
45
- }
46
- }
47
- }
48
-
49
- impl < ' a , T > Iterator for Iter < ' a , T > {
50
- type Item = & ' a T ;
51
-
52
- #[ cfg_attr( feature = "flame-it" , flame( "Iter" ) ) ]
53
- fn next ( & mut self ) -> Option < Self :: Item > {
54
- self . next . map ( |node| {
55
- self . next = node. next . as_ref ( ) . map ( |node| & * * node) ;
56
- & node. elem
57
- } )
58
- }
59
- }
60
-
61
11
#[ derive( Clone ) ]
62
12
pub struct Scope {
63
- locals : RcList < PyDictRef > ,
13
+ locals : Vec < PyDictRef > ,
64
14
pub globals : PyDictRef ,
65
15
}
66
16
@@ -74,8 +24,8 @@ impl fmt::Debug for Scope {
74
24
impl Scope {
75
25
pub fn new ( locals : Option < PyDictRef > , globals : PyDictRef , vm : & VirtualMachine ) -> Scope {
76
26
let locals = match locals {
77
- Some ( dict) => RcList :: new ( ) . insert ( dict) ,
78
- None => RcList :: new ( ) ,
27
+ Some ( dict) => vec ! [ dict] ,
28
+ None => vec ! [ ] ,
79
29
} ;
80
30
let scope = Scope { locals, globals } ;
81
31
scope. store_name ( vm, "__annotations__" , vm. ctx . new_dict ( ) . into_object ( ) ) ;
@@ -97,19 +47,22 @@ impl Scope {
97
47
}
98
48
99
49
pub fn get_locals ( & self ) -> PyDictRef {
100
- match self . locals . iter ( ) . next ( ) {
50
+ match self . locals . first ( ) {
101
51
Some ( dict) => dict. clone ( ) ,
102
52
None => self . globals . clone ( ) ,
103
53
}
104
54
}
105
55
106
56
pub fn get_only_locals ( & self ) -> Option < PyDictRef > {
107
- self . locals . iter ( ) . next ( ) . cloned ( )
57
+ self . locals . first ( ) . cloned ( )
108
58
}
109
59
110
60
pub fn new_child_scope_with_locals ( & self , locals : PyDictRef ) -> Scope {
61
+ let mut new_locals = Vec :: with_capacity ( self . locals . len ( ) + 1 ) ;
62
+ new_locals. push ( locals) ;
63
+ new_locals. extend_from_slice ( & self . locals ) ;
111
64
Scope {
112
- locals : self . locals . clone ( ) . insert ( locals ) ,
65
+ locals : new_locals ,
113
66
globals : self . globals . clone ( ) ,
114
67
}
115
68
}
@@ -161,8 +114,7 @@ impl NameProtocol for Scope {
161
114
162
115
fn store_cell ( & self , vm : & VirtualMachine , name : & str , value : PyObjectRef ) {
163
116
self . locals
164
- . iter ( )
165
- . nth ( 1 )
117
+ . get ( 1 )
166
118
. expect ( "no outer scope for non-local" )
167
119
. set_item ( name, value, vm)
168
120
. unwrap ( ) ;
0 commit comments