[Python-checkins] commit of r41435 - python/trunk/Python

neal.norwitz@python.org neal.norwitz at python.org
Sun Nov 13 19:50:34 CET 2005


Author: neal.norwitz
Date: Sun Nov 13 19:50:34 2005
New Revision: 41435

Modified:
   python/trunk/Python/compile.c
   python/trunk/Python/symtable.c
Log:
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



Modified: python/trunk/Python/compile.c
==============================================================================
--- python/trunk/Python/compile.c	(original)
+++ python/trunk/Python/compile.c	Sun Nov 13 19:50:34 2005
@@ -302,7 +302,7 @@
 	if (c->c_st)
 		PySymtable_Free(c->c_st);
 	if (c->c_future)
-		PyObject_Free((void *)c->c_future);
+		PyMem_Free(c->c_future);
 	Py_DECREF(c->c_stack);
 }
 
@@ -1607,6 +1607,13 @@
 		return 0; \
 }
 
+#define ADDOP_IN_SCOPE(C, OP) { \
+	if (!compiler_addop((C), (OP))) { \
+		compiler_exit_scope(c); \
+		return 0; \
+	} \
+}
+
 #define ADDOP_O(C, OP, O, TYPE) { \
 	if (!compiler_addop_o((C), (OP), (C)->u->u_ ## TYPE, (O))) \
 		return 0; \
@@ -1641,6 +1648,13 @@
 		return 0; \
 }
 
+#define VISIT_IN_SCOPE(C, TYPE, V) {\
+	if (!compiler_visit_ ## TYPE((C), (V))) { \
+		compiler_exit_scope(c); \
+		return 0; \
+	} \
+}
+
 #define VISIT_SLICE(C, V, CTX) {\
 	if (!compiler_visit_slice((C), (V), (CTX))) \
 		return 0; \
@@ -1656,6 +1670,18 @@
 	} \
 }
 
+#define VISIT_SEQ_IN_SCOPE(C, TYPE, SEQ) { \
+	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 (!compiler_visit_ ## TYPE((C), elt)) { \
+			compiler_exit_scope(c); \
+			return 0; \
+		} \
+	} \
+}
+
 static int
 compiler_isdocstring(stmt_ty s)
 {
@@ -1708,15 +1734,15 @@
 		break;
 	case Interactive_kind:
 		c->c_interactive = 1;
-		VISIT_SEQ(c, stmt, mod->v.Interactive.body);
+		VISIT_SEQ_IN_SCOPE(c, stmt, mod->v.Interactive.body);
 		break;
 	case Expression_kind:
-		VISIT(c, expr, mod->v.Expression.body);
+		VISIT_IN_SCOPE(c, expr, mod->v.Expression.body);
                 addNone = 0;
 		break;
 	case Suite_kind:
 		assert(0);      /* XXX: what should we do here? */
-		VISIT_SEQ(c, stmt, mod->v.Suite.body);
+		VISIT_SEQ_IN_SCOPE(c, stmt, mod->v.Suite.body);
 		break;
         default:
             assert(0);
@@ -1890,7 +1916,7 @@
 		if (i == 0 && s2->kind == Expr_kind &&
 		    s2->v.Expr.value->kind == Str_kind)
 			continue;
-		VISIT(c, stmt, s2);
+		VISIT_IN_SCOPE(c, stmt, s2);
 	}
 	co = assemble(c, 1);
 	compiler_exit_scope(c);
@@ -1945,8 +1971,8 @@
 		return 0;
 	}
 
-	ADDOP(c, LOAD_LOCALS);
-	ADDOP(c, RETURN_VALUE);
+	ADDOP_IN_SCOPE(c, LOAD_LOCALS);
+	ADDOP_IN_SCOPE(c, RETURN_VALUE);
 	co = assemble(c, 1);
 	compiler_exit_scope(c);
 	if (co == NULL)
@@ -1981,8 +2007,8 @@
 	compiler_arguments(c, args);
 	
 	c->u->u_argcount = asdl_seq_LEN(args->args);
-	VISIT(c, expr, e->v.Lambda.body);
-	ADDOP(c, RETURN_VALUE);
+	VISIT_IN_SCOPE(c, expr, e->v.Lambda.body);
+	ADDOP_IN_SCOPE(c, RETURN_VALUE);
 	co = assemble(c, 1);
 	compiler_exit_scope(c);
 	if (co == NULL)

Modified: python/trunk/Python/symtable.c
==============================================================================
--- python/trunk/Python/symtable.c	(original)
+++ python/trunk/Python/symtable.c	Sun Nov 13 19:50:34 2005
@@ -16,7 +16,7 @@
 	      void *key, int lineno)
 {
 	PySTEntryObject *ste = NULL;
-	PyObject *k, *v;
+	PyObject *k;
 
 	k = PyLong_FromVoidPtr(key);
 	if (k == NULL)
@@ -29,21 +29,22 @@
 
 	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 @@
 		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 @@
 	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 @@
 	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 @@
 	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 @@
 					Py_DECREF(free_value);
 					return 0;
 				}
+				Py_DECREF(o);
 			}
 			/* else it's not free, probably a cell */
 			continue;
@@ -663,7 +675,7 @@
 	    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 @@
 #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 @@
 			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 @@
 			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 @@
 		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 @@
 			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 @@
 			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 @@
 			}
 			if (!symtable_add_def(st, name, DEF_GLOBAL))
 				return 0;
-			
 		}
-		
 		break;
 	}
         case Expr_kind:
@@ -1031,8 +1071,8 @@
 		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 @@
 	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;


More information about the Python-checkins mailing list