|
14 | 14 | #include "pycore_pymem.h" // _PyMem_FreeDelayed() |
15 | 15 | #include "pycore_pystate.h" // _PyInterpreterState_GET() |
16 | 16 | #include "pycore_setobject.h" // _PySet_NextEntry() |
| 17 | +#include "pycore_dict.h" // _PyFrozenDict_ClearInternal() |
17 | 18 | #include "pycore_tuple.h" // _PyTuple_ITEMS() |
18 | 19 | #include "pycore_unicodeobject.h" // _PyUnicode_InternImmortal() |
19 | 20 | #include "pycore_uniqueid.h" // _PyObject_AssignUniqueId() |
@@ -167,6 +168,16 @@ should_immortalize_constant(PyObject *v) |
167 | 168 | } |
168 | 169 | return 1; |
169 | 170 | } |
| 171 | + else if (PyFrozenDict_CheckExact(v)) { |
| 172 | + Py_ssize_t pos = 0; |
| 173 | + PyObject *key, *value; |
| 174 | + while (PyDict_Next(v, &pos, &key, &value)) { |
| 175 | + if (!_Py_IsImmortal(key) || !_Py_IsImmortal(value)) { |
| 176 | + return 0; |
| 177 | + } |
| 178 | + } |
| 179 | + return 1; |
| 180 | + } |
170 | 181 | else if (PySlice_Check(v)) { |
171 | 182 | PySliceObject *slice = (PySliceObject *)v; |
172 | 183 | return (_Py_IsImmortal(slice->start) && |
@@ -248,6 +259,53 @@ intern_constants(PyObject *tuple, int *modified) |
248 | 259 | } |
249 | 260 | Py_DECREF(tmp); |
250 | 261 | } |
| 262 | + else if (PyFrozenDict_CheckExact(v)) { |
| 263 | + PyObject *w = v; |
| 264 | + PyObject *tmp = PyTuple_New(2 * PyDict_GET_SIZE(v)); |
| 265 | + if (tmp == NULL) { |
| 266 | + return -1; |
| 267 | + } |
| 268 | + Py_ssize_t pos = 0; |
| 269 | + PyObject *k, *val; |
| 270 | + Py_ssize_t j = 0; |
| 271 | + while (PyDict_Next(v, &pos, &k, &val)) { |
| 272 | + PyTuple_SET_ITEM(tmp, j++, Py_NewRef(k)); |
| 273 | + PyTuple_SET_ITEM(tmp, j++, Py_NewRef(val)); |
| 274 | + } |
| 275 | + int tmp_modified = 0; |
| 276 | + if (intern_constants(tmp, &tmp_modified) < 0) { |
| 277 | + Py_DECREF(tmp); |
| 278 | + return -1; |
| 279 | + } |
| 280 | + if (tmp_modified) { |
| 281 | + PyObject *new_dict = PyDict_New(); |
| 282 | + if (new_dict == NULL) { |
| 283 | + Py_DECREF(tmp); |
| 284 | + return -1; |
| 285 | + } |
| 286 | + for (j = 0; j < PyTuple_GET_SIZE(tmp); j += 2) { |
| 287 | + if (PyDict_SetItem(new_dict, |
| 288 | + PyTuple_GET_ITEM(tmp, j), |
| 289 | + PyTuple_GET_ITEM(tmp, j + 1)) < 0) { |
| 290 | + Py_DECREF(tmp); |
| 291 | + Py_DECREF(new_dict); |
| 292 | + return -1; |
| 293 | + } |
| 294 | + } |
| 295 | + v = PyFrozenDict_New(new_dict); |
| 296 | + Py_DECREF(new_dict); |
| 297 | + if (v == NULL) { |
| 298 | + Py_DECREF(tmp); |
| 299 | + return -1; |
| 300 | + } |
| 301 | + PyTuple_SET_ITEM(tuple, i, v); |
| 302 | + Py_DECREF(w); |
| 303 | + if (modified) { |
| 304 | + *modified = 1; |
| 305 | + } |
| 306 | + } |
| 307 | + Py_DECREF(tmp); |
| 308 | + } |
251 | 309 | #ifdef Py_GIL_DISABLED |
252 | 310 | else if (PySlice_Check(v)) { |
253 | 311 | PySliceObject *slice = (PySliceObject *)v; |
@@ -3199,6 +3257,21 @@ compare_constants(const void *key1, const void *key2) |
3199 | 3257 | } |
3200 | 3258 | return 1; |
3201 | 3259 | } |
| 3260 | + else if (PyFrozenDict_CheckExact(op1)) { |
| 3261 | + if (PyDict_GET_SIZE(op1) != PyDict_GET_SIZE(op2)) { |
| 3262 | + return 0; |
| 3263 | + } |
| 3264 | + Py_ssize_t pos1 = 0, pos2 = 0; |
| 3265 | + PyObject *k1, *k2, *v1, *v2; |
| 3266 | + while (PyDict_Next(op1, &pos1, &k1, &v1) && |
| 3267 | + PyDict_Next(op2, &pos2, &k2, &v2)) |
| 3268 | + { |
| 3269 | + if (k1 != k2 || v1 != v2) { |
| 3270 | + return 0; |
| 3271 | + } |
| 3272 | + } |
| 3273 | + return 1; |
| 3274 | + } |
3202 | 3275 | else if (PySlice_Check(op1)) { |
3203 | 3276 | PySliceObject *s1 = (PySliceObject *)op1; |
3204 | 3277 | PySliceObject *s2 = (PySliceObject *)op2; |
@@ -3273,6 +3346,9 @@ clear_containers(_Py_hashtable_t *ht, const void *key, const void *value, |
3273 | 3346 | else if (PyFrozenSet_CheckExact(op)) { |
3274 | 3347 | _PySet_ClearInternal((PySetObject *)op); |
3275 | 3348 | } |
| 3349 | + else if (PyFrozenDict_CheckExact(op)) { |
| 3350 | + _PyFrozenDict_ClearInternal(op); |
| 3351 | + } |
3276 | 3352 | return 0; |
3277 | 3353 | } |
3278 | 3354 |
|
|
0 commit comments