mirror of
https://github.com/python/cpython.git
synced 2025-08-22 17:55:18 +00:00
gh-111178: fix UBSan failures in Objects/frameobject.c
(GH-129777)
fix UBSan failures for `PyFrameObject`, `PyFrameLocalsProxyObject`
This commit is contained in:
parent
12e1d3011b
commit
d046421f4e
1 changed files with 118 additions and 96 deletions
|
@ -16,6 +16,14 @@
|
||||||
#include "pycore_frame.h"
|
#include "pycore_frame.h"
|
||||||
#include "opcode.h" // EXTENDED_ARG
|
#include "opcode.h" // EXTENDED_ARG
|
||||||
|
|
||||||
|
#define PyFrameObject_CAST(op) \
|
||||||
|
(assert(PyObject_TypeCheck((op), &PyFrame_Type)), (PyFrameObject *)(op))
|
||||||
|
|
||||||
|
#define PyFrameLocalsProxyObject_CAST(op) \
|
||||||
|
( \
|
||||||
|
assert(PyObject_TypeCheck((op), &PyFrameLocalsProxy_Type)), \
|
||||||
|
(PyFrameLocalsProxyObject *)(op) \
|
||||||
|
)
|
||||||
|
|
||||||
#define OFF(x) offsetof(PyFrameObject, x)
|
#define OFF(x) offsetof(PyFrameObject, x)
|
||||||
|
|
||||||
|
@ -126,8 +134,8 @@ framelocalsproxy_getkeyindex(PyFrameObject *frame, PyObject* key, bool read)
|
||||||
static PyObject *
|
static PyObject *
|
||||||
framelocalsproxy_getitem(PyObject *self, PyObject *key)
|
framelocalsproxy_getitem(PyObject *self, PyObject *key)
|
||||||
{
|
{
|
||||||
PyFrameObject* frame = ((PyFrameLocalsProxyObject*)self)->frame;
|
PyFrameObject *frame = PyFrameLocalsProxyObject_CAST(self)->frame;
|
||||||
PyCodeObject* co = _PyFrame_GetCode(frame->f_frame);
|
PyCodeObject *co = _PyFrame_GetCode(frame->f_frame);
|
||||||
|
|
||||||
int i = framelocalsproxy_getkeyindex(frame, key, true);
|
int i = framelocalsproxy_getkeyindex(frame, key, true);
|
||||||
if (i == -2) {
|
if (i == -2) {
|
||||||
|
@ -157,7 +165,7 @@ static int
|
||||||
framelocalsproxy_setitem(PyObject *self, PyObject *key, PyObject *value)
|
framelocalsproxy_setitem(PyObject *self, PyObject *key, PyObject *value)
|
||||||
{
|
{
|
||||||
/* Merge locals into fast locals */
|
/* Merge locals into fast locals */
|
||||||
PyFrameObject *frame = ((PyFrameLocalsProxyObject*)self)->frame;
|
PyFrameObject *frame = PyFrameLocalsProxyObject_CAST(self)->frame;
|
||||||
_PyStackRef *fast = _PyFrame_GetLocalsArray(frame->f_frame);
|
_PyStackRef *fast = _PyFrame_GetLocalsArray(frame->f_frame);
|
||||||
PyCodeObject *co = _PyFrame_GetCode(frame->f_frame);
|
PyCodeObject *co = _PyFrame_GetCode(frame->f_frame);
|
||||||
|
|
||||||
|
@ -272,9 +280,9 @@ framelocalsproxy_merge(PyObject* self, PyObject* other)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
framelocalsproxy_keys(PyObject *self, void *Py_UNUSED(ignored))
|
framelocalsproxy_keys(PyObject *self, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
PyFrameObject *frame = ((PyFrameLocalsProxyObject*)self)->frame;
|
PyFrameObject *frame = PyFrameLocalsProxyObject_CAST(self)->frame;
|
||||||
PyCodeObject *co = _PyFrame_GetCode(frame->f_frame);
|
PyCodeObject *co = _PyFrame_GetCode(frame->f_frame);
|
||||||
PyObject *names = PyList_New(0);
|
PyObject *names = PyList_New(0);
|
||||||
if (names == NULL) {
|
if (names == NULL) {
|
||||||
|
@ -314,8 +322,9 @@ framelocalsproxy_keys(PyObject *self, void *Py_UNUSED(ignored))
|
||||||
static void
|
static void
|
||||||
framelocalsproxy_dealloc(PyObject *self)
|
framelocalsproxy_dealloc(PyObject *self)
|
||||||
{
|
{
|
||||||
|
PyFrameLocalsProxyObject *proxy = PyFrameLocalsProxyObject_CAST(self);
|
||||||
PyObject_GC_UnTrack(self);
|
PyObject_GC_UnTrack(self);
|
||||||
Py_CLEAR(((PyFrameLocalsProxyObject*)self)->frame);
|
Py_CLEAR(proxy->frame);
|
||||||
Py_TYPE(self)->tp_free(self);
|
Py_TYPE(self)->tp_free(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -355,14 +364,16 @@ framelocalsproxy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||||
static int
|
static int
|
||||||
framelocalsproxy_tp_clear(PyObject *self)
|
framelocalsproxy_tp_clear(PyObject *self)
|
||||||
{
|
{
|
||||||
Py_CLEAR(((PyFrameLocalsProxyObject*)self)->frame);
|
PyFrameLocalsProxyObject *proxy = PyFrameLocalsProxyObject_CAST(self);
|
||||||
|
Py_CLEAR(proxy->frame);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
framelocalsproxy_visit(PyObject *self, visitproc visit, void *arg)
|
framelocalsproxy_visit(PyObject *self, visitproc visit, void *arg)
|
||||||
{
|
{
|
||||||
Py_VISIT(((PyFrameLocalsProxyObject*)self)->frame);
|
PyFrameLocalsProxyObject *proxy = PyFrameLocalsProxyObject_CAST(self);
|
||||||
|
Py_VISIT(proxy->frame);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -381,27 +392,29 @@ framelocalsproxy_iter(PyObject *self)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
framelocalsproxy_richcompare(PyObject *self, PyObject *other, int op)
|
framelocalsproxy_richcompare(PyObject *lhs, PyObject *rhs, int op)
|
||||||
{
|
{
|
||||||
if (PyFrameLocalsProxy_Check(other)) {
|
PyFrameLocalsProxyObject *self = PyFrameLocalsProxyObject_CAST(lhs);
|
||||||
bool result = ((PyFrameLocalsProxyObject*)self)->frame == ((PyFrameLocalsProxyObject*)other)->frame;
|
if (PyFrameLocalsProxy_Check(rhs)) {
|
||||||
|
PyFrameLocalsProxyObject *other = (PyFrameLocalsProxyObject *)rhs;
|
||||||
|
bool result = self->frame == other->frame;
|
||||||
if (op == Py_EQ) {
|
if (op == Py_EQ) {
|
||||||
return PyBool_FromLong(result);
|
return PyBool_FromLong(result);
|
||||||
} else if (op == Py_NE) {
|
} else if (op == Py_NE) {
|
||||||
return PyBool_FromLong(!result);
|
return PyBool_FromLong(!result);
|
||||||
}
|
}
|
||||||
} else if (PyDict_Check(other)) {
|
} else if (PyDict_Check(rhs)) {
|
||||||
PyObject *dct = PyDict_New();
|
PyObject *dct = PyDict_New();
|
||||||
if (dct == NULL) {
|
if (dct == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PyDict_Update(dct, self) < 0) {
|
if (PyDict_Update(dct, lhs) < 0) {
|
||||||
Py_DECREF(dct);
|
Py_DECREF(dct);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *result = PyObject_RichCompare(dct, other, op);
|
PyObject *result = PyObject_RichCompare(dct, rhs, op);
|
||||||
Py_DECREF(dct);
|
Py_DECREF(dct);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -476,10 +489,10 @@ framelocalsproxy_inplace_or(PyObject *self, PyObject *other)
|
||||||
return Py_NewRef(self);
|
return Py_NewRef(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject*
|
static PyObject *
|
||||||
framelocalsproxy_values(PyObject *self, void *Py_UNUSED(ignored))
|
framelocalsproxy_values(PyObject *self, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
PyFrameObject *frame = ((PyFrameLocalsProxyObject*)self)->frame;
|
PyFrameObject *frame = PyFrameLocalsProxyObject_CAST(self)->frame;
|
||||||
PyCodeObject *co = _PyFrame_GetCode(frame->f_frame);
|
PyCodeObject *co = _PyFrame_GetCode(frame->f_frame);
|
||||||
PyObject *values = PyList_New(0);
|
PyObject *values = PyList_New(0);
|
||||||
if (values == NULL) {
|
if (values == NULL) {
|
||||||
|
@ -513,9 +526,9 @@ framelocalsproxy_values(PyObject *self, void *Py_UNUSED(ignored))
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
framelocalsproxy_items(PyObject *self, void *Py_UNUSED(ignored))
|
framelocalsproxy_items(PyObject *self, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
PyFrameObject *frame = ((PyFrameLocalsProxyObject*)self)->frame;
|
PyFrameObject *frame = PyFrameLocalsProxyObject_CAST(self)->frame;
|
||||||
PyCodeObject *co = _PyFrame_GetCode(frame->f_frame);
|
PyCodeObject *co = _PyFrame_GetCode(frame->f_frame);
|
||||||
PyObject *items = PyList_New(0);
|
PyObject *items = PyList_New(0);
|
||||||
if (items == NULL) {
|
if (items == NULL) {
|
||||||
|
@ -571,7 +584,7 @@ framelocalsproxy_items(PyObject *self, void *Py_UNUSED(ignored))
|
||||||
static Py_ssize_t
|
static Py_ssize_t
|
||||||
framelocalsproxy_length(PyObject *self)
|
framelocalsproxy_length(PyObject *self)
|
||||||
{
|
{
|
||||||
PyFrameObject *frame = ((PyFrameLocalsProxyObject*)self)->frame;
|
PyFrameObject *frame = PyFrameLocalsProxyObject_CAST(self)->frame;
|
||||||
PyCodeObject *co = _PyFrame_GetCode(frame->f_frame);
|
PyCodeObject *co = _PyFrame_GetCode(frame->f_frame);
|
||||||
Py_ssize_t size = 0;
|
Py_ssize_t size = 0;
|
||||||
|
|
||||||
|
@ -591,7 +604,7 @@ framelocalsproxy_length(PyObject *self)
|
||||||
static int
|
static int
|
||||||
framelocalsproxy_contains(PyObject *self, PyObject *key)
|
framelocalsproxy_contains(PyObject *self, PyObject *key)
|
||||||
{
|
{
|
||||||
PyFrameObject *frame = ((PyFrameLocalsProxyObject*)self)->frame;
|
PyFrameObject *frame = PyFrameLocalsProxyObject_CAST(self)->frame;
|
||||||
|
|
||||||
int i = framelocalsproxy_getkeyindex(frame, key, true);
|
int i = framelocalsproxy_getkeyindex(frame, key, true);
|
||||||
if (i == -2) {
|
if (i == -2) {
|
||||||
|
@ -601,7 +614,7 @@ framelocalsproxy_contains(PyObject *self, PyObject *key)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *extra = ((PyFrameObject*)frame)->f_extra_locals;
|
PyObject *extra = frame->f_extra_locals;
|
||||||
if (extra != NULL) {
|
if (extra != NULL) {
|
||||||
return PyDict_Contains(extra, key);
|
return PyDict_Contains(extra, key);
|
||||||
}
|
}
|
||||||
|
@ -702,7 +715,7 @@ framelocalsproxy_pop(PyObject* self, PyObject *const *args, Py_ssize_t nargs)
|
||||||
default_value = args[1];
|
default_value = args[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
PyFrameObject *frame = ((PyFrameLocalsProxyObject*)self)->frame;
|
PyFrameObject *frame = PyFrameLocalsProxyObject_CAST(self)->frame;
|
||||||
|
|
||||||
int i = framelocalsproxy_getkeyindex(frame, key, false);
|
int i = framelocalsproxy_getkeyindex(frame, key, false);
|
||||||
if (i == -2) {
|
if (i == -2) {
|
||||||
|
@ -759,7 +772,7 @@ framelocalsproxy_copy(PyObject *self, PyObject *Py_UNUSED(ignored))
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject*
|
static PyObject*
|
||||||
framelocalsproxy_reversed(PyObject *self, void *Py_UNUSED(ignored))
|
framelocalsproxy_reversed(PyObject *self, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
PyObject *result = framelocalsproxy_keys(self, NULL);
|
PyObject *result = framelocalsproxy_keys(self, NULL);
|
||||||
|
|
||||||
|
@ -784,42 +797,36 @@ static PySequenceMethods framelocalsproxy_as_sequence = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyMappingMethods framelocalsproxy_as_mapping = {
|
static PyMappingMethods framelocalsproxy_as_mapping = {
|
||||||
framelocalsproxy_length, // mp_length
|
.mp_length = framelocalsproxy_length,
|
||||||
framelocalsproxy_getitem, // mp_subscript
|
.mp_subscript = framelocalsproxy_getitem,
|
||||||
framelocalsproxy_setitem, // mp_ass_subscript
|
.mp_ass_subscript = framelocalsproxy_setitem,
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyMethodDef framelocalsproxy_methods[] = {
|
static PyMethodDef framelocalsproxy_methods[] = {
|
||||||
{"__contains__", framelocalsproxy___contains__, METH_O | METH_COEXIST,
|
{"__contains__", framelocalsproxy___contains__, METH_O | METH_COEXIST, NULL},
|
||||||
NULL},
|
{"__getitem__", framelocalsproxy_getitem, METH_O | METH_COEXIST, NULL},
|
||||||
{"__getitem__", framelocalsproxy_getitem, METH_O | METH_COEXIST,
|
{"update", framelocalsproxy_update, METH_O, NULL},
|
||||||
NULL},
|
{"__reversed__", framelocalsproxy_reversed, METH_NOARGS, NULL},
|
||||||
{"update", framelocalsproxy_update, METH_O,
|
{"copy", framelocalsproxy_copy, METH_NOARGS, NULL},
|
||||||
NULL},
|
{"keys", framelocalsproxy_keys, METH_NOARGS, NULL},
|
||||||
{"__reversed__", _PyCFunction_CAST(framelocalsproxy_reversed), METH_NOARGS,
|
{"values", framelocalsproxy_values, METH_NOARGS, NULL},
|
||||||
NULL},
|
{"items", _PyCFunction_CAST(framelocalsproxy_items), METH_NOARGS, NULL},
|
||||||
{"copy", _PyCFunction_CAST(framelocalsproxy_copy), METH_NOARGS,
|
{"get", _PyCFunction_CAST(framelocalsproxy_get), METH_FASTCALL, NULL},
|
||||||
NULL},
|
{"pop", _PyCFunction_CAST(framelocalsproxy_pop), METH_FASTCALL, NULL},
|
||||||
{"keys", _PyCFunction_CAST(framelocalsproxy_keys), METH_NOARGS,
|
{
|
||||||
NULL},
|
"setdefault",
|
||||||
{"values", _PyCFunction_CAST(framelocalsproxy_values), METH_NOARGS,
|
_PyCFunction_CAST(framelocalsproxy_setdefault),
|
||||||
NULL},
|
METH_FASTCALL,
|
||||||
{"items", _PyCFunction_CAST(framelocalsproxy_items), METH_NOARGS,
|
NULL
|
||||||
NULL},
|
},
|
||||||
{"get", _PyCFunction_CAST(framelocalsproxy_get), METH_FASTCALL,
|
{NULL, NULL} /* sentinel */
|
||||||
NULL},
|
|
||||||
{"pop", _PyCFunction_CAST(framelocalsproxy_pop), METH_FASTCALL,
|
|
||||||
NULL},
|
|
||||||
{"setdefault", _PyCFunction_CAST(framelocalsproxy_setdefault), METH_FASTCALL,
|
|
||||||
NULL},
|
|
||||||
{NULL, NULL} /* sentinel */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
PyTypeObject PyFrameLocalsProxy_Type = {
|
PyTypeObject PyFrameLocalsProxy_Type = {
|
||||||
PyVarObject_HEAD_INIT(&PyType_Type, 0)
|
PyVarObject_HEAD_INIT(&PyType_Type, 0)
|
||||||
.tp_name = "FrameLocalsProxy",
|
.tp_name = "FrameLocalsProxy",
|
||||||
.tp_basicsize = sizeof(PyFrameLocalsProxyObject),
|
.tp_basicsize = sizeof(PyFrameLocalsProxyObject),
|
||||||
.tp_dealloc = (destructor)framelocalsproxy_dealloc,
|
.tp_dealloc = framelocalsproxy_dealloc,
|
||||||
.tp_repr = &framelocalsproxy_repr,
|
.tp_repr = &framelocalsproxy_repr,
|
||||||
.tp_as_number = &framelocalsproxy_as_number,
|
.tp_as_number = &framelocalsproxy_as_number,
|
||||||
.tp_as_sequence = &framelocalsproxy_as_sequence,
|
.tp_as_sequence = &framelocalsproxy_as_sequence,
|
||||||
|
@ -845,7 +852,7 @@ _PyFrameLocalsProxy_New(PyFrameObject *frame)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject* proxy = (PyObject*)framelocalsproxy_new(&PyFrameLocalsProxy_Type, args, NULL);
|
PyObject* proxy = framelocalsproxy_new(&PyFrameLocalsProxy_Type, args, NULL);
|
||||||
Py_DECREF(args);
|
Py_DECREF(args);
|
||||||
return proxy;
|
return proxy;
|
||||||
}
|
}
|
||||||
|
@ -856,8 +863,9 @@ static PyMemberDef frame_memberlist[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
frame_getlocals(PyFrameObject *f, void *closure)
|
frame_getlocals(PyObject *op, void *Py_UNUSED(closure))
|
||||||
{
|
{
|
||||||
|
PyFrameObject *f = PyFrameObject_CAST(op);
|
||||||
if (f == NULL) {
|
if (f == NULL) {
|
||||||
PyErr_BadInternalCall();
|
PyErr_BadInternalCall();
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -903,8 +911,9 @@ PyFrame_GetLineNumber(PyFrameObject *f)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
frame_getlineno(PyFrameObject *f, void *closure)
|
frame_getlineno(PyObject *op, void *Py_UNUSED(closure))
|
||||||
{
|
{
|
||||||
|
PyFrameObject *f = PyFrameObject_CAST(op);
|
||||||
int lineno = PyFrame_GetLineNumber(f);
|
int lineno = PyFrame_GetLineNumber(f);
|
||||||
if (lineno < 0) {
|
if (lineno < 0) {
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
|
@ -915,8 +924,9 @@ frame_getlineno(PyFrameObject *f, void *closure)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
frame_getlasti(PyFrameObject *f, void *closure)
|
frame_getlasti(PyObject *op, void *Py_UNUSED(closure))
|
||||||
{
|
{
|
||||||
|
PyFrameObject *f = PyFrameObject_CAST(op);
|
||||||
int lasti = _PyInterpreterFrame_LASTI(f->f_frame);
|
int lasti = _PyInterpreterFrame_LASTI(f->f_frame);
|
||||||
if (lasti < 0) {
|
if (lasti < 0) {
|
||||||
return PyLong_FromLong(-1);
|
return PyLong_FromLong(-1);
|
||||||
|
@ -925,8 +935,9 @@ frame_getlasti(PyFrameObject *f, void *closure)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
frame_getglobals(PyFrameObject *f, void *closure)
|
frame_getglobals(PyObject *op, void *Py_UNUSED(closure))
|
||||||
{
|
{
|
||||||
|
PyFrameObject *f = PyFrameObject_CAST(op);
|
||||||
PyObject *globals = f->f_frame->f_globals;
|
PyObject *globals = f->f_frame->f_globals;
|
||||||
if (globals == NULL) {
|
if (globals == NULL) {
|
||||||
globals = Py_None;
|
globals = Py_None;
|
||||||
|
@ -935,8 +946,9 @@ frame_getglobals(PyFrameObject *f, void *closure)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
frame_getbuiltins(PyFrameObject *f, void *closure)
|
frame_getbuiltins(PyObject *op, void *Py_UNUSED(closure))
|
||||||
{
|
{
|
||||||
|
PyFrameObject *f = PyFrameObject_CAST(op);
|
||||||
PyObject *builtins = f->f_frame->f_builtins;
|
PyObject *builtins = f->f_frame->f_builtins;
|
||||||
if (builtins == NULL) {
|
if (builtins == NULL) {
|
||||||
builtins = Py_None;
|
builtins = Py_None;
|
||||||
|
@ -945,8 +957,9 @@ frame_getbuiltins(PyFrameObject *f, void *closure)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
frame_getcode(PyFrameObject *f, void *closure)
|
frame_getcode(PyObject *op, void *Py_UNUSED(closure))
|
||||||
{
|
{
|
||||||
|
PyFrameObject *f = PyFrameObject_CAST(op);
|
||||||
if (PySys_Audit("object.__getattr__", "Os", f, "f_code") < 0) {
|
if (PySys_Audit("object.__getattr__", "Os", f, "f_code") < 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -954,8 +967,9 @@ frame_getcode(PyFrameObject *f, void *closure)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
frame_getback(PyFrameObject *f, void *closure)
|
frame_getback(PyObject *op, void *Py_UNUSED(closure))
|
||||||
{
|
{
|
||||||
|
PyFrameObject *f = PyFrameObject_CAST(op);
|
||||||
PyObject *res = (PyObject *)PyFrame_GetBack(f);
|
PyObject *res = (PyObject *)PyFrame_GetBack(f);
|
||||||
if (res == NULL) {
|
if (res == NULL) {
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
|
@ -964,15 +978,17 @@ frame_getback(PyFrameObject *f, void *closure)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
frame_gettrace_opcodes(PyFrameObject *f, void *closure)
|
frame_gettrace_opcodes(PyObject *op, void *Py_UNUSED(closure))
|
||||||
{
|
{
|
||||||
|
PyFrameObject *f = PyFrameObject_CAST(op);
|
||||||
PyObject *result = f->f_trace_opcodes ? Py_True : Py_False;
|
PyObject *result = f->f_trace_opcodes ? Py_True : Py_False;
|
||||||
return Py_NewRef(result);
|
return Py_NewRef(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
frame_settrace_opcodes(PyFrameObject *f, PyObject* value, void *Py_UNUSED(ignored))
|
frame_settrace_opcodes(PyObject *op, PyObject* value, void *Py_UNUSED(closure))
|
||||||
{
|
{
|
||||||
|
PyFrameObject *f = PyFrameObject_CAST(op);
|
||||||
if (!PyBool_Check(value)) {
|
if (!PyBool_Check(value)) {
|
||||||
PyErr_SetString(PyExc_TypeError,
|
PyErr_SetString(PyExc_TypeError,
|
||||||
"attribute value type must be bool");
|
"attribute value type must be bool");
|
||||||
|
@ -1464,8 +1480,9 @@ static bool frame_is_suspended(PyFrameObject *frame)
|
||||||
* that time.
|
* that time.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignored))
|
frame_setlineno(PyObject *op, PyObject* p_new_lineno, void *Py_UNUSED(closure))
|
||||||
{
|
{
|
||||||
|
PyFrameObject *f = PyFrameObject_CAST(op);
|
||||||
PyCodeObject *code = _PyFrame_GetCode(f->f_frame);
|
PyCodeObject *code = _PyFrame_GetCode(f->f_frame);
|
||||||
if (p_new_lineno == NULL) {
|
if (p_new_lineno == NULL) {
|
||||||
PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
|
PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
|
||||||
|
@ -1658,8 +1675,9 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno, void *Py_UNUSED(ignore
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
frame_gettrace(PyFrameObject *f, void *closure)
|
frame_gettrace(PyObject *op, void *Py_UNUSED(closure))
|
||||||
{
|
{
|
||||||
|
PyFrameObject *f = PyFrameObject_CAST(op);
|
||||||
PyObject* trace = f->f_trace;
|
PyObject* trace = f->f_trace;
|
||||||
if (trace == NULL)
|
if (trace == NULL)
|
||||||
trace = Py_None;
|
trace = Py_None;
|
||||||
|
@ -1667,8 +1685,9 @@ frame_gettrace(PyFrameObject *f, void *closure)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
frame_settrace(PyFrameObject *f, PyObject* v, void *closure)
|
frame_settrace(PyObject *op, PyObject* v, void *Py_UNUSED(closure))
|
||||||
{
|
{
|
||||||
|
PyFrameObject *f = PyFrameObject_CAST(op);
|
||||||
if (v == Py_None) {
|
if (v == Py_None) {
|
||||||
v = NULL;
|
v = NULL;
|
||||||
}
|
}
|
||||||
|
@ -1682,7 +1701,8 @@ frame_settrace(PyFrameObject *f, PyObject* v, void *closure)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
frame_getgenerator(PyFrameObject *f, void *arg) {
|
frame_getgenerator(PyObject *op, void *Py_UNUSED(closure)) {
|
||||||
|
PyFrameObject *f = PyFrameObject_CAST(op);
|
||||||
if (f->f_frame->owner == FRAME_OWNED_BY_GENERATOR) {
|
if (f->f_frame->owner == FRAME_OWNED_BY_GENERATOR) {
|
||||||
PyObject *gen = (PyObject *)_PyGen_GetGeneratorFromFrame(f->f_frame);
|
PyObject *gen = (PyObject *)_PyGen_GetGeneratorFromFrame(f->f_frame);
|
||||||
return Py_NewRef(gen);
|
return Py_NewRef(gen);
|
||||||
|
@ -1692,26 +1712,25 @@ frame_getgenerator(PyFrameObject *f, void *arg) {
|
||||||
|
|
||||||
|
|
||||||
static PyGetSetDef frame_getsetlist[] = {
|
static PyGetSetDef frame_getsetlist[] = {
|
||||||
{"f_back", (getter)frame_getback, NULL, NULL},
|
{"f_back", frame_getback, NULL, NULL},
|
||||||
{"f_locals", (getter)frame_getlocals, NULL, NULL},
|
{"f_locals", frame_getlocals, NULL, NULL},
|
||||||
{"f_lineno", (getter)frame_getlineno,
|
{"f_lineno", frame_getlineno, frame_setlineno, NULL},
|
||||||
(setter)frame_setlineno, NULL},
|
{"f_trace", frame_gettrace, frame_settrace, NULL},
|
||||||
{"f_trace", (getter)frame_gettrace, (setter)frame_settrace, NULL},
|
{"f_lasti", frame_getlasti, NULL, NULL},
|
||||||
{"f_lasti", (getter)frame_getlasti, NULL, NULL},
|
{"f_globals", frame_getglobals, NULL, NULL},
|
||||||
{"f_globals", (getter)frame_getglobals, NULL, NULL},
|
{"f_builtins", frame_getbuiltins, NULL, NULL},
|
||||||
{"f_builtins", (getter)frame_getbuiltins, NULL, NULL},
|
{"f_code", frame_getcode, NULL, NULL},
|
||||||
{"f_code", (getter)frame_getcode, NULL, NULL},
|
{"f_trace_opcodes", frame_gettrace_opcodes, frame_settrace_opcodes, NULL},
|
||||||
{"f_trace_opcodes", (getter)frame_gettrace_opcodes, (setter)frame_settrace_opcodes, NULL},
|
{"f_generator", frame_getgenerator, NULL, NULL},
|
||||||
{"f_generator", (getter)frame_getgenerator, NULL, NULL},
|
|
||||||
{0}
|
{0}
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
frame_dealloc(PyFrameObject *f)
|
frame_dealloc(PyObject *op)
|
||||||
{
|
{
|
||||||
/* It is the responsibility of the owning generator/coroutine
|
/* It is the responsibility of the owning generator/coroutine
|
||||||
* to have cleared the generator pointer */
|
* to have cleared the generator pointer */
|
||||||
|
PyFrameObject *f = PyFrameObject_CAST(op);
|
||||||
if (_PyObject_GC_IS_TRACKED(f)) {
|
if (_PyObject_GC_IS_TRACKED(f)) {
|
||||||
_PyObject_GC_UNTRACK(f);
|
_PyObject_GC_UNTRACK(f);
|
||||||
}
|
}
|
||||||
|
@ -1744,8 +1763,9 @@ frame_dealloc(PyFrameObject *f)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
frame_traverse(PyFrameObject *f, visitproc visit, void *arg)
|
frame_traverse(PyObject *op, visitproc visit, void *arg)
|
||||||
{
|
{
|
||||||
|
PyFrameObject *f = PyFrameObject_CAST(op);
|
||||||
Py_VISIT(f->f_back);
|
Py_VISIT(f->f_back);
|
||||||
Py_VISIT(f->f_trace);
|
Py_VISIT(f->f_trace);
|
||||||
Py_VISIT(f->f_extra_locals);
|
Py_VISIT(f->f_extra_locals);
|
||||||
|
@ -1758,8 +1778,9 @@ frame_traverse(PyFrameObject *f, visitproc visit, void *arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
frame_tp_clear(PyFrameObject *f)
|
frame_tp_clear(PyObject *op)
|
||||||
{
|
{
|
||||||
|
PyFrameObject *f = PyFrameObject_CAST(op);
|
||||||
Py_CLEAR(f->f_trace);
|
Py_CLEAR(f->f_trace);
|
||||||
Py_CLEAR(f->f_extra_locals);
|
Py_CLEAR(f->f_extra_locals);
|
||||||
Py_CLEAR(f->f_locals_cache);
|
Py_CLEAR(f->f_locals_cache);
|
||||||
|
@ -1778,8 +1799,9 @@ frame_tp_clear(PyFrameObject *f)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
frame_clear(PyFrameObject *f, PyObject *Py_UNUSED(ignored))
|
frame_clear(PyObject *op, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
|
PyFrameObject *f = PyFrameObject_CAST(op);
|
||||||
if (f->f_frame->owner == FRAME_OWNED_BY_GENERATOR) {
|
if (f->f_frame->owner == FRAME_OWNED_BY_GENERATOR) {
|
||||||
PyGenObject *gen = _PyGen_GetGeneratorFromFrame(f->f_frame);
|
PyGenObject *gen = _PyGen_GetGeneratorFromFrame(f->f_frame);
|
||||||
if (gen->gi_frame_state == FRAME_EXECUTING) {
|
if (gen->gi_frame_state == FRAME_EXECUTING) {
|
||||||
|
@ -1795,7 +1817,7 @@ frame_clear(PyFrameObject *f, PyObject *Py_UNUSED(ignored))
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assert(f->f_frame->owner == FRAME_OWNED_BY_FRAME_OBJECT);
|
assert(f->f_frame->owner == FRAME_OWNED_BY_FRAME_OBJECT);
|
||||||
(void)frame_tp_clear(f);
|
(void)frame_tp_clear(op);
|
||||||
}
|
}
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
running:
|
running:
|
||||||
|
@ -1812,8 +1834,9 @@ PyDoc_STRVAR(clear__doc__,
|
||||||
"F.clear(): clear all references held by the frame");
|
"F.clear(): clear all references held by the frame");
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
frame_sizeof(PyFrameObject *f, PyObject *Py_UNUSED(ignored))
|
frame_sizeof(PyObject *op, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
|
PyFrameObject *f = PyFrameObject_CAST(op);
|
||||||
Py_ssize_t res;
|
Py_ssize_t res;
|
||||||
res = offsetof(PyFrameObject, _f_frame_data) + offsetof(_PyInterpreterFrame, localsplus);
|
res = offsetof(PyFrameObject, _f_frame_data) + offsetof(_PyInterpreterFrame, localsplus);
|
||||||
PyCodeObject *code = _PyFrame_GetCode(f->f_frame);
|
PyCodeObject *code = _PyFrame_GetCode(f->f_frame);
|
||||||
|
@ -1825,8 +1848,9 @@ PyDoc_STRVAR(sizeof__doc__,
|
||||||
"F.__sizeof__() -> size of F in memory, in bytes");
|
"F.__sizeof__() -> size of F in memory, in bytes");
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
frame_repr(PyFrameObject *f)
|
frame_repr(PyObject *op)
|
||||||
{
|
{
|
||||||
|
PyFrameObject *f = PyFrameObject_CAST(op);
|
||||||
int lineno = PyFrame_GetLineNumber(f);
|
int lineno = PyFrame_GetLineNumber(f);
|
||||||
PyCodeObject *code = _PyFrame_GetCode(f->f_frame);
|
PyCodeObject *code = _PyFrame_GetCode(f->f_frame);
|
||||||
return PyUnicode_FromFormat(
|
return PyUnicode_FromFormat(
|
||||||
|
@ -1835,11 +1859,9 @@ frame_repr(PyFrameObject *f)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyMethodDef frame_methods[] = {
|
static PyMethodDef frame_methods[] = {
|
||||||
{"clear", (PyCFunction)frame_clear, METH_NOARGS,
|
{"clear", frame_clear, METH_NOARGS, clear__doc__},
|
||||||
clear__doc__},
|
{"__sizeof__", frame_sizeof, METH_NOARGS, sizeof__doc__},
|
||||||
{"__sizeof__", (PyCFunction)frame_sizeof, METH_NOARGS,
|
{NULL, NULL} /* sentinel */
|
||||||
sizeof__doc__},
|
|
||||||
{NULL, NULL} /* sentinel */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
PyTypeObject PyFrame_Type = {
|
PyTypeObject PyFrame_Type = {
|
||||||
|
@ -1848,12 +1870,12 @@ PyTypeObject PyFrame_Type = {
|
||||||
offsetof(PyFrameObject, _f_frame_data) +
|
offsetof(PyFrameObject, _f_frame_data) +
|
||||||
offsetof(_PyInterpreterFrame, localsplus),
|
offsetof(_PyInterpreterFrame, localsplus),
|
||||||
sizeof(PyObject *),
|
sizeof(PyObject *),
|
||||||
(destructor)frame_dealloc, /* tp_dealloc */
|
frame_dealloc, /* tp_dealloc */
|
||||||
0, /* tp_vectorcall_offset */
|
0, /* tp_vectorcall_offset */
|
||||||
0, /* tp_getattr */
|
0, /* tp_getattr */
|
||||||
0, /* tp_setattr */
|
0, /* tp_setattr */
|
||||||
0, /* tp_as_async */
|
0, /* tp_as_async */
|
||||||
(reprfunc)frame_repr, /* tp_repr */
|
frame_repr, /* tp_repr */
|
||||||
0, /* tp_as_number */
|
0, /* tp_as_number */
|
||||||
0, /* tp_as_sequence */
|
0, /* tp_as_sequence */
|
||||||
0, /* tp_as_mapping */
|
0, /* tp_as_mapping */
|
||||||
|
@ -1865,8 +1887,8 @@ PyTypeObject PyFrame_Type = {
|
||||||
0, /* tp_as_buffer */
|
0, /* tp_as_buffer */
|
||||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
|
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
|
||||||
0, /* tp_doc */
|
0, /* tp_doc */
|
||||||
(traverseproc)frame_traverse, /* tp_traverse */
|
frame_traverse, /* tp_traverse */
|
||||||
(inquiry)frame_tp_clear, /* tp_clear */
|
frame_tp_clear, /* tp_clear */
|
||||||
0, /* tp_richcompare */
|
0, /* tp_richcompare */
|
||||||
0, /* tp_weaklistoffset */
|
0, /* tp_weaklistoffset */
|
||||||
0, /* tp_iter */
|
0, /* tp_iter */
|
||||||
|
@ -2186,21 +2208,21 @@ PyObject*
|
||||||
PyFrame_GetLocals(PyFrameObject *frame)
|
PyFrame_GetLocals(PyFrameObject *frame)
|
||||||
{
|
{
|
||||||
assert(!_PyFrame_IsIncomplete(frame->f_frame));
|
assert(!_PyFrame_IsIncomplete(frame->f_frame));
|
||||||
return frame_getlocals(frame, NULL);
|
return frame_getlocals((PyObject *)frame, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject*
|
PyObject*
|
||||||
PyFrame_GetGlobals(PyFrameObject *frame)
|
PyFrame_GetGlobals(PyFrameObject *frame)
|
||||||
{
|
{
|
||||||
assert(!_PyFrame_IsIncomplete(frame->f_frame));
|
assert(!_PyFrame_IsIncomplete(frame->f_frame));
|
||||||
return frame_getglobals(frame, NULL);
|
return frame_getglobals((PyObject *)frame, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject*
|
PyObject*
|
||||||
PyFrame_GetBuiltins(PyFrameObject *frame)
|
PyFrame_GetBuiltins(PyFrameObject *frame)
|
||||||
{
|
{
|
||||||
assert(!_PyFrame_IsIncomplete(frame->f_frame));
|
assert(!_PyFrame_IsIncomplete(frame->f_frame));
|
||||||
return frame_getbuiltins(frame, NULL);
|
return frame_getbuiltins((PyObject *)frame, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue