@@ -1515,6 +1515,7 @@ initialize_locals(PyThreadState *tstate, PyFunctionObject *func,
15151515 }
15161516 assert (PyStackRef_IsNull (localsplus [i ]));
15171517 localsplus [i ] = PyStackRef_FromPyObjectSteal (kwdict );
1518+ PyStackRef_CheckValid (localsplus [i ]);
15181519 }
15191520 else {
15201521 kwdict = NULL ;
@@ -1531,6 +1532,7 @@ initialize_locals(PyThreadState *tstate, PyFunctionObject *func,
15311532 for (j = 0 ; j < n ; j ++ ) {
15321533 assert (PyStackRef_IsNull (localsplus [j ]));
15331534 localsplus [j ] = args [j ];
1535+ PyStackRef_CheckValid (localsplus [j ]);
15341536 }
15351537
15361538 /* Pack other positional arguments into the *args argument */
@@ -1654,6 +1656,7 @@ initialize_locals(PyThreadState *tstate, PyFunctionObject *func,
16541656 goto kw_fail ;
16551657 }
16561658 localsplus [j ] = value_stackref ;
1659+ PyStackRef_CheckValid (localsplus [j ]);
16571660 }
16581661 }
16591662
@@ -1689,6 +1692,7 @@ initialize_locals(PyThreadState *tstate, PyFunctionObject *func,
16891692 if (PyStackRef_AsPyObjectBorrow (localsplus [m + i ]) == NULL ) {
16901693 PyObject * def = defs [i ];
16911694 localsplus [m + i ] = PyStackRef_FromPyObjectNew (def );
1695+ PyStackRef_CheckValid (localsplus [m + i ]);
16921696 }
16931697 }
16941698 }
@@ -1708,6 +1712,7 @@ initialize_locals(PyThreadState *tstate, PyFunctionObject *func,
17081712 }
17091713 if (def ) {
17101714 localsplus [i ] = PyStackRef_FromPyObjectSteal (def );
1715+ PyStackRef_CheckValid (localsplus [i ]);
17111716 continue ;
17121717 }
17131718 }
@@ -1835,12 +1840,27 @@ _PyEvalFramePushAndInit_Ex(PyThreadState *tstate, _PyStackRef func,
18351840 PyStackRef_CLOSE (func );
18361841 goto error ;
18371842 }
1843+ size_t total_args = nargs + PyDict_GET_SIZE (kwargs );
1844+ for (size_t i = 0 ; i < total_args ; i ++ ) {
1845+ ((_PyStackRef * )newargs )[i ] = PyStackRef_FromPyObjectSteal (newargs [i ]);
1846+ }
18381847 }
18391848 else {
1840- newargs = & PyTuple_GET_ITEM (callargs , 0 );
1841- /* We need to incref all our args since the new frame steals the references. */
1842- for (Py_ssize_t i = 0 ; i < nargs ; ++ i ) {
1843- Py_INCREF (PyTuple_GET_ITEM (callargs , i ));
1849+ if (nargs <= 8 ) {
1850+ PyObject * stack_array [8 ];
1851+ newargs = stack_array ;
1852+ }
1853+ else {
1854+ newargs = PyMem_Malloc (sizeof (PyObject * ) * nargs );
1855+ if (newargs == NULL ) {
1856+ PyErr_NoMemory ();
1857+ PyStackRef_CLOSE (func );
1858+ goto error ;
1859+ }
1860+ }
1861+ /* We need to tag all our args since the new frame steals the references. */
1862+ for (Py_ssize_t i = 0 ; i < nargs ; i ++ ) {
1863+ ((_PyStackRef * )newargs )[i ] = PyStackRef_FromPyObjectNew (PyTuple_GET_ITEM (callargs , i ));
18441864 }
18451865 }
18461866 _PyInterpreterFrame * new_frame = _PyEvalFramePushAndInit (
@@ -1850,6 +1870,9 @@ _PyEvalFramePushAndInit_Ex(PyThreadState *tstate, _PyStackRef func,
18501870 if (has_dict ) {
18511871 _PyStack_UnpackDict_FreeNoDecRef (newargs , kwnames );
18521872 }
1873+ else if (nargs > 8 ) {
1874+ PyMem_Free ((void * )newargs );
1875+ }
18531876 /* No need to decref func here because the reference has been stolen by
18541877 _PyEvalFramePushAndInit.
18551878 */
@@ -1868,21 +1891,39 @@ _PyEval_Vector(PyThreadState *tstate, PyFunctionObject *func,
18681891 PyObject * const * args , size_t argcount ,
18691892 PyObject * kwnames )
18701893{
1894+ size_t total_args = argcount ;
1895+ if (kwnames ) {
1896+ total_args += PyTuple_GET_SIZE (kwnames );
1897+ }
1898+ _PyStackRef * arguments ;
1899+ if (total_args <= 8 ) {
1900+ _PyStackRef stack_array [8 ];
1901+ arguments = stack_array ;
1902+ }
1903+ else {
1904+ arguments = PyMem_Malloc (sizeof (_PyStackRef ) * total_args );
1905+ if (arguments == NULL ) {
1906+ return PyErr_NoMemory ();
1907+ }
1908+ }
18711909 /* _PyEvalFramePushAndInit consumes the references
18721910 * to func, locals and all its arguments */
18731911 Py_XINCREF (locals );
18741912 for (size_t i = 0 ; i < argcount ; i ++ ) {
1875- Py_INCREF (args [i ]);
1913+ arguments [ i ] = _PyStackRef_FromPyObjectNew (args [i ]);
18761914 }
18771915 if (kwnames ) {
18781916 Py_ssize_t kwcount = PyTuple_GET_SIZE (kwnames );
18791917 for (Py_ssize_t i = 0 ; i < kwcount ; i ++ ) {
1880- Py_INCREF (args [i + argcount ]);
1918+ arguments [ i + argcount ] = _PyStackRef_FromPyObjectNew (args [i + argcount ]);
18811919 }
18821920 }
18831921 _PyInterpreterFrame * frame = _PyEvalFramePushAndInit (
18841922 tstate , PyStackRef_FromPyObjectNew (func ), locals ,
1885- (_PyStackRef const * )args , argcount , kwnames , NULL );
1923+ arguments , argcount , kwnames , NULL );
1924+ if (total_args > 8 ) {
1925+ PyMem_Free (arguments );
1926+ }
18861927 if (frame == NULL ) {
18871928 return NULL ;
18881929 }
0 commit comments