Skip to content

Commit 3cb2256

Browse files
committed
Queue update of tp_flags as well.
The clearing of Py_TPFLAGS_HAVE_VECTORCALL must be done when the world is stopped too.
1 parent 6cd7644 commit 3cb2256

File tree

1 file changed

+15
-3
lines changed

1 file changed

+15
-3
lines changed

Objects/typeobject.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,9 @@ slot_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
171171
static int
172172
slot_tp_setattro(PyObject *self, PyObject *name, PyObject *value);
173173

174+
static PyObject *
175+
slot_tp_call(PyObject *self, PyObject *args, PyObject *kwds);
176+
174177
static inline PyTypeObject *
175178
type_from_ref(PyObject *ref)
176179
{
@@ -3709,6 +3712,7 @@ solid_base(PyTypeObject *type)
37093712
// safe.
37103713

37113714
typedef struct {
3715+
PyTypeObject *type;
37123716
void **slot_ptr;
37133717
void *slot_value;
37143718
} slot_update_item_t;
@@ -3758,7 +3762,8 @@ slot_update_free_chunks(slot_update_t *updates)
37583762
}
37593763

37603764
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)
37623767
{
37633768
if (*slot_ptr == slot_value) {
37643769
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)
37723777
updates->head = chunk;
37733778
}
37743779
slot_update_item_t *item = &updates->head->updates[updates->head->n];
3780+
item->type = type;
37753781
item->slot_ptr = slot_ptr;
37763782
item->slot_value = slot_value;
37773783
updates->head->n++;
@@ -3788,6 +3794,10 @@ apply_slot_updates(slot_update_t *updates)
37883794
for (Py_ssize_t i = 0; i < chunk->n; i++) {
37893795
slot_update_item_t *item = &chunk->updates[i];
37903796
*(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+
}
37913801
}
37923802
chunk = chunk->prev;
37933803
}
@@ -11517,7 +11527,9 @@ update_one_slot(PyTypeObject *type, pytype_slotdef *p, pytype_slotdef **next_p,
1151711527
}
1151811528
if (p->function == slot_tp_call) {
1151911529
/* 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+
}
1152111533
}
1152211534
}
1152311535
Py_DECREF(descr);
@@ -11533,7 +11545,7 @@ update_one_slot(PyTypeObject *type, pytype_slotdef *p, pytype_slotdef **next_p,
1153311545
#ifdef Py_GIL_DISABLED
1153411546
if (queued_updates != NULL) {
1153511547
// 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) {
1153711549
return -1;
1153811550
}
1153911551
} else {

0 commit comments

Comments
 (0)