diff options
-rw-r--r-- | Include/cpython/pystate.h | 4 | ||||
-rw-r--r-- | Modules/_tracemalloc.c | 2 | ||||
-rw-r--r-- | Modules/_xxsubinterpretersmodule.c | 2 | ||||
-rw-r--r-- | Modules/signalmodule.c | 2 | ||||
-rw-r--r-- | Objects/genobject.c | 10 | ||||
-rw-r--r-- | Python/ceval.c | 47 | ||||
-rw-r--r-- | Python/pylifecycle.c | 2 | ||||
-rw-r--r-- | Python/pystate.c | 10 | ||||
-rw-r--r-- | Python/sysmodule.c | 2 | ||||
-rw-r--r-- | Python/traceback.c | 2 |
10 files changed, 42 insertions, 41 deletions
diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h index 528d2a2..cf69c72 100644 --- a/Include/cpython/pystate.h +++ b/Include/cpython/pystate.h @@ -46,6 +46,8 @@ typedef struct _cframe { * accessed outside of their lifetime. */ int use_tracing; + /* Pointer to the currently executing frame (it can be NULL) */ + struct _interpreter_frame *current_frame; struct _cframe *previous; } CFrame; @@ -77,8 +79,6 @@ struct _ts { struct _ts *next; PyInterpreterState *interp; - /* Borrowed reference to the current frame (it can be NULL) */ - struct _interpreter_frame *frame; int recursion_depth; int recursion_headroom; /* Allow 50 more calls to handle any errors. */ int stackcheck_counter; diff --git a/Modules/_tracemalloc.c b/Modules/_tracemalloc.c index 09d273a..68e5f0d 100644 --- a/Modules/_tracemalloc.c +++ b/Modules/_tracemalloc.c @@ -396,7 +396,7 @@ traceback_get_frames(traceback_t *traceback) return; } - InterpreterFrame *pyframe = tstate->frame; + InterpreterFrame *pyframe = tstate->cframe->current_frame; for (; pyframe != NULL;) { if (traceback->nframe < _Py_tracemalloc_config.max_nframe) { tracemalloc_get_frame(pyframe, &traceback->frames[traceback->nframe]); diff --git a/Modules/_xxsubinterpretersmodule.c b/Modules/_xxsubinterpretersmodule.c index 3f68376..1507abf 100644 --- a/Modules/_xxsubinterpretersmodule.c +++ b/Modules/_xxsubinterpretersmodule.c @@ -1839,7 +1839,7 @@ _is_running(PyInterpreterState *interp) } assert(!PyErr_Occurred()); - InterpreterFrame *frame = tstate->frame; + InterpreterFrame *frame = tstate->cframe->current_frame; if (frame == NULL) { return 0; } diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c index 09f4aed..9278803 100644 --- a/Modules/signalmodule.c +++ b/Modules/signalmodule.c @@ -1788,7 +1788,7 @@ _PyErr_CheckSignalsTstate(PyThreadState *tstate) */ _Py_atomic_store(&is_tripped, 0); - InterpreterFrame *frame = tstate->frame; + InterpreterFrame *frame = tstate->cframe->current_frame; signal_state_t *state = &signal_global_state; for (int i = 1; i < NSIG; i++) { if (!_Py_atomic_load_relaxed(&Handlers[i].tripped)) { diff --git a/Objects/genobject.c b/Objects/genobject.c index 8bf5515..efd255d 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -193,7 +193,7 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult, Py_INCREF(result); _PyFrame_StackPush(frame, result); - frame->previous = tstate->frame; + frame->previous = tstate->cframe->current_frame; gen->gi_exc_state.previous_item = tstate->exc_info; tstate->exc_info = &gen->gi_exc_state; @@ -207,7 +207,7 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult, tstate->exc_info = gen->gi_exc_state.previous_item; gen->gi_exc_state.previous_item = NULL; - assert(tstate->frame == frame->previous); + assert(tstate->cframe->current_frame == frame->previous); /* Don't keep the reference to previous any longer than necessary. It * may keep a chain of frames alive or it could create a reference * cycle. */ @@ -435,9 +435,9 @@ _gen_throw(PyGenObject *gen, int close_on_genexit, will be reported correctly to the user. */ /* XXX We should probably be updating the current frame somewhere in ceval.c. */ - InterpreterFrame *prev = tstate->frame; + InterpreterFrame *prev = tstate->cframe->current_frame; frame->previous = prev; - tstate->frame = frame; + tstate->cframe->current_frame = frame; /* Close the generator that we are currently iterating with 'yield from' or awaiting on with 'await'. */ PyFrameState state = gen->gi_xframe->f_state; @@ -445,7 +445,7 @@ _gen_throw(PyGenObject *gen, int close_on_genexit, ret = _gen_throw((PyGenObject *)yf, close_on_genexit, typ, val, tb); gen->gi_xframe->f_state = state; - tstate->frame = prev; + tstate->cframe->current_frame = prev; frame->previous = NULL; } else { /* `yf` is an iterator or a coroutine-like object. */ diff --git a/Python/ceval.c b/Python/ceval.c index bd01e81..4ac0b53 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1561,8 +1561,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr tstate->cframe = &cframe; assert(frame->depth == 0); - /* push frame */ - tstate->frame = frame; + /* Push frame */ + frame->previous = prev_cframe->current_frame; + cframe.current_frame = frame; start_frame: if (_Py_EnterRecursiveCall(tstate, "")) { @@ -1570,7 +1571,8 @@ start_frame: goto exit_eval_frame; } - assert(frame == tstate->frame); + assert(tstate->cframe == &cframe); + assert(frame == cframe.current_frame); if (cframe.use_tracing) { if (trace_function_entry(tstate, frame)) { @@ -4641,8 +4643,9 @@ check_eval_breaker: goto error; } _PyFrame_SetStackPointer(frame, stack_pointer); + new_frame->previous = frame; + cframe.current_frame = frame = new_frame; new_frame->depth = frame->depth + 1; - tstate->frame = frame = new_frame; goto start_frame; } } @@ -4723,9 +4726,9 @@ check_eval_breaker: STACK_SHRINK(1); Py_DECREF(func); _PyFrame_SetStackPointer(frame, stack_pointer); - new_frame->previous = tstate->frame; + new_frame->previous = frame; + frame = cframe.current_frame = new_frame; new_frame->depth = frame->depth + 1; - tstate->frame = frame = new_frame; goto start_frame; } @@ -5258,11 +5261,12 @@ exit_eval_frame: _Py_LeaveRecursiveCall(tstate); if (frame->depth) { - _PyFrame_StackPush(frame->previous, retval); + cframe.current_frame = frame->previous; + _PyFrame_StackPush(cframe.current_frame, retval); if (_PyEvalFrameClearAndPop(tstate, frame)) { retval = NULL; } - frame = tstate->frame; + frame = cframe.current_frame; if (retval == NULL) { assert(_PyErr_Occurred(tstate)); throwflag = 1; @@ -5270,11 +5274,11 @@ exit_eval_frame: retval = NULL; goto resume_frame; } - tstate->frame = frame->previous; - /* Restore previous cframe */ + /* Restore previous cframe. */ tstate->cframe = cframe.previous; tstate->cframe->use_tracing = cframe.use_tracing; + assert(tstate->cframe->current_frame == frame->previous); return _Py_CheckFunctionResult(tstate, NULL, retval, __func__); } @@ -5891,8 +5895,6 @@ _PyEvalFramePushAndInit(PyThreadState *tstate, PyFrameConstructor *con, _PyFrame_Clear(frame, 0); return NULL; } - frame->previous = tstate->frame; - tstate->frame = frame; return frame; } @@ -5906,7 +5908,6 @@ _PyEvalFrameClearAndPop(PyThreadState *tstate, InterpreterFrame * frame) return -1; } --tstate->recursion_depth; - tstate->frame = frame->previous; _PyThreadState_PopFrame(tstate, frame); return 0; } @@ -6518,17 +6519,17 @@ InterpreterFrame * _PyEval_GetFrame(void) { PyThreadState *tstate = _PyThreadState_GET(); - return tstate->frame; + return tstate->cframe->current_frame; } PyFrameObject * PyEval_GetFrame(void) { PyThreadState *tstate = _PyThreadState_GET(); - if (tstate->frame == NULL) { + if (tstate->cframe->current_frame == NULL) { return NULL; } - PyFrameObject *f = _PyFrame_GetFrameObject(tstate->frame); + PyFrameObject *f = _PyFrame_GetFrameObject(tstate->cframe->current_frame); if (f == NULL) { PyErr_Clear(); } @@ -6538,7 +6539,7 @@ PyEval_GetFrame(void) PyObject * _PyEval_GetBuiltins(PyThreadState *tstate) { - InterpreterFrame *frame = tstate->frame; + InterpreterFrame *frame = tstate->cframe->current_frame; if (frame != NULL) { return frame->f_builtins; } @@ -6571,7 +6572,7 @@ PyObject * PyEval_GetLocals(void) { PyThreadState *tstate = _PyThreadState_GET(); - InterpreterFrame *current_frame = tstate->frame; + InterpreterFrame *current_frame = tstate->cframe->current_frame; if (current_frame == NULL) { _PyErr_SetString(tstate, PyExc_SystemError, "frame does not exist"); return NULL; @@ -6590,7 +6591,7 @@ PyObject * PyEval_GetGlobals(void) { PyThreadState *tstate = _PyThreadState_GET(); - InterpreterFrame *current_frame = tstate->frame; + InterpreterFrame *current_frame = tstate->cframe->current_frame; if (current_frame == NULL) { return NULL; } @@ -6601,7 +6602,7 @@ int PyEval_MergeCompilerFlags(PyCompilerFlags *cf) { PyThreadState *tstate = _PyThreadState_GET(); - InterpreterFrame *current_frame = tstate->frame; + InterpreterFrame *current_frame = tstate->cframe->current_frame; int result = cf->cf_flags != 0; if (current_frame != NULL) { @@ -6651,7 +6652,7 @@ PyEval_GetFuncDesc(PyObject *func) #define C_TRACE(x, call) \ if (use_tracing && tstate->c_profilefunc) { \ if (call_trace(tstate->c_profilefunc, tstate->c_profileobj, \ - tstate, tstate->frame, \ + tstate, tstate->cframe->current_frame, \ PyTrace_C_CALL, func)) { \ x = NULL; \ } \ @@ -6661,13 +6662,13 @@ if (use_tracing && tstate->c_profilefunc) { \ if (x == NULL) { \ call_trace_protected(tstate->c_profilefunc, \ tstate->c_profileobj, \ - tstate, tstate->frame, \ + tstate, tstate->cframe->current_frame, \ PyTrace_C_EXCEPTION, func); \ /* XXX should pass (type, value, tb) */ \ } else { \ if (call_trace(tstate->c_profilefunc, \ tstate->c_profileobj, \ - tstate, tstate->frame, \ + tstate, tstate->cframe->current_frame, \ PyTrace_C_RETURN, func)) { \ Py_DECREF(x); \ x = NULL; \ diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 9ce845c..3ccf32a 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -2031,7 +2031,7 @@ Py_EndInterpreter(PyThreadState *tstate) if (tstate != _PyThreadState_GET()) { Py_FatalError("thread is not current"); } - if (tstate->frame != NULL) { + if (tstate->cframe->current_frame != NULL) { Py_FatalError("thread still has a frame"); } interp->finalizing = 1; diff --git a/Python/pystate.c b/Python/pystate.c index 7804e17..114f915 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -636,12 +636,12 @@ new_threadstate(PyInterpreterState *interp, int init) tstate->interp = interp; - tstate->frame = NULL; tstate->recursion_depth = 0; tstate->recursion_headroom = 0; tstate->stackcheck_counter = 0; tstate->tracing = 0; tstate->root_cframe.use_tracing = 0; + tstate->root_cframe.current_frame = NULL; tstate->cframe = &tstate->root_cframe; tstate->gilstate_counter = 0; tstate->async_exc = NULL; @@ -861,7 +861,7 @@ PyThreadState_Clear(PyThreadState *tstate) { int verbose = _PyInterpreterState_GetConfig(tstate->interp)->verbose; - if (verbose && tstate->frame != NULL) { + if (verbose && tstate->cframe->current_frame != NULL) { /* bpo-20526: After the main thread calls _PyRuntimeState_SetFinalizing() in Py_FinalizeEx(), threads must exit when trying to take the GIL. If a thread exit in the middle of @@ -1134,10 +1134,10 @@ PyFrameObject* PyThreadState_GetFrame(PyThreadState *tstate) { assert(tstate != NULL); - if (tstate->frame == NULL) { + if (tstate->cframe->current_frame == NULL) { return NULL; } - PyFrameObject *frame = _PyFrame_GetFrameObject(tstate->frame); + PyFrameObject *frame = _PyFrame_GetFrameObject(tstate->cframe->current_frame); if (frame == NULL) { PyErr_Clear(); } @@ -1277,7 +1277,7 @@ _PyThread_CurrentFrames(void) for (i = runtime->interpreters.head; i != NULL; i = i->next) { PyThreadState *t; for (t = i->tstate_head; t != NULL; t = t->next) { - InterpreterFrame *frame = t->frame; + InterpreterFrame *frame = t->cframe->current_frame; if (frame == NULL) { continue; } diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 5e663c1..27937a0 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -1813,7 +1813,7 @@ sys__getframe_impl(PyObject *module, int depth) /*[clinic end generated code: output=d438776c04d59804 input=c1be8a6464b11ee5]*/ { PyThreadState *tstate = _PyThreadState_GET(); - InterpreterFrame *frame = tstate->frame; + InterpreterFrame *frame = tstate->cframe->current_frame; if (_PySys_Audit(tstate, "sys._getframe", NULL) < 0) { return NULL; diff --git a/Python/traceback.c b/Python/traceback.c index b18cbb9..22a0922 100644 --- a/Python/traceback.c +++ b/Python/traceback.c @@ -1082,7 +1082,7 @@ dump_traceback(int fd, PyThreadState *tstate, int write_header) PUTS(fd, "Stack (most recent call first):\n"); } - frame = tstate->frame; + frame = tstate->cframe->current_frame; if (frame == NULL) { PUTS(fd, " <no Python frame>\n"); return; |