Issue #15368: make bytecode generation deterministic.

This commit is contained in:
Meador Inge 2012-07-18 14:09:04 -05:00
parent fc095202af
commit 6642d1f97d
2 changed files with 26 additions and 3 deletions

View File

@ -1,4 +1,4 @@
Python News ,Python News
+++++++++++ +++++++++++
What's New in Python 2.7.4 What's New in Python 2.7.4
@ -9,6 +9,9 @@ What's New in Python 2.7.4
Core and Builtins 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, - 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. return the proper failure return value (1). Patch contributed by Jeff Knupp.

View File

@ -359,14 +359,31 @@ each key.
static PyObject * static PyObject *
dictbytype(PyObject *src, int scope_type, int flag, int offset) 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 *k, *v, *dest = PyDict_New();
PyObject *sorted_keys;
assert(offset >= 0); assert(offset >= 0);
if (dest == NULL) if (dest == NULL)
return 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 */ /* XXX this should probably be a macro in symtable.h */
assert(PyInt_Check(v)); assert(PyInt_Check(v));
scope = (PyInt_AS_LONG(v) >> SCOPE_OFF) & SCOPE_MASK; scope = (PyInt_AS_LONG(v) >> SCOPE_OFF) & SCOPE_MASK;
@ -374,12 +391,14 @@ dictbytype(PyObject *src, int scope_type, int flag, int offset)
if (scope == scope_type || PyInt_AS_LONG(v) & flag) { if (scope == scope_type || PyInt_AS_LONG(v) & flag) {
PyObject *tuple, *item = PyInt_FromLong(i); PyObject *tuple, *item = PyInt_FromLong(i);
if (item == NULL) { if (item == NULL) {
Py_DECREF(sorted_keys);
Py_DECREF(dest); Py_DECREF(dest);
return NULL; return NULL;
} }
i++; i++;
tuple = PyTuple_Pack(2, k, k->ob_type); tuple = PyTuple_Pack(2, k, k->ob_type);
if (!tuple || PyDict_SetItem(dest, tuple, item) < 0) { if (!tuple || PyDict_SetItem(dest, tuple, item) < 0) {
Py_DECREF(sorted_keys);
Py_DECREF(item); Py_DECREF(item);
Py_DECREF(dest); Py_DECREF(dest);
Py_XDECREF(tuple); Py_XDECREF(tuple);
@ -389,6 +408,7 @@ dictbytype(PyObject *src, int scope_type, int flag, int offset)
Py_DECREF(tuple); Py_DECREF(tuple);
} }
} }
Py_DECREF(sorted_keys);
return dest; return dest;
} }