# error "this header file must not be included directly"
#endif
+struct _PyInterpreterFrame;
+
/* Standard object interface */
PyAPI_FUNC(PyFrameObject *) PyFrame_New(PyThreadState *, PyCodeObject *,
PyAPI_FUNC(int) PyFrame_FastToLocalsWithError(PyFrameObject *f);
PyAPI_FUNC(void) PyFrame_FastToLocals(PyFrameObject *);
+
+/* The following functions are for use by debuggers and other tools
+ * implementing custom frame evaluators with PEP 523. */
+
+/* Returns the code object of the frame (strong reference).
+ * Does not raise an exception. */
+PyAPI_FUNC(PyCodeObject *) PyUnstable_InterpreterFrame_GetCode(struct _PyInterpreterFrame *frame);
+
+/* Returns a byte ofsset into the last executed instruction.
+ * Does not raise an exception. */
+PyAPI_FUNC(int) PyUnstable_InterpreterFrame_GetLasti(struct _PyInterpreterFrame *frame);
+
+/* Returns the currently executing line number, or -1 if there is no line number.
+ * Does not raise an exception. */
+PyAPI_FUNC(int) PyUnstable_InterpreterFrame_GetLine(struct _PyInterpreterFrame *frame);
return new_frame;
}
-int _PyInterpreterFrame_GetLine(_PyInterpreterFrame *frame);
-
static inline
PyGenObject *_PyFrame_GetGenerator(_PyInterpreterFrame *frame)
{
--- /dev/null
+Add unstable C-API functions to get the code object, lasti and line number from
+the internal ``_PyInterpreterFrame`` in the limited API. The functions are:
+
+* ``PyCodeObject * PyUnstable_InterpreterFrame_GetCode(struct _PyInterpreterFrame *frame)``
+* ``int PyUnstable_InterpreterFrame_GetLasti(struct _PyInterpreterFrame *frame)``
+* ``int PyUnstable_InterpreterFrame_GetLine(struct _PyInterpreterFrame *frame)``
#include "pycore_runtime.h" // _Py_ID()
#include "pycore_traceback.h"
#include <pycore_frame.h>
+#include "frameobject.h" // _PyInterpreterFrame_GetLine
#include <stdlib.h> // malloc()
tracemalloc_get_frame(_PyInterpreterFrame *pyframe, frame_t *frame)
{
frame->filename = &_Py_STR(anon_unknown);
- int lineno = _PyInterpreterFrame_GetLine(pyframe);
+ int lineno = PyUnstable_InterpreterFrame_GetLine(pyframe);
if (lineno < 0) {
lineno = 0;
}
return f->f_lineno;
}
else {
- return _PyInterpreterFrame_GetLine(f->f_frame);
+ return PyUnstable_InterpreterFrame_GetLine(f->f_frame);
}
}
#include "pycore_pystate.h" // _PyThreadState_GET()
#include "structmember.h" // PyMemberDef
#include "opcode.h" // SEND
+#include "frameobject.h" // _PyInterpreterFrame_GetLine
#include "pystats.h"
static PyObject *gen_close(PyGenObject *, PyObject *);
frame = current_frame;
for (int i = 0; i < frame_count; ++i) {
PyCodeObject *code = frame->f_code;
- int line = _PyInterpreterFrame_GetLine(frame);
+ int line = PyUnstable_InterpreterFrame_GetLine(frame);
PyObject *frameinfo = Py_BuildValue("OiO", code->co_filename, line,
code->co_name);
if (!frameinfo) {
#include "pycore_dict.h"
#include "dictobject.h"
#include "pycore_frame.h"
+#include "frameobject.h" // _PyInterpreterFrame_GetLine
#include "opcode.h"
#include "pydtrace.h"
#include "setobject.h"
_PyErr_Format(tstate, PyExc_SystemError,
"%U:%d: unknown opcode %d",
frame->f_code->co_filename,
- _PyInterpreterFrame_GetLine(frame),
+ PyUnstable_InterpreterFrame_GetLine(frame),
opcode);
goto error;
Py_DECREF(frame->f_funcobj);
}
+/* Unstable API functions */
+
+PyCodeObject *
+PyUnstable_InterpreterFrame_GetCode(struct _PyInterpreterFrame *frame)
+{
+ PyCodeObject *code = frame->f_code;
+ Py_INCREF(code);
+ return code;
+}
+
+int
+PyUnstable_InterpreterFrame_GetLasti(struct _PyInterpreterFrame *frame)
+{
+ return _PyInterpreterFrame_LASTI(frame) * sizeof(_Py_CODEUNIT);
+}
+
int
-_PyInterpreterFrame_GetLine(_PyInterpreterFrame *frame)
+PyUnstable_InterpreterFrame_GetLine(_PyInterpreterFrame *frame)
{
int addr = _PyInterpreterFrame_LASTI(frame) * sizeof(_Py_CODEUNIT);
return PyCode_Addr2Line(frame->f_code, addr);
PUTS(fd, "???");
}
- int lineno = _PyInterpreterFrame_GetLine(frame);
+ int lineno = PyUnstable_InterpreterFrame_GetLine(frame);
PUTS(fd, ", line ");
if (lineno >= 0) {
_Py_DumpDecimal(fd, (size_t)lineno);