Skip to content

Commit 3f3d5dc

Browse files
authored
bpo-44878: _PyEval_EvalFrameDefault readability improvements (GH-27725)
* Move a few variable declarations to point of definition. * Factor out tracing of function entry into helper function.
1 parent 1841c70 commit 3f3d5dc

File tree

1 file changed

+49
-51
lines changed

1 file changed

+49
-51
lines changed

Python/ceval.c

Lines changed: 49 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
13951434
PyObject* _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

Comments
 (0)