@@ -101,7 +101,7 @@ static int get_exception_handler(PyCodeObject *, int, int*, int*, int*);
101101static InterpreterFrame *
102102_PyEvalFramePushAndInit (PyThreadState * tstate , PyFrameConstructor * con ,
103103 PyObject * locals , PyObject * const * args ,
104- size_t argcount , PyObject * kwnames , int steal_args );
104+ size_t argcount , PyObject * kwnames );
105105static int
106106_PyEvalFrameClearAndPop (PyThreadState * tstate , InterpreterFrame * frame );
107107
@@ -4633,7 +4633,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
46334633 InterpreterFrame * new_frame = _PyEvalFramePushAndInit (
46344634 tstate , PyFunction_AS_FRAME_CONSTRUCTOR (function ), locals ,
46354635 stack_pointer ,
4636- nargs , kwnames , 1 );
4636+ nargs , kwnames );
46374637 STACK_SHRINK (postcall_shrink );
46384638 // The frame has stolen all the arguments from the stack,
46394639 // so there is no need to clean them up.
@@ -4708,11 +4708,14 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
47084708 /* PEP 523 */
47094709 DEOPT_IF (tstate -> interp -> eval_frame != NULL , CALL_FUNCTION );
47104710 STAT_INC (CALL_FUNCTION , hit );
4711- InterpreterFrame * new_frame = _PyThreadState_PushFrame (
4712- tstate , PyFunction_AS_FRAME_CONSTRUCTOR (func ), NULL );
4711+ PyCodeObject * code = (PyCodeObject * )func -> func_code ;
4712+ size_t size = code -> co_nlocalsplus + code -> co_stacksize + FRAME_SPECIALS_SIZE ;
4713+ InterpreterFrame * new_frame = _PyThreadState_BumpFramePointer (tstate , size );
47134714 if (new_frame == NULL ) {
47144715 goto error ;
47154716 }
4717+ _PyFrame_InitializeSpecials (new_frame , PyFunction_AS_FRAME_CONSTRUCTOR (func ),
4718+ NULL , code -> co_nlocalsplus );
47164719 STACK_SHRINK (argcount );
47174720 for (int i = 0 ; i < argcount ; i ++ ) {
47184721 new_frame -> localsplus [i ] = stack_pointer [i ];
@@ -4723,6 +4726,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
47234726 Py_INCREF (def );
47244727 new_frame -> localsplus [argcount + i ] = def ;
47254728 }
4729+ for (int i = argcount + deflen ; i < code -> co_nlocalsplus ; i ++ ) {
4730+ new_frame -> localsplus [i ] = NULL ;
4731+ }
47264732 STACK_SHRINK (1 );
47274733 Py_DECREF (func );
47284734 _PyFrame_SetStackPointer (frame , stack_pointer );
@@ -5595,7 +5601,7 @@ get_exception_handler(PyCodeObject *code, int index, int *level, int *handler, i
55955601static int
55965602initialize_locals (PyThreadState * tstate , PyFrameConstructor * con ,
55975603 PyObject * * localsplus , PyObject * const * args ,
5598- Py_ssize_t argcount , PyObject * kwnames , int steal_args )
5604+ Py_ssize_t argcount , PyObject * kwnames )
55995605{
56005606 PyCodeObject * co = (PyCodeObject * )con -> fc_code ;
56015607 const Py_ssize_t total_args = co -> co_argcount + co -> co_kwonlyargcount ;
@@ -5629,21 +5635,14 @@ initialize_locals(PyThreadState *tstate, PyFrameConstructor *con,
56295635 }
56305636 for (j = 0 ; j < n ; j ++ ) {
56315637 PyObject * x = args [j ];
5632- if (!steal_args ) {
5633- Py_INCREF (x );
5634- }
56355638 assert (localsplus [j ] == NULL );
56365639 localsplus [j ] = x ;
56375640 }
56385641
56395642 /* Pack other positional arguments into the *args argument */
56405643 if (co -> co_flags & CO_VARARGS ) {
56415644 PyObject * u = NULL ;
5642- if (steal_args ) {
5643- u = _PyTuple_FromArraySteal (args + n , argcount - n );
5644- } else {
5645- u = _PyTuple_FromArray (args + n , argcount - n );
5646- }
5645+ u = _PyTuple_FromArraySteal (args + n , argcount - n );
56475646 if (u == NULL ) {
56485647 goto fail_post_positional ;
56495648 }
@@ -5652,10 +5651,8 @@ initialize_locals(PyThreadState *tstate, PyFrameConstructor *con,
56525651 }
56535652 else if (argcount > n ) {
56545653 /* Too many postional args. Error is reported later */
5655- if (steal_args ) {
5656- for (j = n ; j < argcount ; j ++ ) {
5657- Py_DECREF (args [j ]);
5658- }
5654+ for (j = n ; j < argcount ; j ++ ) {
5655+ Py_DECREF (args [j ]);
56595656 }
56605657 }
56615658
@@ -5717,19 +5714,15 @@ initialize_locals(PyThreadState *tstate, PyFrameConstructor *con,
57175714 if (PyDict_SetItem (kwdict , keyword , value ) == -1 ) {
57185715 goto kw_fail ;
57195716 }
5720- if (steal_args ) {
5721- Py_DECREF (value );
5722- }
5717+ Py_DECREF (value );
57235718 continue ;
57245719
57255720 kw_fail :
5726- if (steal_args ) {
5727- for (;i < kwcount ; i ++ ) {
5728- PyObject * value = args [i + argcount ];
5729- Py_DECREF (value );
5730- }
5721+ for (;i < kwcount ; i ++ ) {
5722+ PyObject * value = args [i + argcount ];
5723+ Py_DECREF (value );
57315724 }
5732- goto fail_noclean ;
5725+ goto fail_post_args ;
57335726
57345727 kw_found :
57355728 if (localsplus [j ] != NULL ) {
@@ -5738,9 +5731,6 @@ initialize_locals(PyThreadState *tstate, PyFrameConstructor *con,
57385731 con -> fc_qualname , keyword );
57395732 goto kw_fail ;
57405733 }
5741- if (!steal_args ) {
5742- Py_INCREF (value );
5743- }
57445734 localsplus [j ] = value ;
57455735 }
57465736 }
@@ -5749,7 +5739,7 @@ initialize_locals(PyThreadState *tstate, PyFrameConstructor *con,
57495739 if ((argcount > co -> co_argcount ) && !(co -> co_flags & CO_VARARGS )) {
57505740 too_many_positional (tstate , co , argcount , con -> fc_defaults , localsplus ,
57515741 con -> fc_qualname );
5752- goto fail_noclean ;
5742+ goto fail_post_args ;
57535743 }
57545744
57555745 /* Add missing positional arguments (copy default values from defs) */
@@ -5765,7 +5755,7 @@ initialize_locals(PyThreadState *tstate, PyFrameConstructor *con,
57655755 if (missing ) {
57665756 missing_arguments (tstate , co , missing , defcount , localsplus ,
57675757 con -> fc_qualname );
5768- goto fail_noclean ;
5758+ goto fail_post_args ;
57695759 }
57705760 if (n > m )
57715761 i = n - m ;
@@ -5798,43 +5788,39 @@ initialize_locals(PyThreadState *tstate, PyFrameConstructor *con,
57985788 continue ;
57995789 }
58005790 else if (_PyErr_Occurred (tstate )) {
5801- goto fail_noclean ;
5791+ goto fail_post_args ;
58025792 }
58035793 }
58045794 missing ++ ;
58055795 }
58065796 if (missing ) {
58075797 missing_arguments (tstate , co , missing , -1 , localsplus ,
58085798 con -> fc_qualname );
5809- goto fail_noclean ;
5799+ goto fail_post_args ;
58105800 }
58115801 }
5812-
58135802 /* Copy closure variables to free variables */
58145803 for (i = 0 ; i < co -> co_nfreevars ; ++ i ) {
58155804 PyObject * o = PyTuple_GET_ITEM (con -> fc_closure , i );
58165805 Py_INCREF (o );
58175806 localsplus [co -> co_nlocals + co -> co_nplaincellvars + i ] = o ;
58185807 }
5819-
58205808 return 0 ;
58215809
58225810fail_pre_positional :
5823- if (steal_args ) {
5824- for (j = 0 ; j < argcount ; j ++ ) {
5825- Py_DECREF (args [j ]);
5826- }
5811+ for (j = 0 ; j < argcount ; j ++ ) {
5812+ Py_DECREF (args [j ]);
58275813 }
58285814 /* fall through */
58295815fail_post_positional :
5830- if (steal_args ) {
5831- Py_ssize_t kwcount = kwnames != NULL ? PyTuple_GET_SIZE (kwnames ) : 0 ;
5816+ if (kwnames ) {
5817+ Py_ssize_t kwcount = PyTuple_GET_SIZE (kwnames );
58325818 for (j = argcount ; j < argcount + kwcount ; j ++ ) {
58335819 Py_DECREF (args [j ]);
58345820 }
58355821 }
58365822 /* fall through */
5837- fail_noclean :
5823+ fail_post_args :
58385824 return -1 ;
58395825}
58405826
@@ -5850,21 +5836,34 @@ make_coro_frame(PyThreadState *tstate,
58505836 int size = code -> co_nlocalsplus + code -> co_stacksize + FRAME_SPECIALS_SIZE ;
58515837 InterpreterFrame * frame = (InterpreterFrame * )PyMem_Malloc (sizeof (PyObject * )* size );
58525838 if (frame == NULL ) {
5853- PyErr_NoMemory ();
5854- return NULL ;
5839+ goto fail_no_memory ;
58555840 }
5856- for (Py_ssize_t i = 0 ; i < code -> co_nlocalsplus ; i ++ ) {
5841+ _PyFrame_InitializeSpecials (frame , con , locals , code -> co_nlocalsplus );
5842+ for (int i = 0 ; i < code -> co_nlocalsplus ; i ++ ) {
58575843 frame -> localsplus [i ] = NULL ;
58585844 }
5859- _PyFrame_InitializeSpecials (frame , con , locals , code -> co_nlocalsplus );
58605845 assert (frame -> frame_obj == NULL );
5861- if (initialize_locals (tstate , con , frame -> localsplus , args , argcount , kwnames , 0 )) {
5846+ if (initialize_locals (tstate , con , frame -> localsplus , args , argcount , kwnames )) {
58625847 _PyFrame_Clear (frame , 1 );
58635848 return NULL ;
58645849 }
58655850 return frame ;
5851+ fail_no_memory :
5852+ /* Consume the references */
5853+ for (Py_ssize_t i = 0 ; i < argcount ; i ++ ) {
5854+ Py_DECREF (args [i ]);
5855+ }
5856+ if (kwnames ) {
5857+ Py_ssize_t kwcount = PyTuple_GET_SIZE (kwnames );
5858+ for (Py_ssize_t i = 0 ; i < kwcount ; i ++ ) {
5859+ Py_DECREF (args [i + argcount ]);
5860+ }
5861+ }
5862+ PyErr_NoMemory ();
5863+ return NULL ;
58665864}
58675865
5866+ /* Consumes all the references to the args */
58685867static PyObject *
58695868make_coro (PyThreadState * tstate , PyFrameConstructor * con ,
58705869 PyObject * locals ,
@@ -5880,28 +5879,44 @@ make_coro(PyThreadState *tstate, PyFrameConstructor *con,
58805879 if (gen == NULL ) {
58815880 return NULL ;
58825881 }
5883-
58845882 return gen ;
58855883}
58865884
5887- // If *steal_args* is set, the function will steal the references to all the arguments.
5888- // In case of error, the function returns null and if *steal_args* is set, the caller
5889- // will still own all the arguments.
5885+ /* Consumes all the references to the args */
58905886static InterpreterFrame *
58915887_PyEvalFramePushAndInit (PyThreadState * tstate , PyFrameConstructor * con ,
58925888 PyObject * locals , PyObject * const * args ,
5893- size_t argcount , PyObject * kwnames , int steal_args )
5889+ size_t argcount , PyObject * kwnames )
58945890{
5895- InterpreterFrame * frame = _PyThreadState_PushFrame (tstate , con , locals );
5891+ PyCodeObject * code = (PyCodeObject * )con -> fc_code ;
5892+ size_t size = code -> co_nlocalsplus + code -> co_stacksize + FRAME_SPECIALS_SIZE ;
5893+ InterpreterFrame * frame = _PyThreadState_BumpFramePointer (tstate , size );
58965894 if (frame == NULL ) {
5897- return NULL ;
5895+ goto fail ;
58985896 }
5899- PyObject * * localsarray = _PyFrame_GetLocalsArray (frame );
5900- if (initialize_locals (tstate , con , localsarray , args , argcount , kwnames , steal_args )) {
5897+ _PyFrame_InitializeSpecials (frame , con , locals , code -> co_nlocalsplus );
5898+ PyObject * * localsarray = & frame -> localsplus [0 ];
5899+ for (int i = 0 ; i < code -> co_nlocalsplus ; i ++ ) {
5900+ localsarray [i ] = NULL ;
5901+ }
5902+ if (initialize_locals (tstate , con , localsarray , args , argcount , kwnames )) {
59015903 _PyFrame_Clear (frame , 0 );
59025904 return NULL ;
59035905 }
59045906 return frame ;
5907+ fail :
5908+ /* Consume the references */
5909+ for (size_t i = 0 ; i < argcount ; i ++ ) {
5910+ Py_DECREF (args [i ]);
5911+ }
5912+ if (kwnames ) {
5913+ Py_ssize_t kwcount = PyTuple_GET_SIZE (kwnames );
5914+ for (Py_ssize_t i = 0 ; i < kwcount ; i ++ ) {
5915+ Py_DECREF (args [i + argcount ]);
5916+ }
5917+ }
5918+ PyErr_NoMemory ();
5919+ return NULL ;
59055920}
59065921
59075922static int
@@ -5925,13 +5940,25 @@ _PyEval_Vector(PyThreadState *tstate, PyFrameConstructor *con,
59255940 PyObject * kwnames )
59265941{
59275942 PyCodeObject * code = (PyCodeObject * )con -> fc_code ;
5943+ /* _PyEvalFramePushAndInit and make_coro consume
5944+ * all the references to their arguments
5945+ */
5946+ for (size_t i = 0 ; i < argcount ; i ++ ) {
5947+ Py_INCREF (args [i ]);
5948+ }
5949+ if (kwnames ) {
5950+ Py_ssize_t kwcount = PyTuple_GET_SIZE (kwnames );
5951+ for (Py_ssize_t i = 0 ; i < kwcount ; i ++ ) {
5952+ Py_INCREF (args [i + argcount ]);
5953+ }
5954+ }
59285955 int is_coro = code -> co_flags &
59295956 (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR );
59305957 if (is_coro ) {
59315958 return make_coro (tstate , con , locals , args , argcount , kwnames );
59325959 }
59335960 InterpreterFrame * frame = _PyEvalFramePushAndInit (
5934- tstate , con , locals , args , argcount , kwnames , 0 );
5961+ tstate , con , locals , args , argcount , kwnames );
59355962 if (frame == NULL ) {
59365963 return NULL ;
59375964 }
0 commit comments