@@ -164,7 +164,7 @@ dump_stack(_PyInterpreterFrame *frame, _PyStackRef *stack_pointer)
164164 PyErr_Clear ();
165165 }
166166 // Don't call __repr__(), it might recurse into the interpreter.
167- printf ("<%s at %p>" , Py_TYPE (obj )-> tp_name , ( void * )( ptr -> bits ));
167+ printf ("<%s at %p>" , Py_TYPE (obj )-> tp_name , PyStackRef_AsPyObjectBorrow ( * ptr ));
168168 }
169169 printf ("]\n" );
170170 fflush (stdout );
@@ -805,7 +805,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
805805
806806
807807
808- #ifdef Py_DEBUG
808+ #if defined( Py_DEBUG ) && !defined( Py_STACKREF_DEBUG )
809809 /* Set these to invalid but identifiable values for debugging. */
810810 entry_frame .f_funcobj = (_PyStackRef ){.bits = 0xaaa0 };
811811 entry_frame .f_locals = (PyObject * )0xaaa1 ;
@@ -1810,27 +1810,48 @@ _PyEvalFramePushAndInit_Ex(PyThreadState *tstate, _PyStackRef func,
18101810{
18111811 bool has_dict = (kwargs != NULL && PyDict_GET_SIZE (kwargs ) > 0 );
18121812 PyObject * kwnames = NULL ;
1813- PyObject * const * newargs ;
1813+ _PyStackRef * newargs ;
1814+ PyObject * const * object_array = NULL ;
1815+ _PyStackRef stack_array [8 ];
18141816 if (has_dict ) {
1815- newargs = _PyStack_UnpackDict (tstate , _PyTuple_ITEMS (callargs ), nargs , kwargs , & kwnames );
1816- if (newargs == NULL ) {
1817+ object_array = _PyStack_UnpackDict (tstate , _PyTuple_ITEMS (callargs ), nargs , kwargs , & kwnames );
1818+ if (object_array == NULL ) {
18171819 PyStackRef_CLOSE (func );
18181820 goto error ;
18191821 }
1822+ size_t total_args = nargs + PyDict_GET_SIZE (kwargs );
1823+ assert (sizeof (PyObject * ) == sizeof (_PyStackRef ));
1824+ newargs = (_PyStackRef * )object_array ;
1825+ for (size_t i = 0 ; i < total_args ; i ++ ) {
1826+ newargs [i ] = PyStackRef_FromPyObjectSteal (object_array [i ]);
1827+ }
18201828 }
18211829 else {
1822- newargs = & PyTuple_GET_ITEM (callargs , 0 );
1823- /* We need to incref all our args since the new frame steals the references. */
1824- for (Py_ssize_t i = 0 ; i < nargs ; ++ i ) {
1825- Py_INCREF (PyTuple_GET_ITEM (callargs , i ));
1830+ if (nargs <= 8 ) {
1831+ newargs = stack_array ;
1832+ }
1833+ else {
1834+ newargs = PyMem_Malloc (sizeof (_PyStackRef ) * nargs );
1835+ if (newargs == NULL ) {
1836+ PyErr_NoMemory ();
1837+ PyStackRef_CLOSE (func );
1838+ goto error ;
1839+ }
1840+ }
1841+ /* We need to create a new reference for all our args since the new frame steals them. */
1842+ for (Py_ssize_t i = 0 ; i < nargs ; i ++ ) {
1843+ newargs [i ] = PyStackRef_FromPyObjectNew (PyTuple_GET_ITEM (callargs , i ));
18261844 }
18271845 }
18281846 _PyInterpreterFrame * new_frame = _PyEvalFramePushAndInit (
18291847 tstate , func , locals ,
1830- ( _PyStackRef const * ) newargs , nargs , kwnames , previous
1848+ newargs , nargs , kwnames , previous
18311849 );
18321850 if (has_dict ) {
1833- _PyStack_UnpackDict_FreeNoDecRef (newargs , kwnames );
1851+ _PyStack_UnpackDict_FreeNoDecRef (object_array , kwnames );
1852+ }
1853+ else if (nargs > 8 ) {
1854+ PyMem_Free ((void * )newargs );
18341855 }
18351856 /* No need to decref func here because the reference has been stolen by
18361857 _PyEvalFramePushAndInit.
@@ -1850,21 +1871,39 @@ _PyEval_Vector(PyThreadState *tstate, PyFunctionObject *func,
18501871 PyObject * const * args , size_t argcount ,
18511872 PyObject * kwnames )
18521873{
1874+ size_t total_args = argcount ;
1875+ if (kwnames ) {
1876+ total_args += PyTuple_GET_SIZE (kwnames );
1877+ }
1878+ _PyStackRef stack_array [8 ];
1879+ _PyStackRef * arguments ;
1880+ if (total_args <= 8 ) {
1881+ arguments = stack_array ;
1882+ }
1883+ else {
1884+ arguments = PyMem_Malloc (sizeof (_PyStackRef ) * total_args );
1885+ if (arguments == NULL ) {
1886+ return PyErr_NoMemory ();
1887+ }
1888+ }
18531889 /* _PyEvalFramePushAndInit consumes the references
18541890 * to func, locals and all its arguments */
18551891 Py_XINCREF (locals );
18561892 for (size_t i = 0 ; i < argcount ; i ++ ) {
1857- Py_INCREF (args [i ]);
1893+ arguments [ i ] = PyStackRef_FromPyObjectNew (args [i ]);
18581894 }
18591895 if (kwnames ) {
18601896 Py_ssize_t kwcount = PyTuple_GET_SIZE (kwnames );
18611897 for (Py_ssize_t i = 0 ; i < kwcount ; i ++ ) {
1862- Py_INCREF (args [i + argcount ]);
1898+ arguments [ i + argcount ] = PyStackRef_FromPyObjectNew (args [i + argcount ]);
18631899 }
18641900 }
18651901 _PyInterpreterFrame * frame = _PyEvalFramePushAndInit (
18661902 tstate , PyStackRef_FromPyObjectNew (func ), locals ,
1867- (_PyStackRef const * )args , argcount , kwnames , NULL );
1903+ arguments , argcount , kwnames , NULL );
1904+ if (total_args > 8 ) {
1905+ PyMem_Free (arguments );
1906+ }
18681907 if (frame == NULL ) {
18691908 return NULL ;
18701909 }
0 commit comments