@@ -3,6 +3,8 @@ use std::collections::HashMap;
3
3
use std:: sync:: atomic:: { AtomicUsize , Ordering , ATOMIC_USIZE_INIT } ;
4
4
use std:: fmt;
5
5
use self :: itertools:: Itertools ;
6
+ use super :: state:: State ;
7
+ use super :: sandbox:: EnvProxy ;
6
8
7
9
#[ derive( Debug ) ]
8
10
#[ derive( Clone ) ]
@@ -53,25 +55,44 @@ pub enum ObjectContent {
53
55
PrimitiveNamespace , // __primitives__
54
56
PrimitiveFunction ( String ) ,
55
57
Class ( Option < ObjectRef > ) ,
58
+ RandomAccessIterator ( ObjectRef , usize , u64 ) , // container, index, container version
56
59
OtherObject ,
57
60
}
58
61
62
+ static CURRENT_VERSION : AtomicUsize = ATOMIC_USIZE_INIT ;
63
+
59
64
#[ derive( Debug ) ]
60
65
#[ derive( Clone ) ]
61
66
pub struct Object {
67
+ pub version : u64 ,
62
68
pub name : Option < String > ,
63
69
pub content : ObjectContent ,
64
70
pub class : ObjectRef ,
65
71
pub bases : Option < Vec < ObjectRef > > , // superclasses
66
72
}
67
73
68
74
impl Object {
75
+ fn new_version ( ) -> u64 {
76
+ CURRENT_VERSION . fetch_add ( 1 , Ordering :: SeqCst ) as u64 // TODO: avoid cast
77
+ }
69
78
pub fn new_instance ( name : Option < String > , class : ObjectRef , content : ObjectContent ) -> Object {
70
- Object { name : name, content : content, class : class, bases : None }
79
+ Object {
80
+ version : Object :: new_version ( ) ,
81
+ name : name,
82
+ content : content,
83
+ class : class,
84
+ bases : None ,
85
+ }
71
86
}
72
87
73
88
pub fn new_class ( name : String , code : Option < ObjectRef > , metaclass : ObjectRef , bases : Vec < ObjectRef > ) -> Object {
74
- Object { name : Some ( name) , content : ObjectContent :: Class ( code) , class : metaclass, bases : Some ( bases) }
89
+ Object {
90
+ version : Object :: new_version ( ) ,
91
+ name : Some ( name) ,
92
+ content : ObjectContent :: Class ( code) ,
93
+ class : metaclass,
94
+ bases : Some ( bases) ,
95
+ }
75
96
}
76
97
}
77
98
@@ -135,6 +156,9 @@ impl ObjectRef {
135
156
Some ( ref s) => format ! ( "<module {}" , s) ,
136
157
}
137
158
} ,
159
+ ObjectContent :: RandomAccessIterator ( ref container, ref index, ref version) => {
160
+ format ! ( "<iterator on {} at index {}>" , store. deref( container) . class. repr( store) , version)
161
+ }
138
162
ObjectContent :: OtherObject => format ! ( "<{} instance>" , obj. class. repr( store) ) ,
139
163
}
140
164
}
@@ -148,6 +172,13 @@ impl ObjectRef {
148
172
_ => panic ! ( format!( "Not a function/module: {:?}" , func) ) ,
149
173
}
150
174
}
175
+
176
+ pub fn iter < EP : EnvProxy > ( & self , state : & mut State < EP > ) -> ObjectRef {
177
+ // TODO: check it's a list or a tuple
178
+ let obj_version = state. store . deref ( self ) . version ;
179
+ let iterator = Object :: new_instance ( None , state. primitive_objects . iterator_type . clone ( ) , ObjectContent :: RandomAccessIterator ( self . clone ( ) , 0 , obj_version) ) ;
180
+ state. store . allocate ( iterator)
181
+ }
151
182
}
152
183
153
184
@@ -214,6 +245,8 @@ pub struct PrimitiveObjects {
214
245
pub bytes_type : ObjectRef ,
215
246
pub str_type : ObjectRef ,
216
247
248
+ pub iterator_type : ObjectRef ,
249
+
217
250
pub function_type : ObjectRef ,
218
251
pub code_type : ObjectRef ,
219
252
@@ -226,6 +259,7 @@ pub struct PrimitiveObjects {
226
259
pub nameerror : ObjectRef ,
227
260
pub attributeerror : ObjectRef ,
228
261
pub typeerror : ObjectRef ,
262
+ pub stopiteration : ObjectRef ,
229
263
230
264
pub lookuperror : ObjectRef ,
231
265
pub keyerror : ObjectRef ,
@@ -237,8 +271,20 @@ impl PrimitiveObjects {
237
271
pub fn new ( store : & mut ObjectStore ) -> PrimitiveObjects {
238
272
let obj_ref = ObjectRef :: new ( ) ;
239
273
let type_ref = ObjectRef :: new ( ) ;
240
- let obj = Object { name : Some ( "object" . to_string ( ) ) , content : ObjectContent :: OtherObject , bases : Some ( vec ! [ ] ) , class : type_ref. clone ( ) } ;
241
- let type_ = Object { name : Some ( "type" . to_string ( ) ) , content : ObjectContent :: OtherObject , bases : Some ( vec ! [ obj_ref. clone( ) ] ) , class : type_ref. clone ( ) } ;
274
+ let obj = Object {
275
+ version : Object :: new_version ( ) ,
276
+ name : Some ( "object" . to_string ( ) ) ,
277
+ content : ObjectContent :: OtherObject ,
278
+ bases : Some ( vec ! [ ] ) ,
279
+ class : type_ref. clone ( )
280
+ } ;
281
+ let type_ = Object {
282
+ version : Object :: new_version ( ) ,
283
+ name : Some ( "type" . to_string ( ) ) ,
284
+ content : ObjectContent :: OtherObject ,
285
+ bases : Some ( vec ! [ obj_ref. clone( ) ] ) ,
286
+ class : type_ref. clone ( )
287
+ } ;
242
288
store. allocate_at ( obj_ref. clone ( ) , obj) ;
243
289
store. allocate_at ( type_ref. clone ( ) , type_) ;
244
290
@@ -256,6 +302,7 @@ impl PrimitiveObjects {
256
302
let frozenset_type = store. allocate ( Object :: new_class ( "frozenset" . to_string ( ) , None , type_ref. clone ( ) , vec ! [ obj_ref. clone( ) ] ) ) ;
257
303
let bytes_type = store. allocate ( Object :: new_class ( "bytes" . to_string ( ) , None , type_ref. clone ( ) , vec ! [ obj_ref. clone( ) ] ) ) ;
258
304
let str_type = store. allocate ( Object :: new_class ( "str" . to_string ( ) , None , type_ref. clone ( ) , vec ! [ obj_ref. clone( ) ] ) ) ;
305
+ let iterator_type = store. allocate ( Object :: new_class ( "iterator" . to_string ( ) , None , type_ref. clone ( ) , vec ! [ obj_ref. clone( ) ] ) ) ;
259
306
260
307
let function_type = store. allocate ( Object :: new_class ( "function" . to_string ( ) , None , type_ref. clone ( ) , vec ! [ obj_ref. clone( ) ] ) ) ;
261
308
let code_type = store. allocate ( Object :: new_class ( "code" . to_string ( ) , None , type_ref. clone ( ) , vec ! [ obj_ref. clone( ) ] ) ) ;
@@ -269,6 +316,7 @@ impl PrimitiveObjects {
269
316
let nameerror = store. allocate ( Object :: new_class ( "NameError" . to_string ( ) , None , type_ref. clone ( ) , vec ! [ exception. clone( ) ] ) ) ;
270
317
let attributeerror = store. allocate ( Object :: new_class ( "AttributeError" . to_string ( ) , None , type_ref. clone ( ) , vec ! [ exception. clone( ) ] ) ) ;
271
318
let typeerror = store. allocate ( Object :: new_class ( "TypeError" . to_string ( ) , None , type_ref. clone ( ) , vec ! [ exception. clone( ) ] ) ) ;
319
+ let stopiteration = store. allocate ( Object :: new_class ( "StopIteration" . to_string ( ) , None , type_ref. clone ( ) , vec ! [ exception. clone( ) ] ) ) ;
272
320
273
321
let lookuperror = store. allocate ( Object :: new_class ( "LookupError" . to_string ( ) , None , type_ref. clone ( ) , vec ! [ exception. clone( ) ] ) ) ;
274
322
let keyerror = store. allocate ( Object :: new_class ( "KeyError" . to_string ( ) , None , type_ref. clone ( ) , vec ! [ lookuperror. clone( ) ] ) ) ;
@@ -301,6 +349,7 @@ impl PrimitiveObjects {
301
349
map. insert ( "NameError" . to_string ( ) , nameerror. clone ( ) ) ;
302
350
map. insert ( "AttributeError" . to_string ( ) , attributeerror. clone ( ) ) ;
303
351
map. insert ( "TypeError" . to_string ( ) , typeerror. clone ( ) ) ;
352
+ map. insert ( "StopIteration" . to_string ( ) , stopiteration. clone ( ) ) ;
304
353
305
354
map. insert ( "LookupError" . to_string ( ) , lookuperror. clone ( ) ) ;
306
355
map. insert ( "KeyError" . to_string ( ) , keyerror. clone ( ) ) ;
@@ -312,9 +361,10 @@ impl PrimitiveObjects {
312
361
tuple_type : tuple_type, list_type : list_type,
313
362
set_type : set_type, frozenset_type : frozenset_type,
314
363
bytes_type : bytes_type, str_type : str_type,
364
+ iterator_type : iterator_type,
315
365
function_type : function_type, code_type : code_type,
316
366
baseexception : baseexception, processorerror : processorerror, exception : exception,
317
- nameerror : nameerror, attributeerror : attributeerror, typeerror : typeerror,
367
+ nameerror : nameerror, attributeerror : attributeerror, typeerror : typeerror, stopiteration : stopiteration ,
318
368
lookuperror : lookuperror, keyerror : keyerror,
319
369
module : module,
320
370
names_map : map,
0 commit comments