diff options
author | Antoine Pitrou <solipsis@pitrou.net> | 2008-12-18 11:06:25 (GMT) |
---|---|---|
committer | Antoine Pitrou <solipsis@pitrou.net> | 2008-12-18 11:06:25 (GMT) |
commit | f289ae6f01683689dfd07785c9617175b40aea91 (patch) | |
tree | dd9a6f78817fcedbd95db286188507cf21a52bc0 /Python | |
parent | 621601a698a285a45231a6fd223db33566dcb842 (diff) | |
download | cpython-f289ae6f01683689dfd07785c9617175b40aea91.zip cpython-f289ae6f01683689dfd07785c9617175b40aea91.tar.gz cpython-f289ae6f01683689dfd07785c9617175b40aea91.tar.bz2 |
Merged revisions 67818 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r67818 | antoine.pitrou | 2008-12-17 01:38:28 +0100 (mer., 17 déc. 2008) | 3 lines
Issue #2183: Simplify and optimize bytecode for list comprehensions.
........
Diffstat (limited to 'Python')
-rw-r--r-- | Python/ceval.c | 21 | ||||
-rw-r--r-- | Python/compile.c | 33 | ||||
-rw-r--r-- | Python/import.c | 4 |
3 files changed, 29 insertions, 29 deletions
diff --git a/Python/ceval.c b/Python/ceval.c index b17d3db..2ce3ec9 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1306,9 +1306,8 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) case LIST_APPEND: w = POP(); - v = POP(); + v = stack_pointer[-oparg]; err = PyList_Append(v, w); - Py_DECREF(v); Py_DECREF(w); if (err == 0) { PREDICT(JUMP_ABSOLUTE); @@ -1318,9 +1317,8 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) case SET_ADD: w = POP(); - v = POP(); + v = stack_pointer[-oparg]; err = PySet_Add(v, w); - Py_DECREF(v); Py_DECREF(w); if (err == 0) { PREDICT(JUMP_ABSOLUTE); @@ -1935,6 +1933,21 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) if (err == 0) continue; break; + case MAP_ADD: + w = TOP(); /* key */ + u = SECOND(); /* value */ + STACKADJ(-2); + v = stack_pointer[-oparg]; /* dict */ + assert (PyDict_CheckExact(v)); + err = PyDict_SetItem(v, w, u); /* v[w] = u */ + Py_DECREF(u); + Py_DECREF(w); + if (err == 0) { + PREDICT(JUMP_ABSOLUTE); + continue; + } + break; + case LOAD_ATTR: w = GETITEM(names, oparg); v = TOP(); diff --git a/Python/compile.c b/Python/compile.c index 50eb169..36f8c13 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -707,6 +707,8 @@ opcode_stack_effect(int opcode, int oparg) case SET_ADD: case LIST_APPEND: + return -1; + case MAP_ADD: return -2; case BINARY_POWER: @@ -2823,7 +2825,7 @@ compiler_call_helper(struct compiler *c, */ static int -compiler_comprehension_generator(struct compiler *c, PyObject *tmpname, +compiler_comprehension_generator(struct compiler *c, asdl_seq *generators, int gen_index, expr_ty elt, expr_ty val, int type) { @@ -2871,7 +2873,7 @@ compiler_comprehension_generator(struct compiler *c, PyObject *tmpname, } if (++gen_index < asdl_seq_LEN(generators)) - if (!compiler_comprehension_generator(c, tmpname, + if (!compiler_comprehension_generator(c, generators, gen_index, elt, val, type)) return 0; @@ -2886,27 +2888,19 @@ compiler_comprehension_generator(struct compiler *c, PyObject *tmpname, ADDOP(c, POP_TOP); break; case COMP_LISTCOMP: - if (!compiler_nameop(c, tmpname, Load)) - return 0; VISIT(c, expr, elt); - ADDOP(c, LIST_APPEND); + ADDOP_I(c, LIST_APPEND, gen_index + 1); break; case COMP_SETCOMP: - if (!compiler_nameop(c, tmpname, Load)) - return 0; VISIT(c, expr, elt); - ADDOP(c, SET_ADD); + ADDOP_I(c, SET_ADD, gen_index + 1); break; case COMP_DICTCOMP: - if (!compiler_nameop(c, tmpname, Load)) - return 0; /* With 'd[k] = v', v is evaluated before k, so we do - the same. STORE_SUBSCR requires (item, map, key), - so we still end up ROTing once. */ + the same. */ VISIT(c, expr, val); - ADDOP(c, ROT_TWO); VISIT(c, expr, elt); - ADDOP(c, STORE_SUBSCR); + ADDOP_I(c, MAP_ADD, gen_index + 1); break; default: return 0; @@ -2932,7 +2926,6 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type, identifier name, asdl_seq *generators, expr_ty elt, expr_ty val) { PyCodeObject *co = NULL; - identifier tmp = NULL; expr_ty outermost_iter; outermost_iter = ((comprehension_ty) @@ -2943,9 +2936,6 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type, identifier name, if (type != COMP_GENEXP) { int op; - tmp = compiler_new_tmpname(c); - if (!tmp) - goto error_in_scope; switch (type) { case COMP_LISTCOMP: op = BUILD_LIST; @@ -2963,12 +2953,9 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type, identifier name, } ADDOP_I(c, op, 0); - ADDOP(c, DUP_TOP); - if (!compiler_nameop(c, tmp, Store)) - goto error_in_scope; } - if (!compiler_comprehension_generator(c, tmp, generators, 0, elt, + if (!compiler_comprehension_generator(c, generators, 0, elt, val, type)) goto error_in_scope; @@ -2984,7 +2971,6 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type, identifier name, if (!compiler_make_closure(c, co, 0)) goto error; Py_DECREF(co); - Py_XDECREF(tmp); VISIT(c, expr, outermost_iter); ADDOP(c, GET_ITER); @@ -2994,7 +2980,6 @@ error_in_scope: compiler_exit_scope(c); error: Py_XDECREF(co); - Py_XDECREF(tmp); return 0; } diff --git a/Python/import.c b/Python/import.c index 2bad2e5..621284e 100644 --- a/Python/import.c +++ b/Python/import.c @@ -87,8 +87,10 @@ extern time_t PyOS_GetLastModificationTime(char *, FILE *); 3102 (__file__ points to source file) Python 3.0a4: 3110 (WITH_CLEANUP optimization). Python 3.0a5: 3130 (lexical exception stacking, including POP_EXCEPT) + Python 3.1a0: 3140 (optimize list, set and dict comprehensions: + change LIST_APPEND and SET_ADD, add MAP_ADD) */ -#define MAGIC (3130 | ((long)'\r'<<16) | ((long)'\n'<<24)) +#define MAGIC (3140 | ((long)'\r'<<16) | ((long)'\n'<<24)) /* Magic word as global; note that _PyImport_Init() can change the value of this global to accommodate for alterations of how the |