summaryrefslogtreecommitdiffstats
path: root/Python/peephole.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/peephole.c')
-rw-r--r--Python/peephole.c53
1 files changed, 38 insertions, 15 deletions
diff --git a/Python/peephole.c b/Python/peephole.c
index 7c4640c..d012d39 100644
--- a/Python/peephole.c
+++ b/Python/peephole.c
@@ -257,6 +257,37 @@ markblocks(unsigned char *code, int len)
return blocks;
}
+/* Helper to replace LOAD_NAME None/True/False with LOAD_CONST
+ Returns: 0 if no change, 1 if change, -1 if error */
+static int
+load_global(unsigned char *codestr, Py_ssize_t i, char *name, PyObject *consts)
+{
+ Py_ssize_t j;
+ PyObject *obj;
+ if (name == NULL)
+ return 0;
+ if (strcmp(name, "None") == 0)
+ obj = Py_None;
+ else if (strcmp(name, "True") == 0)
+ obj = Py_True;
+ else if (strcmp(name, "False") == 0)
+ obj = Py_False;
+ else
+ return 0;
+ for (j = 0; j < PyList_GET_SIZE(consts); j++) {
+ if (PyList_GET_ITEM(consts, j) == obj)
+ break;
+ }
+ if (j == PyList_GET_SIZE(consts)) {
+ if (PyList_Append(consts, obj) < 0)
+ return -1;
+ }
+ assert(PyList_GET_ITEM(consts, j) == obj);
+ codestr[i] = LOAD_CONST;
+ SETARG(codestr, i, j);
+ return 1;
+}
+
/* Perform basic peephole optimizations to components of a code object.
The consts object should still be in list form to allow new constants
to be appended.
@@ -302,7 +333,7 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
/* Avoid situations where jump retargeting could overflow */
assert(PyString_Check(code));
- codelen = PyString_Size(code);
+ codelen = PyString_GET_SIZE(code);
if (codelen > 32700)
goto exitUnchanged;
@@ -371,25 +402,17 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
codestr[i+3] = NOP;
break;
- /* Replace LOAD_GLOBAL/LOAD_NAME None
- with LOAD_CONST None */
+ /* Replace LOAD_GLOBAL/LOAD_NAME None/True/False
+ with LOAD_CONST None/True/False */
case LOAD_NAME:
case LOAD_GLOBAL:
j = GETARG(codestr, i);
name = PyString_AsString(PyTuple_GET_ITEM(names, j));
- if (name == NULL || strcmp(name, "None") != 0)
+ h = load_global(codestr, i, name, consts);
+ if (h < 0)
+ goto exitUnchanged;
+ else if (h == 0)
continue;
- for (j=0 ; j < PyList_GET_SIZE(consts) ; j++) {
- if (PyList_GET_ITEM(consts, j) == Py_None)
- break;
- }
- if (j == PyList_GET_SIZE(consts)) {
- if (PyList_Append(consts, Py_None) == -1)
- goto exitUnchanged;
- }
- assert(PyList_GET_ITEM(consts, j) == Py_None);
- codestr[i] = LOAD_CONST;
- SETARG(codestr, i, j);
cumlc = lastlc + 1;
break;