summaryrefslogtreecommitdiffstats
path: root/Python/symtable.c
diff options
context:
space:
mode:
authorNeal Norwitz <nnorwitz@gmail.com>2005-11-13 18:50:34 (GMT)
committerNeal Norwitz <nnorwitz@gmail.com>2005-11-13 18:50:34 (GMT)
commitb6fc9df8fc34271a881ab954b843872834f5f112 (patch)
tree6361c1262125e2fec2a92dd4836a8d4f5e40747c /Python/symtable.c
parent6576bd844fb49b37ebbfc6d7567bcd495ddbdbae (diff)
downloadcpython-b6fc9df8fc34271a881ab954b843872834f5f112.zip
cpython-b6fc9df8fc34271a881ab954b843872834f5f112.tar.gz
cpython-b6fc9df8fc34271a881ab954b843872834f5f112.tar.bz2
Fix a lot of memory and ref leaks in error paths.
(Call symtable_exit_block or compiler_exit_scope as appropriate) Use PyMem_Free on c_future since it was allocated with PyMem_Malloc
Diffstat (limited to 'Python/symtable.c')
-rw-r--r--Python/symtable.c108
1 files changed, 75 insertions, 33 deletions
diff --git a/Python/symtable.c b/Python/symtable.c
index 28da563..2681cbd 100644
--- a/Python/symtable.c
+++ b/Python/symtable.c
@@ -16,7 +16,7 @@ PySTEntry_New(struct symtable *st, identifier name, _Py_block_ty block,
void *key, int lineno)
{
PySTEntryObject *ste = NULL;
- PyObject *k, *v;
+ PyObject *k;
k = PyLong_FromVoidPtr(key);
if (k == NULL)
@@ -29,21 +29,22 @@ PySTEntry_New(struct symtable *st, identifier name, _Py_block_ty block,
ste->ste_name = name;
Py_INCREF(name);
-
- v = PyDict_New();
- if (v == NULL)
+
+ ste->ste_symbols = NULL;
+ ste->ste_varnames = NULL;
+ ste->ste_children = NULL;
+
+ ste->ste_symbols = PyDict_New();
+ if (ste->ste_symbols == NULL)
goto fail;
- ste->ste_symbols = v;
- v = PyList_New(0);
- if (v == NULL)
+ ste->ste_varnames = PyList_New(0);
+ if (ste->ste_varnames == NULL)
goto fail;
- ste->ste_varnames = v;
- v = PyList_New(0);
- if (v == NULL)
+ ste->ste_children = PyList_New(0);
+ if (ste->ste_children == NULL)
goto fail;
- ste->ste_children = v;
ste->ste_type = block;
ste->ste_unoptimized = 0;
@@ -187,6 +188,8 @@ symtable_new(void)
return NULL;
st->st_filename = NULL;
+ st->st_symbols = NULL;
+
if ((st->st_stack = PyList_New(0)) == NULL)
goto fail;
if ((st->st_symbols = PyDict_New()) == NULL)
@@ -236,13 +239,18 @@ PySymtable_Build(mod_ty mod, const char *filename, PyFutureFeatures *future)
case Suite_kind:
PyErr_SetString(PyExc_RuntimeError,
"this compiler does not handle Suites");
- return NULL;
+ goto error;
}
- if (!symtable_exit_block(st, (void *)mod))
+ if (!symtable_exit_block(st, (void *)mod)) {
+ PySymtable_Free(st);
return NULL;
+ }
if (symtable_analyze(st))
return st;
+ PySymtable_Free(st);
+ return NULL;
error:
+ (void) symtable_exit_block(st, (void *)mod);
PySymtable_Free(st);
return NULL;
}
@@ -266,15 +274,15 @@ PySymtable_Lookup(struct symtable *st, void *key)
v = PyDict_GetItem(st->st_symbols, k);
if (v) {
assert(PySTEntry_Check(v));
- Py_DECREF(k);
Py_INCREF(v);
- return (PySTEntryObject *)v;
}
else {
PyErr_SetString(PyExc_KeyError,
"unknown symbol table entry");
- return NULL;
}
+
+ Py_DECREF(k);
+ return (PySTEntryObject *)v;
}
int
@@ -329,8 +337,11 @@ PyST_GetScope(PySTEntryObject *ste, PyObject *name)
PyObject *o = PyInt_FromLong(I); \
if (!o) \
return 0; \
- if (PyDict_SetItem((DICT), (NAME), o) < 0) \
+ if (PyDict_SetItem((DICT), (NAME), o) < 0) { \
+ Py_DECREF(o); \
return 0; \
+ } \
+ Py_DECREF(o); \
}
/* Decide on scope of name, given flags.
@@ -536,6 +547,7 @@ update_symbols(PyObject *symbols, PyObject *scope,
Py_DECREF(free_value);
return 0;
}
+ Py_DECREF(o);
}
/* else it's not free, probably a cell */
continue;
@@ -663,7 +675,7 @@ symtable_analyze(struct symtable *st)
return 0;
global = PyDict_New();
if (!global) {
- Py_DECREF(global);
+ Py_DECREF(free);
return 0;
}
r = analyze_block(st->st_top, NULL, free, global);
@@ -820,7 +832,13 @@ error:
#define VISIT(ST, TYPE, V) \
if (!symtable_visit_ ## TYPE((ST), (V))) \
return 0;
-
+
+#define VISIT_IN_BLOCK(ST, TYPE, V, S) \
+ if (!symtable_visit_ ## TYPE((ST), (V))) { \
+ symtable_exit_block((ST), (S)); \
+ return 0; \
+ }
+
#define VISIT_SEQ(ST, TYPE, SEQ) { \
int i; \
asdl_seq *seq = (SEQ); /* avoid variable capture */ \
@@ -830,7 +848,19 @@ error:
return 0; \
} \
}
-
+
+#define VISIT_SEQ_IN_BLOCK(ST, TYPE, SEQ, S) { \
+ int i; \
+ asdl_seq *seq = (SEQ); /* avoid variable capture */ \
+ for (i = 0; i < asdl_seq_LEN(seq); i++) { \
+ TYPE ## _ty elt = asdl_seq_GET(seq, i); \
+ if (!symtable_visit_ ## TYPE((ST), elt)) { \
+ symtable_exit_block((ST), (S)); \
+ return 0; \
+ } \
+ } \
+}
+
#define VISIT_SEQ_TAIL(ST, TYPE, SEQ, START) { \
int i; \
asdl_seq *seq = (SEQ); /* avoid variable capture */ \
@@ -840,7 +870,19 @@ error:
return 0; \
} \
}
-
+
+#define VISIT_SEQ_TAIL_IN_BLOCK(ST, TYPE, SEQ, START, S) { \
+ int i; \
+ asdl_seq *seq = (SEQ); /* avoid variable capture */ \
+ for (i = (START); i < asdl_seq_LEN(seq); i++) { \
+ TYPE ## _ty elt = asdl_seq_GET(seq, i); \
+ if (!symtable_visit_ ## TYPE((ST), elt)) { \
+ symtable_exit_block((ST), (S)); \
+ return 0; \
+ } \
+ } \
+}
+
static int
symtable_visit_stmt(struct symtable *st, stmt_ty s)
{
@@ -855,8 +897,8 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
if (!symtable_enter_block(st, s->v.FunctionDef.name,
FunctionBlock, (void *)s, s->lineno))
return 0;
- VISIT(st, arguments, s->v.FunctionDef.args);
- VISIT_SEQ(st, stmt, s->v.FunctionDef.body);
+ VISIT_IN_BLOCK(st, arguments, s->v.FunctionDef.args, s);
+ VISIT_SEQ_IN_BLOCK(st, stmt, s->v.FunctionDef.body, s);
if (!symtable_exit_block(st, s))
return 0;
break;
@@ -870,7 +912,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
return 0;
tmp = st->st_private;
st->st_private = s->v.ClassDef.name;
- VISIT_SEQ(st, stmt, s->v.ClassDef.body);
+ VISIT_SEQ_IN_BLOCK(st, stmt, s->v.ClassDef.body, s);
st->st_private = tmp;
if (!symtable_exit_block(st, s))
return 0;
@@ -977,7 +1019,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
if (cur < 0)
return 0;
if (cur & (DEF_LOCAL | USE)) {
- char buf[1000];
+ char buf[256];
if (cur & DEF_LOCAL)
PyOS_snprintf(buf, sizeof(buf),
GLOBAL_AFTER_ASSIGN,
@@ -991,9 +1033,7 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
}
if (!symtable_add_def(st, name, DEF_GLOBAL))
return 0;
-
}
-
break;
}
case Expr_kind:
@@ -1031,8 +1071,8 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
if (!symtable_enter_block(st, GET_IDENTIFIER(lambda),
FunctionBlock, (void *)e, 0))
return 0;
- VISIT(st, arguments, e->v.Lambda.args);
- VISIT(st, expr, e->v.Lambda.body);
+ VISIT_IN_BLOCK(st, arguments, e->v.Lambda.args, (void*)e);
+ VISIT_IN_BLOCK(st, expr, e->v.Lambda.body, (void*)e);
if (!symtable_exit_block(st, (void *)e))
return 0;
break;
@@ -1302,12 +1342,14 @@ symtable_visit_genexp(struct symtable *st, expr_ty e)
st->st_cur->ste_generator = 1;
/* Outermost iter is received as an argument */
if (!symtable_implicit_arg(st, 0)) {
+ symtable_exit_block(st, (void *)e);
return 0;
}
- VISIT(st, expr, outermost->target);
- VISIT_SEQ(st, expr, outermost->ifs);
- VISIT_SEQ_TAIL(st, comprehension, e->v.GeneratorExp.generators, 1);
- VISIT(st, expr, e->v.GeneratorExp.elt);
+ VISIT_IN_BLOCK(st, expr, outermost->target, (void*)e);
+ VISIT_SEQ_IN_BLOCK(st, expr, outermost->ifs, (void*)e);
+ VISIT_SEQ_TAIL_IN_BLOCK(st, comprehension,
+ e->v.GeneratorExp.generators, 1, (void*)e);
+ VISIT_IN_BLOCK(st, expr, e->v.GeneratorExp.elt, (void*)e);
if (!symtable_exit_block(st, (void *)e))
return 0;
return 1;