@@ -164,16 +164,6 @@ pub(crate) type InitFunc = fn(PyObjectRef, FuncArgs, &VirtualMachine) -> PyResul
164
164
pub ( crate ) type DelFunc = fn ( & PyObject , & VirtualMachine ) -> PyResult < ( ) > ;
165
165
pub ( crate ) type AsSequenceFunc = fn ( & PyObject , & VirtualMachine ) -> Cow < ' static , PySequenceMethods > ;
166
166
167
- macro_rules! then_some_closure {
168
- ( $cond: expr, $closure: expr) => {
169
- if $cond {
170
- Some ( $closure)
171
- } else {
172
- None
173
- }
174
- } ;
175
- }
176
-
177
167
fn length_wrapper ( obj : & PyObject , vm : & VirtualMachine ) -> PyResult < usize > {
178
168
let ret = vm. call_special_method ( obj. to_owned ( ) , identifier ! ( vm, __len__) , ( ) ) ?;
179
169
let len = ret. payload :: < PyInt > ( ) . ok_or_else ( || {
@@ -282,45 +272,73 @@ fn as_mapping_generic(zelf: &PyObject, vm: &VirtualMachine) -> &'static PyMappin
282
272
static_as_mapping_generic ( has_length, has_subscript, has_ass_subscript)
283
273
}
284
274
285
- fn as_sequence_wrapper ( zelf : & PyObject , vm : & VirtualMachine ) -> Cow < ' static , PySequenceMethods > {
275
+ pub ( crate ) fn static_as_sequence_generic (
276
+ has_length : bool ,
277
+ has_ass_item : bool ,
278
+ ) -> & ' static PySequenceMethods {
279
+ static METHODS : & [ PySequenceMethods ] = & [
280
+ new_generic ( false , false ) ,
281
+ new_generic ( true , false ) ,
282
+ new_generic ( false , true ) ,
283
+ new_generic ( true , true ) ,
284
+ ] ;
285
+
286
+ fn length ( seq : & PySequence , vm : & VirtualMachine ) -> PyResult < usize > {
287
+ length_wrapper ( seq. obj , vm)
288
+ }
289
+ fn item ( seq : & PySequence , i : isize , vm : & VirtualMachine ) -> PyResult {
290
+ vm. call_special_method ( seq. obj . to_owned ( ) , identifier ! ( vm, __getitem__) , ( i, ) )
291
+ }
292
+ fn ass_item (
293
+ seq : & PySequence ,
294
+ i : isize ,
295
+ value : Option < PyObjectRef > ,
296
+ vm : & VirtualMachine ,
297
+ ) -> PyResult < ( ) > {
298
+ match value {
299
+ Some ( value) => vm
300
+ . call_special_method (
301
+ seq. obj . to_owned ( ) ,
302
+ identifier ! ( vm, __setitem__) ,
303
+ ( i. to_pyobject ( vm) , value) ,
304
+ )
305
+ . map ( |_| Ok ( ( ) ) ) ?,
306
+ None => vm
307
+ . call_special_method (
308
+ seq. obj . to_owned ( ) ,
309
+ identifier ! ( vm, __delitem__) ,
310
+ ( i. to_pyobject ( vm) , ) ,
311
+ )
312
+ . map ( |_| Ok ( ( ) ) ) ?,
313
+ }
314
+ }
315
+
316
+ const fn new_generic ( has_length : bool , has_ass_item : bool ) -> PySequenceMethods {
317
+ PySequenceMethods {
318
+ length : if has_length { Some ( length) } else { None } ,
319
+ item : Some ( item) ,
320
+ ass_item : if has_ass_item { Some ( ass_item) } else { None } ,
321
+ ..PySequenceMethods :: NOT_IMPLEMENTED
322
+ }
323
+ }
324
+
325
+ let key = bool_int ( has_length) | ( bool_int ( has_ass_item) << 1 ) ;
326
+
327
+ & METHODS [ key]
328
+ }
329
+
330
+ fn as_sequence_generic ( zelf : & PyObject , vm : & VirtualMachine ) -> Cow < ' static , PySequenceMethods > {
286
331
if !zelf. class ( ) . has_attr ( identifier ! ( vm, __getitem__) ) {
287
- return Cow :: Borrowed ( PySequenceMethods :: not_implemented ( ) ) ;
288
- }
289
-
290
- Cow :: Owned ( PySequenceMethods {
291
- length : then_some_closure ! (
292
- zelf. class( ) . has_attr( identifier!( vm, __len__) ) ,
293
- |seq, vm| { length_wrapper( seq. obj, vm) }
294
- ) ,
295
- item : Some ( |seq, i, vm| {
296
- vm. call_special_method (
297
- seq. obj . to_owned ( ) ,
298
- identifier ! ( vm, __getitem__) ,
299
- ( i. to_pyobject ( vm) , ) ,
300
- )
301
- } ) ,
302
- ass_item : then_some_closure ! (
303
- zelf. class( ) . has_attr( identifier!( vm, __setitem__) )
304
- | zelf. class( ) . has_attr( identifier!( vm, __delitem__) ) ,
305
- |seq, i, value, vm| match value {
306
- Some ( value) => vm
307
- . call_special_method(
308
- seq. obj. to_owned( ) ,
309
- identifier!( vm, __setitem__) ,
310
- ( i. to_pyobject( vm) , value) ,
311
- )
312
- . map( |_| Ok ( ( ) ) ) ?,
313
- None => vm
314
- . call_special_method(
315
- seq. obj. to_owned( ) ,
316
- identifier!( vm, __delitem__) ,
317
- ( i. to_pyobject( vm) , )
318
- )
319
- . map( |_| Ok ( ( ) ) ) ?,
320
- }
321
- ) ,
322
- ..Default :: default ( )
323
- } )
332
+ return Cow :: Borrowed ( & PySequenceMethods :: NOT_IMPLEMENTED ) ;
333
+ }
334
+
335
+ let ( has_length, has_ass_item) = (
336
+ zelf. class ( ) . has_attr ( identifier ! ( vm, __len__) ) ,
337
+ zelf. class ( ) . has_attr ( identifier ! ( vm, __setitem__) )
338
+ | zelf. class ( ) . has_attr ( identifier ! ( vm, __delitem__) ) ,
339
+ ) ;
340
+
341
+ Cow :: Borrowed ( static_as_sequence_generic ( has_length, has_ass_item) )
324
342
}
325
343
326
344
fn hash_wrapper ( zelf : & PyObject , vm : & VirtualMachine ) -> PyResult < PyHash > {
@@ -436,7 +454,7 @@ impl PyType {
436
454
match name. as_str ( ) {
437
455
"__len__" | "__getitem__" | "__setitem__" | "__delitem__" => {
438
456
update_slot ! ( as_mapping, as_mapping_generic) ;
439
- update_slot ! ( as_sequence, as_sequence_wrapper ) ;
457
+ update_slot ! ( as_sequence, as_sequence_generic ) ;
440
458
}
441
459
"__hash__" => {
442
460
update_slot ! ( hash, hash_wrapper) ;
0 commit comments