mirror of
https://github.com/python/cpython.git
synced 2025-08-04 17:08:35 +00:00
gh-127271: Remove the PyCell_Get usage for framelocalsproxy (#130383)
This commit is contained in:
parent
043ab3af9a
commit
6140b0896e
1 changed files with 59 additions and 20 deletions
|
@ -28,7 +28,7 @@
|
|||
#define OFF(x) offsetof(PyFrameObject, x)
|
||||
|
||||
|
||||
// Returns borrowed reference or NULL
|
||||
// Returns new reference or NULL
|
||||
static PyObject *
|
||||
framelocalsproxy_getval(_PyInterpreterFrame *frame, PyCodeObject *co, int i)
|
||||
{
|
||||
|
@ -57,7 +57,10 @@ framelocalsproxy_getval(_PyInterpreterFrame *frame, PyCodeObject *co, int i)
|
|||
}
|
||||
|
||||
if (cell != NULL) {
|
||||
value = PyCell_GET(cell);
|
||||
value = PyCell_GetRef((PyCellObject *)cell);
|
||||
}
|
||||
else {
|
||||
Py_XINCREF(value);
|
||||
}
|
||||
|
||||
if (value == NULL) {
|
||||
|
@ -67,8 +70,19 @@ framelocalsproxy_getval(_PyInterpreterFrame *frame, PyCodeObject *co, int i)
|
|||
return value;
|
||||
}
|
||||
|
||||
static bool
|
||||
framelocalsproxy_hasval(_PyInterpreterFrame *frame, PyCodeObject *co, int i)
|
||||
{
|
||||
PyObject *value = framelocalsproxy_getval(frame, co, i);
|
||||
if (value == NULL) {
|
||||
return false;
|
||||
}
|
||||
Py_DECREF(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
static int
|
||||
framelocalsproxy_getkeyindex(PyFrameObject *frame, PyObject* key, bool read)
|
||||
framelocalsproxy_getkeyindex(PyFrameObject *frame, PyObject *key, bool read, PyObject **value_ptr)
|
||||
{
|
||||
/*
|
||||
* Returns -2 (!) if an error occurred; exception will be set.
|
||||
|
@ -76,8 +90,14 @@ framelocalsproxy_getkeyindex(PyFrameObject *frame, PyObject* key, bool read)
|
|||
* - if read == true, returns the index if the value is not NULL
|
||||
* - if read == false, returns the index if the value is not hidden
|
||||
* Otherwise returns -1.
|
||||
*
|
||||
* If read == true and value_ptr is not NULL, *value_ptr is set to
|
||||
* the value of the key if it is found (with a new reference).
|
||||
*/
|
||||
|
||||
// value_ptr should only be given if we are reading the value
|
||||
assert(read || value_ptr == NULL);
|
||||
|
||||
PyCodeObject *co = _PyFrame_GetCode(frame->f_frame);
|
||||
|
||||
// Ensure that the key is hashable.
|
||||
|
@ -85,6 +105,7 @@ framelocalsproxy_getkeyindex(PyFrameObject *frame, PyObject* key, bool read)
|
|||
if (key_hash == -1) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
|
||||
// We do 2 loops here because it's highly possible the key is interned
|
||||
|
@ -93,7 +114,14 @@ framelocalsproxy_getkeyindex(PyFrameObject *frame, PyObject* key, bool read)
|
|||
PyObject *name = PyTuple_GET_ITEM(co->co_localsplusnames, i);
|
||||
if (name == key) {
|
||||
if (read) {
|
||||
if (framelocalsproxy_getval(frame->f_frame, co, i) != NULL) {
|
||||
PyObject *value = framelocalsproxy_getval(frame->f_frame, co, i);
|
||||
if (value != NULL) {
|
||||
if (value_ptr != NULL) {
|
||||
*value_ptr = value;
|
||||
}
|
||||
else {
|
||||
Py_DECREF(value);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
} else {
|
||||
|
@ -124,7 +152,14 @@ framelocalsproxy_getkeyindex(PyFrameObject *frame, PyObject* key, bool read)
|
|||
}
|
||||
if (same) {
|
||||
if (read) {
|
||||
if (framelocalsproxy_getval(frame->f_frame, co, i) != NULL) {
|
||||
PyObject *value = framelocalsproxy_getval(frame->f_frame, co, i);
|
||||
if (value != NULL) {
|
||||
if (value_ptr != NULL) {
|
||||
*value_ptr = value;
|
||||
}
|
||||
else {
|
||||
Py_DECREF(value);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
} else {
|
||||
|
@ -142,25 +177,27 @@ static PyObject *
|
|||
framelocalsproxy_getitem(PyObject *self, PyObject *key)
|
||||
{
|
||||
PyFrameObject *frame = PyFrameLocalsProxyObject_CAST(self)->frame;
|
||||
PyCodeObject *co = _PyFrame_GetCode(frame->f_frame);
|
||||
PyObject *value = NULL;
|
||||
|
||||
int i = framelocalsproxy_getkeyindex(frame, key, true);
|
||||
int i = framelocalsproxy_getkeyindex(frame, key, true, &value);
|
||||
if (i == -2) {
|
||||
return NULL;
|
||||
}
|
||||
if (i >= 0) {
|
||||
PyObject *value = framelocalsproxy_getval(frame->f_frame, co, i);
|
||||
assert(value != NULL);
|
||||
return Py_NewRef(value);
|
||||
return value;
|
||||
}
|
||||
assert(value == NULL);
|
||||
|
||||
// Okay not in the fast locals, try extra locals
|
||||
|
||||
PyObject *extra = frame->f_extra_locals;
|
||||
if (extra != NULL) {
|
||||
PyObject *value = PyDict_GetItem(extra, key);
|
||||
if (PyDict_GetItemRef(extra, key, &value) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (value != NULL) {
|
||||
return Py_NewRef(value);
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -176,7 +213,7 @@ framelocalsproxy_setitem(PyObject *self, PyObject *key, PyObject *value)
|
|||
_PyStackRef *fast = _PyFrame_GetLocalsArray(frame->f_frame);
|
||||
PyCodeObject *co = _PyFrame_GetCode(frame->f_frame);
|
||||
|
||||
int i = framelocalsproxy_getkeyindex(frame, key, false);
|
||||
int i = framelocalsproxy_getkeyindex(frame, key, false, NULL);
|
||||
if (i == -2) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -297,8 +334,7 @@ framelocalsproxy_keys(PyObject *self, PyObject *Py_UNUSED(ignored))
|
|||
}
|
||||
|
||||
for (int i = 0; i < co->co_nlocalsplus; i++) {
|
||||
PyObject *val = framelocalsproxy_getval(frame->f_frame, co, i);
|
||||
if (val) {
|
||||
if (framelocalsproxy_hasval(frame->f_frame, co, i)) {
|
||||
PyObject *name = PyTuple_GET_ITEM(co->co_localsplusnames, i);
|
||||
if (PyList_Append(names, name) < 0) {
|
||||
Py_DECREF(names);
|
||||
|
@ -511,8 +547,10 @@ framelocalsproxy_values(PyObject *self, PyObject *Py_UNUSED(ignored))
|
|||
if (value) {
|
||||
if (PyList_Append(values, value) < 0) {
|
||||
Py_DECREF(values);
|
||||
Py_DECREF(value);
|
||||
return NULL;
|
||||
}
|
||||
Py_DECREF(value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -550,16 +588,19 @@ framelocalsproxy_items(PyObject *self, PyObject *Py_UNUSED(ignored))
|
|||
PyObject *pair = PyTuple_Pack(2, name, value);
|
||||
if (pair == NULL) {
|
||||
Py_DECREF(items);
|
||||
Py_DECREF(value);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (PyList_Append(items, pair) < 0) {
|
||||
Py_DECREF(items);
|
||||
Py_DECREF(pair);
|
||||
Py_DECREF(value);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_DECREF(pair);
|
||||
Py_DECREF(value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -601,7 +642,7 @@ framelocalsproxy_length(PyObject *self)
|
|||
}
|
||||
|
||||
for (int i = 0; i < co->co_nlocalsplus; i++) {
|
||||
if (framelocalsproxy_getval(frame->f_frame, co, i) != NULL) {
|
||||
if (framelocalsproxy_hasval(frame->f_frame, co, i)) {
|
||||
size++;
|
||||
}
|
||||
}
|
||||
|
@ -613,7 +654,7 @@ framelocalsproxy_contains(PyObject *self, PyObject *key)
|
|||
{
|
||||
PyFrameObject *frame = PyFrameLocalsProxyObject_CAST(self)->frame;
|
||||
|
||||
int i = framelocalsproxy_getkeyindex(frame, key, true);
|
||||
int i = framelocalsproxy_getkeyindex(frame, key, true, NULL);
|
||||
if (i == -2) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -724,7 +765,7 @@ framelocalsproxy_pop(PyObject* self, PyObject *const *args, Py_ssize_t nargs)
|
|||
|
||||
PyFrameObject *frame = PyFrameLocalsProxyObject_CAST(self)->frame;
|
||||
|
||||
int i = framelocalsproxy_getkeyindex(frame, key, false);
|
||||
int i = framelocalsproxy_getkeyindex(frame, key, false, NULL);
|
||||
if (i == -2) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -2066,9 +2107,7 @@ _PyFrame_HasHiddenLocals(_PyInterpreterFrame *frame)
|
|||
_PyLocals_Kind kind = _PyLocals_GetKind(co->co_localspluskinds, i);
|
||||
|
||||
if (kind & CO_FAST_HIDDEN) {
|
||||
PyObject* value = framelocalsproxy_getval(frame, co, i);
|
||||
|
||||
if (value != NULL) {
|
||||
if (framelocalsproxy_hasval(frame, co, i)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue