@@ -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)
17261752static void
17271753methodcaller_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
17391766static void
17401767methodcaller_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)
17491778static int
17501779methodcaller_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