[Python-checkins] cpython (2.7): Issue #15368: make bytecode generation deterministic.
meador.inge
python-checkins at python.org
Wed Jul 18 21:29:54 CEST 2012
http://hg.python.org/cpython/rev/7eb0180c1734
changeset: 78163:7eb0180c1734
branch: 2.7
parent: 78144:227a22288688
user: Meador Inge <meadori at gmail.com>
date: Wed Jul 18 14:09:04 2012 -0500
summary:
Issue #15368: make bytecode generation deterministic.
files:
Misc/NEWS | 5 ++++-
Python/compile.c | 24 ++++++++++++++++++++++--
2 files changed, 26 insertions(+), 3 deletions(-)
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -1,4 +1,4 @@
-Python News
+,Python News
+++++++++++
What's New in Python 2.7.4
@@ -9,6 +9,9 @@
Core and Builtins
-----------------
+- Issue #15368: An issue that caused bytecode generation to be
+ non-deterministic when using randomized hashing (-R) has been fixed.
+
- Issue #15033: Fix the exit status bug when modules invoked using -m swith,
return the proper failure return value (1). Patch contributed by Jeff Knupp.
diff --git a/Python/compile.c b/Python/compile.c
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -359,14 +359,31 @@
static PyObject *
dictbytype(PyObject *src, int scope_type, int flag, int offset)
{
- Py_ssize_t pos = 0, i = offset, scope;
+ Py_ssize_t pos = 0, i = offset, scope, num_keys, key_i;
PyObject *k, *v, *dest = PyDict_New();
+ PyObject *sorted_keys;
assert(offset >= 0);
if (dest == NULL)
return NULL;
- while (PyDict_Next(src, &pos, &k, &v)) {
+ /* Sort the keys so that we have a deterministic order on the indexes
+ saved in the returned dictionary. These indexes are used as indexes
+ into the free and cell var storage. Therefore if they aren't
+ deterministic, then the generated bytecode is not deterministic.
+ */
+ sorted_keys = PyDict_Keys(src);
+ if (sorted_keys == NULL)
+ return NULL;
+ if (PyList_Sort(sorted_keys) != 0) {
+ Py_DECREF(sorted_keys);
+ return NULL;
+ }
+ num_keys = PyList_GET_SIZE(src);
+
+ for (key_i = 0; key_i < num_keys; key_i++) {
+ k = PyList_GET_ITEM(sorted_keys, key_i);
+ v = PyDict_GetItem(src, k);
/* XXX this should probably be a macro in symtable.h */
assert(PyInt_Check(v));
scope = (PyInt_AS_LONG(v) >> SCOPE_OFF) & SCOPE_MASK;
@@ -374,12 +391,14 @@
if (scope == scope_type || PyInt_AS_LONG(v) & flag) {
PyObject *tuple, *item = PyInt_FromLong(i);
if (item == NULL) {
+ Py_DECREF(sorted_keys);
Py_DECREF(dest);
return NULL;
}
i++;
tuple = PyTuple_Pack(2, k, k->ob_type);
if (!tuple || PyDict_SetItem(dest, tuple, item) < 0) {
+ Py_DECREF(sorted_keys);
Py_DECREF(item);
Py_DECREF(dest);
Py_XDECREF(tuple);
@@ -389,6 +408,7 @@
Py_DECREF(tuple);
}
}
+ Py_DECREF(sorted_keys);
return dest;
}
--
Repository URL: http://hg.python.org/cpython
More information about the Python-checkins
mailing list