[Python-checkins] bpo-44878: _PyEval_EvalFrameDefault readability improvements (GH-27725)
markshannon
webhook-mailer at python.org
Wed Aug 11 06:48:23 EDT 2021
https://github.com/python/cpython/commit/3f3d5dcac336463bd0eed64ba0bd7666ff2da1e1
commit: 3f3d5dcac336463bd0eed64ba0bd7666ff2da1e1
branch: main
author: Mark Shannon <mark at hotpy.org>
committer: markshannon <mark at hotpy.org>
date: 2021-08-11T11:47:52+01:00
summary:
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.
files:
M Python/ceval.c
diff --git a/Python/ceval.c b/Python/ceval.c
index 104dbe44ecf2e..6bfbf68324184 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -1392,6 +1392,45 @@ eval_frame_handle_pending(PyThreadState *tstate)
#define BUILTINS() frame->f_builtins
#define LOCALS() frame->f_locals
+static int
+trace_function_entry(PyThreadState *tstate, InterpreterFrame *frame)
+{
+ if (tstate->c_tracefunc != NULL) {
+ /* tstate->c_tracefunc, if defined, is a
+ function that will be called on *every* entry
+ to a code block. Its return value, if not
+ None, is a function that will be called at
+ the start of each executed line of code.
+ (Actually, the function must return itself
+ in order to continue tracing.) The trace
+ functions are called with three arguments:
+ a pointer to the current frame, a string
+ indicating why the function is called, and
+ an argument which depends on the situation.
+ The global trace function is also called
+ whenever an exception is detected. */
+ if (call_trace_protected(tstate->c_tracefunc,
+ tstate->c_traceobj,
+ tstate, frame,
+ PyTrace_CALL, Py_None)) {
+ /* Trace function raised an error */
+ return -1;
+ }
+ }
+ if (tstate->c_profilefunc != NULL) {
+ /* Similar for c_profilefunc, except it needn't
+ return itself and isn't called for "line" events */
+ if (call_trace_protected(tstate->c_profilefunc,
+ tstate->c_profileobj,
+ tstate, frame,
+ PyTrace_CALL, Py_None)) {
+ /* Profile function raised an error */
+ return -1;
+ }
+ }
+ return 0;
+}
+
PyObject* _Py_HOT_FUNCTION
_PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int throwflag)
{
@@ -1405,22 +1444,10 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
#ifdef DXPAIRS
int lastopcode = 0;
#endif
- PyObject **stack_pointer; /* Next free slot in value stack */
- _Py_CODEUNIT *next_instr;
int opcode; /* Current opcode */
int oparg; /* Current opcode argument, if any */
- PyObject **localsplus;
PyObject *retval = NULL; /* Return value */
_Py_atomic_int * const eval_breaker = &tstate->interp->ceval.eval_breaker;
- PyCodeObject *co;
-
- _Py_CODEUNIT *first_instr;
- PyObject *names;
- PyObject *consts;
-
-#ifdef LLTRACE
- _Py_IDENTIFIER(__ltrace__);
-#endif
if (_Py_EnterRecursiveCall(tstate, "")) {
return NULL;
@@ -1439,47 +1466,17 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
/* push frame */
tstate->frame = frame;
- co = frame->f_code;
if (cframe.use_tracing) {
- if (tstate->c_tracefunc != NULL) {
- /* tstate->c_tracefunc, if defined, is a
- function that will be called on *every* entry
- to a code block. Its return value, if not
- None, is a function that will be called at
- the start of each executed line of code.
- (Actually, the function must return itself
- in order to continue tracing.) The trace
- functions are called with three arguments:
- a pointer to the current frame, a string
- indicating why the function is called, and
- an argument which depends on the situation.
- The global trace function is also called
- whenever an exception is detected. */
- if (call_trace_protected(tstate->c_tracefunc,
- tstate->c_traceobj,
- tstate, frame,
- PyTrace_CALL, Py_None)) {
- /* Trace function raised an error */
- goto exit_eval_frame;
- }
- }
- if (tstate->c_profilefunc != NULL) {
- /* Similar for c_profilefunc, except it needn't
- return itself and isn't called for "line" events */
- if (call_trace_protected(tstate->c_profilefunc,
- tstate->c_profileobj,
- tstate, frame,
- PyTrace_CALL, Py_None)) {
- /* Profile function raised an error */
- goto exit_eval_frame;
- }
+ if (trace_function_entry(tstate, frame)) {
+ goto exit_eval_frame;
}
}
if (PyDTrace_FUNCTION_ENTRY_ENABLED())
dtrace_function_entry(frame);
+ PyCodeObject *co = frame->f_code;
/* Increment the warmup counter and quicken if warm enough
* _Py_Quicken is idempotent so we don't worry about overflow */
if (!PyCodeObject_IsWarmedUp(co)) {
@@ -1492,10 +1489,10 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
}
- names = co->co_names;
- consts = co->co_consts;
- localsplus = _PyFrame_GetLocalsArray(frame);
- first_instr = co->co_firstinstr;
+ PyObject *names = co->co_names;
+ PyObject *consts = co->co_consts;
+ PyObject **localsplus = _PyFrame_GetLocalsArray(frame);
+ _Py_CODEUNIT *first_instr = co->co_firstinstr;
/*
frame->f_lasti refers to the index of the last instruction,
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
to the beginning of the combined pair.)
*/
assert(frame->f_lasti >= -1);
- next_instr = first_instr + frame->f_lasti + 1;
- stack_pointer = frame->stack + frame->stackdepth;
+ _Py_CODEUNIT *next_instr = first_instr + frame->f_lasti + 1;
+ PyObject **stack_pointer = frame->stack + frame->stackdepth;
/* Set stackdepth to -1.
* Update when returning or calling trace function.
Having f_stackdepth <= 0 ensures that invalid
@@ -1524,6 +1521,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
frame->f_state = FRAME_EXECUTING;
#ifdef LLTRACE
+ _Py_IDENTIFIER(__ltrace__);
{
int r = _PyDict_ContainsId(GLOBALS(), &PyId___ltrace__);
if (r < 0) {
More information about the Python-checkins
mailing list