@@ -212,6 +212,9 @@ static _PyInterpreterFrame *
212212_PyEvalFramePushAndInit (PyThreadState * tstate , PyFunctionObject * func ,
213213 PyObject * locals , PyObject * const * args ,
214214 size_t argcount , PyObject * kwnames );
215+ static _PyInterpreterFrame *
216+ _PyEvalFramePushAndInit_Ex (PyThreadState * tstate , PyFunctionObject * func ,
217+ PyObject * locals , Py_ssize_t nargs , PyObject * callargs , PyObject * kwargs );
215218static void
216219_PyEvalFrameClearAndPop (PyThreadState * tstate , _PyInterpreterFrame * frame );
217220
@@ -1501,6 +1504,49 @@ _PyEvalFramePushAndInit(PyThreadState *tstate, PyFunctionObject *func,
15011504 return NULL ;
15021505}
15031506
1507+ /* Same as _PyEvalFramePushAndInit but takes an args tuple and kwargs dict.
1508+ Steals references to func, callargs and kwargs.
1509+ */
1510+ static _PyInterpreterFrame *
1511+ _PyEvalFramePushAndInit_Ex (PyThreadState * tstate , PyFunctionObject * func ,
1512+ PyObject * locals , Py_ssize_t nargs , PyObject * callargs , PyObject * kwargs )
1513+ {
1514+ bool has_dict = (kwargs != NULL && PyDict_GET_SIZE (kwargs ) > 0 );
1515+ PyObject * kwnames = NULL ;
1516+ PyObject * const * newargs ;
1517+ if (has_dict ) {
1518+ newargs = _PyStack_UnpackDict (tstate , _PyTuple_ITEMS (callargs ), nargs , kwargs , & kwnames );
1519+ if (newargs == NULL ) {
1520+ Py_DECREF (func );
1521+ goto error ;
1522+ }
1523+ }
1524+ else {
1525+ newargs = & PyTuple_GET_ITEM (callargs , 0 );
1526+ /* We need to incref all our args since the new frame steals the references. */
1527+ for (Py_ssize_t i = 0 ; i < nargs ; ++ i ) {
1528+ Py_INCREF (PyTuple_GET_ITEM (callargs , i ));
1529+ }
1530+ }
1531+ _PyInterpreterFrame * new_frame = _PyEvalFramePushAndInit (
1532+ tstate , (PyFunctionObject * )func , locals ,
1533+ newargs , nargs , kwnames
1534+ );
1535+ if (has_dict ) {
1536+ _PyStack_UnpackDict_FreeNoDecRef (newargs , kwnames );
1537+ }
1538+ /* No need to decref func here because the reference has been stolen by
1539+ _PyEvalFramePushAndInit.
1540+ */
1541+ Py_DECREF (callargs );
1542+ Py_XDECREF (kwargs );
1543+ return new_frame ;
1544+ error :
1545+ Py_DECREF (callargs );
1546+ Py_XDECREF (kwargs );
1547+ return NULL ;
1548+ }
1549+
15041550PyObject *
15051551_PyEval_Vector (PyThreadState * tstate , PyFunctionObject * func ,
15061552 PyObject * locals ,
0 commit comments