@@ -1392,6 +1392,45 @@ eval_frame_handle_pending(PyThreadState *tstate)
13921392#define BUILTINS () frame->f_builtins
13931393#define LOCALS () frame->f_locals
13941394
1395+ static int
1396+ trace_function_entry (PyThreadState * tstate , InterpreterFrame * frame )
1397+ {
1398+ if (tstate -> c_tracefunc != NULL ) {
1399+ /* tstate->c_tracefunc, if defined, is a
1400+ function that will be called on *every* entry
1401+ to a code block. Its return value, if not
1402+ None, is a function that will be called at
1403+ the start of each executed line of code.
1404+ (Actually, the function must return itself
1405+ in order to continue tracing.) The trace
1406+ functions are called with three arguments:
1407+ a pointer to the current frame, a string
1408+ indicating why the function is called, and
1409+ an argument which depends on the situation.
1410+ The global trace function is also called
1411+ whenever an exception is detected. */
1412+ if (call_trace_protected (tstate -> c_tracefunc ,
1413+ tstate -> c_traceobj ,
1414+ tstate , frame ,
1415+ PyTrace_CALL , Py_None )) {
1416+ /* Trace function raised an error */
1417+ return -1 ;
1418+ }
1419+ }
1420+ if (tstate -> c_profilefunc != NULL ) {
1421+ /* Similar for c_profilefunc, except it needn't
1422+ return itself and isn't called for "line" events */
1423+ if (call_trace_protected (tstate -> c_profilefunc ,
1424+ tstate -> c_profileobj ,
1425+ tstate , frame ,
1426+ PyTrace_CALL , Py_None )) {
1427+ /* Profile function raised an error */
1428+ return -1 ;
1429+ }
1430+ }
1431+ return 0 ;
1432+ }
1433+
13951434PyObject * _Py_HOT_FUNCTION
13961435_PyEval_EvalFrameDefault (PyThreadState * tstate , InterpreterFrame * frame , int throwflag )
13971436{
@@ -1405,22 +1444,10 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
14051444#ifdef DXPAIRS
14061445 int lastopcode = 0 ;
14071446#endif
1408- PyObject * * stack_pointer ; /* Next free slot in value stack */
1409- _Py_CODEUNIT * next_instr ;
14101447 int opcode ; /* Current opcode */
14111448 int oparg ; /* Current opcode argument, if any */
1412- PyObject * * localsplus ;
14131449 PyObject * retval = NULL ; /* Return value */
14141450 _Py_atomic_int * const eval_breaker = & tstate -> interp -> ceval .eval_breaker ;
1415- PyCodeObject * co ;
1416-
1417- _Py_CODEUNIT * first_instr ;
1418- PyObject * names ;
1419- PyObject * consts ;
1420-
1421- #ifdef LLTRACE
1422- _Py_IDENTIFIER (__ltrace__ );
1423- #endif
14241451
14251452 if (_Py_EnterRecursiveCall (tstate , "" )) {
14261453 return NULL ;
@@ -1439,47 +1466,17 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
14391466
14401467 /* push frame */
14411468 tstate -> frame = frame ;
1442- co = frame -> f_code ;
14431469
14441470 if (cframe .use_tracing ) {
1445- if (tstate -> c_tracefunc != NULL ) {
1446- /* tstate->c_tracefunc, if defined, is a
1447- function that will be called on *every* entry
1448- to a code block. Its return value, if not
1449- None, is a function that will be called at
1450- the start of each executed line of code.
1451- (Actually, the function must return itself
1452- in order to continue tracing.) The trace
1453- functions are called with three arguments:
1454- a pointer to the current frame, a string
1455- indicating why the function is called, and
1456- an argument which depends on the situation.
1457- The global trace function is also called
1458- whenever an exception is detected. */
1459- if (call_trace_protected (tstate -> c_tracefunc ,
1460- tstate -> c_traceobj ,
1461- tstate , frame ,
1462- PyTrace_CALL , Py_None )) {
1463- /* Trace function raised an error */
1464- goto exit_eval_frame ;
1465- }
1466- }
1467- if (tstate -> c_profilefunc != NULL ) {
1468- /* Similar for c_profilefunc, except it needn't
1469- return itself and isn't called for "line" events */
1470- if (call_trace_protected (tstate -> c_profilefunc ,
1471- tstate -> c_profileobj ,
1472- tstate , frame ,
1473- PyTrace_CALL , Py_None )) {
1474- /* Profile function raised an error */
1475- goto exit_eval_frame ;
1476- }
1471+ if (trace_function_entry (tstate , frame )) {
1472+ goto exit_eval_frame ;
14771473 }
14781474 }
14791475
14801476 if (PyDTrace_FUNCTION_ENTRY_ENABLED ())
14811477 dtrace_function_entry (frame );
14821478
1479+ PyCodeObject * co = frame -> f_code ;
14831480 /* Increment the warmup counter and quicken if warm enough
14841481 * _Py_Quicken is idempotent so we don't worry about overflow */
14851482 if (!PyCodeObject_IsWarmedUp (co )) {
@@ -1492,10 +1489,10 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
14921489 }
14931490
14941491
1495- names = co -> co_names ;
1496- consts = co -> co_consts ;
1497- localsplus = _PyFrame_GetLocalsArray (frame );
1498- first_instr = co -> co_firstinstr ;
1492+ PyObject * names = co -> co_names ;
1493+ PyObject * consts = co -> co_consts ;
1494+ PyObject * * localsplus = _PyFrame_GetLocalsArray (frame );
1495+ _Py_CODEUNIT * first_instr = co -> co_firstinstr ;
14991496 /*
15001497 frame->f_lasti refers to the index of the last instruction,
15011498 unless it's -1 in which case next_instr should be first_instr.
@@ -1512,8 +1509,8 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
15121509 to the beginning of the combined pair.)
15131510 */
15141511 assert (frame -> f_lasti >= -1 );
1515- next_instr = first_instr + frame -> f_lasti + 1 ;
1516- stack_pointer = frame -> stack + frame -> stackdepth ;
1512+ _Py_CODEUNIT * next_instr = first_instr + frame -> f_lasti + 1 ;
1513+ PyObject * * stack_pointer = frame -> stack + frame -> stackdepth ;
15171514 /* Set stackdepth to -1.
15181515 * Update when returning or calling trace function.
15191516 Having f_stackdepth <= 0 ensures that invalid
@@ -1524,6 +1521,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
15241521 frame -> f_state = FRAME_EXECUTING ;
15251522
15261523#ifdef LLTRACE
1524+ _Py_IDENTIFIER (__ltrace__ );
15271525 {
15281526 int r = _PyDict_ContainsId (GLOBALS (), & PyId___ltrace__ );
15291527 if (r < 0 ) {
0 commit comments