Skip to content

Commit d208307

Browse files
committed
use strong refs
1 parent f9f53fe commit d208307

File tree

1 file changed

+58
-16
lines changed

1 file changed

+58
-16
lines changed

Modules/_operator.c

Lines changed: 58 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1589,6 +1589,15 @@ static PyType_Spec attrgetter_type_spec = {
15891589
.slots = attrgetter_type_slots,
15901590
};
15911591

1592+
static void print_str(PyObject *o)
1593+
{
1594+
PyObject_Print(o, stdout, Py_PRINT_RAW);
1595+
}
1596+
1597+
static void print_repr(PyObject *o)
1598+
{
1599+
PyObject_Print(o, stdout, 0);
1600+
}
15921601

15931602
/* methodcaller object **********************************************************/
15941603

@@ -1597,7 +1606,7 @@ typedef struct {
15971606
PyObject *name;
15981607
PyObject *args;
15991608
PyObject *kwds;
1600-
PyObject **vectorcall_args; /* Borrowed references */
1609+
PyObject *vectorcall_args;
16011610
PyObject *vectorcall_kwnames;
16021611
vectorcallfunc vectorcall;
16031612
} methodcallerobject;
@@ -1615,13 +1624,16 @@ methodcaller_vectorcall(methodcallerobject *mc, PyObject *const *args,
16151624
}
16161625
assert(mc->vectorcall_args != NULL);
16171626

1627+
<<<<<<< HEAD
16181628
Py_ssize_t number_of_arguments = PyTuple_GET_SIZE(mc->args) +
16191629
(mc->vectorcall_kwnames ? PyTuple_GET_SIZE(mc->vectorcall_kwnames) : 0);
16201630

1631+
=======
1632+
>>>>>>> a0f342840ea (use strong refs)
16211633
PyObject *tmp_args[_METHODCALLER_MAX_ARGS];
16221634
tmp_args[0] = args[0];
1623-
assert(1 + number_of_arguments <= _METHODCALLER_MAX_ARGS);
1624-
memcpy(tmp_args + 1, mc->vectorcall_args, sizeof(PyObject *) * number_of_arguments);
1635+
assert(1 + PyTuple_GET_SIZE(mc->vectorcall_args) <= _METHODCALLER_MAX_ARGS);
1636+
memcpy(tmp_args + 1, _PyTuple_ITEMS(mc->vectorcall_args), sizeof(PyObject *) * PyTuple_GET_SIZE(mc->vectorcall_args));
16251637

16261638
return PyObject_VectorcallMethod(mc->name, tmp_args,
16271639
(1 + PyTuple_GET_SIZE(mc->args)) | PY_VECTORCALL_ARGUMENTS_OFFSET,
@@ -1634,6 +1646,7 @@ _methodcaller_initialize_vectorcall(methodcallerobject* mc)
16341646
PyObject* args = mc->args;
16351647
PyObject* kwds = mc->kwds;
16361648

1649+
<<<<<<< HEAD
16371650
Py_ssize_t nargs = PyTuple_GET_SIZE(args);
16381651
mc->vectorcall_args = PyMem_Calloc(
16391652
nargs + (kwds ? PyDict_Size(kwds) : 0),
@@ -1646,25 +1659,38 @@ _methodcaller_initialize_vectorcall(methodcallerobject* mc)
16461659
// from mc->args and the keys from mc->kwds
16471660
memcpy(mc->vectorcall_args, _PyTuple_ITEMS(args),
16481661
nargs * sizeof(PyObject *)); // borrowed references
1662+
=======
1663+
>>>>>>> a0f342840ea (use strong refs)
16491664
if (kwds && PyDict_Size(kwds)) {
1650-
const Py_ssize_t nkwds = PyDict_Size(kwds);
1651-
mc->vectorcall_kwnames = PyTuple_New(nkwds);
1652-
if (!mc->vectorcall_kwnames) {
1665+
PyObject *values = PyDict_Values(kwds);
1666+
if (!values) {
1667+
PyErr_NoMemory();
16531668
return -1;
16541669
}
1655-
Py_ssize_t i = 0, ppos = 0;
1656-
PyObject* key, * value;
1657-
while (PyDict_Next(kwds, &ppos, &key, &value)) {
1658-
PyTuple_SET_ITEM(mc->vectorcall_kwnames, i, Py_NewRef(key));
1659-
mc->vectorcall_args[nargs + i] = value; // borrowed reference
1660-
++i;
1670+
PyObject *values_tuple = PySequence_Tuple(values);
1671+
Py_DECREF(values);
1672+
if (!values_tuple) {
1673+
PyErr_NoMemory();
1674+
return -1;
1675+
}
1676+
mc->vectorcall_args = PySequence_Concat(args, values_tuple);
1677+
Py_DECREF(values);
1678+
if (mc->vectorcall_args == 0) {
1679+
PyErr_NoMemory();
1680+
return -1;
1681+
}
1682+
mc->vectorcall_kwnames = PySequence_Tuple(kwds);
1683+
if (!mc->vectorcall_kwnames) {
1684+
PyErr_NoMemory();
1685+
return -1;
16611686
}
16621687
}
16631688
else {
1689+
mc->vectorcall_args = Py_NewRef(args);
16641690
mc->vectorcall_kwnames = NULL;
16651691
}
1666-
mc->vectorcall = (vectorcallfunc)methodcaller_vectorcall;
16671692

1693+
mc->vectorcall = (vectorcallfunc)methodcaller_vectorcall;
16681694
return 1;
16691695
}
16701696

@@ -1726,19 +1752,22 @@ methodcaller_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
17261752
static void
17271753
methodcaller_clear(methodcallerobject *mc)
17281754
{
1755+
// printf("methodcaller_clear: mc->vectorcall_kwnames %ld\n", mc->vectorcall_kwnames);
17291756
Py_CLEAR(mc->name);
17301757
Py_CLEAR(mc->args);
17311758
Py_CLEAR(mc->kwds);
1732-
if (mc->vectorcall_args != NULL) {
1733-
PyMem_Free(mc->vectorcall_args);
1734-
mc->vectorcall_args = NULL;
1759+
Py_CLEAR(mc->vectorcall_args);
1760+
if (mc->vectorcall_kwnames) {
17351761
Py_CLEAR(mc->vectorcall_kwnames);
1762+
mc->vectorcall_kwnames = NULL;
17361763
}
17371764
}
17381765

17391766
static void
17401767
methodcaller_dealloc(methodcallerobject *mc)
17411768
{
1769+
//printf("methodcaller_dealloc: \n");
1770+
17421771
PyTypeObject *tp = Py_TYPE(mc);
17431772
PyObject_GC_UnTrack(mc);
17441773
methodcaller_clear(mc);
@@ -1749,9 +1778,22 @@ methodcaller_dealloc(methodcallerobject *mc)
17491778
static int
17501779
methodcaller_traverse(methodcallerobject *mc, visitproc visit, void *arg)
17511780
{
1781+
//printf("methodcaller_traverse\n");
17521782
Py_VISIT(mc->name);
1783+
//printf("methodcaller_traverse: args %ld (refcount %ld)\n", mc->args, Py_REFCNT(mc->args ));
17531784
Py_VISIT(mc->args);
1785+
//printf("methodcaller_traverse: kwds\n");
17541786
Py_VISIT(mc->kwds);
1787+
// printf("methodcaller_traverse: vectorcall_args mc->vectorcall_args %ld\n", mc->vectorcall_args);
1788+
if (mc->vectorcall_kwnames != NULL && 0) {
1789+
printf("methodcaller_traverse: mv->vectorcall_args ");
1790+
print_str(mc->vectorcall_args);
1791+
printf("\n");
1792+
}
1793+
Py_VISIT(mc->vectorcall_args);
1794+
if (mc->vectorcall_kwnames != NULL) {
1795+
Py_VISIT(mc->vectorcall_kwnames);
1796+
}
17551797
Py_VISIT(Py_TYPE(mc));
17561798
return 0;
17571799
}

0 commit comments

Comments
 (0)