diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2016-09-30 07:23:01 (GMT) |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2016-09-30 07:23:01 (GMT) |
commit | 3738c2d8ae44347835b655a22bb4a3c4340af147 (patch) | |
tree | 8c417a9bd2645d61d458dba2f28c869dd6b6a4f8 /Objects/codeobject.c | |
parent | c6b5f08f04c7986cd48cec6d32a5d2983862255a (diff) | |
parent | 00a0fc1144d928515ff8abd0de7bb6ad072fcbdb (diff) | |
download | cpython-3738c2d8ae44347835b655a22bb4a3c4340af147.zip cpython-3738c2d8ae44347835b655a22bb4a3c4340af147.tar.gz cpython-3738c2d8ae44347835b655a22bb4a3c4340af147.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 | 52 |
1 files changed, 45 insertions, 7 deletions
diff --git a/Objects/codeobject.c b/Objects/codeobject.c index d514ec1..fdd357e 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -54,6 +54,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 (PyUnicode_CheckExact(v)) { + if (all_name_chars(v)) { + PyObject *w = v; + PyUnicode_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 kwonlyargcount, @@ -92,13 +136,7 @@ PyCode_New(int argcount, int kwonlyargcount, intern_strings(varnames); intern_strings(freevars); intern_strings(cellvars); - /* Intern selected string constants */ - for (i = PyTuple_GET_SIZE(consts); --i >= 0; ) { - PyObject *v = PyTuple_GetItem(consts, i); - if (!all_name_chars(v)) - continue; - PyUnicode_InternInPlace(&PyTuple_GET_ITEM(consts, i)); - } + intern_string_constants(consts); /* Create mapping between cells and arguments if needed. */ if (n_cellvars) { Py_ssize_t total_args = argcount + kwonlyargcount + |