Issue #18772: fix the gdb plugin after the set implementation changes
This commit is contained in:
parent
f5e30d8b54
commit
9d95254bb7
|
@ -706,7 +706,6 @@ PyAPI_DATA(Py_ssize_t) _Py_RefTotal;
|
|||
PyAPI_FUNC(void) _Py_NegativeRefcount(const char *fname,
|
||||
int lineno, PyObject *op);
|
||||
PyAPI_FUNC(PyObject *) _PyDict_Dummy(void);
|
||||
PyAPI_FUNC(PyObject *) _PySet_Dummy(void);
|
||||
PyAPI_FUNC(Py_ssize_t) _Py_GetRefTotal(void);
|
||||
#define _Py_INC_REFTOTAL _Py_RefTotal++
|
||||
#define _Py_DEC_REFTOTAL _Py_RefTotal--
|
||||
|
|
|
@ -61,6 +61,10 @@ struct _setobject {
|
|||
PyAPI_DATA(PyTypeObject) PySet_Type;
|
||||
PyAPI_DATA(PyTypeObject) PyFrozenSet_Type;
|
||||
PyAPI_DATA(PyTypeObject) PySetIter_Type;
|
||||
#ifndef Py_LIMITED_API
|
||||
PyAPI_DATA(PyObject *) _PySet_Dummy;
|
||||
#endif
|
||||
|
||||
|
||||
/* Invariants for frozensets:
|
||||
* data is immutable.
|
||||
|
|
|
@ -22,7 +22,7 @@ _Py_GetRefTotal(void)
|
|||
o = _PyDict_Dummy();
|
||||
if (o != NULL)
|
||||
total -= o->ob_refcnt;
|
||||
o = _PySet_Dummy();
|
||||
o = _PySet_Dummy;
|
||||
if (o != NULL)
|
||||
total -= o->ob_refcnt;
|
||||
return total;
|
||||
|
|
|
@ -29,18 +29,12 @@ set_key_error(PyObject *arg)
|
|||
#define PERTURB_SHIFT 5
|
||||
|
||||
/* Object used as dummy key to fill deleted entries */
|
||||
|
||||
static PyObject _dummy_struct;
|
||||
|
||||
#define dummy (&_dummy_struct)
|
||||
|
||||
#ifdef Py_REF_DEBUG
|
||||
PyObject *
|
||||
_PySet_Dummy(void)
|
||||
{
|
||||
return dummy;
|
||||
}
|
||||
#endif
|
||||
/* Exported for the gdb plugin's benefit. */
|
||||
PyObject *_PySet_Dummy = dummy;
|
||||
|
||||
#define INIT_NONZERO_SET_SLOTS(so) do { \
|
||||
(so)->table = (so)->smalltable; \
|
||||
|
|
|
@ -922,21 +922,26 @@ class PyFrameObjectPtr(PyObjectPtr):
|
|||
class PySetObjectPtr(PyObjectPtr):
|
||||
_typename = 'PySetObject'
|
||||
|
||||
@classmethod
|
||||
def _dummy_key(self):
|
||||
return gdb.lookup_global_symbol('_PySet_Dummy').value()
|
||||
|
||||
def __iter__(self):
|
||||
dummy_ptr = self._dummy_key()
|
||||
table = self.field('table')
|
||||
for i in safe_range(self.field('mask') + 1):
|
||||
setentry = table[i]
|
||||
key = setentry['key']
|
||||
if key != 0 and key != dummy_ptr:
|
||||
yield PyObjectPtr.from_pyobject_ptr(key)
|
||||
|
||||
def proxyval(self, visited):
|
||||
# Guard against infinite loops:
|
||||
if self.as_address() in visited:
|
||||
return ProxyAlreadyVisited('%s(...)' % self.safe_tp_name())
|
||||
visited.add(self.as_address())
|
||||
|
||||
members = []
|
||||
table = self.field('table')
|
||||
for i in safe_range(self.field('mask')+1):
|
||||
setentry = table[i]
|
||||
key = setentry['key']
|
||||
if key != 0:
|
||||
key_proxy = PyObjectPtr.from_pyobject_ptr(key).proxyval(visited)
|
||||
if key_proxy != '<dummy key>':
|
||||
members.append(key_proxy)
|
||||
members = (key.proxyval(visited) for key in self)
|
||||
if self.safe_tp_name() == 'frozenset':
|
||||
return frozenset(members)
|
||||
else:
|
||||
|
@ -965,18 +970,11 @@ class PySetObjectPtr(PyObjectPtr):
|
|||
|
||||
out.write('{')
|
||||
first = True
|
||||
table = self.field('table')
|
||||
for i in safe_range(self.field('mask')+1):
|
||||
setentry = table[i]
|
||||
key = setentry['key']
|
||||
if key != 0:
|
||||
pyop_key = PyObjectPtr.from_pyobject_ptr(key)
|
||||
key_proxy = pyop_key.proxyval(visited) # FIXME!
|
||||
if key_proxy != '<dummy key>':
|
||||
if not first:
|
||||
out.write(', ')
|
||||
first = False
|
||||
pyop_key.write_repr(out, visited)
|
||||
for key in self:
|
||||
if not first:
|
||||
out.write(', ')
|
||||
first = False
|
||||
key.write_repr(out, visited)
|
||||
out.write('}')
|
||||
|
||||
if tp_name != 'set':
|
||||
|
|
Loading…
Reference in New Issue