mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
Issue #15368: make bytecode generation deterministic.
This commit is contained in:
commit
1f336adc8f
2 changed files with 25 additions and 2 deletions
|
@ -10,6 +10,9 @@ What's New in Python 3.3.0 Beta 2?
|
||||||
Core and Builtins
|
Core and Builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Issue #15368: An issue that caused bytecode generation to be
|
||||||
|
non-deterministic has been fixed.
|
||||||
|
|
||||||
- Issue #15202: Consistently use the name "follow_symlinks" for
|
- Issue #15202: Consistently use the name "follow_symlinks" for
|
||||||
new parameters in os and shutil functions.
|
new parameters in os and shutil functions.
|
||||||
|
|
||||||
|
|
|
@ -397,16 +397,33 @@ 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++) {
|
||||||
/* XXX this should probably be a macro in symtable.h */
|
/* XXX this should probably be a macro in symtable.h */
|
||||||
long vi;
|
long vi;
|
||||||
|
k = PyList_GET_ITEM(sorted_keys, key_i);
|
||||||
|
v = PyDict_GetItem(src, k);
|
||||||
assert(PyLong_Check(v));
|
assert(PyLong_Check(v));
|
||||||
vi = PyLong_AS_LONG(v);
|
vi = PyLong_AS_LONG(v);
|
||||||
scope = (vi >> SCOPE_OFFSET) & SCOPE_MASK;
|
scope = (vi >> SCOPE_OFFSET) & SCOPE_MASK;
|
||||||
|
@ -414,12 +431,14 @@ dictbytype(PyObject *src, int scope_type, int flag, int offset)
|
||||||
if (scope == scope_type || vi & flag) {
|
if (scope == scope_type || vi & flag) {
|
||||||
PyObject *tuple, *item = PyLong_FromLong(i);
|
PyObject *tuple, *item = PyLong_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);
|
||||||
|
@ -429,6 +448,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue