@@ -101,7 +101,7 @@ static int get_exception_handler(PyCodeObject *, int, int*, int*, int*);
101
101
static InterpreterFrame *
102
102
_PyEvalFramePushAndInit (PyThreadState * tstate , PyFrameConstructor * con ,
103
103
PyObject * locals , PyObject * const * args ,
104
- size_t argcount , PyObject * kwnames , int steal_args );
104
+ size_t argcount , PyObject * kwnames );
105
105
static int
106
106
_PyEvalFrameClearAndPop (PyThreadState * tstate , InterpreterFrame * frame );
107
107
@@ -4646,7 +4646,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
4646
4646
InterpreterFrame * new_frame = _PyEvalFramePushAndInit (
4647
4647
tstate , PyFunction_AS_FRAME_CONSTRUCTOR (function ), locals ,
4648
4648
stack_pointer ,
4649
- nargs , kwnames , 1 );
4649
+ nargs , kwnames );
4650
4650
STACK_SHRINK (postcall_shrink );
4651
4651
// The frame has stolen all the arguments from the stack,
4652
4652
// so there is no need to clean them up.
@@ -4720,11 +4720,14 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
4720
4720
/* PEP 523 */
4721
4721
DEOPT_IF (tstate -> interp -> eval_frame != NULL , CALL_FUNCTION );
4722
4722
STAT_INC (CALL_FUNCTION , hit );
4723
- InterpreterFrame * new_frame = _PyThreadState_PushFrame (
4724
- tstate , PyFunction_AS_FRAME_CONSTRUCTOR (func ), NULL );
4723
+ PyCodeObject * code = (PyCodeObject * )func -> func_code ;
4724
+ size_t size = code -> co_nlocalsplus + code -> co_stacksize + FRAME_SPECIALS_SIZE ;
4725
+ InterpreterFrame * new_frame = _PyThreadState_BumpFramePointer (tstate , size );
4725
4726
if (new_frame == NULL ) {
4726
4727
goto error ;
4727
4728
}
4729
+ _PyFrame_InitializeSpecials (new_frame , PyFunction_AS_FRAME_CONSTRUCTOR (func ),
4730
+ NULL , code -> co_nlocalsplus );
4728
4731
STACK_SHRINK (argcount );
4729
4732
for (int i = 0 ; i < argcount ; i ++ ) {
4730
4733
new_frame -> localsplus [i ] = stack_pointer [i ];
@@ -4735,6 +4738,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
4735
4738
Py_INCREF (def );
4736
4739
new_frame -> localsplus [argcount + i ] = def ;
4737
4740
}
4741
+ for (int i = argcount + deflen ; i < code -> co_nlocalsplus ; i ++ ) {
4742
+ new_frame -> localsplus [i ] = NULL ;
4743
+ }
4738
4744
STACK_SHRINK (1 );
4739
4745
Py_DECREF (func );
4740
4746
_PyFrame_SetStackPointer (frame , stack_pointer );
@@ -5592,7 +5598,7 @@ get_exception_handler(PyCodeObject *code, int index, int *level, int *handler, i
5592
5598
static int
5593
5599
initialize_locals (PyThreadState * tstate , PyFrameConstructor * con ,
5594
5600
PyObject * * localsplus , PyObject * const * args ,
5595
- Py_ssize_t argcount , PyObject * kwnames , int steal_args )
5601
+ Py_ssize_t argcount , PyObject * kwnames )
5596
5602
{
5597
5603
PyCodeObject * co = (PyCodeObject * )con -> fc_code ;
5598
5604
const Py_ssize_t total_args = co -> co_argcount + co -> co_kwonlyargcount ;
@@ -5626,21 +5632,14 @@ initialize_locals(PyThreadState *tstate, PyFrameConstructor *con,
5626
5632
}
5627
5633
for (j = 0 ; j < n ; j ++ ) {
5628
5634
PyObject * x = args [j ];
5629
- if (!steal_args ) {
5630
- Py_INCREF (x );
5631
- }
5632
5635
assert (localsplus [j ] == NULL );
5633
5636
localsplus [j ] = x ;
5634
5637
}
5635
5638
5636
5639
/* Pack other positional arguments into the *args argument */
5637
5640
if (co -> co_flags & CO_VARARGS ) {
5638
5641
PyObject * u = NULL ;
5639
- if (steal_args ) {
5640
- u = _PyTuple_FromArraySteal (args + n , argcount - n );
5641
- } else {
5642
- u = _PyTuple_FromArray (args + n , argcount - n );
5643
- }
5642
+ u = _PyTuple_FromArraySteal (args + n , argcount - n );
5644
5643
if (u == NULL ) {
5645
5644
goto fail_post_positional ;
5646
5645
}
@@ -5649,10 +5648,8 @@ initialize_locals(PyThreadState *tstate, PyFrameConstructor *con,
5649
5648
}
5650
5649
else if (argcount > n ) {
5651
5650
/* Too many postional args. Error is reported later */
5652
- if (steal_args ) {
5653
- for (j = n ; j < argcount ; j ++ ) {
5654
- Py_DECREF (args [j ]);
5655
- }
5651
+ for (j = n ; j < argcount ; j ++ ) {
5652
+ Py_DECREF (args [j ]);
5656
5653
}
5657
5654
}
5658
5655
@@ -5714,19 +5711,15 @@ initialize_locals(PyThreadState *tstate, PyFrameConstructor *con,
5714
5711
if (PyDict_SetItem (kwdict , keyword , value ) == -1 ) {
5715
5712
goto kw_fail ;
5716
5713
}
5717
- if (steal_args ) {
5718
- Py_DECREF (value );
5719
- }
5714
+ Py_DECREF (value );
5720
5715
continue ;
5721
5716
5722
5717
kw_fail :
5723
- if (steal_args ) {
5724
- for (;i < kwcount ; i ++ ) {
5725
- PyObject * value = args [i + argcount ];
5726
- Py_DECREF (value );
5727
- }
5718
+ for (;i < kwcount ; i ++ ) {
5719
+ PyObject * value = args [i + argcount ];
5720
+ Py_DECREF (value );
5728
5721
}
5729
- goto fail_noclean ;
5722
+ goto fail_post_args ;
5730
5723
5731
5724
kw_found :
5732
5725
if (localsplus [j ] != NULL ) {
@@ -5735,9 +5728,6 @@ initialize_locals(PyThreadState *tstate, PyFrameConstructor *con,
5735
5728
con -> fc_qualname , keyword );
5736
5729
goto kw_fail ;
5737
5730
}
5738
- if (!steal_args ) {
5739
- Py_INCREF (value );
5740
- }
5741
5731
localsplus [j ] = value ;
5742
5732
}
5743
5733
}
@@ -5746,7 +5736,7 @@ initialize_locals(PyThreadState *tstate, PyFrameConstructor *con,
5746
5736
if ((argcount > co -> co_argcount ) && !(co -> co_flags & CO_VARARGS )) {
5747
5737
too_many_positional (tstate , co , argcount , con -> fc_defaults , localsplus ,
5748
5738
con -> fc_qualname );
5749
- goto fail_noclean ;
5739
+ goto fail_post_args ;
5750
5740
}
5751
5741
5752
5742
/* Add missing positional arguments (copy default values from defs) */
@@ -5762,7 +5752,7 @@ initialize_locals(PyThreadState *tstate, PyFrameConstructor *con,
5762
5752
if (missing ) {
5763
5753
missing_arguments (tstate , co , missing , defcount , localsplus ,
5764
5754
con -> fc_qualname );
5765
- goto fail_noclean ;
5755
+ goto fail_post_args ;
5766
5756
}
5767
5757
if (n > m )
5768
5758
i = n - m ;
@@ -5795,43 +5785,39 @@ initialize_locals(PyThreadState *tstate, PyFrameConstructor *con,
5795
5785
continue ;
5796
5786
}
5797
5787
else if (_PyErr_Occurred (tstate )) {
5798
- goto fail_noclean ;
5788
+ goto fail_post_args ;
5799
5789
}
5800
5790
}
5801
5791
missing ++ ;
5802
5792
}
5803
5793
if (missing ) {
5804
5794
missing_arguments (tstate , co , missing , -1 , localsplus ,
5805
5795
con -> fc_qualname );
5806
- goto fail_noclean ;
5796
+ goto fail_post_args ;
5807
5797
}
5808
5798
}
5809
-
5810
5799
/* Copy closure variables to free variables */
5811
5800
for (i = 0 ; i < co -> co_nfreevars ; ++ i ) {
5812
5801
PyObject * o = PyTuple_GET_ITEM (con -> fc_closure , i );
5813
5802
Py_INCREF (o );
5814
5803
localsplus [co -> co_nlocals + co -> co_nplaincellvars + i ] = o ;
5815
5804
}
5816
-
5817
5805
return 0 ;
5818
5806
5819
5807
fail_pre_positional :
5820
- if (steal_args ) {
5821
- for (j = 0 ; j < argcount ; j ++ ) {
5822
- Py_DECREF (args [j ]);
5823
- }
5808
+ for (j = 0 ; j < argcount ; j ++ ) {
5809
+ Py_DECREF (args [j ]);
5824
5810
}
5825
5811
/* fall through */
5826
5812
fail_post_positional :
5827
- if (steal_args ) {
5828
- Py_ssize_t kwcount = kwnames != NULL ? PyTuple_GET_SIZE (kwnames ) : 0 ;
5813
+ if (kwnames ) {
5814
+ Py_ssize_t kwcount = PyTuple_GET_SIZE (kwnames );
5829
5815
for (j = argcount ; j < argcount + kwcount ; j ++ ) {
5830
5816
Py_DECREF (args [j ]);
5831
5817
}
5832
5818
}
5833
5819
/* fall through */
5834
- fail_noclean :
5820
+ fail_post_args :
5835
5821
return -1 ;
5836
5822
}
5837
5823
@@ -5847,21 +5833,34 @@ make_coro_frame(PyThreadState *tstate,
5847
5833
int size = code -> co_nlocalsplus + code -> co_stacksize + FRAME_SPECIALS_SIZE ;
5848
5834
InterpreterFrame * frame = (InterpreterFrame * )PyMem_Malloc (sizeof (PyObject * )* size );
5849
5835
if (frame == NULL ) {
5850
- PyErr_NoMemory ();
5851
- return NULL ;
5836
+ goto fail ;
5852
5837
}
5853
- for (Py_ssize_t i = 0 ; i < code -> co_nlocalsplus ; i ++ ) {
5838
+ _PyFrame_InitializeSpecials (frame , con , locals , code -> co_nlocalsplus );
5839
+ for (int i = 0 ; i < code -> co_nlocalsplus ; i ++ ) {
5854
5840
frame -> localsplus [i ] = NULL ;
5855
5841
}
5856
- _PyFrame_InitializeSpecials (frame , con , locals , code -> co_nlocalsplus );
5857
5842
assert (frame -> frame_obj == NULL );
5858
- if (initialize_locals (tstate , con , frame -> localsplus , args , argcount , kwnames , 0 )) {
5843
+ if (initialize_locals (tstate , con , frame -> localsplus , args , argcount , kwnames )) {
5859
5844
_PyFrame_Clear (frame , 1 );
5860
5845
return NULL ;
5861
5846
}
5862
5847
return frame ;
5848
+ fail :
5849
+ /* Consume the references */
5850
+ for (Py_ssize_t i = 0 ; i < argcount ; i ++ ) {
5851
+ Py_DECREF (args [i ]);
5852
+ }
5853
+ if (kwnames ) {
5854
+ Py_ssize_t kwcount = PyTuple_GET_SIZE (kwnames );
5855
+ for (Py_ssize_t i = 0 ; i < kwcount ; i ++ ) {
5856
+ Py_DECREF (args [i + argcount ]);
5857
+ }
5858
+ }
5859
+ PyErr_NoMemory ();
5860
+ return NULL ;
5863
5861
}
5864
5862
5863
+ /* Consumes all the references to the args */
5865
5864
static PyObject *
5866
5865
make_coro (PyThreadState * tstate , PyFrameConstructor * con ,
5867
5866
PyObject * locals ,
@@ -5877,30 +5876,46 @@ make_coro(PyThreadState *tstate, PyFrameConstructor *con,
5877
5876
if (gen == NULL ) {
5878
5877
return NULL ;
5879
5878
}
5880
-
5881
5879
return gen ;
5882
5880
}
5883
5881
5884
- // If *steal_args* is set, the function will steal the references to all the arguments.
5885
- // In case of error, the function returns null and if *steal_args* is set, the caller
5886
- // will still own all the arguments.
5882
+ /* Consumes all the references to the args */
5887
5883
static InterpreterFrame *
5888
5884
_PyEvalFramePushAndInit (PyThreadState * tstate , PyFrameConstructor * con ,
5889
5885
PyObject * locals , PyObject * const * args ,
5890
- size_t argcount , PyObject * kwnames , int steal_args )
5886
+ size_t argcount , PyObject * kwnames )
5891
5887
{
5892
- InterpreterFrame * frame = _PyThreadState_PushFrame (tstate , con , locals );
5888
+ PyCodeObject * code = (PyCodeObject * )con -> fc_code ;
5889
+ size_t size = code -> co_nlocalsplus + code -> co_stacksize + FRAME_SPECIALS_SIZE ;
5890
+ InterpreterFrame * frame = _PyThreadState_BumpFramePointer (tstate , size );
5893
5891
if (frame == NULL ) {
5894
- return NULL ;
5892
+ goto fail ;
5895
5893
}
5896
- PyObject * * localsarray = _PyFrame_GetLocalsArray (frame );
5897
- if (initialize_locals (tstate , con , localsarray , args , argcount , kwnames , steal_args )) {
5894
+ _PyFrame_InitializeSpecials (frame , con , locals , code -> co_nlocalsplus );
5895
+ PyObject * * localsarray = & frame -> localsplus [0 ];
5896
+ for (int i = 0 ; i < code -> co_nlocalsplus ; i ++ ) {
5897
+ localsarray [i ] = NULL ;
5898
+ }
5899
+ if (initialize_locals (tstate , con , localsarray , args , argcount , kwnames )) {
5898
5900
_PyFrame_Clear (frame , 0 );
5899
5901
return NULL ;
5900
5902
}
5901
5903
frame -> previous = tstate -> frame ;
5902
5904
tstate -> frame = frame ;
5903
5905
return frame ;
5906
+ fail :
5907
+ /* Consume the references */
5908
+ for (size_t i = 0 ; i < argcount ; i ++ ) {
5909
+ Py_DECREF (args [i ]);
5910
+ }
5911
+ if (kwnames ) {
5912
+ Py_ssize_t kwcount = PyTuple_GET_SIZE (kwnames );
5913
+ for (Py_ssize_t i = 0 ; i < kwcount ; i ++ ) {
5914
+ Py_DECREF (args [i + argcount ]);
5915
+ }
5916
+ }
5917
+ PyErr_NoMemory ();
5918
+ return NULL ;
5904
5919
}
5905
5920
5906
5921
static int
@@ -5925,13 +5940,25 @@ _PyEval_Vector(PyThreadState *tstate, PyFrameConstructor *con,
5925
5940
PyObject * kwnames )
5926
5941
{
5927
5942
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
+ }
5928
5955
int is_coro = code -> co_flags &
5929
5956
(CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR );
5930
5957
if (is_coro ) {
5931
5958
return make_coro (tstate , con , locals , args , argcount , kwnames );
5932
5959
}
5933
5960
InterpreterFrame * frame = _PyEvalFramePushAndInit (
5934
- tstate , con , locals , args , argcount , kwnames , 0 );
5961
+ tstate , con , locals , args , argcount , kwnames );
5935
5962
if (frame == NULL ) {
5936
5963
return NULL ;
5937
5964
}
0 commit comments