Mercurial > cpython-lru_cache-weakref
diff Python/compile.c @ 29226:3aaf24b949df 2.2
Backport fix for SF bug 734869 and sundry compiler cleanups.
| author | Jeremy Hylton <jeremy@alum.mit.edu> |
|---|---|
| date | Thu, 22 May 2003 16:43:04 +0000 |
| parents | 9b4ff4bf033b |
| children | 76979afc785b |
line wrap: on
line diff
--- a/Python/compile.c Thu May 22 15:39:10 2003 +0000 +++ b/Python/compile.c Thu May 22 16:43:04 2003 +0000 @@ -561,6 +561,7 @@ static void symtable_import(struct symtable *, node *); static void symtable_assign(struct symtable *, node *, int); static void symtable_list_comprehension(struct symtable *, node *); +static void symtable_list_for(struct symtable *, node *); static int symtable_update_free_vars(struct symtable *); static int symtable_undo_free(struct symtable *, PyObject *, PyObject *); @@ -1381,6 +1382,8 @@ { /* listmaker: test list_for */ char tmpname[30]; + + REQ(n, listmaker); PyOS_snprintf(tmpname, sizeof(tmpname), "_[%d]", ++c->c_tmpname); com_addoparg(c, BUILD_LIST, 0); com_addbyte(c, DUP_TOP); /* leave the result on the stack */ @@ -4389,9 +4392,9 @@ } } } - if (list == NULL) /* There used to be a check here for the size of */ - return 0; /* the list being 0, which would have leaked the */ - /* list if that condition was ever possible. JRH */ + if (list == NULL) + return 0; + /* There are cellvars that are also arguments. Create a dict to replace cellvars and put the args at the front. */ @@ -4406,6 +4409,7 @@ goto fail; if (PyDict_DelItem(*cellvars, PyList_GET_ITEM(list, i)) < 0) goto fail; + Py_DECREF(v); } pos = 0; i = PyList_GET_SIZE(list); @@ -4416,6 +4420,7 @@ goto fail; if (PyDict_SetItem(d, v, w) < 0) { Py_DECREF(w); + v = NULL; goto fail; } Py_DECREF(w); @@ -4425,6 +4430,7 @@ return 1; fail: Py_DECREF(d); + Py_XDECREF(v); return -1; } @@ -4688,7 +4694,6 @@ st->st_cur = NULL; st->st_nscopes = 0; st->st_errors = 0; - st->st_tmpname = 0; st->st_private = NULL; return st; fail: @@ -4732,15 +4737,9 @@ for (i = 0; i < PyList_GET_SIZE(ste->ste_children); ++i) { int pos = 0; - if (list) - if (PyList_SetSlice(list, 0, - ((PyVarObject*)list)->ob_size, 0) < 0) + if (list && PyList_SetSlice(list, 0, + PyList_GET_SIZE(list), 0) < 0) return -1; - /* Yes, the above call CAN fail, even though it's reducing - the size of the list. The current implementation will - allocate temp memory equal to the size of the list: this - is avoidable in this specific case, but probably not - worth the effort of special-casing it. - JRH */ child = (PySymtableEntryObject *) PyList_GET_ITEM(ste->ste_children, i); while (PyDict_Next(child->ste_symbols, &pos, &name, &o)) { @@ -4890,9 +4889,6 @@ if (st->st_cur) { prev = st->st_cur; if (PyList_Append(st->st_stack, (PyObject *)st->st_cur) < 0) { - /* Py_DECREF(st->st_cur); */ - /* I believe the previous line would lead to a - double-DECREF when st is disposed - JRH */ st->st_errors++; return; } @@ -5154,12 +5150,12 @@ } goto loop; case list_iter: + /* only occurs when there are multiple for loops + in a list comprehension */ n = CHILD(n, 0); - if (TYPE(n) == list_for) { - st->st_tmpname++; - symtable_list_comprehension(st, n); - st->st_tmpname--; - } else { + if (TYPE(n) == list_for) + symtable_list_for(st, n); + else { REQ(n, list_if); symtable_node(st, CHILD(n, 1)); if (NCH(n) == 3) { @@ -5187,10 +5183,7 @@ /* fall through */ case listmaker: if (NCH(n) > 1 && TYPE(CHILD(n, 1)) == list_for) { - st->st_tmpname++; - symtable_list_comprehension(st, CHILD(n, 1)); - symtable_node(st, CHILD(n, 0)); - st->st_tmpname--; + symtable_list_comprehension(st, n); break; } /* fall through */ @@ -5229,7 +5222,7 @@ } /* The next two functions parse the argument tuple. - symtable_default_arg() checks for names in the default arguments, + symtable_default_args() checks for names in the default arguments, which are references in the defining scope. symtable_params() parses the parameter names, which are defined in the function's body. @@ -5388,10 +5381,23 @@ static void symtable_list_comprehension(struct symtable *st, node *n) { + /* listmaker: test list_for */ char tmpname[30]; - PyOS_snprintf(tmpname, sizeof(tmpname), "_[%d]", st->st_tmpname); + REQ(n, listmaker); + PyOS_snprintf(tmpname, sizeof(tmpname), "_[%d]", + ++st->st_cur->ste_tmpname); symtable_add_def(st, tmpname, DEF_LOCAL); + symtable_list_for(st, CHILD(n, 1)); + symtable_node(st, CHILD(n, 0)); + --st->st_cur->ste_tmpname; +} + +static void +symtable_list_for(struct symtable *st, node *n) +{ + REQ(n, list_for); + /* list_for: for v in expr [list_iter] */ symtable_assign(st, CHILD(n, 1), 0); symtable_node(st, CHILD(n, 3)); if (NCH(n) == 5)
