diff options
author | Gregory P. Smith <greg@krypto.org> | 2012-07-22 04:23:00 (GMT) |
---|---|---|
committer | Gregory P. Smith <greg@krypto.org> | 2012-07-22 04:23:00 (GMT) |
commit | ea2ce479580a8fbb71b5da82f6e0dc69eb20505c (patch) | |
tree | 875c9908abdd18b8e4ba6d8b81271c7d5efae39e /Python | |
parent | b9e9e0d5a8be470ade2bb497019a5cf737138182 (diff) | |
parent | 68f555c03ad32671a76c5762313bbf33c0ae4842 (diff) | |
download | cpython-ea2ce479580a8fbb71b5da82f6e0dc69eb20505c.zip cpython-ea2ce479580a8fbb71b5da82f6e0dc69eb20505c.tar.gz cpython-ea2ce479580a8fbb71b5da82f6e0dc69eb20505c.tar.bz2 |
merge heads
Diffstat (limited to 'Python')
-rw-r--r-- | Python/bltinmodule.c | 8 | ||||
-rw-r--r-- | Python/compile.c | 24 | ||||
-rw-r--r-- | Python/peephole.c | 36 |
3 files changed, 44 insertions, 24 deletions
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 373f870..3def080 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -53,8 +53,12 @@ builtin___import__(PyObject *self, PyObject *args, PyObject *kwds) PyDoc_STRVAR(import_doc, "__import__(name, globals={}, locals={}, fromlist=[], level=-1) -> module\n\ \n\ -Import a module. The globals are only used to determine the context;\n\ -they are not modified. The locals are currently unused. The fromlist\n\ +Import a module. Because this function is meant for use by the Python\n\ +interpreter and not for general use it is better to use\n\ +importlib.import_module() to programmatically import a module.\n\ +\n\ +The globals argument is only used to determine the context;\n\ +they are not modified. The locals argument is unused. The fromlist\n\ should be a list of names to emulate ``from name import ...'', or an\n\ empty list to emulate ``import name''.\n\ When importing a module from a package, note that __import__('A.B', ...)\n\ diff --git a/Python/compile.c b/Python/compile.c index 119c60f..531bed4 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -359,14 +359,31 @@ each key. static PyObject * dictbytype(PyObject *src, int scope_type, int flag, int offset) { - Py_ssize_t pos = 0, i = offset, scope; + Py_ssize_t 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(sorted_keys); + + 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 @@ dictbytype(PyObject *src, int scope_type, int flag, int offset) 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 @@ dictbytype(PyObject *src, int scope_type, int flag, int offset) Py_DECREF(tuple); } } + Py_DECREF(sorted_keys); return dest; } diff --git a/Python/peephole.c b/Python/peephole.c index 7521b9c..ae84efa 100644 --- a/Python/peephole.c +++ b/Python/peephole.c @@ -347,7 +347,7 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, codestr = (unsigned char *)memcpy(codestr, PyString_AS_STRING(code), codelen); - /* Verify that RETURN_VALUE terminates the codestring. This allows + /* Verify that RETURN_VALUE terminates the codestring. This allows the various transformation patterns to look ahead several instructions without additional checks to make sure they are not looking beyond the end of the code string. @@ -445,8 +445,8 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, case BUILD_LIST: j = GETARG(codestr, i); h = i - 3 * j; - if (h >= 0 && - j <= lastlc && + if (h >= 0 && + j <= lastlc && ((opcode == BUILD_TUPLE && ISBASICBLOCK(blocks, h, 3*(j+1))) || (opcode == BUILD_LIST && @@ -490,8 +490,8 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, case BINARY_AND: case BINARY_XOR: case BINARY_OR: - if (lastlc >= 2 && - ISBASICBLOCK(blocks, i-6, 7) && + if (lastlc >= 2 && + ISBASICBLOCK(blocks, i-6, 7) && fold_binops_on_constants(&codestr[i-6], consts)) { i -= 2; assert(codestr[i] == LOAD_CONST); @@ -500,13 +500,13 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, break; /* Fold unary ops on constants. - LOAD_CONST c1 UNARY_OP --> LOAD_CONST unary_op(c) */ + LOAD_CONST c1 UNARY_OP --> LOAD_CONST unary_op(c) */ case UNARY_NEGATIVE: case UNARY_CONVERT: case UNARY_INVERT: - if (lastlc >= 1 && - ISBASICBLOCK(blocks, i-3, 4) && - fold_unaryops_on_constants(&codestr[i-3], consts)) { + if (lastlc >= 1 && + ISBASICBLOCK(blocks, i-3, 4) && + fold_unaryops_on_constants(&codestr[i-3], consts)) { i -= 2; assert(codestr[i] == LOAD_CONST); cumlc = 1; @@ -532,8 +532,7 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, tgt = GETJUMPTGT(codestr, i); j = codestr[tgt]; if (CONDITIONAL_JUMP(j)) { - /* NOTE: all possible jumps here are - absolute! */ + /* NOTE: all possible jumps here are absolute! */ if (JUMPS_ON_TRUE(j) == JUMPS_ON_TRUE(opcode)) { /* The second jump will be taken iff the first is. */ @@ -544,13 +543,10 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, SETARG(codestr, i, tgttgt); goto reoptimize_current; } else { - /* The second jump is not taken - if the first is (so jump past - it), and all conditional - jumps pop their argument when - they're not taken (so change - the first jump to pop its - argument when it's taken). */ + /* The second jump is not taken if the first is (so + jump past it), and all conditional jumps pop their + argument when they're not taken (so change the + first jump to pop its argument when it's taken). */ if (JUMPS_ON_TRUE(opcode)) codestr[i] = POP_JUMP_IF_TRUE; else @@ -586,8 +582,8 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names, if (opcode == JUMP_FORWARD) /* JMP_ABS can go backwards */ opcode = JUMP_ABSOLUTE; if (!ABSOLUTE_JUMP(opcode)) - tgttgt -= i + 3; /* Calc relative jump addr */ - if (tgttgt < 0) /* No backward relative jumps */ + tgttgt -= i + 3; /* Calc relative jump addr */ + if (tgttgt < 0) /* No backward relative jumps */ continue; codestr[i] = opcode; SETARG(codestr, i, tgttgt); |