@@ -46,10 +46,10 @@ _Py_IDENTIFIER(__name__);
46
46
47
47
/* Forward declarations */
48
48
Py_LOCAL_INLINE (PyObject * ) call_function (
49
- PyThreadState * tstate , PyObject * * * pp_stack ,
49
+ PyThreadState * tstate , PyCodeAddressRange * , PyObject * * * pp_stack ,
50
50
Py_ssize_t oparg , PyObject * kwnames );
51
51
static PyObject * do_call_core (
52
- PyThreadState * tstate , PyObject * func ,
52
+ PyThreadState * tstate , PyCodeAddressRange * , PyObject * func ,
53
53
PyObject * callargs , PyObject * kwdict );
54
54
55
55
#ifdef LLTRACE
@@ -58,12 +58,15 @@ static int prtrace(PyThreadState *, PyObject *, const char *);
58
58
#endif
59
59
static int call_trace (Py_tracefunc , PyObject * ,
60
60
PyThreadState * , PyFrameObject * ,
61
+ PyCodeAddressRange * ,
61
62
int , PyObject * );
62
63
static int call_trace_protected (Py_tracefunc , PyObject * ,
63
64
PyThreadState * , PyFrameObject * ,
65
+ PyCodeAddressRange * ,
64
66
int , PyObject * );
65
67
static void call_exc_trace (Py_tracefunc , PyObject * ,
66
- PyThreadState * , PyFrameObject * );
68
+ PyThreadState * , PyFrameObject * ,
69
+ PyCodeAddressRange * );
67
70
static int maybe_call_line_trace (Py_tracefunc , PyObject * ,
68
71
PyThreadState * , PyFrameObject * ,
69
72
PyCodeAddressRange * , int * );
@@ -1380,6 +1383,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
1380
1383
}
1381
1384
1382
1385
tstate -> frame = f ;
1386
+ co = f -> f_code ;
1387
+ PyCodeAddressRange bounds ;
1388
+ _PyCode_InitAddressRange (co , & bounds );
1383
1389
1384
1390
if (tstate -> use_tracing ) {
1385
1391
if (tstate -> c_tracefunc != NULL ) {
@@ -1398,7 +1404,8 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
1398
1404
whenever an exception is detected. */
1399
1405
if (call_trace_protected (tstate -> c_tracefunc ,
1400
1406
tstate -> c_traceobj ,
1401
- tstate , f , PyTrace_CALL , Py_None )) {
1407
+ tstate , f , & bounds ,
1408
+ PyTrace_CALL , Py_None )) {
1402
1409
/* Trace function raised an error */
1403
1410
goto exit_eval_frame ;
1404
1411
}
@@ -1408,7 +1415,8 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
1408
1415
return itself and isn't called for "line" events */
1409
1416
if (call_trace_protected (tstate -> c_profilefunc ,
1410
1417
tstate -> c_profileobj ,
1411
- tstate , f , PyTrace_CALL , Py_None )) {
1418
+ tstate , f , & bounds ,
1419
+ PyTrace_CALL , Py_None )) {
1412
1420
/* Profile function raised an error */
1413
1421
goto exit_eval_frame ;
1414
1422
}
@@ -1418,9 +1426,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
1418
1426
if (PyDTrace_FUNCTION_ENTRY_ENABLED ())
1419
1427
dtrace_function_entry (f );
1420
1428
1421
- co = f -> f_code ;
1422
- PyCodeAddressRange bounds ;
1423
- _PyCode_InitAddressRange (co , & bounds );
1424
1429
int instr_prev = -1 ;
1425
1430
1426
1431
names = co -> co_names ;
@@ -2348,7 +2353,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
2348
2353
if (retval == NULL ) {
2349
2354
if (tstate -> c_tracefunc != NULL
2350
2355
&& _PyErr_ExceptionMatches (tstate , PyExc_StopIteration ))
2351
- call_exc_trace (tstate -> c_tracefunc , tstate -> c_traceobj , tstate , f );
2356
+ call_exc_trace (tstate -> c_tracefunc , tstate -> c_traceobj , tstate , f , & bounds );
2352
2357
if (_PyGen_FetchStopIterationValue (& retval ) == 0 ) {
2353
2358
gen_status = PYGEN_RETURN ;
2354
2359
}
@@ -3596,7 +3601,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
3596
3601
goto error ;
3597
3602
}
3598
3603
else if (tstate -> c_tracefunc != NULL ) {
3599
- call_exc_trace (tstate -> c_tracefunc , tstate -> c_traceobj , tstate , f );
3604
+ call_exc_trace (tstate -> c_tracefunc , tstate -> c_traceobj , tstate , f , & bounds );
3600
3605
}
3601
3606
_PyErr_Clear (tstate );
3602
3607
}
@@ -3764,7 +3769,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
3764
3769
`callable` will be POPed by call_function.
3765
3770
NULL will will be POPed manually later.
3766
3771
*/
3767
- res = call_function (tstate , & sp , oparg , NULL );
3772
+ res = call_function (tstate , & bounds , & sp , oparg , NULL );
3768
3773
stack_pointer = sp ;
3769
3774
(void )POP (); /* POP the NULL. */
3770
3775
}
@@ -3781,7 +3786,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
3781
3786
We'll be passing `oparg + 1` to call_function, to
3782
3787
make it accept the `self` as a first argument.
3783
3788
*/
3784
- res = call_function (tstate , & sp , oparg + 1 , NULL );
3789
+ res = call_function (tstate , & bounds , & sp , oparg + 1 , NULL );
3785
3790
stack_pointer = sp ;
3786
3791
}
3787
3792
@@ -3795,7 +3800,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
3795
3800
PREDICTED (CALL_FUNCTION );
3796
3801
PyObject * * sp , * res ;
3797
3802
sp = stack_pointer ;
3798
- res = call_function (tstate , & sp , oparg , NULL );
3803
+ res = call_function (tstate , & bounds , & sp , oparg , NULL );
3799
3804
stack_pointer = sp ;
3800
3805
PUSH (res );
3801
3806
if (res == NULL ) {
@@ -3812,7 +3817,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
3812
3817
assert (PyTuple_GET_SIZE (names ) <= oparg );
3813
3818
/* We assume without checking that names contains only strings */
3814
3819
sp = stack_pointer ;
3815
- res = call_function (tstate , & sp , oparg , names );
3820
+ res = call_function (tstate , & bounds , & sp , oparg , names );
3816
3821
stack_pointer = sp ;
3817
3822
PUSH (res );
3818
3823
Py_DECREF (names );
@@ -3857,7 +3862,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
3857
3862
}
3858
3863
assert (PyTuple_CheckExact (callargs ));
3859
3864
3860
- result = do_call_core (tstate , func , callargs , kwargs );
3865
+ result = do_call_core (tstate , & bounds , func , callargs , kwargs );
3861
3866
Py_DECREF (func );
3862
3867
Py_DECREF (callargs );
3863
3868
Py_XDECREF (kwargs );
@@ -4024,7 +4029,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
4024
4029
assert (f -> f_state == FRAME_EXECUTING );
4025
4030
f -> f_state = FRAME_UNWINDING ;
4026
4031
call_exc_trace (tstate -> c_tracefunc , tstate -> c_traceobj ,
4027
- tstate , f );
4032
+ tstate , f , & bounds );
4028
4033
}
4029
4034
exception_unwind :
4030
4035
f -> f_state = FRAME_UNWINDING ;
@@ -4102,13 +4107,13 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
4102
4107
if (tstate -> use_tracing ) {
4103
4108
if (tstate -> c_tracefunc ) {
4104
4109
if (call_trace_protected (tstate -> c_tracefunc , tstate -> c_traceobj ,
4105
- tstate , f , PyTrace_RETURN , retval )) {
4110
+ tstate , f , & bounds , PyTrace_RETURN , retval )) {
4106
4111
Py_CLEAR (retval );
4107
4112
}
4108
4113
}
4109
4114
if (tstate -> c_profilefunc ) {
4110
4115
if (call_trace_protected (tstate -> c_profilefunc , tstate -> c_profileobj ,
4111
- tstate , f , PyTrace_RETURN , retval )) {
4116
+ tstate , f , & bounds , PyTrace_RETURN , retval )) {
4112
4117
Py_CLEAR (retval );
4113
4118
}
4114
4119
}
@@ -4902,7 +4907,9 @@ prtrace(PyThreadState *tstate, PyObject *v, const char *str)
4902
4907
4903
4908
static void
4904
4909
call_exc_trace (Py_tracefunc func , PyObject * self ,
4905
- PyThreadState * tstate , PyFrameObject * f )
4910
+ PyThreadState * tstate ,
4911
+ PyFrameObject * f ,
4912
+ PyCodeAddressRange * bounds )
4906
4913
{
4907
4914
PyObject * type , * value , * traceback , * orig_traceback , * arg ;
4908
4915
int err ;
@@ -4918,7 +4925,7 @@ call_exc_trace(Py_tracefunc func, PyObject *self,
4918
4925
_PyErr_Restore (tstate , type , value , orig_traceback );
4919
4926
return ;
4920
4927
}
4921
- err = call_trace (func , self , tstate , f , PyTrace_EXCEPTION , arg );
4928
+ err = call_trace (func , self , tstate , f , bounds , PyTrace_EXCEPTION , arg );
4922
4929
Py_DECREF (arg );
4923
4930
if (err == 0 ) {
4924
4931
_PyErr_Restore (tstate , type , value , orig_traceback );
@@ -4933,12 +4940,13 @@ call_exc_trace(Py_tracefunc func, PyObject *self,
4933
4940
static int
4934
4941
call_trace_protected (Py_tracefunc func , PyObject * obj ,
4935
4942
PyThreadState * tstate , PyFrameObject * frame ,
4943
+ PyCodeAddressRange * bounds ,
4936
4944
int what , PyObject * arg )
4937
4945
{
4938
4946
PyObject * type , * value , * traceback ;
4939
4947
int err ;
4940
4948
_PyErr_Fetch (tstate , & type , & value , & traceback );
4941
- err = call_trace (func , obj , tstate , frame , what , arg );
4949
+ err = call_trace (func , obj , tstate , frame , bounds , what , arg );
4942
4950
if (err == 0 )
4943
4951
{
4944
4952
_PyErr_Restore (tstate , type , value , traceback );
@@ -4955,14 +4963,22 @@ call_trace_protected(Py_tracefunc func, PyObject *obj,
4955
4963
static int
4956
4964
call_trace (Py_tracefunc func , PyObject * obj ,
4957
4965
PyThreadState * tstate , PyFrameObject * frame ,
4966
+ PyCodeAddressRange * bounds ,
4958
4967
int what , PyObject * arg )
4959
4968
{
4960
4969
int result ;
4961
4970
if (tstate -> tracing )
4962
4971
return 0 ;
4963
4972
tstate -> tracing ++ ;
4964
4973
tstate -> use_tracing = 0 ;
4974
+ if (frame -> f_lasti < 0 ) {
4975
+ frame -> f_lineno = frame -> f_code -> co_firstlineno ;
4976
+ }
4977
+ else {
4978
+ frame -> f_lineno = _PyCode_CheckLineNumber (frame -> f_lasti , bounds );
4979
+ }
4965
4980
result = func (obj , frame , what , arg );
4981
+ frame -> f_lineno = 0 ;
4966
4982
tstate -> use_tracing = ((tstate -> c_tracefunc != NULL )
4967
4983
|| (tstate -> c_profilefunc != NULL ));
4968
4984
tstate -> tracing -- ;
@@ -5005,16 +5021,12 @@ maybe_call_line_trace(Py_tracefunc func, PyObject *obj,
5005
5021
if (frame -> f_lasti < * instr_prev ||
5006
5022
(line != lastline && frame -> f_lasti == bounds -> ar_start ))
5007
5023
{
5008
- frame -> f_lineno = line ;
5009
- result = call_trace (func , obj , tstate , frame , PyTrace_LINE , Py_None );
5010
- frame -> f_lineno = 0 ;
5024
+ result = call_trace (func , obj , tstate , frame , bounds , PyTrace_LINE , Py_None );
5011
5025
}
5012
5026
}
5013
5027
/* Always emit an opcode event if we're tracing all opcodes. */
5014
5028
if (frame -> f_trace_opcodes ) {
5015
- frame -> f_lineno = _PyCode_CheckLineNumber (frame -> f_lasti , bounds );
5016
- result = call_trace (func , obj , tstate , frame , PyTrace_OPCODE , Py_None );
5017
- frame -> f_lineno = 0 ;
5029
+ result = call_trace (func , obj , tstate , frame , bounds , PyTrace_OPCODE , Py_None );
5018
5030
}
5019
5031
* instr_prev = frame -> f_lasti ;
5020
5032
return result ;
@@ -5281,7 +5293,7 @@ PyEval_GetFuncDesc(PyObject *func)
5281
5293
#define C_TRACE (x , call ) \
5282
5294
if (tstate->use_tracing && tstate->c_profilefunc) { \
5283
5295
if (call_trace(tstate->c_profilefunc, tstate->c_profileobj, \
5284
- tstate, tstate->frame, \
5296
+ tstate, tstate->frame, bounds, \
5285
5297
PyTrace_C_CALL, func)) { \
5286
5298
x = NULL; \
5287
5299
} \
@@ -5291,13 +5303,13 @@ if (tstate->use_tracing && tstate->c_profilefunc) { \
5291
5303
if (x == NULL) { \
5292
5304
call_trace_protected(tstate->c_profilefunc, \
5293
5305
tstate->c_profileobj, \
5294
- tstate, tstate->frame, \
5306
+ tstate, tstate->frame, bounds, \
5295
5307
PyTrace_C_EXCEPTION, func); \
5296
5308
/* XXX should pass (type, value, tb) */ \
5297
5309
} else { \
5298
5310
if (call_trace (tstate -> c_profilefunc , \
5299
5311
tstate -> c_profileobj , \
5300
- tstate , tstate -> frame , \
5312
+ tstate , tstate -> frame , bounds , \
5301
5313
PyTrace_C_RETURN , func )) { \
5302
5314
Py_DECREF (x ); \
5303
5315
x = NULL ; \
@@ -5312,6 +5324,7 @@ if (tstate->use_tracing && tstate->c_profilefunc) { \
5312
5324
5313
5325
static PyObject *
5314
5326
trace_call_function (PyThreadState * tstate ,
5327
+ PyCodeAddressRange * bounds ,
5315
5328
PyObject * func ,
5316
5329
PyObject * * args , Py_ssize_t nargs ,
5317
5330
PyObject * kwnames )
@@ -5346,7 +5359,11 @@ trace_call_function(PyThreadState *tstate,
5346
5359
/* Issue #29227: Inline call_function() into _PyEval_EvalFrameDefault()
5347
5360
to reduce the stack consumption. */
5348
5361
Py_LOCAL_INLINE (PyObject * ) _Py_HOT_FUNCTION
5349
- call_function (PyThreadState * tstate , PyObject * * * pp_stack , Py_ssize_t oparg , PyObject * kwnames )
5362
+ call_function (PyThreadState * tstate ,
5363
+ PyCodeAddressRange * bounds ,
5364
+ PyObject * * * pp_stack ,
5365
+ Py_ssize_t oparg ,
5366
+ PyObject * kwnames )
5350
5367
{
5351
5368
PyObject * * pfunc = (* pp_stack ) - oparg - 1 ;
5352
5369
PyObject * func = * pfunc ;
@@ -5356,7 +5373,7 @@ call_function(PyThreadState *tstate, PyObject ***pp_stack, Py_ssize_t oparg, PyO
5356
5373
PyObject * * stack = (* pp_stack ) - nargs - nkwargs ;
5357
5374
5358
5375
if (tstate -> use_tracing ) {
5359
- x = trace_call_function (tstate , func , stack , nargs , kwnames );
5376
+ x = trace_call_function (tstate , bounds , func , stack , nargs , kwnames );
5360
5377
}
5361
5378
else {
5362
5379
x = PyObject_Vectorcall (func , stack , nargs | PY_VECTORCALL_ARGUMENTS_OFFSET , kwnames );
@@ -5374,7 +5391,11 @@ call_function(PyThreadState *tstate, PyObject ***pp_stack, Py_ssize_t oparg, PyO
5374
5391
}
5375
5392
5376
5393
static PyObject *
5377
- do_call_core (PyThreadState * tstate , PyObject * func , PyObject * callargs , PyObject * kwdict )
5394
+ do_call_core (PyThreadState * tstate ,
5395
+ PyCodeAddressRange * bounds ,
5396
+ PyObject * func ,
5397
+ PyObject * callargs ,
5398
+ PyObject * kwdict )
5378
5399
{
5379
5400
PyObject * result ;
5380
5401
0 commit comments