@@ -171,6 +171,9 @@ slot_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
171
171
static int
172
172
slot_tp_setattro (PyObject * self , PyObject * name , PyObject * value );
173
173
174
+ static PyObject *
175
+ slot_tp_call (PyObject * self , PyObject * args , PyObject * kwds );
176
+
174
177
static inline PyTypeObject *
175
178
type_from_ref (PyObject * ref )
176
179
{
@@ -3709,6 +3712,7 @@ solid_base(PyTypeObject *type)
3709
3712
// safe.
3710
3713
3711
3714
typedef struct {
3715
+ PyTypeObject * type ;
3712
3716
void * * slot_ptr ;
3713
3717
void * slot_value ;
3714
3718
} slot_update_item_t ;
@@ -3758,7 +3762,8 @@ slot_update_free_chunks(slot_update_t *updates)
3758
3762
}
3759
3763
3760
3764
static int
3761
- queue_slot_update (slot_update_t * updates , void * * slot_ptr , void * slot_value )
3765
+ queue_slot_update (slot_update_t * updates , PyTypeObject * type ,
3766
+ void * * slot_ptr , void * slot_value )
3762
3767
{
3763
3768
if (* slot_ptr == slot_value ) {
3764
3769
return 0 ; // slot pointer not actually changed, don't queue update
@@ -3772,6 +3777,7 @@ queue_slot_update(slot_update_t *updates, void **slot_ptr, void *slot_value)
3772
3777
updates -> head = chunk ;
3773
3778
}
3774
3779
slot_update_item_t * item = & updates -> head -> updates [updates -> head -> n ];
3780
+ item -> type = type ;
3775
3781
item -> slot_ptr = slot_ptr ;
3776
3782
item -> slot_value = slot_value ;
3777
3783
updates -> head -> n ++ ;
@@ -3788,6 +3794,10 @@ apply_slot_updates(slot_update_t *updates)
3788
3794
for (Py_ssize_t i = 0 ; i < chunk -> n ; i ++ ) {
3789
3795
slot_update_item_t * item = & chunk -> updates [i ];
3790
3796
* (item -> slot_ptr ) = item -> slot_value ;
3797
+ if (item -> slot_value == slot_tp_call ) {
3798
+ /* A generic __call__ is incompatible with vectorcall */
3799
+ type_clear_flags (item -> type , Py_TPFLAGS_HAVE_VECTORCALL );
3800
+ }
3791
3801
}
3792
3802
chunk = chunk -> prev ;
3793
3803
}
@@ -11517,7 +11527,9 @@ update_one_slot(PyTypeObject *type, pytype_slotdef *p, pytype_slotdef **next_p,
11517
11527
}
11518
11528
if (p -> function == slot_tp_call ) {
11519
11529
/* A generic __call__ is incompatible with vectorcall */
11520
- type_clear_flags (type , Py_TPFLAGS_HAVE_VECTORCALL );
11530
+ if (queued_updates == NULL ) {
11531
+ type_clear_flags (type , Py_TPFLAGS_HAVE_VECTORCALL );
11532
+ }
11521
11533
}
11522
11534
}
11523
11535
Py_DECREF (descr );
@@ -11533,7 +11545,7 @@ update_one_slot(PyTypeObject *type, pytype_slotdef *p, pytype_slotdef **next_p,
11533
11545
#ifdef Py_GIL_DISABLED
11534
11546
if (queued_updates != NULL ) {
11535
11547
// queue the update to perform later, while world is stopped
11536
- if (queue_slot_update (queued_updates , ptr , slot_value ) < 0 ) {
11548
+ if (queue_slot_update (queued_updates , type , ptr , slot_value ) < 0 ) {
11537
11549
return -1 ;
11538
11550
}
11539
11551
} else {
0 commit comments