@@ -164,7 +164,7 @@ dump_stack(_PyInterpreterFrame *frame, _PyStackRef *stack_pointer)
164
164
PyErr_Clear ();
165
165
}
166
166
// 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 ));
168
168
}
169
169
printf ("]\n" );
170
170
fflush (stdout );
@@ -805,7 +805,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
805
805
806
806
807
807
808
- #ifdef Py_DEBUG
808
+ #if defined( Py_DEBUG ) && !defined( Py_STACKREF_DEBUG )
809
809
/* Set these to invalid but identifiable values for debugging. */
810
810
entry_frame .f_funcobj = (_PyStackRef ){.bits = 0xaaa0 };
811
811
entry_frame .f_locals = (PyObject * )0xaaa1 ;
@@ -1810,27 +1810,48 @@ _PyEvalFramePushAndInit_Ex(PyThreadState *tstate, _PyStackRef func,
1810
1810
{
1811
1811
bool has_dict = (kwargs != NULL && PyDict_GET_SIZE (kwargs ) > 0 );
1812
1812
PyObject * kwnames = NULL ;
1813
- PyObject * const * newargs ;
1813
+ _PyStackRef * newargs ;
1814
+ PyObject * const * object_array = NULL ;
1815
+ _PyStackRef stack_array [8 ];
1814
1816
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 ) {
1817
1819
PyStackRef_CLOSE (func );
1818
1820
goto error ;
1819
1821
}
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
+ }
1820
1828
}
1821
1829
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 ));
1826
1844
}
1827
1845
}
1828
1846
_PyInterpreterFrame * new_frame = _PyEvalFramePushAndInit (
1829
1847
tstate , func , locals ,
1830
- ( _PyStackRef const * ) newargs , nargs , kwnames , previous
1848
+ newargs , nargs , kwnames , previous
1831
1849
);
1832
1850
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 );
1834
1855
}
1835
1856
/* No need to decref func here because the reference has been stolen by
1836
1857
_PyEvalFramePushAndInit.
@@ -1850,21 +1871,39 @@ _PyEval_Vector(PyThreadState *tstate, PyFunctionObject *func,
1850
1871
PyObject * const * args , size_t argcount ,
1851
1872
PyObject * kwnames )
1852
1873
{
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
+ }
1853
1889
/* _PyEvalFramePushAndInit consumes the references
1854
1890
* to func, locals and all its arguments */
1855
1891
Py_XINCREF (locals );
1856
1892
for (size_t i = 0 ; i < argcount ; i ++ ) {
1857
- Py_INCREF (args [i ]);
1893
+ arguments [ i ] = PyStackRef_FromPyObjectNew (args [i ]);
1858
1894
}
1859
1895
if (kwnames ) {
1860
1896
Py_ssize_t kwcount = PyTuple_GET_SIZE (kwnames );
1861
1897
for (Py_ssize_t i = 0 ; i < kwcount ; i ++ ) {
1862
- Py_INCREF (args [i + argcount ]);
1898
+ arguments [ i + argcount ] = PyStackRef_FromPyObjectNew (args [i + argcount ]);
1863
1899
}
1864
1900
}
1865
1901
_PyInterpreterFrame * frame = _PyEvalFramePushAndInit (
1866
1902
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
+ }
1868
1907
if (frame == NULL ) {
1869
1908
return NULL ;
1870
1909
}
0 commit comments