mirror of
https://github.com/python/cpython.git
synced 2025-08-31 14:07:50 +00:00
bpo-38500: Add _PyInterpreterState_SetEvalFrameFunc() (GH-17340)
PyInterpreterState.eval_frame function now requires a tstate (Python thread state) parameter. Add private functions to the C API to get and set the frame evaluation function: * Add tstate parameter to _PyFrameEvalFunction function type. * Add _PyInterpreterState_GetEvalFrameFunc() and _PyInterpreterState_SetEvalFrameFunc() functions. * Add tstate parameter to _PyEval_EvalFrameDefault().
This commit is contained in:
parent
c846ef004d
commit
0b72b23fb0
9 changed files with 67 additions and 13 deletions
|
@ -725,9 +725,7 @@ PyEval_EvalCode(PyObject *co, PyObject *globals, PyObject *locals)
|
|||
PyObject *
|
||||
PyEval_EvalFrame(PyFrameObject *f)
|
||||
{
|
||||
/* This is for backward compatibility with extension modules that
|
||||
used this API; core interpreter code should call
|
||||
PyEval_EvalFrameEx() */
|
||||
/* Function kept for backward compatibility */
|
||||
PyThreadState *tstate = _PyThreadState_GET();
|
||||
return _PyEval_EvalFrame(tstate, f, 0);
|
||||
}
|
||||
|
@ -740,8 +738,10 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
|
|||
}
|
||||
|
||||
PyObject* _Py_HOT_FUNCTION
|
||||
_PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
|
||||
_PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
|
||||
{
|
||||
ensure_tstate_not_null(__func__, tstate);
|
||||
|
||||
#ifdef DXPAIRS
|
||||
int lastopcode = 0;
|
||||
#endif
|
||||
|
@ -756,9 +756,6 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
|
|||
_Py_atomic_int * const eval_breaker = &ceval->eval_breaker;
|
||||
PyCodeObject *co;
|
||||
|
||||
PyThreadState * const tstate = _PyRuntimeState_GetThreadState(runtime);
|
||||
ensure_tstate_not_null(__func__, tstate);
|
||||
|
||||
/* when tracing we set things up so that
|
||||
|
||||
not (instr_lb <= current_bytecode_offset < instr_ub)
|
||||
|
@ -1181,7 +1178,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
|
|||
goto error;
|
||||
|
||||
#ifdef Py_DEBUG
|
||||
/* PyEval_EvalFrameEx() must not be called with an exception set,
|
||||
/* _PyEval_EvalFrameDefault() must not be called with an exception set,
|
||||
because it can clear it (directly or indirectly) and so the
|
||||
caller loses its exception */
|
||||
assert(!_PyErr_Occurred(tstate));
|
||||
|
@ -3702,7 +3699,7 @@ exit_eval_frame:
|
|||
f->f_executing = 0;
|
||||
tstate->frame = f->f_back;
|
||||
|
||||
return _Py_CheckFunctionResult(tstate, NULL, retval, "PyEval_EvalFrameEx");
|
||||
return _Py_CheckFunctionResult(tstate, NULL, retval, __func__);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -1722,6 +1722,20 @@ _register_builtins_for_crossinterpreter_data(struct _xidregistry *xidregistry)
|
|||
}
|
||||
|
||||
|
||||
_PyFrameEvalFunction
|
||||
_PyInterpreterState_GetEvalFrameFunc(PyInterpreterState *interp)
|
||||
{
|
||||
return interp->eval_frame;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_PyInterpreterState_SetEvalFrameFunc(PyInterpreterState *interp,
|
||||
_PyFrameEvalFunction eval_frame)
|
||||
{
|
||||
interp->eval_frame = eval_frame;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue