mirror of
https://github.com/python/cpython.git
synced 2025-10-08 08:01:55 +00:00
GH-100987: Allow objects other than code objects as the "executable" of an internal frame. (GH-105727)
* Add table describing possible executable classes for out-of-process debuggers. * Remove shim code object creation code as it is no longer needed. * Make lltrace a bit more robust w.r.t. non-standard frames.
This commit is contained in:
parent
ad56340b66
commit
7199584ac8
28 changed files with 541 additions and 606 deletions
|
@ -14,7 +14,7 @@ _PyFrame_Traverse(_PyInterpreterFrame *frame, visitproc visit, void *arg)
|
|||
Py_VISIT(frame->frame_obj);
|
||||
Py_VISIT(frame->f_locals);
|
||||
Py_VISIT(frame->f_funcobj);
|
||||
Py_VISIT(frame->f_code);
|
||||
Py_VISIT(_PyFrame_GetCode(frame));
|
||||
/* locals */
|
||||
PyObject **locals = _PyFrame_GetLocalsArray(frame);
|
||||
int i = 0;
|
||||
|
@ -31,7 +31,7 @@ _PyFrame_MakeAndSetFrameObject(_PyInterpreterFrame *frame)
|
|||
assert(frame->frame_obj == NULL);
|
||||
PyObject *exc = PyErr_GetRaisedException();
|
||||
|
||||
PyFrameObject *f = _PyFrame_New_NoTrack(frame->f_code);
|
||||
PyFrameObject *f = _PyFrame_New_NoTrack(_PyFrame_GetCode(frame));
|
||||
if (f == NULL) {
|
||||
Py_XDECREF(exc);
|
||||
return NULL;
|
||||
|
@ -65,7 +65,7 @@ _PyFrame_MakeAndSetFrameObject(_PyInterpreterFrame *frame)
|
|||
void
|
||||
_PyFrame_Copy(_PyInterpreterFrame *src, _PyInterpreterFrame *dest)
|
||||
{
|
||||
assert(src->stacktop >= src->f_code->co_nlocalsplus);
|
||||
assert(src->stacktop >= _PyFrame_GetCode(src)->co_nlocalsplus);
|
||||
Py_ssize_t size = ((char*)&src->localsplus[src->stacktop]) - (char *)src;
|
||||
memcpy(dest, src, size);
|
||||
// Don't leave a dangling pointer to the old frame when creating generators
|
||||
|
@ -81,7 +81,7 @@ take_ownership(PyFrameObject *f, _PyInterpreterFrame *frame)
|
|||
assert(frame->owner != FRAME_OWNED_BY_FRAME_OBJECT);
|
||||
assert(frame->owner != FRAME_CLEARED);
|
||||
Py_ssize_t size = ((char*)&frame->localsplus[frame->stacktop]) - (char *)frame;
|
||||
Py_INCREF(frame->f_code);
|
||||
Py_INCREF(_PyFrame_GetCode(frame));
|
||||
memcpy((_PyInterpreterFrame *)f->_f_frame_data, frame, size);
|
||||
frame = (_PyInterpreterFrame *)f->_f_frame_data;
|
||||
f->f_frame = frame;
|
||||
|
@ -89,7 +89,7 @@ take_ownership(PyFrameObject *f, _PyInterpreterFrame *frame)
|
|||
if (_PyFrame_IsIncomplete(frame)) {
|
||||
// This may be a newly-created generator or coroutine frame. Since it's
|
||||
// dead anyways, just pretend that the first RESUME ran:
|
||||
PyCodeObject *code = frame->f_code;
|
||||
PyCodeObject *code = _PyFrame_GetCode(frame);
|
||||
frame->prev_instr = _PyCode_CODE(code) + code->_co_firsttraceable;
|
||||
}
|
||||
assert(!_PyFrame_IsIncomplete(frame));
|
||||
|
@ -149,7 +149,7 @@ _PyFrame_ClearExceptCode(_PyInterpreterFrame *frame)
|
|||
PyObject *
|
||||
PyUnstable_InterpreterFrame_GetCode(struct _PyInterpreterFrame *frame)
|
||||
{
|
||||
PyObject *code = (PyObject *)frame->f_code;
|
||||
PyObject *code = frame->f_executable;
|
||||
Py_INCREF(code);
|
||||
return code;
|
||||
}
|
||||
|
@ -164,5 +164,13 @@ int
|
|||
PyUnstable_InterpreterFrame_GetLine(_PyInterpreterFrame *frame)
|
||||
{
|
||||
int addr = _PyInterpreterFrame_LASTI(frame) * sizeof(_Py_CODEUNIT);
|
||||
return PyCode_Addr2Line(frame->f_code, addr);
|
||||
return PyCode_Addr2Line(_PyFrame_GetCode(frame), addr);
|
||||
}
|
||||
|
||||
const PyTypeObject *const PyUnstable_ExecutableKinds[PY_EXECUTABLE_KINDS+1] = {
|
||||
[PY_EXECUTABLE_KIND_SKIP] = &_PyNone_Type,
|
||||
[PY_EXECUTABLE_KIND_PY_FUNCTION] = &PyCode_Type,
|
||||
[PY_EXECUTABLE_KIND_BUILTIN_FUNCTION] = &PyMethod_Type,
|
||||
[PY_EXECUTABLE_KIND_METHOD_DESCRIPTOR] = &PyMethodDescr_Type,
|
||||
[PY_EXECUTABLE_KINDS] = NULL,
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue