mirror of
https://github.com/python/cpython.git
synced 2025-08-03 16:39:00 +00:00
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. ........
This commit is contained in:
parent
621601a698
commit
f289ae6f01
8 changed files with 70 additions and 55 deletions
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue