@@ -13,18 +13,26 @@ use super::objiter;
13
13
use super :: objstr;
14
14
use super :: objtype;
15
15
use crate :: pyobject:: {
16
- PyContext , PyFuncArgs , PyObject , PyObjectPayload , PyObjectRef , PyResult , TypeProtocol ,
16
+ PyContext , PyFuncArgs , PyObject , PyObjectPayload , PyObjectPayload2 , PyObjectRef , PyResult ,
17
+ TypeProtocol ,
17
18
} ;
18
19
use crate :: vm:: { ReprGuard , VirtualMachine } ;
19
20
20
- pub fn get_elements ( obj : & PyObjectRef ) -> HashMap < u64 , PyObjectRef > {
21
- if let PyObjectPayload :: Set { elements } = & obj. payload {
22
- elements. borrow ( ) . clone ( )
23
- } else {
24
- panic ! ( "Cannot extract set elements from non-set" ) ;
21
+ #[ derive( Debug , Default ) ]
22
+ pub struct PySet {
23
+ elements : RefCell < HashMap < u64 , PyObjectRef > > ,
24
+ }
25
+
26
+ impl PyObjectPayload2 for PySet {
27
+ fn required_type ( ctx : & PyContext ) -> PyObjectRef {
28
+ ctx. set_type ( )
25
29
}
26
30
}
27
31
32
+ pub fn get_elements ( obj : & PyObjectRef ) -> HashMap < u64 , PyObjectRef > {
33
+ obj. payload :: < PySet > ( ) . unwrap ( ) . elements . borrow ( ) . clone ( )
34
+ }
35
+
28
36
fn perform_action_with_hash (
29
37
vm : & mut VirtualMachine ,
30
38
elements : & mut HashMap < u64 , PyObjectRef > ,
@@ -62,12 +70,10 @@ fn set_add(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
62
70
arg_check ! (
63
71
vm,
64
72
args,
65
- required = [ ( s , Some ( vm. ctx. set_type( ) ) ) , ( item, None ) ]
73
+ required = [ ( zelf , Some ( vm. ctx. set_type( ) ) ) , ( item, None ) ]
66
74
) ;
67
- match s. payload {
68
- PyObjectPayload :: Set { ref elements } => {
69
- insert_into_set ( vm, & mut elements. borrow_mut ( ) , item)
70
- }
75
+ match zelf. payload :: < PySet > ( ) {
76
+ Some ( set) => insert_into_set ( vm, & mut set. elements . borrow_mut ( ) , item) ,
71
77
_ => Err ( vm. new_type_error ( "set.add is called with no item" . to_string ( ) ) ) ,
72
78
}
73
79
}
@@ -79,8 +85,8 @@ fn set_remove(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
79
85
args,
80
86
required = [ ( s, Some ( vm. ctx. set_type( ) ) ) , ( item, None ) ]
81
87
) ;
82
- match s. payload {
83
- PyObjectPayload :: Set { ref elements } => {
88
+ match s. payload :: < PySet > ( ) {
89
+ Some ( set ) => {
84
90
fn remove (
85
91
vm : & mut VirtualMachine ,
86
92
elements : & mut HashMap < u64 , PyObjectRef > ,
@@ -95,7 +101,7 @@ fn set_remove(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
95
101
Some ( _) => Ok ( vm. get_none ( ) ) ,
96
102
}
97
103
}
98
- perform_action_with_hash ( vm, & mut elements. borrow_mut ( ) , item, & remove)
104
+ perform_action_with_hash ( vm, & mut set . elements . borrow_mut ( ) , item, & remove)
99
105
}
100
106
_ => Err ( vm. new_type_error ( "set.remove is called with no item" . to_string ( ) ) ) ,
101
107
}
@@ -108,8 +114,8 @@ fn set_discard(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
108
114
args,
109
115
required = [ ( s, Some ( vm. ctx. set_type( ) ) ) , ( item, None ) ]
110
116
) ;
111
- match s. payload {
112
- PyObjectPayload :: Set { ref elements } => {
117
+ match s. payload :: < PySet > ( ) {
118
+ Some ( set ) => {
113
119
fn discard (
114
120
vm : & mut VirtualMachine ,
115
121
elements : & mut HashMap < u64 , PyObjectRef > ,
@@ -119,21 +125,21 @@ fn set_discard(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
119
125
elements. remove ( & key) ;
120
126
Ok ( vm. get_none ( ) )
121
127
}
122
- perform_action_with_hash ( vm, & mut elements. borrow_mut ( ) , item, & discard)
128
+ perform_action_with_hash ( vm, & mut set . elements . borrow_mut ( ) , item, & discard)
123
129
}
124
- _ => Err ( vm. new_type_error ( "set.discard is called with no item" . to_string ( ) ) ) ,
130
+ None => Err ( vm. new_type_error ( "set.discard is called with no item" . to_string ( ) ) ) ,
125
131
}
126
132
}
127
133
128
134
fn set_clear ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
129
135
trace ! ( "set.clear called" ) ;
130
136
arg_check ! ( vm, args, required = [ ( s, Some ( vm. ctx. set_type( ) ) ) ] ) ;
131
- match s. payload {
132
- PyObjectPayload :: Set { ref elements } => {
133
- elements. borrow_mut ( ) . clear ( ) ;
137
+ match s. payload :: < PySet > ( ) {
138
+ Some ( set ) => {
139
+ set . elements . borrow_mut ( ) . clear ( ) ;
134
140
Ok ( vm. get_none ( ) )
135
141
}
136
- _ => Err ( vm. new_type_error ( "" . to_string ( ) ) ) ,
142
+ None => Err ( vm. new_type_error ( "" . to_string ( ) ) ) ,
137
143
}
138
144
}
139
145
@@ -163,8 +169,10 @@ fn set_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
163
169
} ;
164
170
165
171
Ok ( PyObject :: new (
166
- PyObjectPayload :: Set {
167
- elements : RefCell :: new ( elements) ,
172
+ PyObjectPayload :: AnyRustValue {
173
+ value : Box :: new ( PySet {
174
+ elements : RefCell :: new ( elements) ,
175
+ } ) ,
168
176
} ,
169
177
cls. clone ( ) ,
170
178
) )
@@ -182,8 +190,10 @@ fn set_copy(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
182
190
arg_check ! ( vm, args, required = [ ( s, Some ( vm. ctx. set_type( ) ) ) ] ) ;
183
191
let elements = get_elements ( s) ;
184
192
Ok ( PyObject :: new (
185
- PyObjectPayload :: Set {
186
- elements : RefCell :: new ( elements) ,
193
+ PyObjectPayload :: AnyRustValue {
194
+ value : Box :: new ( PySet {
195
+ elements : RefCell :: new ( elements) ,
196
+ } ) ,
187
197
} ,
188
198
vm. ctx . set_type ( ) ,
189
199
) )
@@ -336,8 +346,10 @@ fn set_union(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
336
346
elements. extend ( get_elements ( other) . clone ( ) ) ;
337
347
338
348
Ok ( PyObject :: new (
339
- PyObjectPayload :: Set {
340
- elements : RefCell :: new ( elements) ,
349
+ PyObjectPayload :: AnyRustValue {
350
+ value : Box :: new ( PySet {
351
+ elements : RefCell :: new ( elements) ,
352
+ } ) ,
341
353
} ,
342
354
vm. ctx . set_type ( ) ,
343
355
) )
@@ -378,8 +390,10 @@ fn set_symmetric_difference(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResu
378
390
}
379
391
380
392
Ok ( PyObject :: new (
381
- PyObjectPayload :: Set {
382
- elements : RefCell :: new ( elements) ,
393
+ PyObjectPayload :: AnyRustValue {
394
+ value : Box :: new ( PySet {
395
+ elements : RefCell :: new ( elements) ,
396
+ } ) ,
383
397
} ,
384
398
vm. ctx . set_type ( ) ,
385
399
) )
@@ -418,8 +432,10 @@ fn set_combine_inner(
418
432
}
419
433
420
434
Ok ( PyObject :: new (
421
- PyObjectPayload :: Set {
422
- elements : RefCell :: new ( elements) ,
435
+ PyObjectPayload :: AnyRustValue {
436
+ value : Box :: new ( PySet {
437
+ elements : RefCell :: new ( elements) ,
438
+ } ) ,
423
439
} ,
424
440
vm. ctx . set_type ( ) ,
425
441
) )
@@ -428,9 +444,9 @@ fn set_combine_inner(
428
444
fn set_pop ( vm : & mut VirtualMachine , args : PyFuncArgs ) -> PyResult {
429
445
arg_check ! ( vm, args, required = [ ( s, Some ( vm. ctx. set_type( ) ) ) ] ) ;
430
446
431
- match s. payload {
432
- PyObjectPayload :: Set { ref elements } => {
433
- let mut elements = elements. borrow_mut ( ) ;
447
+ match s. payload :: < PySet > ( ) {
448
+ Some ( set ) => {
449
+ let mut elements = set . elements . borrow_mut ( ) ;
434
450
match elements. clone ( ) . keys ( ) . next ( ) {
435
451
Some ( key) => Ok ( elements. remove ( key) . unwrap ( ) ) ,
436
452
None => Err ( vm. new_key_error ( "pop from an empty set" . to_string ( ) ) ) ,
@@ -452,11 +468,11 @@ fn set_ior(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
452
468
required = [ ( zelf, Some ( vm. ctx. set_type( ) ) ) , ( iterable, None ) ]
453
469
) ;
454
470
455
- match zelf. payload {
456
- PyObjectPayload :: Set { ref elements } => {
471
+ match zelf. payload :: < PySet > ( ) {
472
+ Some ( set ) => {
457
473
let iterator = objiter:: get_iter ( vm, iterable) ?;
458
474
while let Ok ( v) = vm. call_method ( & iterator, "__next__" , vec ! [ ] ) {
459
- insert_into_set ( vm, & mut elements. borrow_mut ( ) , & v) ?;
475
+ insert_into_set ( vm, & mut set . elements . borrow_mut ( ) , & v) ?;
460
476
}
461
477
}
462
478
_ => return Err ( vm. new_type_error ( "set.update is called with no other" . to_string ( ) ) ) ,
@@ -493,9 +509,9 @@ fn set_combine_update_inner(
493
509
required = [ ( zelf, Some ( vm. ctx. set_type( ) ) ) , ( iterable, None ) ]
494
510
) ;
495
511
496
- match zelf. payload {
497
- PyObjectPayload :: Set { ref elements } => {
498
- let mut elements = elements. borrow_mut ( ) ;
512
+ match zelf. payload :: < PySet > ( ) {
513
+ Some ( set ) => {
514
+ let mut elements = set . elements . borrow_mut ( ) ;
499
515
for element in elements. clone ( ) . iter ( ) {
500
516
let value = vm. call_method ( iterable, "__contains__" , vec ! [ element. 1 . clone( ) ] ) ?;
501
517
let should_remove = match op {
@@ -524,17 +540,17 @@ fn set_ixor(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
524
540
required = [ ( zelf, Some ( vm. ctx. set_type( ) ) ) , ( iterable, None ) ]
525
541
) ;
526
542
527
- match zelf. payload {
528
- PyObjectPayload :: Set { ref elements } => {
529
- let elements_original = elements. borrow ( ) . clone ( ) ;
543
+ match zelf. payload :: < PySet > ( ) {
544
+ Some ( set ) => {
545
+ let elements_original = set . elements . borrow ( ) . clone ( ) ;
530
546
let iterator = objiter:: get_iter ( vm, iterable) ?;
531
547
while let Ok ( v) = vm. call_method ( & iterator, "__next__" , vec ! [ ] ) {
532
- insert_into_set ( vm, & mut elements. borrow_mut ( ) , & v) ?;
548
+ insert_into_set ( vm, & mut set . elements . borrow_mut ( ) , & v) ?;
533
549
}
534
550
for element in elements_original. iter ( ) {
535
551
let value = vm. call_method ( iterable, "__contains__" , vec ! [ element. 1 . clone( ) ] ) ?;
536
552
if objbool:: get_value ( & value) {
537
- elements. borrow_mut ( ) . remove ( & element. 0 . clone ( ) ) ;
553
+ set . elements . borrow_mut ( ) . remove ( & element. 0 . clone ( ) ) ;
538
554
}
539
555
}
540
556
}
0 commit comments