@@ -397,29 +397,48 @@ each key.
397397static PyObject *
398398dictbytype (PyObject * src , int scope_type , int flag , int offset )
399399{
400- Py_ssize_t pos = 0 , i = offset , scope ;
400+ Py_ssize_t pos = 0 , i = offset , scope , num_keys , key_i ;
401401 PyObject * k , * v , * dest = PyDict_New ();
402+ PyObject * sorted_keys ;
402403
403404 assert (offset >= 0 );
404405 if (dest == NULL )
405406 return NULL ;
406407
407- while (PyDict_Next (src , & pos , & k , & v )) {
408+ /* Sort the keys so that we have a deterministic order on the indexes
409+ saved in the returned dictionary. These indexes are used as indexes
410+ into the free and cell var storage. Therefore if they aren't
411+ deterministic, then the generated bytecode is not deterministic.
412+ */
413+ sorted_keys = PyDict_Keys (src );
414+ if (sorted_keys == NULL )
415+ return NULL ;
416+ if (PyList_Sort (sorted_keys ) != 0 ) {
417+ Py_DECREF (sorted_keys );
418+ return NULL ;
419+ }
420+ num_keys = PyList_GET_SIZE (src );
421+
422+ for (key_i = 0 ; key_i < num_keys ; key_i ++ ) {
408423 /* XXX this should probably be a macro in symtable.h */
409424 long vi ;
425+ k = PyList_GET_ITEM (sorted_keys , key_i );
426+ v = PyDict_GetItem (src , k );
410427 assert (PyLong_Check (v ));
411428 vi = PyLong_AS_LONG (v );
412429 scope = (vi >> SCOPE_OFFSET ) & SCOPE_MASK ;
413430
414431 if (scope == scope_type || vi & flag ) {
415432 PyObject * tuple , * item = PyLong_FromLong (i );
416433 if (item == NULL ) {
434+ Py_DECREF (sorted_keys );
417435 Py_DECREF (dest );
418436 return NULL ;
419437 }
420438 i ++ ;
421439 tuple = PyTuple_Pack (2 , k , k -> ob_type );
422440 if (!tuple || PyDict_SetItem (dest , tuple , item ) < 0 ) {
441+ Py_DECREF (sorted_keys );
423442 Py_DECREF (item );
424443 Py_DECREF (dest );
425444 Py_XDECREF (tuple );
@@ -429,6 +448,7 @@ dictbytype(PyObject *src, int scope_type, int flag, int offset)
429448 Py_DECREF (tuple );
430449 }
431450 }
451+ Py_DECREF (sorted_keys );
432452 return dest ;
433453}
434454
0 commit comments