diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2016-09-30 07:38:08 (GMT) |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2016-09-30 07:38:08 (GMT) |
commit | 67edf73183b8bf0127456454747f596428cc28f6 (patch) | |
tree | f7073352c2a146b0fc1498ee128e56f061bc31cf /Objects/codeobject.c | |
parent | 8d7fa40cb32f3f0539ac67f457a78427708ded1a (diff) | |
download | cpython-67edf73183b8bf0127456454747f596428cc28f6.zip cpython-67edf73183b8bf0127456454747f596428cc28f6.tar.gz cpython-67edf73183b8bf0127456454747f596428cc28f6.tar.bz2 |
Issue #27942: String constants now interned recursively in tuples and frozensets.
Diffstat (limited to 'Objects/codeobject.c')
-rw-r--r-- | Objects/codeobject.c | 54 |
1 files changed, 45 insertions, 9 deletions
diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 0643c36..827fafa 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -39,6 +39,50 @@ intern_strings(PyObject *tuple) } } +/* Intern selected string constants */ +static int +intern_string_constants(PyObject *tuple) +{ + int modified = 0; + Py_ssize_t i; + + for (i = PyTuple_GET_SIZE(tuple); --i >= 0; ) { + PyObject *v = PyTuple_GET_ITEM(tuple, i); + if (PyString_CheckExact(v)) { + if (all_name_chars((unsigned char *)PyString_AS_STRING(v))) { + PyObject *w = v; + PyString_InternInPlace(&v); + if (w != v) { + PyTuple_SET_ITEM(tuple, i, v); + modified = 1; + } + } + } + else if (PyTuple_CheckExact(v)) { + intern_string_constants(v); + } + else if (PyFrozenSet_CheckExact(v)) { + PyObject *tmp = PySequence_Tuple(v); + if (tmp == NULL) { + PyErr_Clear(); + continue; + } + if (intern_string_constants(tmp)) { + v = PyFrozenSet_New(tmp); + if (v == NULL) { + PyErr_Clear(); + } + else { + PyTuple_SET_ITEM(tuple, i, v); + modified = 1; + } + } + Py_DECREF(tmp); + } + } + return modified; +} + PyCodeObject * PyCode_New(int argcount, int nlocals, int stacksize, int flags, @@ -68,15 +112,7 @@ PyCode_New(int argcount, int nlocals, int stacksize, int flags, intern_strings(varnames); intern_strings(freevars); intern_strings(cellvars); - /* Intern selected string constants */ - for (i = PyTuple_Size(consts); --i >= 0; ) { - PyObject *v = PyTuple_GetItem(consts, i); - if (!PyString_Check(v)) - continue; - if (!all_name_chars((unsigned char *)PyString_AS_STRING(v))) - continue; - PyString_InternInPlace(&PyTuple_GET_ITEM(consts, i)); - } + intern_string_constants(consts); co = PyObject_NEW(PyCodeObject, &PyCode_Type); if (co != NULL) { co->co_argcount = argcount; |