[Python-checkins] commit of r41739 - in python/trunk: Include/Python-ast.h Include/Python.h Include/asdl.h Include/ast.h Include/compile.h Include/pyarena.h Include/pythonrun.h Makefile.pre.in Parser/asdl_c.py Python/Python-ast.c Python/asdl.c Python/ast.c Python/compile.c Python/import.c Python/pyarena.c Python/pythonrun.c

neal.norwitz python-checkins at python.org
Sat Dec 17 21:54:53 CET 2005


Author: neal.norwitz
Date: Sat Dec 17 21:54:49 2005
New Revision: 41739

Added:
   python/trunk/Include/pyarena.h
   python/trunk/Python/pyarena.c
Modified:
   python/trunk/Include/Python-ast.h
   python/trunk/Include/Python.h
   python/trunk/Include/asdl.h
   python/trunk/Include/ast.h
   python/trunk/Include/compile.h
   python/trunk/Include/pythonrun.h
   python/trunk/Makefile.pre.in
   python/trunk/Parser/asdl_c.py
   python/trunk/Python/Python-ast.c
   python/trunk/Python/asdl.c
   python/trunk/Python/ast.c
   python/trunk/Python/compile.c
   python/trunk/Python/import.c
   python/trunk/Python/pythonrun.c
Log:
Merge from ast-arena.  This reduces the code in Python/ast.c by ~300 lines,
simplifies a lot of error handling code, and fixes many memory leaks.



Modified: python/trunk/Include/Python-ast.h
==============================================================================
--- python/trunk/Include/Python-ast.h	(original)
+++ python/trunk/Include/Python-ast.h	Sat Dec 17 21:54:49 2005
@@ -328,81 +328,79 @@
 };
 
 
-mod_ty Module(asdl_seq * body);
-mod_ty Interactive(asdl_seq * body);
-mod_ty Expression(expr_ty body);
-mod_ty Suite(asdl_seq * body);
+mod_ty Module(asdl_seq * body, PyArena *arena);
+mod_ty Interactive(asdl_seq * body, PyArena *arena);
+mod_ty Expression(expr_ty body, PyArena *arena);
+mod_ty Suite(asdl_seq * body, PyArena *arena);
 stmt_ty FunctionDef(identifier name, arguments_ty args, asdl_seq * body,
-                    asdl_seq * decorators, int lineno);
+                    asdl_seq * decorators, int lineno, PyArena *arena);
 stmt_ty ClassDef(identifier name, asdl_seq * bases, asdl_seq * body, int
-                 lineno);
-stmt_ty Return(expr_ty value, int lineno);
-stmt_ty Delete(asdl_seq * targets, int lineno);
-stmt_ty Assign(asdl_seq * targets, expr_ty value, int lineno);
-stmt_ty AugAssign(expr_ty target, operator_ty op, expr_ty value, int lineno);
-stmt_ty Print(expr_ty dest, asdl_seq * values, bool nl, int lineno);
+                 lineno, PyArena *arena);
+stmt_ty Return(expr_ty value, int lineno, PyArena *arena);
+stmt_ty Delete(asdl_seq * targets, int lineno, PyArena *arena);
+stmt_ty Assign(asdl_seq * targets, expr_ty value, int lineno, PyArena *arena);
+stmt_ty AugAssign(expr_ty target, operator_ty op, expr_ty value, int lineno,
+                  PyArena *arena);
+stmt_ty Print(expr_ty dest, asdl_seq * values, bool nl, int lineno, PyArena
+              *arena);
 stmt_ty For(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * orelse,
-            int lineno);
-stmt_ty While(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno);
-stmt_ty If(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno);
-stmt_ty Raise(expr_ty type, expr_ty inst, expr_ty tback, int lineno);
+            int lineno, PyArena *arena);
+stmt_ty While(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno,
+              PyArena *arena);
+stmt_ty If(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno,
+           PyArena *arena);
+stmt_ty Raise(expr_ty type, expr_ty inst, expr_ty tback, int lineno, PyArena
+              *arena);
 stmt_ty TryExcept(asdl_seq * body, asdl_seq * handlers, asdl_seq * orelse, int
-                  lineno);
-stmt_ty TryFinally(asdl_seq * body, asdl_seq * finalbody, int lineno);
-stmt_ty Assert(expr_ty test, expr_ty msg, int lineno);
-stmt_ty Import(asdl_seq * names, int lineno);
-stmt_ty ImportFrom(identifier module, asdl_seq * names, int lineno);
-stmt_ty Exec(expr_ty body, expr_ty globals, expr_ty locals, int lineno);
-stmt_ty Global(asdl_seq * names, int lineno);
-stmt_ty Expr(expr_ty value, int lineno);
-stmt_ty Pass(int lineno);
-stmt_ty Break(int lineno);
-stmt_ty Continue(int lineno);
-expr_ty BoolOp(boolop_ty op, asdl_seq * values, int lineno);
-expr_ty BinOp(expr_ty left, operator_ty op, expr_ty right, int lineno);
-expr_ty UnaryOp(unaryop_ty op, expr_ty operand, int lineno);
-expr_ty Lambda(arguments_ty args, expr_ty body, int lineno);
-expr_ty Dict(asdl_seq * keys, asdl_seq * values, int lineno);
-expr_ty ListComp(expr_ty elt, asdl_seq * generators, int lineno);
-expr_ty GeneratorExp(expr_ty elt, asdl_seq * generators, int lineno);
-expr_ty Yield(expr_ty value, int lineno);
+                  lineno, PyArena *arena);
+stmt_ty TryFinally(asdl_seq * body, asdl_seq * finalbody, int lineno, PyArena
+                   *arena);
+stmt_ty Assert(expr_ty test, expr_ty msg, int lineno, PyArena *arena);
+stmt_ty Import(asdl_seq * names, int lineno, PyArena *arena);
+stmt_ty ImportFrom(identifier module, asdl_seq * names, int lineno, PyArena
+                   *arena);
+stmt_ty Exec(expr_ty body, expr_ty globals, expr_ty locals, int lineno, PyArena
+             *arena);
+stmt_ty Global(asdl_seq * names, int lineno, PyArena *arena);
+stmt_ty Expr(expr_ty value, int lineno, PyArena *arena);
+stmt_ty Pass(int lineno, PyArena *arena);
+stmt_ty Break(int lineno, PyArena *arena);
+stmt_ty Continue(int lineno, PyArena *arena);
+expr_ty BoolOp(boolop_ty op, asdl_seq * values, int lineno, PyArena *arena);
+expr_ty BinOp(expr_ty left, operator_ty op, expr_ty right, int lineno, PyArena
+              *arena);
+expr_ty UnaryOp(unaryop_ty op, expr_ty operand, int lineno, PyArena *arena);
+expr_ty Lambda(arguments_ty args, expr_ty body, int lineno, PyArena *arena);
+expr_ty Dict(asdl_seq * keys, asdl_seq * values, int lineno, PyArena *arena);
+expr_ty ListComp(expr_ty elt, asdl_seq * generators, int lineno, PyArena
+                 *arena);
+expr_ty GeneratorExp(expr_ty elt, asdl_seq * generators, int lineno, PyArena
+                     *arena);
+expr_ty Yield(expr_ty value, int lineno, PyArena *arena);
 expr_ty Compare(expr_ty left, asdl_seq * ops, asdl_seq * comparators, int
-                lineno);
+                lineno, PyArena *arena);
 expr_ty Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, expr_ty
-             starargs, expr_ty kwargs, int lineno);
-expr_ty Repr(expr_ty value, int lineno);
-expr_ty Num(object n, int lineno);
-expr_ty Str(string s, int lineno);
+             starargs, expr_ty kwargs, int lineno, PyArena *arena);
+expr_ty Repr(expr_ty value, int lineno, PyArena *arena);
+expr_ty Num(object n, int lineno, PyArena *arena);
+expr_ty Str(string s, int lineno, PyArena *arena);
 expr_ty Attribute(expr_ty value, identifier attr, expr_context_ty ctx, int
-                  lineno);
+                  lineno, PyArena *arena);
 expr_ty Subscript(expr_ty value, slice_ty slice, expr_context_ty ctx, int
-                  lineno);
-expr_ty Name(identifier id, expr_context_ty ctx, int lineno);
-expr_ty List(asdl_seq * elts, expr_context_ty ctx, int lineno);
-expr_ty Tuple(asdl_seq * elts, expr_context_ty ctx, int lineno);
-slice_ty Ellipsis(void);
-slice_ty Slice(expr_ty lower, expr_ty upper, expr_ty step);
-slice_ty ExtSlice(asdl_seq * dims);
-slice_ty Index(expr_ty value);
-comprehension_ty comprehension(expr_ty target, expr_ty iter, asdl_seq * ifs);
-excepthandler_ty excepthandler(expr_ty type, expr_ty name, asdl_seq * body);
+                  lineno, PyArena *arena);
+expr_ty Name(identifier id, expr_context_ty ctx, int lineno, PyArena *arena);
+expr_ty List(asdl_seq * elts, expr_context_ty ctx, int lineno, PyArena *arena);
+expr_ty Tuple(asdl_seq * elts, expr_context_ty ctx, int lineno, PyArena *arena);
+slice_ty Ellipsis(PyArena *arena);
+slice_ty Slice(expr_ty lower, expr_ty upper, expr_ty step, PyArena *arena);
+slice_ty ExtSlice(asdl_seq * dims, PyArena *arena);
+slice_ty Index(expr_ty value, PyArena *arena);
+comprehension_ty comprehension(expr_ty target, expr_ty iter, asdl_seq * ifs,
+                               PyArena *arena);
+excepthandler_ty excepthandler(expr_ty type, expr_ty name, asdl_seq * body,
+                               PyArena *arena);
 arguments_ty arguments(asdl_seq * args, identifier vararg, identifier kwarg,
-                       asdl_seq * defaults);
-keyword_ty keyword(identifier arg, expr_ty value);
-alias_ty alias(identifier name, identifier asname);
-
-void free_mod(mod_ty);
-void free_stmt(stmt_ty);
-void free_expr(expr_ty);
-void free_expr_context(expr_context_ty);
-void free_slice(slice_ty);
-void free_boolop(boolop_ty);
-void free_operator(operator_ty);
-void free_unaryop(unaryop_ty);
-void free_cmpop(cmpop_ty);
-void free_comprehension(comprehension_ty);
-void free_excepthandler(excepthandler_ty);
-void free_arguments(arguments_ty);
-void free_keyword(keyword_ty);
-void free_alias(alias_ty);
+                       asdl_seq * defaults, PyArena *arena);
+keyword_ty keyword(identifier arg, expr_ty value, PyArena *arena);
+alias_ty alias(identifier name, identifier asname, PyArena *arena);
 

Modified: python/trunk/Include/Python.h
==============================================================================
--- python/trunk/Include/Python.h	(original)
+++ python/trunk/Include/Python.h	Sat Dec 17 21:54:49 2005
@@ -113,6 +113,7 @@
 
 #include "pystate.h"
 
+#include "pyarena.h"
 #include "modsupport.h"
 #include "pythonrun.h"
 #include "ceval.h"

Modified: python/trunk/Include/asdl.h
==============================================================================
--- python/trunk/Include/asdl.h	(original)
+++ python/trunk/Include/asdl.h	Sat Dec 17 21:54:49 2005
@@ -23,7 +23,7 @@
     void *elements[1];
 } asdl_seq;
 
-asdl_seq *asdl_seq_new(int size);
+asdl_seq *asdl_seq_new(int size, PyArena *arena);
 void asdl_seq_free(asdl_seq *);
 
 #ifdef Py_DEBUG

Modified: python/trunk/Include/ast.h
==============================================================================
--- python/trunk/Include/ast.h	(original)
+++ python/trunk/Include/ast.h	Sat Dec 17 21:54:49 2005
@@ -5,7 +5,7 @@
 #endif
 
 PyAPI_FUNC(mod_ty) PyAST_FromNode(const node *, PyCompilerFlags *flags,
-				  const char *);
+				  const char *, PyArena *);
 
 #ifdef __cplusplus
 }

Modified: python/trunk/Include/compile.h
==============================================================================
--- python/trunk/Include/compile.h	(original)
+++ python/trunk/Include/compile.h	Sat Dec 17 21:54:49 2005
@@ -25,7 +25,7 @@
 
 struct _mod; /* Declare the existence of this type */
 PyAPI_FUNC(PyCodeObject *) PyAST_Compile(struct _mod *, const char *,
-					PyCompilerFlags *);
+					PyCompilerFlags *, PyArena *);
 PyAPI_FUNC(PyFutureFeatures *) PyFuture_FromAST(struct _mod *, const char *);
 
 #define ERR_LATE_FUTURE \

Added: python/trunk/Include/pyarena.h
==============================================================================
--- (empty file)
+++ python/trunk/Include/pyarena.h	Sat Dec 17 21:54:49 2005
@@ -0,0 +1,42 @@
+/* An arena-like memory interface for the compiler.
+ */
+
+#ifndef Py_PYARENA_H
+#define Py_PYARENA_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+  typedef struct _arena PyArena;
+
+  /* PyArena_New() and PyArena_Free() create a new arena and free it,
+     respectively.  Once an arena has been created, it can be used
+     to allocate memory.  Once it is freed, all the memory it allocated
+     is freed and none of its pointers are valid.
+
+     PyArena_New() returns an arena pointer.  On error, it
+     returns a negative number and sets an exception.
+  */
+  PyAPI_FUNC(PyArena *) PyArena_New(void);
+  PyAPI_FUNC(void) PyArena_Free(PyArena *);
+
+  PyAPI_FUNC(void *) PyArena_Malloc(PyArena *, size_t);
+
+  /* The next two routines aren't proper arena allocation routines.
+     They exist to experiment with the arena API without making wholesale
+     changes to the implementation.
+
+     The two functions register pointers with the arena id.  These
+     are externally allocated pointers that will be freed when the
+     arena is freed.  One takes a pointer allocated with malloc.  The
+     other takes a PyObject that is DECREFed when the arena is freed.
+  */
+  PyAPI_FUNC(int) PyArena_AddMallocPointer(PyArena *, void *);
+  PyAPI_FUNC(int) PyArena_AddPyObject(PyArena *, PyObject *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !Py_PYARENA_H */

Modified: python/trunk/Include/pythonrun.h
==============================================================================
--- python/trunk/Include/pythonrun.h	(original)
+++ python/trunk/Include/pythonrun.h	Sat Dec 17 21:54:49 2005
@@ -37,10 +37,12 @@
 PyAPI_FUNC(int) PyRun_InteractiveLoopFlags(FILE *, const char *, PyCompilerFlags *);
 
 PyAPI_FUNC(struct _mod *) PyParser_ASTFromString(const char *, const char *, 
-						 int, PyCompilerFlags *flags);
+						 int, PyCompilerFlags *flags,
+                                                 PyArena *);
 PyAPI_FUNC(struct _mod *) PyParser_ASTFromFile(FILE *, const char *, int, 
 					       char *, char *,
-                                               PyCompilerFlags *, int *);
+                                               PyCompilerFlags *, int *,
+                                               PyArena *);
 #define PyParser_SimpleParseString(S, B) \
         PyParser_SimpleParseStringFlags(S, B, 0)
 #define PyParser_SimpleParseFile(FP, S, B) \

Modified: python/trunk/Makefile.pre.in
==============================================================================
--- python/trunk/Makefile.pre.in	(original)
+++ python/trunk/Makefile.pre.in	Sat Dec 17 21:54:49 2005
@@ -254,6 +254,7 @@
 		Python/modsupport.o \
 		Python/mystrtoul.o \
 		Python/mysnprintf.o \
+		Python/pyarena.o \
 		Python/pyfpe.o \
 		Python/pystate.o \
 		Python/pythonrun.o \
@@ -520,6 +521,7 @@
 		Include/object.h \
 		Include/objimpl.h \
 		Include/patchlevel.h \
+		Include/pyarena.h \
 		Include/pydebug.h \
 		Include/pyerrors.h \
 		Include/pyfpe.h \

Modified: python/trunk/Parser/asdl_c.py
==============================================================================
--- python/trunk/Parser/asdl_c.py	(original)
+++ python/trunk/Parser/asdl_c.py	Sat Dec 17 21:54:49 2005
@@ -249,8 +249,9 @@
         if args:
             argstr = ", ".join(["%s %s" % (atype, aname)
                                 for atype, aname, opt in args])
+            argstr += ", PyArena *arena"
         else:
-            argstr = "void"
+            argstr = "PyArena *arena"
         self.emit("%s %s(%s);" % (ctype, name, argstr), 0)
 
     def visitProduct(self, prod, name):
@@ -265,6 +266,10 @@
             self.emit(s, depth, reflow)
         argstr = ", ".join(["%s %s" % (atype, aname)
                             for atype, aname, opt in args + attrs])
+        if argstr:
+            argstr += ", PyArena *arena"
+        else:
+            argstr = "PyArena *arena"
         self.emit("%s" % ctype, 0)
         emit("%s(%s)" % (name, argstr))
         emit("{")
@@ -280,7 +285,7 @@
                 emit('return NULL;', 2)
                 emit('}', 1)
 
-        emit("p = (%s)malloc(sizeof(*p));" % ctype, 1)
+        emit("p = (%s)PyArena_Malloc(arena, sizeof(*p));" % ctype, 1);
         emit("if (!p) {", 1)
         emit("PyErr_NoMemory();", 2)
         emit("return NULL;", 2)
@@ -655,7 +660,7 @@
     c = ChainOfVisitors(TypeDefVisitor(f),
                         StructVisitor(f),
                         PrototypeVisitor(f),
-                        FreePrototypeVisitor(f),
+##                        FreePrototypeVisitor(f),
                         )
     c.visit(mod)
     f.close()
@@ -671,8 +676,8 @@
     print >> f
     v = ChainOfVisitors(MarshalPrototypeVisitor(f),
                         FunctionVisitor(f),
-                        FreeUtilVisitor(f),
-                        FreeVisitor(f),
+##                        FreeUtilVisitor(f),
+##                        FreeVisitor(f),
                         MarshalUtilVisitor(f),
                         MarshalFunctionVisitor(f),
                         )

Modified: python/trunk/Python/Python-ast.c
==============================================================================
--- python/trunk/Python/Python-ast.c	(original)
+++ python/trunk/Python/Python-ast.c	Sat Dec 17 21:54:49 2005
@@ -19,10 +19,10 @@
 static int marshal_write_alias(PyObject **, int *, alias_ty);
 
 mod_ty
-Module(asdl_seq * body)
+Module(asdl_seq * body, PyArena *arena)
 {
         mod_ty p;
-        p = (mod_ty)malloc(sizeof(*p));
+        p = (mod_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -33,10 +33,10 @@
 }
 
 mod_ty
-Interactive(asdl_seq * body)
+Interactive(asdl_seq * body, PyArena *arena)
 {
         mod_ty p;
-        p = (mod_ty)malloc(sizeof(*p));
+        p = (mod_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -47,7 +47,7 @@
 }
 
 mod_ty
-Expression(expr_ty body)
+Expression(expr_ty body, PyArena *arena)
 {
         mod_ty p;
         if (!body) {
@@ -55,7 +55,7 @@
                                 "field body is required for Expression");
                 return NULL;
         }
-        p = (mod_ty)malloc(sizeof(*p));
+        p = (mod_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -66,10 +66,10 @@
 }
 
 mod_ty
-Suite(asdl_seq * body)
+Suite(asdl_seq * body, PyArena *arena)
 {
         mod_ty p;
-        p = (mod_ty)malloc(sizeof(*p));
+        p = (mod_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -81,7 +81,7 @@
 
 stmt_ty
 FunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq *
-            decorators, int lineno)
+            decorators, int lineno, PyArena *arena)
 {
         stmt_ty p;
         if (!name) {
@@ -94,7 +94,7 @@
                                 "field args is required for FunctionDef");
                 return NULL;
         }
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -109,7 +109,8 @@
 }
 
 stmt_ty
-ClassDef(identifier name, asdl_seq * bases, asdl_seq * body, int lineno)
+ClassDef(identifier name, asdl_seq * bases, asdl_seq * body, int lineno,
+         PyArena *arena)
 {
         stmt_ty p;
         if (!name) {
@@ -117,7 +118,7 @@
                                 "field name is required for ClassDef");
                 return NULL;
         }
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -131,10 +132,10 @@
 }
 
 stmt_ty
-Return(expr_ty value, int lineno)
+Return(expr_ty value, int lineno, PyArena *arena)
 {
         stmt_ty p;
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -146,10 +147,10 @@
 }
 
 stmt_ty
-Delete(asdl_seq * targets, int lineno)
+Delete(asdl_seq * targets, int lineno, PyArena *arena)
 {
         stmt_ty p;
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -161,7 +162,7 @@
 }
 
 stmt_ty
-Assign(asdl_seq * targets, expr_ty value, int lineno)
+Assign(asdl_seq * targets, expr_ty value, int lineno, PyArena *arena)
 {
         stmt_ty p;
         if (!value) {
@@ -169,7 +170,7 @@
                                 "field value is required for Assign");
                 return NULL;
         }
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -182,7 +183,8 @@
 }
 
 stmt_ty
-AugAssign(expr_ty target, operator_ty op, expr_ty value, int lineno)
+AugAssign(expr_ty target, operator_ty op, expr_ty value, int lineno, PyArena
+          *arena)
 {
         stmt_ty p;
         if (!target) {
@@ -200,7 +202,7 @@
                                 "field value is required for AugAssign");
                 return NULL;
         }
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -214,10 +216,10 @@
 }
 
 stmt_ty
-Print(expr_ty dest, asdl_seq * values, bool nl, int lineno)
+Print(expr_ty dest, asdl_seq * values, bool nl, int lineno, PyArena *arena)
 {
         stmt_ty p;
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -232,7 +234,7 @@
 
 stmt_ty
 For(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * orelse, int
-    lineno)
+    lineno, PyArena *arena)
 {
         stmt_ty p;
         if (!target) {
@@ -245,7 +247,7 @@
                                 "field iter is required for For");
                 return NULL;
         }
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -260,7 +262,8 @@
 }
 
 stmt_ty
-While(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno)
+While(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, PyArena
+      *arena)
 {
         stmt_ty p;
         if (!test) {
@@ -268,7 +271,7 @@
                                 "field test is required for While");
                 return NULL;
         }
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -282,7 +285,7 @@
 }
 
 stmt_ty
-If(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno)
+If(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, PyArena *arena)
 {
         stmt_ty p;
         if (!test) {
@@ -290,7 +293,7 @@
                                 "field test is required for If");
                 return NULL;
         }
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -304,10 +307,10 @@
 }
 
 stmt_ty
-Raise(expr_ty type, expr_ty inst, expr_ty tback, int lineno)
+Raise(expr_ty type, expr_ty inst, expr_ty tback, int lineno, PyArena *arena)
 {
         stmt_ty p;
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -321,10 +324,11 @@
 }
 
 stmt_ty
-TryExcept(asdl_seq * body, asdl_seq * handlers, asdl_seq * orelse, int lineno)
+TryExcept(asdl_seq * body, asdl_seq * handlers, asdl_seq * orelse, int lineno,
+          PyArena *arena)
 {
         stmt_ty p;
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -338,10 +342,10 @@
 }
 
 stmt_ty
-TryFinally(asdl_seq * body, asdl_seq * finalbody, int lineno)
+TryFinally(asdl_seq * body, asdl_seq * finalbody, int lineno, PyArena *arena)
 {
         stmt_ty p;
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -354,7 +358,7 @@
 }
 
 stmt_ty
-Assert(expr_ty test, expr_ty msg, int lineno)
+Assert(expr_ty test, expr_ty msg, int lineno, PyArena *arena)
 {
         stmt_ty p;
         if (!test) {
@@ -362,7 +366,7 @@
                                 "field test is required for Assert");
                 return NULL;
         }
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -375,10 +379,10 @@
 }
 
 stmt_ty
-Import(asdl_seq * names, int lineno)
+Import(asdl_seq * names, int lineno, PyArena *arena)
 {
         stmt_ty p;
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -390,7 +394,7 @@
 }
 
 stmt_ty
-ImportFrom(identifier module, asdl_seq * names, int lineno)
+ImportFrom(identifier module, asdl_seq * names, int lineno, PyArena *arena)
 {
         stmt_ty p;
         if (!module) {
@@ -398,7 +402,7 @@
                                 "field module is required for ImportFrom");
                 return NULL;
         }
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -411,7 +415,7 @@
 }
 
 stmt_ty
-Exec(expr_ty body, expr_ty globals, expr_ty locals, int lineno)
+Exec(expr_ty body, expr_ty globals, expr_ty locals, int lineno, PyArena *arena)
 {
         stmt_ty p;
         if (!body) {
@@ -419,7 +423,7 @@
                                 "field body is required for Exec");
                 return NULL;
         }
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -433,10 +437,10 @@
 }
 
 stmt_ty
-Global(asdl_seq * names, int lineno)
+Global(asdl_seq * names, int lineno, PyArena *arena)
 {
         stmt_ty p;
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -448,7 +452,7 @@
 }
 
 stmt_ty
-Expr(expr_ty value, int lineno)
+Expr(expr_ty value, int lineno, PyArena *arena)
 {
         stmt_ty p;
         if (!value) {
@@ -456,7 +460,7 @@
                                 "field value is required for Expr");
                 return NULL;
         }
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -468,10 +472,10 @@
 }
 
 stmt_ty
-Pass(int lineno)
+Pass(int lineno, PyArena *arena)
 {
         stmt_ty p;
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -482,10 +486,10 @@
 }
 
 stmt_ty
-Break(int lineno)
+Break(int lineno, PyArena *arena)
 {
         stmt_ty p;
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -496,10 +500,10 @@
 }
 
 stmt_ty
-Continue(int lineno)
+Continue(int lineno, PyArena *arena)
 {
         stmt_ty p;
-        p = (stmt_ty)malloc(sizeof(*p));
+        p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -510,7 +514,7 @@
 }
 
 expr_ty
-BoolOp(boolop_ty op, asdl_seq * values, int lineno)
+BoolOp(boolop_ty op, asdl_seq * values, int lineno, PyArena *arena)
 {
         expr_ty p;
         if (!op) {
@@ -518,7 +522,7 @@
                                 "field op is required for BoolOp");
                 return NULL;
         }
-        p = (expr_ty)malloc(sizeof(*p));
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -531,7 +535,7 @@
 }
 
 expr_ty
-BinOp(expr_ty left, operator_ty op, expr_ty right, int lineno)
+BinOp(expr_ty left, operator_ty op, expr_ty right, int lineno, PyArena *arena)
 {
         expr_ty p;
         if (!left) {
@@ -549,7 +553,7 @@
                                 "field right is required for BinOp");
                 return NULL;
         }
-        p = (expr_ty)malloc(sizeof(*p));
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -563,7 +567,7 @@
 }
 
 expr_ty
-UnaryOp(unaryop_ty op, expr_ty operand, int lineno)
+UnaryOp(unaryop_ty op, expr_ty operand, int lineno, PyArena *arena)
 {
         expr_ty p;
         if (!op) {
@@ -576,7 +580,7 @@
                                 "field operand is required for UnaryOp");
                 return NULL;
         }
-        p = (expr_ty)malloc(sizeof(*p));
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -589,7 +593,7 @@
 }
 
 expr_ty
-Lambda(arguments_ty args, expr_ty body, int lineno)
+Lambda(arguments_ty args, expr_ty body, int lineno, PyArena *arena)
 {
         expr_ty p;
         if (!args) {
@@ -602,7 +606,7 @@
                                 "field body is required for Lambda");
                 return NULL;
         }
-        p = (expr_ty)malloc(sizeof(*p));
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -615,10 +619,10 @@
 }
 
 expr_ty
-Dict(asdl_seq * keys, asdl_seq * values, int lineno)
+Dict(asdl_seq * keys, asdl_seq * values, int lineno, PyArena *arena)
 {
         expr_ty p;
-        p = (expr_ty)malloc(sizeof(*p));
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -631,7 +635,7 @@
 }
 
 expr_ty
-ListComp(expr_ty elt, asdl_seq * generators, int lineno)
+ListComp(expr_ty elt, asdl_seq * generators, int lineno, PyArena *arena)
 {
         expr_ty p;
         if (!elt) {
@@ -639,7 +643,7 @@
                                 "field elt is required for ListComp");
                 return NULL;
         }
-        p = (expr_ty)malloc(sizeof(*p));
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -652,7 +656,7 @@
 }
 
 expr_ty
-GeneratorExp(expr_ty elt, asdl_seq * generators, int lineno)
+GeneratorExp(expr_ty elt, asdl_seq * generators, int lineno, PyArena *arena)
 {
         expr_ty p;
         if (!elt) {
@@ -660,7 +664,7 @@
                                 "field elt is required for GeneratorExp");
                 return NULL;
         }
-        p = (expr_ty)malloc(sizeof(*p));
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -673,10 +677,10 @@
 }
 
 expr_ty
-Yield(expr_ty value, int lineno)
+Yield(expr_ty value, int lineno, PyArena *arena)
 {
         expr_ty p;
-        p = (expr_ty)malloc(sizeof(*p));
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -688,7 +692,8 @@
 }
 
 expr_ty
-Compare(expr_ty left, asdl_seq * ops, asdl_seq * comparators, int lineno)
+Compare(expr_ty left, asdl_seq * ops, asdl_seq * comparators, int lineno,
+        PyArena *arena)
 {
         expr_ty p;
         if (!left) {
@@ -696,7 +701,7 @@
                                 "field left is required for Compare");
                 return NULL;
         }
-        p = (expr_ty)malloc(sizeof(*p));
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -711,7 +716,7 @@
 
 expr_ty
 Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, expr_ty starargs,
-     expr_ty kwargs, int lineno)
+     expr_ty kwargs, int lineno, PyArena *arena)
 {
         expr_ty p;
         if (!func) {
@@ -719,7 +724,7 @@
                                 "field func is required for Call");
                 return NULL;
         }
-        p = (expr_ty)malloc(sizeof(*p));
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -735,7 +740,7 @@
 }
 
 expr_ty
-Repr(expr_ty value, int lineno)
+Repr(expr_ty value, int lineno, PyArena *arena)
 {
         expr_ty p;
         if (!value) {
@@ -743,7 +748,7 @@
                                 "field value is required for Repr");
                 return NULL;
         }
-        p = (expr_ty)malloc(sizeof(*p));
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -755,7 +760,7 @@
 }
 
 expr_ty
-Num(object n, int lineno)
+Num(object n, int lineno, PyArena *arena)
 {
         expr_ty p;
         if (!n) {
@@ -763,7 +768,7 @@
                                 "field n is required for Num");
                 return NULL;
         }
-        p = (expr_ty)malloc(sizeof(*p));
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -775,7 +780,7 @@
 }
 
 expr_ty
-Str(string s, int lineno)
+Str(string s, int lineno, PyArena *arena)
 {
         expr_ty p;
         if (!s) {
@@ -783,7 +788,7 @@
                                 "field s is required for Str");
                 return NULL;
         }
-        p = (expr_ty)malloc(sizeof(*p));
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -795,7 +800,8 @@
 }
 
 expr_ty
-Attribute(expr_ty value, identifier attr, expr_context_ty ctx, int lineno)
+Attribute(expr_ty value, identifier attr, expr_context_ty ctx, int lineno,
+          PyArena *arena)
 {
         expr_ty p;
         if (!value) {
@@ -813,7 +819,7 @@
                                 "field ctx is required for Attribute");
                 return NULL;
         }
-        p = (expr_ty)malloc(sizeof(*p));
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -827,7 +833,8 @@
 }
 
 expr_ty
-Subscript(expr_ty value, slice_ty slice, expr_context_ty ctx, int lineno)
+Subscript(expr_ty value, slice_ty slice, expr_context_ty ctx, int lineno,
+          PyArena *arena)
 {
         expr_ty p;
         if (!value) {
@@ -845,7 +852,7 @@
                                 "field ctx is required for Subscript");
                 return NULL;
         }
-        p = (expr_ty)malloc(sizeof(*p));
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -859,7 +866,7 @@
 }
 
 expr_ty
-Name(identifier id, expr_context_ty ctx, int lineno)
+Name(identifier id, expr_context_ty ctx, int lineno, PyArena *arena)
 {
         expr_ty p;
         if (!id) {
@@ -872,7 +879,7 @@
                                 "field ctx is required for Name");
                 return NULL;
         }
-        p = (expr_ty)malloc(sizeof(*p));
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -885,7 +892,7 @@
 }
 
 expr_ty
-List(asdl_seq * elts, expr_context_ty ctx, int lineno)
+List(asdl_seq * elts, expr_context_ty ctx, int lineno, PyArena *arena)
 {
         expr_ty p;
         if (!ctx) {
@@ -893,7 +900,7 @@
                                 "field ctx is required for List");
                 return NULL;
         }
-        p = (expr_ty)malloc(sizeof(*p));
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -906,7 +913,7 @@
 }
 
 expr_ty
-Tuple(asdl_seq * elts, expr_context_ty ctx, int lineno)
+Tuple(asdl_seq * elts, expr_context_ty ctx, int lineno, PyArena *arena)
 {
         expr_ty p;
         if (!ctx) {
@@ -914,7 +921,7 @@
                                 "field ctx is required for Tuple");
                 return NULL;
         }
-        p = (expr_ty)malloc(sizeof(*p));
+        p = (expr_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -927,10 +934,10 @@
 }
 
 slice_ty
-Ellipsis()
+Ellipsis(PyArena *arena)
 {
         slice_ty p;
-        p = (slice_ty)malloc(sizeof(*p));
+        p = (slice_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -940,10 +947,10 @@
 }
 
 slice_ty
-Slice(expr_ty lower, expr_ty upper, expr_ty step)
+Slice(expr_ty lower, expr_ty upper, expr_ty step, PyArena *arena)
 {
         slice_ty p;
-        p = (slice_ty)malloc(sizeof(*p));
+        p = (slice_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -956,10 +963,10 @@
 }
 
 slice_ty
-ExtSlice(asdl_seq * dims)
+ExtSlice(asdl_seq * dims, PyArena *arena)
 {
         slice_ty p;
-        p = (slice_ty)malloc(sizeof(*p));
+        p = (slice_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -970,7 +977,7 @@
 }
 
 slice_ty
-Index(expr_ty value)
+Index(expr_ty value, PyArena *arena)
 {
         slice_ty p;
         if (!value) {
@@ -978,7 +985,7 @@
                                 "field value is required for Index");
                 return NULL;
         }
-        p = (slice_ty)malloc(sizeof(*p));
+        p = (slice_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -989,7 +996,7 @@
 }
 
 comprehension_ty
-comprehension(expr_ty target, expr_ty iter, asdl_seq * ifs)
+comprehension(expr_ty target, expr_ty iter, asdl_seq * ifs, PyArena *arena)
 {
         comprehension_ty p;
         if (!target) {
@@ -1002,7 +1009,7 @@
                                 "field iter is required for comprehension");
                 return NULL;
         }
-        p = (comprehension_ty)malloc(sizeof(*p));
+        p = (comprehension_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -1014,10 +1021,10 @@
 }
 
 excepthandler_ty
-excepthandler(expr_ty type, expr_ty name, asdl_seq * body)
+excepthandler(expr_ty type, expr_ty name, asdl_seq * body, PyArena *arena)
 {
         excepthandler_ty p;
-        p = (excepthandler_ty)malloc(sizeof(*p));
+        p = (excepthandler_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -1030,10 +1037,10 @@
 
 arguments_ty
 arguments(asdl_seq * args, identifier vararg, identifier kwarg, asdl_seq *
-          defaults)
+          defaults, PyArena *arena)
 {
         arguments_ty p;
-        p = (arguments_ty)malloc(sizeof(*p));
+        p = (arguments_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -1046,7 +1053,7 @@
 }
 
 keyword_ty
-keyword(identifier arg, expr_ty value)
+keyword(identifier arg, expr_ty value, PyArena *arena)
 {
         keyword_ty p;
         if (!arg) {
@@ -1059,7 +1066,7 @@
                                 "field value is required for keyword");
                 return NULL;
         }
-        p = (keyword_ty)malloc(sizeof(*p));
+        p = (keyword_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -1070,7 +1077,7 @@
 }
 
 alias_ty
-alias(identifier name, identifier asname)
+alias(identifier name, identifier asname, PyArena *arena)
 {
         alias_ty p;
         if (!name) {
@@ -1078,7 +1085,7 @@
                                 "field name is required for alias");
                 return NULL;
         }
-        p = (alias_ty)malloc(sizeof(*p));
+        p = (alias_ty)PyArena_Malloc(arena, sizeof(*p));
         if (!p) {
                 PyErr_NoMemory();
                 return NULL;
@@ -1089,454 +1096,6 @@
 }
 
 
-static void
-free_seq_exprs(asdl_seq *seq)
-{
-        int i, n;
-        n = asdl_seq_LEN(seq);
-        for (i = 0; i < n; i++)
-                free_expr((expr_ty)asdl_seq_GET(seq, i));
-        asdl_seq_free(seq);
-}
-
-static void
-free_seq_stmts(asdl_seq *seq)
-{
-        int i, n;
-        n = asdl_seq_LEN(seq);
-        for (i = 0; i < n; i++)
-                free_stmt((stmt_ty)asdl_seq_GET(seq, i));
-        asdl_seq_free(seq);
-}
-
-
-void
-free_mod(mod_ty o)
-{
-        if (!o)
-                return;
-
-        switch (o->kind) {
-        case Module_kind:
-                free_seq_stmts(o->v.Module.body);
-                break;
-        case Interactive_kind:
-                free_seq_stmts(o->v.Interactive.body);
-                break;
-        case Expression_kind:
-                free_expr((expr_ty)o->v.Expression.body);
-                break;
-        case Suite_kind:
-                free_seq_stmts(o->v.Suite.body);
-                break;
-        }
-
-        free(o);
-}
-
-void
-free_stmt(stmt_ty o)
-{
-        int i, n;
-        asdl_seq *seq;
-
-        if (!o)
-                return;
-
-        switch (o->kind) {
-        case FunctionDef_kind:
-                Py_DECREF((identifier)o->v.FunctionDef.name);
-                free_arguments((arguments_ty)o->v.FunctionDef.args);
-                free_seq_stmts(o->v.FunctionDef.body);
-                free_seq_exprs(o->v.FunctionDef.decorators);
-                break;
-        case ClassDef_kind:
-                Py_DECREF((identifier)o->v.ClassDef.name);
-                free_seq_exprs(o->v.ClassDef.bases);
-                free_seq_stmts(o->v.ClassDef.body);
-                break;
-        case Return_kind:
-                if (o->v.Return.value) {
-                        free_expr((expr_ty)o->v.Return.value);
-                }
-                break;
-        case Delete_kind:
-                free_seq_exprs(o->v.Delete.targets);
-                break;
-        case Assign_kind:
-                free_seq_exprs(o->v.Assign.targets);
-                free_expr((expr_ty)o->v.Assign.value);
-                break;
-        case AugAssign_kind:
-                free_expr((expr_ty)o->v.AugAssign.target);
-                free_operator((operator_ty)o->v.AugAssign.op);
-                free_expr((expr_ty)o->v.AugAssign.value);
-                break;
-        case Print_kind:
-                if (o->v.Print.dest) {
-                        free_expr((expr_ty)o->v.Print.dest);
-                }
-                free_seq_exprs(o->v.Print.values);
-                break;
-        case For_kind:
-                free_expr((expr_ty)o->v.For.target);
-                free_expr((expr_ty)o->v.For.iter);
-                free_seq_stmts(o->v.For.body);
-                free_seq_stmts(o->v.For.orelse);
-                break;
-        case While_kind:
-                free_expr((expr_ty)o->v.While.test);
-                free_seq_stmts(o->v.While.body);
-                free_seq_stmts(o->v.While.orelse);
-                break;
-        case If_kind:
-                free_expr((expr_ty)o->v.If.test);
-                free_seq_stmts(o->v.If.body);
-                free_seq_stmts(o->v.If.orelse);
-                break;
-        case Raise_kind:
-                if (o->v.Raise.type) {
-                        free_expr((expr_ty)o->v.Raise.type);
-                }
-                if (o->v.Raise.inst) {
-                        free_expr((expr_ty)o->v.Raise.inst);
-                }
-                if (o->v.Raise.tback) {
-                        free_expr((expr_ty)o->v.Raise.tback);
-                }
-                break;
-        case TryExcept_kind:
-                free_seq_stmts(o->v.TryExcept.body);
-                seq = o->v.TryExcept.handlers;
-                n = asdl_seq_LEN(seq);
-                for (i = 0; i < n; i++)
-                        free_excepthandler((excepthandler_ty)asdl_seq_GET(seq,
-                                           i));
-                asdl_seq_free(seq);
-                free_seq_stmts(o->v.TryExcept.orelse);
-                break;
-        case TryFinally_kind:
-                free_seq_stmts(o->v.TryFinally.body);
-                free_seq_stmts(o->v.TryFinally.finalbody);
-                break;
-        case Assert_kind:
-                free_expr((expr_ty)o->v.Assert.test);
-                if (o->v.Assert.msg) {
-                        free_expr((expr_ty)o->v.Assert.msg);
-                }
-                break;
-        case Import_kind:
-                seq = o->v.Import.names;
-                n = asdl_seq_LEN(seq);
-                for (i = 0; i < n; i++)
-                        free_alias((alias_ty)asdl_seq_GET(seq, i));
-                asdl_seq_free(seq);
-                break;
-        case ImportFrom_kind:
-                Py_DECREF((identifier)o->v.ImportFrom.module);
-                seq = o->v.ImportFrom.names;
-                n = asdl_seq_LEN(seq);
-                for (i = 0; i < n; i++)
-                        free_alias((alias_ty)asdl_seq_GET(seq, i));
-                asdl_seq_free(seq);
-                break;
-        case Exec_kind:
-                free_expr((expr_ty)o->v.Exec.body);
-                if (o->v.Exec.globals) {
-                        free_expr((expr_ty)o->v.Exec.globals);
-                }
-                if (o->v.Exec.locals) {
-                        free_expr((expr_ty)o->v.Exec.locals);
-                }
-                break;
-        case Global_kind:
-                seq = o->v.Global.names;
-                n = asdl_seq_LEN(seq);
-                for (i = 0; i < n; i++)
-                        Py_DECREF((identifier)asdl_seq_GET(seq, i));
-                asdl_seq_free(seq);
-                break;
-        case Expr_kind:
-                free_expr((expr_ty)o->v.Expr.value);
-                break;
-        case Pass_kind:
-                break;
-        case Break_kind:
-                break;
-        case Continue_kind:
-                break;
-        }
-
-        free(o);
-}
-
-void
-free_expr(expr_ty o)
-{
-        int i, n;
-        asdl_seq *seq;
-
-        if (!o)
-                return;
-
-        switch (o->kind) {
-        case BoolOp_kind:
-                free_boolop((boolop_ty)o->v.BoolOp.op);
-                free_seq_exprs(o->v.BoolOp.values);
-                break;
-        case BinOp_kind:
-                free_expr((expr_ty)o->v.BinOp.left);
-                free_operator((operator_ty)o->v.BinOp.op);
-                free_expr((expr_ty)o->v.BinOp.right);
-                break;
-        case UnaryOp_kind:
-                free_unaryop((unaryop_ty)o->v.UnaryOp.op);
-                free_expr((expr_ty)o->v.UnaryOp.operand);
-                break;
-        case Lambda_kind:
-                free_arguments((arguments_ty)o->v.Lambda.args);
-                free_expr((expr_ty)o->v.Lambda.body);
-                break;
-        case Dict_kind:
-                free_seq_exprs(o->v.Dict.keys);
-                free_seq_exprs(o->v.Dict.values);
-                break;
-        case ListComp_kind:
-                free_expr((expr_ty)o->v.ListComp.elt);
-                seq = o->v.ListComp.generators;
-                n = asdl_seq_LEN(seq);
-                for (i = 0; i < n; i++)
-                        free_comprehension((comprehension_ty)asdl_seq_GET(seq,
-                                           i));
-                asdl_seq_free(seq);
-                break;
-        case GeneratorExp_kind:
-                free_expr((expr_ty)o->v.GeneratorExp.elt);
-                seq = o->v.GeneratorExp.generators;
-                n = asdl_seq_LEN(seq);
-                for (i = 0; i < n; i++)
-                        free_comprehension((comprehension_ty)asdl_seq_GET(seq,
-                                           i));
-                asdl_seq_free(seq);
-                break;
-        case Yield_kind:
-                if (o->v.Yield.value) {
-                        free_expr((expr_ty)o->v.Yield.value);
-                }
-                break;
-        case Compare_kind:
-                free_expr((expr_ty)o->v.Compare.left);
-                seq = o->v.Compare.ops;
-                n = asdl_seq_LEN(seq);
-                for (i = 0; i < n; i++)
-                        free_cmpop((cmpop_ty)asdl_seq_GET(seq, i));
-                asdl_seq_free(seq);
-                free_seq_exprs(o->v.Compare.comparators);
-                break;
-        case Call_kind:
-                free_expr((expr_ty)o->v.Call.func);
-                free_seq_exprs(o->v.Call.args);
-                seq = o->v.Call.keywords;
-                n = asdl_seq_LEN(seq);
-                for (i = 0; i < n; i++)
-                        free_keyword((keyword_ty)asdl_seq_GET(seq, i));
-                asdl_seq_free(seq);
-                if (o->v.Call.starargs) {
-                        free_expr((expr_ty)o->v.Call.starargs);
-                }
-                if (o->v.Call.kwargs) {
-                        free_expr((expr_ty)o->v.Call.kwargs);
-                }
-                break;
-        case Repr_kind:
-                free_expr((expr_ty)o->v.Repr.value);
-                break;
-        case Num_kind:
-                Py_DECREF((object)o->v.Num.n);
-                break;
-        case Str_kind:
-                Py_DECREF((string)o->v.Str.s);
-                break;
-        case Attribute_kind:
-                free_expr((expr_ty)o->v.Attribute.value);
-                Py_DECREF((identifier)o->v.Attribute.attr);
-                free_expr_context((expr_context_ty)o->v.Attribute.ctx);
-                break;
-        case Subscript_kind:
-                free_expr((expr_ty)o->v.Subscript.value);
-                free_slice((slice_ty)o->v.Subscript.slice);
-                free_expr_context((expr_context_ty)o->v.Subscript.ctx);
-                break;
-        case Name_kind:
-                Py_DECREF((identifier)o->v.Name.id);
-                free_expr_context((expr_context_ty)o->v.Name.ctx);
-                break;
-        case List_kind:
-                free_seq_exprs(o->v.List.elts);
-                free_expr_context((expr_context_ty)o->v.List.ctx);
-                break;
-        case Tuple_kind:
-                free_seq_exprs(o->v.Tuple.elts);
-                free_expr_context((expr_context_ty)o->v.Tuple.ctx);
-                break;
-        }
-
-        free(o);
-}
-
-void
-free_expr_context(expr_context_ty o)
-{
-        if (!o)
-                return;
-
-}
-
-void
-free_slice(slice_ty o)
-{
-        int i, n;
-        asdl_seq *seq;
-
-        if (!o)
-                return;
-
-        switch (o->kind) {
-        case Ellipsis_kind:
-                break;
-        case Slice_kind:
-                if (o->v.Slice.lower) {
-                        free_expr((expr_ty)o->v.Slice.lower);
-                }
-                if (o->v.Slice.upper) {
-                        free_expr((expr_ty)o->v.Slice.upper);
-                }
-                if (o->v.Slice.step) {
-                        free_expr((expr_ty)o->v.Slice.step);
-                }
-                break;
-        case ExtSlice_kind:
-                seq = o->v.ExtSlice.dims;
-                n = asdl_seq_LEN(seq);
-                for (i = 0; i < n; i++)
-                        free_slice((slice_ty)asdl_seq_GET(seq, i));
-                asdl_seq_free(seq);
-                break;
-        case Index_kind:
-                free_expr((expr_ty)o->v.Index.value);
-                break;
-        }
-
-        free(o);
-}
-
-void
-free_boolop(boolop_ty o)
-{
-        if (!o)
-                return;
-
-}
-
-void
-free_operator(operator_ty o)
-{
-        if (!o)
-                return;
-
-}
-
-void
-free_unaryop(unaryop_ty o)
-{
-        if (!o)
-                return;
-
-}
-
-void
-free_cmpop(cmpop_ty o)
-{
-        if (!o)
-                return;
-
-}
-
-void
-free_comprehension(comprehension_ty o)
-{
-        if (!o)
-                return;
-
-        free_expr((expr_ty)o->target);
-        free_expr((expr_ty)o->iter);
-        free_seq_exprs(o->ifs);
-
-        free(o);
-}
-
-void
-free_excepthandler(excepthandler_ty o)
-{
-        if (!o)
-                return;
-
-        if (o->type) {
-                free_expr((expr_ty)o->type);
-        }
-        if (o->name) {
-                free_expr((expr_ty)o->name);
-        }
-        free_seq_stmts(o->body);
-
-        free(o);
-}
-
-void
-free_arguments(arguments_ty o)
-{
-        if (!o)
-                return;
-
-        free_seq_exprs(o->args);
-        if (o->vararg) {
-                Py_DECREF((identifier)o->vararg);
-        }
-        if (o->kwarg) {
-                Py_DECREF((identifier)o->kwarg);
-        }
-        free_seq_exprs(o->defaults);
-
-        free(o);
-}
-
-void
-free_keyword(keyword_ty o)
-{
-        if (!o)
-                return;
-
-        Py_DECREF((identifier)o->arg);
-        free_expr((expr_ty)o->value);
-
-        free(o);
-}
-
-void
-free_alias(alias_ty o)
-{
-        if (!o)
-                return;
-
-        Py_DECREF((identifier)o->name);
-        if (o->asname) {
-                Py_DECREF((identifier)o->asname);
-        }
-
-        free(o);
-}
-
-
 
 #define CHECKSIZE(BUF, OFF, MIN) { \
 	int need = *(OFF) + MIN; \

Modified: python/trunk/Python/asdl.c
==============================================================================
--- python/trunk/Python/asdl.c	(original)
+++ python/trunk/Python/asdl.c	Sat Dec 17 21:54:49 2005
@@ -2,17 +2,18 @@
 #include "asdl.h"
 
 asdl_seq *
-asdl_seq_new(int size)
+asdl_seq_new(int size, PyArena *arena)
 {
 	asdl_seq *seq = NULL;
 	size_t n = sizeof(asdl_seq) +
 			(size ? (sizeof(void *) * (size - 1)) : 0);
 
-	seq = (asdl_seq *)PyObject_Malloc(n);
+	seq = (asdl_seq *)malloc(n);
 	if (!seq) {
 		PyErr_NoMemory();
 		return NULL;
 	}
+        PyArena_AddMallocPointer(arena, (void *)seq);
 	memset(seq, 0, n);
 	seq->size = size;
 	return seq;
@@ -21,6 +22,4 @@
 void
 asdl_seq_free(asdl_seq *seq)
 {
-	PyObject_Free(seq);
 }
-

Modified: python/trunk/Python/ast.c
==============================================================================
--- python/trunk/Python/ast.c	(original)
+++ python/trunk/Python/ast.c	Sat Dec 17 21:54:49 2005
@@ -7,6 +7,7 @@
 #include "Python-ast.h"
 #include "grammar.h"
 #include "node.h"
+#include "pyarena.h"
 #include "ast.h"
 #include "token.h"
 #include "parsetok.h"
@@ -20,51 +21,10 @@
    - syntax errors
 */
 
-/*
-  Note:
-  
-  You should rarely need to use the asdl_seq_free() in this file.
-  If you use asdl_seq_free(), you will leak any objects held in the seq.
-  If there is an appropriate asdl_*_seq_free() function, use it.
-  If there isn't an asdl_*_seq_free() function for you, you will
-  need to loop over the data in the sequence and free it.
-
-  asdl_seq* seq;
-  int i;
-
-  for (i = 0; i < asdl_seq_LEN(seq); i++)
-      free_***(asdl_seq_GET(seq, i));
-  asdl_seq_free(seq); / * ok * /
-
-  Almost all of the ast functions return a seq of expr, so you should
-  use asdl_expr_seq_free().  The exception is ast_for_suite() which
-  returns a seq of stmt's, so use asdl_stmt_seq_free() to free it.
-
-  If asdl_seq_free is appropriate, you should mark it with an ok comment.
-
-  There are still many memory problems in this file even though
-  it runs clean in valgrind, save one problem that may have existed
-  before the AST.
-
-  Any code which does something like this:
-
-      return ASTconstruct(local, LINENO(n));
-
-  will leak memory.  The problem is if ASTconstruct (e.g., TryFinally)
-  cannot allocate memory, local will be leaked.
-
-  There was discussion on python-dev to replace the entire allocation
-  scheme in this file with arenas.  Basically rather than allocate
-  memory in little blocks with malloc(), we allocate one big honking
-  hunk and deref everything into this block.  We would still need
-  another block or technique to handle the PyObject*s.
-
-  http://mail.python.org/pipermail/python-dev/2005-November/058138.html
-*/
-
 /* Data structure used internally */
 struct compiling {
-	char *c_encoding; /* source encoding */
+    char *c_encoding; /* source encoding */
+    PyArena *c_arena; /* arena for allocating memeory */
 };
 
 static asdl_seq *seq_for_testlist(struct compiling *, const node *);
@@ -86,63 +46,14 @@
 #define LINENO(n)	((n)->n_lineno)
 #endif
 
-#define NEW_IDENTIFIER(n) PyString_InternFromString(STR(n))
-
-static void
-asdl_stmt_seq_free(asdl_seq* seq)
-{
-    int n, i;
-
-    if (!seq)
-	return;
-
-    n = asdl_seq_LEN(seq);
-    for (i = 0; i < n; i++)
-	free_stmt(asdl_seq_GET(seq, i));
-    asdl_seq_free(seq); /* ok */
+static identifier
+new_identifier(const char* n, PyArena *arena) {
+    PyObject* id = PyString_InternFromString(n);
+    PyArena_AddPyObject(arena, id);
+    return id;
 }
 
-static void
-asdl_expr_seq_free(asdl_seq* seq)
-{
-    int n, i;
-
-    if (!seq)
-	return;
-
-    n = asdl_seq_LEN(seq);
-    for (i = 0; i < n; i++)
-	free_expr(asdl_seq_GET(seq, i));
-    asdl_seq_free(seq); /* ok */
-}
-
-static void
-asdl_alias_seq_free(asdl_seq* seq)
-{
-    int n, i;
-
-    if (!seq)
-	return;
-
-    n = asdl_seq_LEN(seq);
-    for (i = 0; i < n; i++)
-	free_alias(asdl_seq_GET(seq, i));
-    asdl_seq_free(seq); /* ok */
-}
-
-static void
-asdl_comprehension_seq_free(asdl_seq* seq)
-{
-    int n, i;
-
-    if (!seq)
-	return;
-
-    n = asdl_seq_LEN(seq);
-    for (i = 0; i < n; i++)
-	free_comprehension(asdl_seq_GET(seq, i));
-    asdl_seq_free(seq); /* ok */
-}
+#define NEW_IDENTIFIER(n) new_identifier(STR(n), c->c_arena)
 
 /* This routine provides an invalid object for the syntax error.
    The outermost routine must unpack this error and create the
@@ -269,7 +180,8 @@
 */
 
 mod_ty
-PyAST_FromNode(const node *n, PyCompilerFlags *flags, const char *filename)
+PyAST_FromNode(const node *n, PyCompilerFlags *flags, const char *filename,
+               PyArena *arena)
 {
     int i, j, num;
     asdl_seq *stmts = NULL;
@@ -278,17 +190,18 @@
     struct compiling c;
 
     if (flags && flags->cf_flags & PyCF_SOURCE_IS_UTF8) {
-            c.c_encoding = "utf-8";
+        c.c_encoding = "utf-8";
     } else if (TYPE(n) == encoding_decl) {
         c.c_encoding = STR(n);
         n = CHILD(n, 0);
     } else {
         c.c_encoding = NULL;
     }
+    c.c_arena = arena;
 
     switch (TYPE(n)) {
         case file_input:
-            stmts = asdl_seq_new(num_stmts(n));
+            stmts = asdl_seq_new(num_stmts(n), arena);
             if (!stmts)
                     return NULL;
             for (i = 0; i < NCH(n) - 1; i++) {
@@ -314,7 +227,7 @@
                     }
                 }
             }
-            return Module(stmts);
+            return Module(stmts, arena);
         case eval_input: {
             expr_ty testlist_ast;
 
@@ -322,20 +235,20 @@
             testlist_ast = ast_for_testlist(&c, CHILD(n, 0));
             if (!testlist_ast)
                 goto error;
-            return Expression(testlist_ast);
+            return Expression(testlist_ast, arena);
         }
         case single_input:
             if (TYPE(CHILD(n, 0)) == NEWLINE) {
-                stmts = asdl_seq_new(1);
+                stmts = asdl_seq_new(1, arena);
                 if (!stmts)
 		    goto error;
-                asdl_seq_SET(stmts, 0, Pass(n->n_lineno));
-                return Interactive(stmts);
+                asdl_seq_SET(stmts, 0, Pass(n->n_lineno, arena));
+                return Interactive(stmts, arena);
             }
             else {
                 n = CHILD(n, 0);
                 num = num_stmts(n);
-                stmts = asdl_seq_new(num);
+                stmts = asdl_seq_new(num, arena);
                 if (!stmts)
 		    goto error;
                 if (num == 1) {
@@ -358,14 +271,12 @@
                     }
                 }
 
-                return Interactive(stmts);
+                return Interactive(stmts, arena);
             }
         default:
             goto error;
     }
  error:
-    if (stmts)
-	asdl_stmt_seq_free(stmts);
     ast_error_finish(filename);
     return NULL;
 }
@@ -589,7 +500,7 @@
 	   || TYPE(n) == testlist_safe
 	   );
 
-    seq = asdl_seq_new((NCH(n) + 1) / 2);
+    seq = asdl_seq_new((NCH(n) + 1) / 2, c->c_arena);
     if (!seq)
         return NULL;
 
@@ -597,10 +508,8 @@
         REQ(CHILD(n, i), test);
 
         expression = ast_for_expr(c, CHILD(n, i));
-        if (!expression) {
-            asdl_expr_seq_free(seq);
+        if (!expression)
             return NULL;
-        }
 
         assert(i / 2 < seq->size);
         asdl_seq_SET(seq, i / 2, expression);
@@ -609,11 +518,11 @@
 }
 
 static expr_ty
-compiler_complex_args(const node *n)
+compiler_complex_args(struct compiling *c, const node *n)
 {
     int i, len = (NCH(n) + 1) / 2;
     expr_ty result;
-    asdl_seq *args = asdl_seq_new(len);
+    asdl_seq *args = asdl_seq_new(len, c->c_arena);
     if (!args)
         return NULL;
 
@@ -627,15 +536,16 @@
 			ast_error(child, "assignment to None");
 			return NULL;
 		}
-            arg = Name(NEW_IDENTIFIER(child), Store, LINENO(child));
+            arg = Name(NEW_IDENTIFIER(child), Store, LINENO(child),
+                       c->c_arena);
 	}
         else
-            arg = compiler_complex_args(CHILD(CHILD(n, 2*i), 1));
+            arg = compiler_complex_args(c, CHILD(CHILD(n, 2*i), 1));
 	set_context(arg, Store, n);
         asdl_seq_SET(args, i, arg);
     }
 
-    result = Tuple(args, Store, LINENO(n));
+    result = Tuple(args, Store, LINENO(n), c->c_arena);
     set_context(result, Store, n);
     return result;
 }
@@ -660,7 +570,7 @@
 
     if (TYPE(n) == parameters) {
 	if (NCH(n) == 2) /* () as argument list */
-	    return arguments(NULL, NULL, NULL, NULL);
+	    return arguments(NULL, NULL, NULL, NULL, c->c_arena);
 	n = CHILD(n, 1);
     }
     REQ(n, varargslist);
@@ -674,10 +584,10 @@
 	if (TYPE(ch) == EQUAL)
 	    n_defaults++;
     }
-    args = (n_args ? asdl_seq_new(n_args) : NULL);
+    args = (n_args ? asdl_seq_new(n_args, c->c_arena) : NULL);
     if (!args && n_args)
     	return NULL; /* Don't need to go to NULL; nothing allocated */
-    defaults = (n_defaults ? asdl_seq_new(n_defaults) : NULL);
+    defaults = (n_defaults ? asdl_seq_new(n_defaults, c->c_arena) : NULL);
     if (!defaults && n_defaults)
         goto error;
 
@@ -706,7 +616,7 @@
 
                 if (NCH(ch) == 3) {
                     asdl_seq_APPEND(args, 
-                                    compiler_complex_args(CHILD(ch, 1))); 
+                                    compiler_complex_args(c, CHILD(ch, 1))); 
 		}
                 else if (TYPE(CHILD(ch, 0)) == NAME) {
 		    expr_ty name;
@@ -715,7 +625,7 @@
 			    goto error;
 		    }
                     name = Name(NEW_IDENTIFIER(CHILD(ch, 0)),
-                                Param, LINENO(ch));
+                                Param, LINENO(ch), c->c_arena);
                     if (!name)
                         goto error;
                     asdl_seq_APPEND(args, name);
@@ -747,15 +657,11 @@
 	}
     }
 
-    return arguments(args, vararg, kwarg, defaults);
+    return arguments(args, vararg, kwarg, defaults, c->c_arena);
 
  error:
     Py_XDECREF(vararg);
     Py_XDECREF(kwarg);
-    if (args)
-        asdl_expr_seq_free(args);
-    if (defaults)
-        asdl_expr_seq_free(defaults);
     return NULL;
 }
 
@@ -771,29 +677,24 @@
     
     id = NEW_IDENTIFIER(CHILD(n, 0));
     if (!id)
-        goto error;
-    e = Name(id, Load, LINENO(n));
+        return NULL;
+    e = Name(id, Load, LINENO(n), c->c_arena);
     if (!e)
-	goto error;
+	return NULL;
     id = NULL;
 
     for (i = 2; i < NCH(n); i+=2) {
         id = NEW_IDENTIFIER(CHILD(n, i));
 	if (!id)
-	    goto error;
-	attrib = Attribute(e, id, Load, LINENO(CHILD(n, i)));
+	    return NULL;
+	attrib = Attribute(e, id, Load, LINENO(CHILD(n, i)), c->c_arena);
 	if (!attrib)
-	    goto error;
+	    return NULL;
 	e = attrib;
 	attrib = NULL;
     }
 
     return e;
-    
-  error:
-    Py_XDECREF(id);
-    free_expr(e);
-    return NULL;
 }
 
 static expr_ty
@@ -808,36 +709,31 @@
     if ((NCH(n) < 3 && NCH(n) != 5 && NCH(n) != 6)
 	|| TYPE(CHILD(n, 0)) != AT || TYPE(RCHILD(n, -1)) != NEWLINE) {
 	ast_error(n, "Invalid decorator node");
-	goto error;
+	return NULL;
     }
     
     name_expr = ast_for_dotted_name(c, CHILD(n, 1));
     if (!name_expr)
-	goto error;
+	return NULL;
 	
     if (NCH(n) == 3) { /* No arguments */
 	d = name_expr;
 	name_expr = NULL;
     }
     else if (NCH(n) == 5) { /* Call with no arguments */
-	d = Call(name_expr, NULL, NULL, NULL, NULL, LINENO(n));
+	d = Call(name_expr, NULL, NULL, NULL, NULL, LINENO(n), c->c_arena);
 	if (!d)
-	    goto error;
+	    return NULL;
 	name_expr = NULL;
     }
     else {
 	d = ast_for_call(c, CHILD(n, 3), name_expr);
 	if (!d)
-	    goto error;
+	    return NULL;
 	name_expr = NULL;
     }
 
     return d;
-    
-  error:
-    free_expr(name_expr);
-    free_expr(d);
-    return NULL;
 }
 
 static asdl_seq*
@@ -849,20 +745,17 @@
     
     REQ(n, decorators);
 
-    decorator_seq = asdl_seq_new(NCH(n));
+    decorator_seq = asdl_seq_new(NCH(n), c->c_arena);
     if (!decorator_seq)
         return NULL;
 	
     for (i = 0; i < NCH(n); i++) {
 	d = ast_for_decorator(c, CHILD(n, i));
 	if (!d)
-	    goto error;
+	    return NULL;
 	asdl_seq_APPEND(decorator_seq, d);
     }
     return decorator_seq;
-  error:
-    asdl_expr_seq_free(decorator_seq);
-    return NULL;
 }
 
 static stmt_ty
@@ -880,7 +773,7 @@
     if (NCH(n) == 6) { /* decorators are present */
 	decorator_seq = ast_for_decorators(c, CHILD(n, 0));
 	if (!decorator_seq)
-	    goto error;
+	    return NULL;
 	name_i = 2;
     }
     else {
@@ -889,26 +782,19 @@
 
     name = NEW_IDENTIFIER(CHILD(n, name_i));
     if (!name)
-	goto error;
+	return NULL;
     else if (!strcmp(STR(CHILD(n, name_i)), "None")) {
 	ast_error(CHILD(n, name_i), "assignment to None");
-	goto error;
+	return NULL;
     }
     args = ast_for_arguments(c, CHILD(n, name_i + 1));
     if (!args)
-	goto error;
+	return NULL;
     body = ast_for_suite(c, CHILD(n, name_i + 3));
     if (!body)
-	goto error;
-
-    return FunctionDef(name, args, body, decorator_seq, LINENO(n));
+	return NULL;
 
-error:
-    asdl_stmt_seq_free(body);
-    asdl_expr_seq_free(decorator_seq);
-    free_arguments(args);
-    Py_XDECREF(name);
-    return NULL;
+    return FunctionDef(name, args, body, decorator_seq, LINENO(n), c->c_arena);
 }
 
 static expr_ty
@@ -919,27 +805,23 @@
     expr_ty expression;
 
     if (NCH(n) == 3) {
-        args = arguments(NULL, NULL, NULL, NULL);
+        args = arguments(NULL, NULL, NULL, NULL, c->c_arena);
         if (!args)
             return NULL;
         expression = ast_for_expr(c, CHILD(n, 2));
-        if (!expression) {
-            free_arguments(args);
+        if (!expression)
             return NULL;
-        }
     }
     else {
         args = ast_for_arguments(c, CHILD(n, 1));
         if (!args)
             return NULL;
         expression = ast_for_expr(c, CHILD(n, 3));
-        if (!expression) {
-            free_arguments(args);
+        if (!expression)
             return NULL;
-        }
     }
 
-    return Lambda(args, expression, LINENO(n));
+    return Lambda(args, expression, LINENO(n), c->c_arena);
 }
 
 /* Count the number of 'for' loop in a list comprehension.
@@ -1028,12 +910,10 @@
     if (n_fors == -1)
         return NULL;
 
-    listcomps = asdl_seq_new(n_fors);
-    if (!listcomps) {
-        free_expr(elt);
+    listcomps = asdl_seq_new(n_fors, c->c_arena);
+    if (!listcomps)
     	return NULL;
-    }
-    
+
     ch = CHILD(n, 1);
     for (i = 0; i < n_fors; i++) {
 	comprehension_ty lc;
@@ -1043,35 +923,20 @@
 	REQ(ch, list_for);
 
 	t = ast_for_exprlist(c, CHILD(ch, 1), Store);
-        if (!t) {
-            asdl_comprehension_seq_free(listcomps);
-            free_expr(elt);
+        if (!t)
             return NULL;
-        }
         expression = ast_for_testlist(c, CHILD(ch, 3));
-        if (!expression) {
-            asdl_expr_seq_free(t);
-            asdl_comprehension_seq_free(listcomps);
-            free_expr(elt);
+        if (!expression)
             return NULL;
-        }
 
-	if (asdl_seq_LEN(t) == 1) {
-	    lc = comprehension(asdl_seq_GET(t, 0), expression, NULL);
-	    /* only free the sequence since we grabbed element 0 above */
-	    if (lc)
-	        asdl_seq_free(t); /* ok */
-	}
+	if (asdl_seq_LEN(t) == 1)
+	    lc = comprehension(asdl_seq_GET(t, 0), expression, NULL,
+                               c->c_arena);
 	else
-	    lc = comprehension(Tuple(t, Store, LINENO(ch)), expression, NULL);
-
-        if (!lc) {
-            asdl_expr_seq_free(t);
-            asdl_comprehension_seq_free(listcomps);
-            free_expr(expression);
-            free_expr(elt);
+	    lc = comprehension(Tuple(t, Store, LINENO(ch), c->c_arena),
+                               expression, NULL, c->c_arena);
+        if (!lc)
             return NULL;
-        }
 
 	if (NCH(ch) == 5) {
 	    int j, n_ifs;
@@ -1079,20 +944,12 @@
 
 	    ch = CHILD(ch, 4);
 	    n_ifs = count_list_ifs(ch);
-            if (n_ifs == -1) {
-                free_comprehension(lc);
-                asdl_comprehension_seq_free(listcomps);
-                free_expr(elt);
+            if (n_ifs == -1)
                 return NULL;
-            }
 
-	    ifs = asdl_seq_new(n_ifs);
-	    if (!ifs) {
-                free_comprehension(lc);
-		asdl_comprehension_seq_free(listcomps);
-                free_expr(elt);
+	    ifs = asdl_seq_new(n_ifs, c->c_arena);
+	    if (!ifs)
 		return NULL;
-	    }
 
 	    for (j = 0; j < n_ifs; j++) {
 		REQ(ch, list_iter);
@@ -1112,7 +969,7 @@
 	asdl_seq_APPEND(listcomps, lc);
     }
 
-    return ListComp(elt, listcomps, LINENO(n));
+    return ListComp(elt, listcomps, LINENO(n), c->c_arena);
 }
 
 /*
@@ -1198,13 +1055,11 @@
     n_fors = count_gen_fors(n);
     if (n_fors == -1)
         return NULL;
-    
-    genexps = asdl_seq_new(n_fors);
-    if (!genexps) {
-        free_expr(elt);
+
+    genexps = asdl_seq_new(n_fors, c->c_arena);
+    if (!genexps)
         return NULL;
-    }
-    
+
     ch = CHILD(n, 1);
     for (i = 0; i < n_fors; i++) {
         comprehension_ty ge;
@@ -1214,59 +1069,35 @@
         REQ(ch, gen_for);
         
         t = ast_for_exprlist(c, CHILD(ch, 1), Store);
-        if (!t) {
-            asdl_comprehension_seq_free(genexps);
-	    asdl_expr_seq_free(t);
-            free_expr(elt);
+        if (!t)
             return NULL;
-        }
         expression = ast_for_expr(c, CHILD(ch, 3));
-        if (!expression) {
-            asdl_comprehension_seq_free(genexps);
-	    asdl_expr_seq_free(t);
-            free_expr(elt);
+        if (!expression)
             return NULL;
-        }
-        
-        if (asdl_seq_LEN(t) == 1) {
+
+        if (asdl_seq_LEN(t) == 1)
             ge = comprehension(asdl_seq_GET(t, 0), expression,
-                               NULL);
-	    /* only free the sequence since we grabbed element 0 above */
-	    if (ge)
-	        asdl_seq_free(t); /* ok */
-	}
+                               NULL, c->c_arena);
         else
-            ge = comprehension(Tuple(t, Store, LINENO(ch)),
-                               expression, NULL);
-        
-        if (!ge) {
-            asdl_comprehension_seq_free(genexps);
-	    asdl_expr_seq_free(t);
-            free_expr(elt);
+            ge = comprehension(Tuple(t, Store, LINENO(ch), c->c_arena),
+                               expression, NULL, c->c_arena);
+
+        if (!ge)
             return NULL;
-        }
-        
+
         if (NCH(ch) == 5) {
             int j, n_ifs;
             asdl_seq *ifs;
             
             ch = CHILD(ch, 4);
             n_ifs = count_gen_ifs(ch);
-            if (n_ifs == -1) {
-                asdl_comprehension_seq_free(genexps);
-		free_comprehension(ge);
-                free_expr(elt);
+            if (n_ifs == -1)
                 return NULL;
-            }
-            
-            ifs = asdl_seq_new(n_ifs);
-            if (!ifs) {
-                asdl_comprehension_seq_free(genexps);
-		free_comprehension(ge);
-                free_expr(elt);
+
+            ifs = asdl_seq_new(n_ifs, c->c_arena);
+            if (!ifs)
                 return NULL;
-            }
-            
+
             for (j = 0; j < n_ifs; j++) {
                 expr_ty expression;
                 REQ(ch, gen_iter);
@@ -1274,13 +1105,8 @@
                 REQ(ch, gen_if);
                 
                 expression = ast_for_expr(c, CHILD(ch, 1));
-                if (!expression) {
-		    asdl_expr_seq_free(ifs);
-                    asdl_comprehension_seq_free(genexps);
-		    free_comprehension(ge);
-                    free_expr(elt);
+                if (!expression)
                     return NULL;
-                }
                 asdl_seq_APPEND(ifs, expression);
                 if (NCH(ch) == 3)
                     ch = CHILD(ch, 2);
@@ -1293,7 +1119,7 @@
         asdl_seq_APPEND(genexps, ge);
     }
     
-    return GeneratorExp(elt, genexps, LINENO(n));
+    return GeneratorExp(elt, genexps, LINENO(n), c->c_arena);
 }
 
 static expr_ty
@@ -1308,28 +1134,28 @@
     case NAME:
 	/* All names start in Load context, but may later be
 	   changed. */
-	return Name(NEW_IDENTIFIER(ch), Load, LINENO(n));
+	return Name(NEW_IDENTIFIER(ch), Load, LINENO(n), c->c_arena);
     case STRING: {
 	PyObject *str = parsestrplus(c, n);
-	
 	if (!str)
 	    return NULL;
-	
-	return Str(str, LINENO(n));
+
+	PyArena_AddPyObject(c->c_arena, str);
+	return Str(str, LINENO(n), c->c_arena);
     }
     case NUMBER: {
 	PyObject *pynum = parsenumber(STR(ch));
-	
 	if (!pynum)
 	    return NULL;
-	
-	return Num(pynum, LINENO(n));
+
+	PyArena_AddPyObject(c->c_arena, pynum);
+	return Num(pynum, LINENO(n), c->c_arena);
     }
     case LPAR: /* some parenthesized expressions */
 	ch = CHILD(n, 1);
 	
 	if (TYPE(ch) == RPAR)
-	    return Tuple(NULL, Load, LINENO(n));
+	    return Tuple(NULL, Load, LINENO(n), c->c_arena);
 	
 	if (TYPE(ch) == yield_expr)
 	    return ast_for_expr(c, ch);
@@ -1342,16 +1168,15 @@
 	ch = CHILD(n, 1);
 	
 	if (TYPE(ch) == RSQB)
-	    return List(NULL, Load, LINENO(n));
+	    return List(NULL, Load, LINENO(n), c->c_arena);
 	
 	REQ(ch, listmaker);
 	if (NCH(ch) == 1 || TYPE(CHILD(ch, 1)) == COMMA) {
 	    asdl_seq *elts = seq_for_testlist(c, ch);
-	    
 	    if (!elts)
 		return NULL;
-	    
-	    return List(elts, Load, LINENO(n));
+
+	    return List(elts, Load, LINENO(n), c->c_arena);
 	}
 	else
 	    return ast_for_listcomp(c, ch);
@@ -1362,46 +1187,37 @@
 	
 	ch = CHILD(n, 1);
 	size = (NCH(ch) + 1) / 4; /* +1 in case no trailing comma */
-	keys = asdl_seq_new(size);
+	keys = asdl_seq_new(size, c->c_arena);
 	if (!keys)
 	    return NULL;
 	
-	values = asdl_seq_new(size);
-	if (!values) {
-	    asdl_seq_free(keys); /* ok */
+	values = asdl_seq_new(size, c->c_arena);
+	if (!values)
 	    return NULL;
-	}
 	
 	for (i = 0; i < NCH(ch); i += 4) {
 	    expr_ty expression;
 	    
 	    expression = ast_for_expr(c, CHILD(ch, i));
-	    if (!expression) {
-		asdl_expr_seq_free(keys);
-		asdl_expr_seq_free(values);
+	    if (!expression)
 		return NULL;
-	    }
-	    
+
 	    asdl_seq_SET(keys, i / 4, expression);
-	    
+
 	    expression = ast_for_expr(c, CHILD(ch, i + 2));
-	    if (!expression) {
-		asdl_expr_seq_free(keys);
-		asdl_expr_seq_free(values);
+	    if (!expression)
 		return NULL;
-	    }
 
 	    asdl_seq_SET(values, i / 4, expression);
 	}
-	return Dict(keys, values, LINENO(n));
+	return Dict(keys, values, LINENO(n), c->c_arena);
     }
     case BACKQUOTE: { /* repr */
 	expr_ty expression = ast_for_testlist(c, CHILD(n, 1));
-	
 	if (!expression)
 	    return NULL;
-	
-	return Repr(expression, LINENO(n));
+
+	return Repr(expression, LINENO(n), c->c_arena);
     }
     default:
 	PyErr_Format(PyExc_SystemError, "unhandled atom %d", TYPE(ch));
@@ -1423,7 +1239,7 @@
     */
     ch = CHILD(n, 0);
     if (TYPE(ch) == DOT)
-	return Ellipsis();
+	return Ellipsis(c->c_arena);
 
     if (NCH(n) == 1 && TYPE(ch) == test) {
         /* 'step' variable hold no significance in terms of being used over
@@ -1432,7 +1248,7 @@
         if (!step)
             return NULL;
             
-	return Index(step);
+	return Index(step, c->c_arena);
     }
 
     if (TYPE(ch) == test) {
@@ -1477,7 +1293,7 @@
         }
     }
 
-    return Slice(lower, upper, step);
+    return Slice(lower, upper, step, c->c_arena);
 }
 
 static expr_ty
@@ -1504,7 +1320,7 @@
         if (!operator)
             return NULL;
 
-	result = BinOp(expr1, operator, expr2, LINENO(n));
+	result = BinOp(expr1, operator, expr2, LINENO(n), c->c_arena);
 	if (!result)
             return NULL;
 
@@ -1522,7 +1338,7 @@
                     return NULL;
 
                 tmp_result = BinOp(result, operator, tmp, 
-				   LINENO(next_oper));
+				   LINENO(next_oper), c->c_arena);
 		if (!tmp) 
 			return NULL;
 		result = tmp_result;
@@ -1538,7 +1354,7 @@
     REQ(n, trailer);
     if (TYPE(CHILD(n, 0)) == LPAR) {
         if (NCH(n) == 2)
-            e = Call(left_expr, NULL, NULL, NULL, NULL, LINENO(n));
+            e = Call(left_expr, NULL, NULL, NULL, NULL, LINENO(n), c->c_arena);
         else
             e = ast_for_call(c, CHILD(n, 1), left_expr);
     }
@@ -1549,40 +1365,32 @@
             slice_ty slc = ast_for_slice(c, CHILD(n, 0));
             if (!slc)
                 return NULL;
-            e = Subscript(left_expr, slc, Load, LINENO(n));
-            if (!e) {
-                free_slice(slc);
+            e = Subscript(left_expr, slc, Load, LINENO(n), c->c_arena);
+            if (!e)
                 return NULL;
-            }
         }
         else {
             int j;
             slice_ty slc;
-            asdl_seq *slices = asdl_seq_new((NCH(n) + 1) / 2);
+            asdl_seq *slices = asdl_seq_new((NCH(n) + 1) / 2, c->c_arena);
             if (!slices)
                 return NULL;
             for (j = 0; j < NCH(n); j += 2) {
                 slc = ast_for_slice(c, CHILD(n, j));
-                if (!slc) {
-		    for (j = j / 2; j >= 0; j--)
-                        free_slice(asdl_seq_GET(slices, j));
-                    asdl_seq_free(slices); /* ok */
+                if (!slc)
                     return NULL;
-                }
                 asdl_seq_SET(slices, j / 2, slc);
             }
-            e = Subscript(left_expr, ExtSlice(slices), Load, LINENO(n));
-            if (!e) {
-		for (j = 0; j < asdl_seq_LEN(slices); j++)
-                    free_slice(asdl_seq_GET(slices, j));
-                asdl_seq_free(slices); /* ok */
+            e = Subscript(left_expr, ExtSlice(slices, c->c_arena),
+                          Load, LINENO(n), c->c_arena);
+            if (!e)
                 return NULL;
-            }
         }
     }
     else {
         assert(TYPE(CHILD(n, 0)) == DOT);
-        e = Attribute(left_expr, NEW_IDENTIFIER(CHILD(n, 1)), Load, LINENO(n));
+        e = Attribute(left_expr, NEW_IDENTIFIER(CHILD(n, 1)), Load, LINENO(n),
+                      c->c_arena);
     }
     return e;
 }
@@ -1605,24 +1413,17 @@
         if (TYPE(ch) != trailer)
             break;
         tmp = ast_for_trailer(c, ch, e);
-        if (!tmp) {
-            free_expr(e);
+        if (!tmp)
             return NULL;
-        }
         e = tmp;
     }
     if (TYPE(CHILD(n, NCH(n) - 1)) == factor) {
         expr_ty f = ast_for_expr(c, CHILD(n, NCH(n) - 1));
-        if (!f) {
-            free_expr(e);
+        if (!f)
             return NULL;
-        }
-        tmp = BinOp(e, Pow, f, LINENO(n));
-        if (!tmp) {
-            free_expr(f);
-            free_expr(e);
+        tmp = BinOp(e, Pow, f, LINENO(n), c->c_arena);
+        if (!tmp)
             return NULL;
-        }
         e = tmp;
     }
     return e;
@@ -1663,7 +1464,7 @@
                 n = CHILD(n, 0);
                 goto loop;
             }
-            seq = asdl_seq_new((NCH(n) + 1) / 2);
+            seq = asdl_seq_new((NCH(n) + 1) / 2, c->c_arena);
             if (!seq)
                 return NULL;
             for (i = 0; i < NCH(n); i += 2) {
@@ -1673,10 +1474,10 @@
                 asdl_seq_SET(seq, i / 2, e);
             }
             if (!strcmp(STR(CHILD(n, 1)), "and"))
-                return BoolOp(And, seq, LINENO(n));
+                return BoolOp(And, seq, LINENO(n), c->c_arena);
             else {
                 assert(!strcmp(STR(CHILD(n, 1)), "or"));
-                return BoolOp(Or, seq, LINENO(n));
+                return BoolOp(Or, seq, LINENO(n), c->c_arena);
             }
             break;
         case not_test:
@@ -1689,7 +1490,7 @@
                 if (!expression)
                     return NULL;
 
-                return UnaryOp(Not, expression, LINENO(n));
+                return UnaryOp(Not, expression, LINENO(n), c->c_arena);
             }
         case comparison:
             if (NCH(n) == 1) {
@@ -1699,12 +1500,11 @@
             else {
                 expr_ty expression;
                 asdl_seq *ops, *cmps;
-                ops = asdl_seq_new(NCH(n) / 2);
+                ops = asdl_seq_new(NCH(n) / 2, c->c_arena);
                 if (!ops)
                     return NULL;
-                cmps = asdl_seq_new(NCH(n) / 2);
+                cmps = asdl_seq_new(NCH(n) / 2, c->c_arena);
                 if (!cmps) {
-                    asdl_seq_free(ops); /* ok */
                     return NULL;
                 }
                 for (i = 1; i < NCH(n); i += 2) {
@@ -1713,15 +1513,11 @@
 
                     operator = ast_for_comp_op(CHILD(n, i));
                     if (!operator) {
-		        asdl_expr_seq_free(ops);
-		        asdl_expr_seq_free(cmps);
                         return NULL;
 		    }
 
                     expression = ast_for_expr(c, CHILD(n, i + 1));
                     if (!expression) {
-		        asdl_expr_seq_free(ops);
-		        asdl_expr_seq_free(cmps);
                         return NULL;
 		    }
                         
@@ -1730,12 +1526,10 @@
                 }
                 expression = ast_for_expr(c, CHILD(n, 0));
                 if (!expression) {
-		    asdl_expr_seq_free(ops);
-		    asdl_expr_seq_free(cmps);
                     return NULL;
 		}
                     
-                return Compare(expression, ops, cmps, LINENO(n));
+                return Compare(expression, ops, cmps, LINENO(n), c->c_arena);
             }
             break;
 
@@ -1761,7 +1555,7 @@
 		if (!exp)
 		    return NULL;
 	    }
-	    return Yield(exp, LINENO(n));
+	    return Yield(exp, LINENO(n), c->c_arena);
 	}
         case factor: {
             expr_ty expression;
@@ -1777,11 +1571,11 @@
 
             switch (TYPE(CHILD(n, 0))) {
                 case PLUS:
-                    return UnaryOp(UAdd, expression, LINENO(n));
+                    return UnaryOp(UAdd, expression, LINENO(n), c->c_arena);
                 case MINUS:
-                    return UnaryOp(USub, expression, LINENO(n));
+                    return UnaryOp(USub, expression, LINENO(n), c->c_arena);
                 case TILDE:
-                    return UnaryOp(Invert, expression, LINENO(n));
+                    return UnaryOp(Invert, expression, LINENO(n), c->c_arena);
             }
             PyErr_Format(PyExc_SystemError, "unhandled factor: %d",
 	    		 TYPE(CHILD(n, 0)));
@@ -1793,7 +1587,7 @@
             PyErr_Format(PyExc_SystemError, "unhandled expr: %d", TYPE(n));
             return NULL;
     }
-    /* should never get here */
+    /* should never get here unless if error is set*/
     return NULL;
 }
 
@@ -1838,12 +1632,12 @@
       return NULL;
     }
 
-    args = asdl_seq_new(nargs + ngens);
+    args = asdl_seq_new(nargs + ngens, c->c_arena);
     if (!args)
-        goto error;
-    keywords = asdl_seq_new(nkeywords);
+        return NULL;
+    keywords = asdl_seq_new(nkeywords, c->c_arena);
     if (!keywords)
-        goto error;
+        return NULL;
     nargs = 0;
     nkeywords = 0;
     for (i = 0; i < NCH(n); i++) {
@@ -1853,13 +1647,13 @@
 	    if (NCH(ch) == 1) {
 		e = ast_for_expr(c, CHILD(ch, 0));
                 if (!e)
-                    goto error;
+                    return NULL;
 		asdl_seq_SET(args, nargs++, e);
 	    }  
 	    else if (TYPE(CHILD(ch, 1)) == gen_for) {
         	e = ast_for_genexp(c, ch);
                 if (!e)
-                    goto error;
+                    return NULL;
 		asdl_seq_SET(args, nargs++, e);
             }
 	    else {
@@ -1869,7 +1663,7 @@
 		/* CHILD(ch, 0) is test, but must be an identifier? */ 
 		e = ast_for_expr(c, CHILD(ch, 0));
                 if (!e)
-                    goto error;
+                    return NULL;
                 /* f(lambda x: x[0] = 3) ends up getting parsed with
                  * LHS test = lambda x: x[0], and RHS test = 3.
                  * SF bug 132313 points out that complaining about a keyword
@@ -1877,19 +1671,18 @@
                  */
                 if (e->kind == Lambda_kind) {
                   ast_error(CHILD(ch, 0), "lambda cannot contain assignment");
-                  goto error;
+                  return NULL;
                 } else if (e->kind != Name_kind) {
                   ast_error(CHILD(ch, 0), "keyword can't be an expression");
-                  goto error;
+                  return NULL;
                 }
 		key = e->v.Name.id;
-		free(e); /* XXX: is free correct here? */
 		e = ast_for_expr(c, CHILD(ch, 2));
                 if (!e)
-                    goto error;
-		kw = keyword(key, e);
+                    return NULL;
+		kw = keyword(key, e, c->c_arena);
                 if (!kw)
-                    goto error;
+                    return NULL;
 		asdl_seq_SET(keywords, nkeywords++, kw);
 	    }
 	}
@@ -1903,19 +1696,7 @@
 	}
     }
 
-    return Call(func, args, keywords, vararg, kwarg, LINENO(n));
-
- error:
-    free_expr(vararg);
-    free_expr(kwarg);
-    if (args)
-        asdl_expr_seq_free(args);
-    if (keywords) {
-	for (i = 0; i < asdl_seq_LEN(keywords); i++)
-            free_keyword(asdl_seq_GET(keywords, i));
-        asdl_seq_free(keywords); /* ok */
-    }
-    return NULL;
+    return Call(func, args, keywords, vararg, kwarg, LINENO(n), c->c_arena);
 }
 
 static expr_ty
@@ -1941,7 +1722,7 @@
         asdl_seq *tmp = seq_for_testlist(c, n);
         if (!tmp)
             return NULL;
-	return Tuple(tmp, Load, LINENO(n));
+	return Tuple(tmp, Load, LINENO(n), c->c_arena);
     }
 }
 
@@ -1967,12 +1748,11 @@
     REQ(n, testlist);
     if (NCH(n) == 1) {
         expr_ty base;
-        asdl_seq *bases = asdl_seq_new(1);
+        asdl_seq *bases = asdl_seq_new(1, c->c_arena);
         if (!bases)
             return NULL;
         base = ast_for_expr(c, CHILD(n, 0));
         if (!base) {
-            asdl_seq_free(bases); /* ok */
             return NULL;
         }
         asdl_seq_SET(bases, 0, base);
@@ -2000,7 +1780,7 @@
         if (!e)
             return NULL;
 
-	return Expr(e, LINENO(n));
+	return Expr(e, LINENO(n), c->c_arena);
     }
     else if (TYPE(CHILD(n, 1)) == augassign) {
         expr_ty expr1, expr2;
@@ -2010,12 +1790,12 @@
 	if (TYPE(ch) == testlist)
 	    expr1 = ast_for_testlist(c, ch);
 	else
-	    expr1 = Yield(ast_for_expr(c, CHILD(ch, 0)), LINENO(ch));
+	    expr1 = Yield(ast_for_expr(c, CHILD(ch, 0)), LINENO(ch),
+                          c->c_arena);
 
         if (!expr1)
             return NULL;
         if (expr1->kind == GeneratorExp_kind) {
-	    free_expr(expr1);
 	    ast_error(ch, "augmented assignment to generator "
 		      "expression not possible");
 	    return NULL;
@@ -2023,7 +1803,6 @@
 	if (expr1->kind == Name_kind) {
 		char *var_name = PyString_AS_STRING(expr1->v.Name.id);
 		if (var_name[0] == 'N' && !strcmp(var_name, "None")) {
-			free_expr(expr1);
 			ast_error(ch, "assignment to None");
 			return NULL;
 		}
@@ -2033,20 +1812,17 @@
 	if (TYPE(ch) == testlist)
 	    expr2 = ast_for_testlist(c, ch);
 	else
-	    expr2 = Yield(ast_for_expr(c, ch), LINENO(ch));
+	    expr2 = Yield(ast_for_expr(c, ch), LINENO(ch), c->c_arena);
         if (!expr2) {
-            free_expr(expr1);
             return NULL;
         }
 
         operator = ast_for_augassign(CHILD(n, 1));
         if (!operator) {
-            free_expr(expr1);
-            free_expr(expr2);
             return NULL;
         }
 
-	return AugAssign(expr1, operator, expr2, LINENO(n));
+	return AugAssign(expr1, operator, expr2, LINENO(n), c->c_arena);
     }
     else {
 	int i;
@@ -2056,7 +1832,7 @@
 
 	/* a normal assignment */
 	REQ(CHILD(n, 1), EQUAL);
-	targets = asdl_seq_new(NCH(n) / 2);
+	targets = asdl_seq_new(NCH(n) / 2, c->c_arena);
 	if (!targets)
 	    return NULL;
 	for (i = 0; i < NCH(n) - 2; i += 2) {
@@ -2064,17 +1840,16 @@
 	    node *ch = CHILD(n, i);
 	    if (TYPE(ch) == yield_expr) {
 		ast_error(ch, "assignment to yield expression not possible");
-		goto error;
+		return NULL;
 	    }
 	    e = ast_for_testlist(c, ch);
 
 	    /* set context to assign */
 	    if (!e) 
-	      goto error;
+	      return NULL;
 
 	    if (!set_context(e, Store, CHILD(n, i))) {
-              free_expr(e);
-	      goto error;
+	      return NULL;
             }
 
 	    asdl_seq_SET(targets, i / 2, e);
@@ -2085,12 +1860,9 @@
 	else
 	    expression = ast_for_expr(c, value);
 	if (!expression)
-	    goto error;
-	return Assign(targets, expression, LINENO(n));
-    error:
-        asdl_expr_seq_free(targets);
+	    return NULL;
+	return Assign(targets, expression, LINENO(n), c->c_arena);
     }
-    return NULL;
 }
 
 static stmt_ty
@@ -2111,21 +1883,19 @@
             return NULL;
 	start = 4;
     }
-    seq = asdl_seq_new((NCH(n) + 1 - start) / 2);
+    seq = asdl_seq_new((NCH(n) + 1 - start) / 2, c->c_arena);
     if (!seq)
 	return NULL;
     for (i = start; i < NCH(n); i += 2) {
         expression = ast_for_expr(c, CHILD(n, i));
         if (!expression) {
-	    free_expr(dest);
-	    asdl_expr_seq_free(seq);
             return NULL;
 	}
 
 	asdl_seq_APPEND(seq, expression);
     }
     nl = (TYPE(CHILD(n, NCH(n) - 1)) == COMMA) ? false : true;
-    return Print(dest, seq, nl, LINENO(n));
+    return Print(dest, seq, nl, LINENO(n), c->c_arena);
 }
 
 static asdl_seq *
@@ -2137,24 +1907,20 @@
 
     REQ(n, exprlist);
 
-    seq = asdl_seq_new((NCH(n) + 1) / 2);
+    seq = asdl_seq_new((NCH(n) + 1) / 2, c->c_arena);
     if (!seq)
 	return NULL;
     for (i = 0; i < NCH(n); i += 2) {
 	e = ast_for_expr(c, CHILD(n, i));
 	if (!e)
-	    goto error;
+	    return NULL;
 	asdl_seq_SET(seq, i / 2, e);
 	if (context) {
 	    if (!set_context(e, context, CHILD(n, i)))
-	    	goto error;
+	    	return NULL;
         }
     }
     return seq;
-
-error:
-    asdl_expr_seq_free(seq);
-    return NULL;
 }
 
 static stmt_ty
@@ -2168,7 +1934,7 @@
     expr_list = ast_for_exprlist(c, CHILD(n, 1), Del);
     if (!expr_list)
         return NULL;
-    return Delete(expr_list, LINENO(n));
+    return Delete(expr_list, LINENO(n), c->c_arena);
 }
 
 static stmt_ty
@@ -2190,32 +1956,32 @@
     ch = CHILD(n, 0);
     switch (TYPE(ch)) {
         case break_stmt:
-            return Break(LINENO(n));
+            return Break(LINENO(n), c->c_arena);
         case continue_stmt:
-            return Continue(LINENO(n));
+            return Continue(LINENO(n), c->c_arena);
         case yield_stmt: { /* will reduce to yield_expr */
 	    expr_ty exp = ast_for_expr(c, CHILD(ch, 0));
 	    if (!exp)
 		return NULL;
-            return Expr(exp, LINENO(n));
+            return Expr(exp, LINENO(n), c->c_arena);
         }
         case return_stmt:
             if (NCH(ch) == 1)
-                return Return(NULL, LINENO(n));
+                return Return(NULL, LINENO(n), c->c_arena);
             else {
                 expr_ty expression = ast_for_testlist(c, CHILD(ch, 1));
                 if (!expression)
                     return NULL;
-                return Return(expression, LINENO(n));
+                return Return(expression, LINENO(n), c->c_arena);
             }
         case raise_stmt:
             if (NCH(ch) == 1)
-                return Raise(NULL, NULL, NULL, LINENO(n));
+                return Raise(NULL, NULL, NULL, LINENO(n), c->c_arena);
             else if (NCH(ch) == 2) {
                 expr_ty expression = ast_for_expr(c, CHILD(ch, 1));
                 if (!expression)
                     return NULL;
-                return Raise(expression, NULL, NULL, LINENO(n));
+                return Raise(expression, NULL, NULL, LINENO(n), c->c_arena);
             }
             else if (NCH(ch) == 4) {
                 expr_ty expr1, expr2;
@@ -2227,7 +1993,7 @@
                 if (!expr2)
                     return NULL;
 
-                return Raise(expr1, expr2, NULL, LINENO(n));
+                return Raise(expr1, expr2, NULL, LINENO(n), c->c_arena);
             }
             else if (NCH(ch) == 6) {
                 expr_ty expr1, expr2, expr3;
@@ -2242,7 +2008,7 @@
                 if (!expr3)
                     return NULL;
                     
-                return Raise(expr1, expr2, expr3, LINENO(n));
+                return Raise(expr1, expr2, expr3, LINENO(n), c->c_arena);
             }
         default:
             PyErr_Format(PyExc_SystemError,
@@ -2252,22 +2018,24 @@
 }
 
 static alias_ty
-alias_for_import_name(const node *n)
+alias_for_import_name(struct compiling *c, const node *n)
 {
     /*
       import_as_name: NAME [NAME NAME]
       dotted_as_name: dotted_name [NAME NAME]
       dotted_name: NAME ('.' NAME)*
     */
+    PyObject *str;
+
  loop:
     switch (TYPE(n)) {
         case import_as_name:
             if (NCH(n) == 3)
                 return alias(NEW_IDENTIFIER(CHILD(n, 0)),
-                             NEW_IDENTIFIER(CHILD(n, 2)));
+                             NEW_IDENTIFIER(CHILD(n, 2)), c->c_arena);
             else
                 return alias(NEW_IDENTIFIER(CHILD(n, 0)),
-                             NULL);
+                             NULL, c->c_arena);
             break;
         case dotted_as_name:
             if (NCH(n) == 1) {
@@ -2275,7 +2043,7 @@
                 goto loop;
             }
             else {
-                alias_ty a = alias_for_import_name(CHILD(n, 0));
+                alias_ty a = alias_for_import_name(c, CHILD(n, 0));
                 assert(!a->asname);
                 a->asname = NEW_IDENTIFIER(CHILD(n, 2));
                 return a;
@@ -2283,11 +2051,10 @@
             break;
         case dotted_name:
             if (NCH(n) == 1)
-                return alias(NEW_IDENTIFIER(CHILD(n, 0)), NULL);
+                return alias(NEW_IDENTIFIER(CHILD(n, 0)), NULL, c->c_arena);
             else {
                 /* Create a string of the form "a.b.c" */
                 int i, len;
-                PyObject *str;
                 char *s;
 
                 len = 0;
@@ -2310,11 +2077,14 @@
                 --s;
                 *s = '\0';
                 PyString_InternInPlace(&str);
-                return alias(str, NULL);
+		PyArena_AddPyObject(c->c_arena, str);
+                return alias(str, NULL, c->c_arena);
             }
             break;
         case STAR:
-            return alias(PyString_InternFromString("*"), NULL);
+	    str = PyString_InternFromString("*");
+	    PyArena_AddPyObject(c->c_arena, str);
+            return alias(str, NULL, c->c_arena);
         default:
             PyErr_Format(PyExc_SystemError,
                          "unexpected import name: %d", TYPE(n));
@@ -2341,25 +2111,23 @@
     if (STR(CHILD(n, 0))[0] == 'i') { /* import */
         n = CHILD(n, 1);
 	REQ(n, dotted_as_names);
-	aliases = asdl_seq_new((NCH(n) + 1) / 2);
+	aliases = asdl_seq_new((NCH(n) + 1) / 2, c->c_arena);
 	if (!aliases)
 		return NULL;
 	for (i = 0; i < NCH(n); i += 2) {
-            alias_ty import_alias = alias_for_import_name(CHILD(n, i));
+            alias_ty import_alias = alias_for_import_name(c, CHILD(n, i));
             if (!import_alias) {
-                asdl_alias_seq_free(aliases);
                 return NULL;
             }
 	    asdl_seq_SET(aliases, i / 2, import_alias);
         }
-	return Import(aliases, LINENO(n));
+	return Import(aliases, LINENO(n), c->c_arena);
     }
     else if (STR(CHILD(n, 0))[0] == 'f') { /* from */
-	stmt_ty import;
         int n_children;
         const char *from_modules;
 	int lineno = LINENO(n);
-	alias_ty mod = alias_for_import_name(CHILD(n, 1));
+	alias_ty mod = alias_for_import_name(c, CHILD(n, 1));
 	if (!mod)
             return NULL;
 
@@ -2370,7 +2138,6 @@
             n = CHILD(n, 3);                  /* from ... import x, y, z */
             if (NCH(n) % 2 == 0) {
                 /* it ends with a comma, not valid but the parser allows it */
-		free_alias(mod);
                 ast_error(n, "trailing comma not allowed without"
                              " surrounding parentheses");
                 return NULL;
@@ -2383,7 +2150,6 @@
             n = CHILD(n, 4);                  /* from ... import (x, y, z) */
         else {
 	    /* XXX: don't we need to call ast_error(n, "..."); */
-	    free_alias(mod);
             return NULL;
 	}
 
@@ -2391,36 +2157,28 @@
         if (from_modules && from_modules[0] == '*')
             n_children = 1;
 
-	aliases = asdl_seq_new((n_children + 1) / 2);
+	aliases = asdl_seq_new((n_children + 1) / 2, c->c_arena);
 	if (!aliases) {
-            free_alias(mod);
             return NULL;
 	}
 
         /* handle "from ... import *" special b/c there's no children */
         if (from_modules && from_modules[0] == '*') {
-            alias_ty import_alias = alias_for_import_name(n);
+            alias_ty import_alias = alias_for_import_name(c, n);
             if (!import_alias) {
-                asdl_alias_seq_free(aliases);
-                free_alias(mod);
                 return NULL;
             }
 	    asdl_seq_APPEND(aliases, import_alias);
         }
 
 	for (i = 0; i < NCH(n); i += 2) {
-            alias_ty import_alias = alias_for_import_name(CHILD(n, i));
+            alias_ty import_alias = alias_for_import_name(c, CHILD(n, i));
             if (!import_alias) {
-                asdl_alias_seq_free(aliases);
-                free_alias(mod);
                 return NULL;
             }
 	    asdl_seq_APPEND(aliases, import_alias);
         }
-        Py_INCREF(mod->name);
-	import = ImportFrom(mod->name, aliases, lineno);
-	free_alias(mod);
-	return import;
+	return ImportFrom(mod->name, aliases, lineno, c->c_arena);
     }
     PyErr_Format(PyExc_SystemError,
                  "unknown import statement: starts with command '%s'",
@@ -2437,20 +2195,17 @@
     int i;
 
     REQ(n, global_stmt);
-    s = asdl_seq_new(NCH(n) / 2);
+    s = asdl_seq_new(NCH(n) / 2, c->c_arena);
     if (!s)
     	return NULL;
     for (i = 1; i < NCH(n); i += 2) {
 	name = NEW_IDENTIFIER(CHILD(n, i));
 	if (!name) {
-	    for (i = i / 2; i > 0; i--)
-                Py_XDECREF((identifier) asdl_seq_GET(s, i));
-	    asdl_seq_free(s); /* ok */
 	    return NULL;
 	}
 	asdl_seq_SET(s, i / 2, name);
     }
-    return Global(s, LINENO(n));
+    return Global(s, LINENO(n), c->c_arena);
 }
 
 static stmt_ty
@@ -2481,7 +2236,7 @@
             return NULL;
     }
 
-    return Exec(expr1, globals, locals, LINENO(n));
+    return Exec(expr1, globals, locals, LINENO(n), c->c_arena);
 }
 
 static stmt_ty
@@ -2493,7 +2248,7 @@
         expr_ty expression = ast_for_expr(c, CHILD(n, 1));
         if (!expression)
             return NULL;
-	return Assert(expression, NULL, LINENO(n));
+	return Assert(expression, NULL, LINENO(n), c->c_arena);
     }
     else if (NCH(n) == 4) {
         expr_ty expr1, expr2;
@@ -2505,7 +2260,7 @@
         if (!expr2)
             return NULL;
             
-	return Assert(expr1, expr2, LINENO(n));
+	return Assert(expr1, expr2, LINENO(n), c->c_arena);
     }
     PyErr_Format(PyExc_SystemError,
                  "improper number of parts to 'assert' statement: %d",
@@ -2525,7 +2280,7 @@
     REQ(n, suite);
 
     total = num_stmts(n);
-    seq = asdl_seq_new(total);
+    seq = asdl_seq_new(total, c->c_arena);
     if (!seq)
     	return NULL;
     if (TYPE(CHILD(n, 0)) == simple_stmt) {
@@ -2541,7 +2296,7 @@
 	    ch = CHILD(n, i);
 	    s = ast_for_stmt(c, ch);
 	    if (!s)
-		goto error;
+		return NULL;
 	    asdl_seq_SET(seq, pos++, s);
 	}
     }
@@ -2554,7 +2309,7 @@
 		/* small_stmt or compound_stmt with only one child */
 		s = ast_for_stmt(c, ch);
 		if (!s)
-		    goto error;
+		    return NULL;
 		asdl_seq_SET(seq, pos++, s);
 	    }
 	    else {
@@ -2564,12 +2319,12 @@
 		for (j = 0; j < NCH(ch); j += 2) {
 		    /* statement terminates with a semi-colon ';' */
 		    if (NCH(CHILD(ch, j)) == 0) {
-		    	assert((j + 1) == NCH(ch));
-		    	break;
+			assert((j + 1) == NCH(ch));
+			break;
 		    }
 		    s = ast_for_stmt(c, CHILD(ch, j));
 		    if (!s)
-			goto error;
+			return NULL;
 		    asdl_seq_SET(seq, pos++, s);
 		}
 	    }
@@ -2577,10 +2332,6 @@
     }
     assert(pos == seq->size);
     return seq;
- error:
-    if (seq)
-	asdl_stmt_seq_free(seq);
-    return NULL;
 }
 
 static stmt_ty
@@ -2602,11 +2353,10 @@
             return NULL;
         suite_seq = ast_for_suite(c, CHILD(n, 3)); 
         if (!suite_seq) {
-	    free_expr(expression);
             return NULL;
 	}
             
-	return If(expression, suite_seq, NULL, LINENO(n));
+	return If(expression, suite_seq, NULL, LINENO(n), c->c_arena);
     }
     s = STR(CHILD(n, 4));
     /* s[2], the third character in the string, will be
@@ -2622,17 +2372,14 @@
             return NULL;
         seq1 = ast_for_suite(c, CHILD(n, 3));
         if (!seq1) {
-	    free_expr(expression);
             return NULL;
 	}
         seq2 = ast_for_suite(c, CHILD(n, 6));
         if (!seq2) {
-	    asdl_stmt_seq_free(seq1);
-	    free_expr(expression);
             return NULL;
 	}
 
-	return If(expression, seq1, seq2, LINENO(n));
+	return If(expression, seq1, seq2, LINENO(n), c->c_arena);
     }
     else if (s[2] == 'i') {
 	int i, n_elif, has_else = 0;
@@ -2651,30 +2398,25 @@
             expr_ty expression;
             asdl_seq *seq1, *seq2;
 
-	    orelse = asdl_seq_new(1);
+	    orelse = asdl_seq_new(1, c->c_arena);
 	    if (!orelse)
 		return NULL;
             expression = ast_for_expr(c, CHILD(n, NCH(n) - 6));
             if (!expression) {
-                asdl_seq_free(orelse); /* ok */
                 return NULL;
             }
             seq1 = ast_for_suite(c, CHILD(n, NCH(n) - 4));
             if (!seq1) {
-                free_expr(expression);
-                asdl_seq_free(orelse); /* ok */
                 return NULL;
             }
             seq2 = ast_for_suite(c, CHILD(n, NCH(n) - 1));
             if (!seq2) {
-                free_expr(expression);
-                asdl_stmt_seq_free(seq1);
-                asdl_seq_free(orelse); /* ok */
                 return NULL;
             }
 
 	    asdl_seq_SET(orelse, 0, If(expression, seq1, seq2, 
-				       LINENO(CHILD(n, NCH(n) - 6))));
+				       LINENO(CHILD(n, NCH(n) - 6)),
+                                       c->c_arena));
 	    /* the just-created orelse handled the last elif */
 	    n_elif--;
 	}
@@ -2685,33 +2427,27 @@
 	    int off = 5 + (n_elif - i - 1) * 4;
             expr_ty expression;
             asdl_seq *suite_seq;
-	    asdl_seq *new = asdl_seq_new(1);
+	    asdl_seq *new = asdl_seq_new(1, c->c_arena);
 	    if (!new) {
-		asdl_stmt_seq_free(orelse);
 		return NULL;
 	    }
             expression = ast_for_expr(c, CHILD(n, off));
             if (!expression) {
-		asdl_stmt_seq_free(orelse);
-                asdl_seq_free(new); /* ok */
                 return NULL;
             }
             suite_seq = ast_for_suite(c, CHILD(n, off + 2));
             if (!suite_seq) {
-		asdl_stmt_seq_free(orelse);
-	        free_expr(expression);
-                asdl_seq_free(new); /* ok */
                 return NULL;
             }
 
 	    asdl_seq_SET(new, 0,
 			 If(expression, suite_seq, orelse, 
-			    LINENO(CHILD(n, off))));
+			    LINENO(CHILD(n, off)), c->c_arena));
 	    orelse = new;
 	}
 	return If(ast_for_expr(c, CHILD(n, 1)),
 		  ast_for_suite(c, CHILD(n, 3)),
-		  orelse, LINENO(n));
+		  orelse, LINENO(n), c->c_arena);
     }
     else {
         PyErr_Format(PyExc_SystemError,
@@ -2735,10 +2471,9 @@
             return NULL;
         suite_seq = ast_for_suite(c, CHILD(n, 3));
         if (!suite_seq) {
-	    free_expr(expression);
             return NULL;
 	}
-	return While(expression, suite_seq, NULL, LINENO(n));
+	return While(expression, suite_seq, NULL, LINENO(n), c->c_arena);
     }
     else if (NCH(n) == 7) {
         expr_ty expression;
@@ -2749,17 +2484,14 @@
             return NULL;
         seq1 = ast_for_suite(c, CHILD(n, 3));
         if (!seq1) {
-	    free_expr(expression);
             return NULL;
 	}
         seq2 = ast_for_suite(c, CHILD(n, 6));
         if (!seq2) {
-	    asdl_stmt_seq_free(seq1);
-	    free_expr(expression);
             return NULL;
 	}
 
-	return While(expression, seq1, seq2, LINENO(n));
+	return While(expression, seq1, seq2, LINENO(n), c->c_arena);
     }
     else {
         PyErr_Format(PyExc_SystemError,
@@ -2786,31 +2518,24 @@
 
     _target = ast_for_exprlist(c, CHILD(n, 1), Store);
     if (!_target) {
-	asdl_stmt_seq_free(seq);
         return NULL;
     }
     if (asdl_seq_LEN(_target) == 1) {
 	target = asdl_seq_GET(_target, 0);
-	asdl_seq_free(_target); /* ok */
     }
     else
-	target = Tuple(_target, Store, LINENO(n));
+	target = Tuple(_target, Store, LINENO(n), c->c_arena);
 
     expression = ast_for_testlist(c, CHILD(n, 3));
     if (!expression) {
-	free_expr(target);
-	asdl_stmt_seq_free(seq);
         return NULL;
     }
     suite_seq = ast_for_suite(c, CHILD(n, 5));
     if (!suite_seq) {
-	free_expr(target);
-	free_expr(expression);
-	asdl_stmt_seq_free(seq);
         return NULL;
     }
 
-    return For(target, expression, suite_seq, seq, LINENO(n));
+    return For(target, expression, suite_seq, seq, LINENO(n), c->c_arena);
 }
 
 static excepthandler_ty
@@ -2825,7 +2550,7 @@
         if (!suite_seq)
             return NULL;
 
-	return excepthandler(NULL, NULL, suite_seq);
+	return excepthandler(NULL, NULL, suite_seq, c->c_arena);
     }
     else if (NCH(exc) == 2) {
         expr_ty expression;
@@ -2836,11 +2561,10 @@
             return NULL;
         suite_seq = ast_for_suite(c, body);
         if (!suite_seq) {
-	    free_expr(expression);
             return NULL;
 	}
 
-	return excepthandler(expression, NULL, suite_seq);
+	return excepthandler(expression, NULL, suite_seq, c->c_arena);
     }
     else if (NCH(exc) == 4) {
         asdl_seq *suite_seq;
@@ -2849,22 +2573,18 @@
 	if (!e)
             return NULL;
 	if (!set_context(e, Store, CHILD(exc, 3))) {
-	    free_expr(e);
             return NULL;
 	}
         expression = ast_for_expr(c, CHILD(exc, 1));
         if (!expression) {
-	    free_expr(e);
             return NULL;
 	}
         suite_seq = ast_for_suite(c, body);
         if (!suite_seq) {
-	    free_expr(expression);
-	    free_expr(e);
             return NULL;
 	}
 
-	return excepthandler(expression, e, suite_seq);
+	return excepthandler(expression, e, suite_seq, c->c_arena);
     }
     else {
         PyErr_Format(PyExc_SystemError,
@@ -2887,11 +2607,10 @@
             return NULL;
         s2 = ast_for_suite(c, CHILD(n, 5));
         if (!s2) {
-	    asdl_stmt_seq_free(s1);
             return NULL;
 	}
             
-	return TryFinally(s1, s2, LINENO(n));
+	return TryFinally(s1, s2, LINENO(n), c->c_arena);
     }
     else if (TYPE(CHILD(n, 3)) == except_clause) {
 	/* try_stmt: ('try' ':' suite (except_clause ':' suite)+
@@ -2905,7 +2624,7 @@
 	    n_except -= 3;
 	}
 	n_except /= 3;
-	handlers = asdl_seq_new(n_except);
+	handlers = asdl_seq_new(n_except, c->c_arena);
 	if (!handlers)
 		return NULL;
 	for (i = 0; i < n_except; i++) {
@@ -2913,9 +2632,6 @@
                                                        CHILD(n, 3 + i * 3),
                                                        CHILD(n, 5 + i * 3));
             if (!e) {
-		for ( ; i >= 0; i--)
-		    free_excepthandler(asdl_seq_GET(handlers, i));
-	        asdl_seq_free(handlers); /* ok */
                 return NULL;
 	    }
 	    asdl_seq_SET(handlers, i, e);
@@ -2923,25 +2639,19 @@
 
         suite_seq1 = ast_for_suite(c, CHILD(n, 2));
         if (!suite_seq1) {
-	    for (i = 0; i < asdl_seq_LEN(handlers); i++)
-		free_excepthandler(asdl_seq_GET(handlers, i));
-	    asdl_seq_free(handlers); /* ok */
             return NULL;
 	}
         if (has_else) {
             suite_seq2 = ast_for_suite(c, CHILD(n, NCH(n) - 1));
             if (!suite_seq2) {
-	        for (i = 0; i < asdl_seq_LEN(handlers); i++)
-		    free_excepthandler(asdl_seq_GET(handlers, i));
-	        asdl_seq_free(handlers); /* ok */
-		asdl_stmt_seq_free(suite_seq1);
                 return NULL;
 	    }
         }
         else
             suite_seq2 = NULL;
 
-	return TryExcept(suite_seq1, handlers, suite_seq2, LINENO(n));
+	return TryExcept(suite_seq1, handlers, suite_seq2, LINENO(n),
+                         c->c_arena);
     }
     else {
         ast_error(n, "malformed 'try' statement");
@@ -2966,14 +2676,16 @@
         s = ast_for_suite(c, CHILD(n, 3));
         if (!s)
             return NULL;
-	return ClassDef(NEW_IDENTIFIER(CHILD(n, 1)), NULL, s, LINENO(n));
+	return ClassDef(NEW_IDENTIFIER(CHILD(n, 1)), NULL, s, LINENO(n),
+                        c->c_arena);
     }
     /* check for empty base list */
     if (TYPE(CHILD(n,3)) == RPAR) {
 	s = ast_for_suite(c, CHILD(n,5));
 	if (!s)
 		return NULL;
-	return ClassDef(NEW_IDENTIFIER(CHILD(n, 1)), NULL, s, LINENO(n));
+	return ClassDef(NEW_IDENTIFIER(CHILD(n, 1)), NULL, s, LINENO(n),
+                        c->c_arena);
     }
 
     /* else handle the base class list */
@@ -2983,10 +2695,10 @@
 
     s = ast_for_suite(c, CHILD(n, 6));
     if (!s) {
-        asdl_expr_seq_free(bases);
         return NULL;
     }
-    return ClassDef(NEW_IDENTIFIER(CHILD(n, 1)), bases, s, LINENO(n));
+    return ClassDef(NEW_IDENTIFIER(CHILD(n, 1)), bases, s, LINENO(n),
+                    c->c_arena);
 }
 
 static stmt_ty
@@ -3015,7 +2727,7 @@
             case del_stmt:
                 return ast_for_del_stmt(c, n);
             case pass_stmt:
-                return Pass(LINENO(n));
+                return Pass(LINENO(n), c->c_arena);
             case flow_stmt:
                 return ast_for_flow_stmt(c, n);
             case import_stmt:
@@ -3204,7 +2916,6 @@
 static PyObject *
 parsestr(const char *s, const char *encoding)
 {
-	PyObject *v;
 	size_t len;
 	int quote = *s;
 	int rawmode = 0;
@@ -3259,7 +2970,7 @@
 			   encoding. */
 			Py_FatalError("cannot deal with encodings in this build.");
 #else
-			PyObject* u = PyUnicode_DecodeUTF8(s, len, NULL);
+			PyObject *v, *u = PyUnicode_DecodeUTF8(s, len, NULL);
 			if (u == NULL)
 				return NULL;
 			v = PyUnicode_AsEncodedString(u, encoding, NULL);
@@ -3271,9 +2982,8 @@
 		}
 	}
 
-	v = PyString_DecodeEscape(s, len, NULL, unicode,
-				  need_encoding ? encoding : NULL);
-	return v;
+	return PyString_DecodeEscape(s, len, NULL, unicode,
+				     need_encoding ? encoding : NULL);
 }
 
 /* Build a Python string object out of a STRING atom.  This takes care of
@@ -3300,13 +3010,12 @@
 			}
 #ifdef Py_USING_UNICODE
 			else {
-				PyObject *temp;
-				temp = PyUnicode_Concat(v, s);
+				PyObject *temp = PyUnicode_Concat(v, s);
 				Py_DECREF(s);
-				if (temp == NULL)
-					goto onError;
 				Py_DECREF(v);
 				v = temp;
+				if (v == NULL)
+				    goto onError;
 			}
 #endif
 		}

Modified: python/trunk/Python/compile.c
==============================================================================
--- python/trunk/Python/compile.c	(original)
+++ python/trunk/Python/compile.c	Sat Dec 17 21:54:49 2005
@@ -23,6 +23,7 @@
 
 #include "Python-ast.h"
 #include "node.h"
+#include "pyarena.h"
 #include "ast.h"
 #include "code.h"
 #include "compile.h"
@@ -148,6 +149,7 @@
         struct compiler_unit *u; /* compiler state for current block */
 	PyObject *c_stack;       /* Python list holding compiler_unit ptrs */
 	char *c_encoding;	 /* source encoding (a borrowed reference) */
+        PyArena *c_arena;        /* pointer to memory allocation arena */
 };
 
 struct assembler {
@@ -243,7 +245,8 @@
 }
 
 PyCodeObject *
-PyAST_Compile(mod_ty mod, const char *filename, PyCompilerFlags *flags)
+PyAST_Compile(mod_ty mod, const char *filename, PyCompilerFlags *flags,
+              PyArena *arena)
 {
 	struct compiler c;
 	PyCodeObject *co = NULL;
@@ -259,6 +262,7 @@
 	if (!compiler_init(&c))
 		goto error;
 	c.c_filename = filename;
+        c.c_arena = arena;
 	c.c_future = PyFuture_FromAST(mod, filename);
 	if (c.c_future == NULL)
 		goto error;
@@ -292,12 +296,13 @@
 PyCodeObject *
 PyNode_Compile(struct _node *n, const char *filename)
 {
-	PyCodeObject *co;
-	mod_ty mod = PyAST_FromNode(n, NULL, filename);
-	if (!mod)
-		return NULL;
-	co = PyAST_Compile(mod, filename, NULL);
-	free_mod(mod);
+	PyCodeObject *co = NULL;
+        PyArena *arena;
+        arena = PyArena_New();
+	mod_ty mod = PyAST_FromNode(n, NULL, filename, arena);
+	if (mod)
+		co = PyAST_Compile(mod, filename, NULL, arena);
+        PyArena_Free(arena);
 	return co;
 }
 
@@ -3404,7 +3409,7 @@
 	switch (e->kind) {
                 case Attribute_kind:
 		auge = Attribute(e->v.Attribute.value, e->v.Attribute.attr,
-				 AugLoad, e->lineno);
+				 AugLoad, e->lineno, c->c_arena);
                 if (auge == NULL)
                     return 0;
 		VISIT(c, expr, auge);
@@ -3412,11 +3417,10 @@
 		ADDOP(c, inplace_binop(c, s->v.AugAssign.op));
 		auge->v.Attribute.ctx = AugStore;
 		VISIT(c, expr, auge);
-		free(auge);
 		break;
 	case Subscript_kind:
 		auge = Subscript(e->v.Subscript.value, e->v.Subscript.slice,
-				 AugLoad, e->lineno);
+				 AugLoad, e->lineno, c->c_arena);
                 if (auge == NULL)
                     return 0;
 		VISIT(c, expr, auge);
@@ -3424,7 +3428,6 @@
 		ADDOP(c, inplace_binop(c, s->v.AugAssign.op));
                 auge->v.Subscript.ctx = AugStore;
 		VISIT(c, expr, auge);
-		free(auge);
                 break;
 	case Name_kind:
 		VISIT(c, expr, s->v.AugAssign.target);

Modified: python/trunk/Python/import.c
==============================================================================
--- python/trunk/Python/import.c	(original)
+++ python/trunk/Python/import.c	Sat Dec 17 21:54:49 2005
@@ -4,6 +4,7 @@
 #include "Python.h"
 
 #include "Python-ast.h"
+#include "pyarena.h"
 #include "pythonrun.h"
 #include "errcode.h"
 #include "marshal.h"
@@ -773,13 +774,14 @@
 {
 	PyCodeObject *co = NULL;
 	mod_ty mod;
+        PyArena *arena = PyArena_New();
 
 	mod = PyParser_ASTFromFile(fp, pathname, Py_file_input, 0, 0, 0, 
-				   NULL);
+				   NULL, arena);
 	if (mod) {
-		co = PyAST_Compile(mod, pathname, NULL);
-		free_mod(mod);
+		co = PyAST_Compile(mod, pathname, NULL, arena);
 	}
+        PyArena_Free(arena);
 	return co;
 }
 

Added: python/trunk/Python/pyarena.c
==============================================================================
--- (empty file)
+++ python/trunk/Python/pyarena.c	Sat Dec 17 21:54:49 2005
@@ -0,0 +1,133 @@
+#include "Python.h"
+#include "pyarena.h"
+
+/* An arena list is a linked list that can store either pointers or
+   PyObjects.  The type is clear from context.
+ */
+
+typedef struct _arena_list {
+  struct _arena_list *al_next;
+  void *al_pointer;
+} PyArenaList;
+
+/* There are two linked lists in an arena, one for malloc pointers and
+   one for PyObject.  For each list, there is a pointer to the head
+   and to the tail.  The head is used to free the list.  The tail is
+   used to add a new element to the list.
+
+   The list always keeps one un-used node at the end of the list.
+*/
+
+struct _arena {
+  PyArenaList *a_malloc_head;
+  PyArenaList *a_malloc_tail;
+  PyArenaList *a_object_head;
+  PyArenaList *a_object_tail;
+};
+
+static PyArenaList*
+PyArenaList_New(void) 
+{
+  PyArenaList *alist = (PyArenaList *)malloc(sizeof(PyArenaList));
+  if (!alist)
+    return NULL;
+
+  alist->al_next = NULL;
+  alist->al_pointer = NULL;
+  return alist;
+}
+
+static void
+PyArenaList_FreeObject(PyArenaList *alist) 
+{
+  if (!alist)
+    return;
+
+  while (alist) {
+    PyArenaList *prev;
+    Py_XDECREF((PyObject *)alist->al_pointer);
+    alist->al_pointer = NULL;
+    prev = alist;
+    alist = alist->al_next;
+    free(prev);
+  }
+}
+
+static void
+PyArenaList_FreeMalloc(PyArenaList *alist)
+{
+  if (!alist)
+    return;
+
+  while (alist) {
+    PyArenaList *prev;
+    if (alist->al_pointer) {
+      free(alist->al_pointer);
+    }
+    alist->al_pointer = NULL;
+    prev = alist;
+    alist = alist->al_next;
+    free(prev);
+  }
+}
+
+
+PyArena *
+PyArena_New()
+{
+  PyArena* arena = (PyArena *)malloc(sizeof(PyArena));
+  if (!arena)
+    return NULL;
+
+  arena->a_object_head = PyArenaList_New();
+  arena->a_object_tail = arena->a_object_head;
+  arena->a_malloc_head = PyArenaList_New();
+  arena->a_malloc_tail = arena->a_malloc_head;
+  return arena;
+}
+
+void
+PyArena_Free(PyArena *arena)
+{
+  assert(arena);
+  PyArenaList_FreeObject(arena->a_object_head);
+  PyArenaList_FreeMalloc(arena->a_malloc_head);
+  free(arena);
+}
+
+void *
+PyArena_Malloc(PyArena *arena, size_t size) 
+{
+  /* A better implementation might actually use an arena.  The current
+     approach is just a trivial implementation of the API that allows
+     it to be tested.
+  */
+  void *p;
+  assert(size != 0);
+  p = malloc(size);
+  PyArena_AddMallocPointer(arena, p);
+  return p;
+}
+
+int
+PyArena_AddMallocPointer(PyArena *arena, void *pointer) 
+{
+  assert(pointer);
+  PyArenaList *tail = arena->a_malloc_tail;
+  assert(tail->al_pointer != pointer);
+  tail->al_next = PyArenaList_New();
+  tail->al_pointer = pointer;
+  arena->a_malloc_tail = tail->al_next;
+  return 1;
+}
+
+int
+PyArena_AddPyObject(PyArena *arena, PyObject *pointer) 
+{
+  assert(pointer);
+  PyArenaList *tail = arena->a_object_tail;
+  tail->al_next = PyArenaList_New();
+  tail->al_pointer = pointer;
+  arena->a_object_tail = tail->al_next;
+  return 1;
+}

Modified: python/trunk/Python/pythonrun.c
==============================================================================
--- python/trunk/Python/pythonrun.c	(original)
+++ python/trunk/Python/pythonrun.c	Sat Dec 17 21:54:49 2005
@@ -12,6 +12,7 @@
 #include "code.h"
 #include "compile.h"
 #include "symtable.h"
+#include "pyarena.h"
 #include "ast.h"
 #include "eval.h"
 #include "marshal.h"
@@ -36,9 +37,9 @@
 static void initmain(void);
 static void initsite(void);
 static PyObject *run_err_mod(mod_ty, const char *, PyObject *, PyObject *,
-			      PyCompilerFlags *);
+			      PyCompilerFlags *, PyArena *arena);
 static PyObject *run_mod(mod_ty, const char *, PyObject *, PyObject *,
-			  PyCompilerFlags *);
+			  PyCompilerFlags *, PyArena *);
 static PyObject *run_pyc_file(FILE *, const char *, PyObject *, PyObject *,
 			      PyCompilerFlags *);
 static void err_input(perrdetail *);
@@ -697,6 +698,7 @@
 {
 	PyObject *m, *d, *v, *w;
 	mod_ty mod;
+        PyArena *arena;
 	char *ps1 = "", *ps2 = "";
 	int errcode = 0;
 
@@ -716,12 +718,14 @@
 		else if (PyString_Check(w))
 			ps2 = PyString_AsString(w);
 	}
+        arena = PyArena_New();
 	mod = PyParser_ASTFromFile(fp, filename, 
 				   Py_single_input, ps1, ps2,
-				   flags, &errcode);
+				   flags, &errcode, arena);
 	Py_XDECREF(v);
 	Py_XDECREF(w);
 	if (mod == NULL) {
+        	PyArena_Free(arena);
 		if (errcode == E_EOF) {
 			PyErr_Clear();
 			return E_EOF;
@@ -730,11 +734,13 @@
 		return -1;
 	}
 	m = PyImport_AddModule("__main__");
-	if (m == NULL)
+	if (m == NULL) {
+        	PyArena_Free(arena);
 		return -1;
+	}
 	d = PyModule_GetDict(m);
-	v = run_mod(mod, filename, d, d, flags);
-	free_mod(mod);
+	v = run_mod(mod, filename, d, d, flags, arena);
+        PyArena_Free(arena);
 	if (v == NULL) {
 		PyErr_Print();
 		return -1;
@@ -1155,9 +1161,11 @@
 		  PyObject *locals, PyCompilerFlags *flags)
 {
 	PyObject *ret;
-	mod_ty mod = PyParser_ASTFromString(str, "<string>", start, flags);
-	ret = run_err_mod(mod, "<string>", globals, locals, flags);
-	free_mod(mod);
+        PyArena *arena = PyArena_New();
+	mod_ty mod = PyParser_ASTFromString(str, "<string>", start, flags,
+                                            arena);
+	ret = run_err_mod(mod, "<string>", globals, locals, flags, arena);
+        PyArena_Free(arena);
 	return ret;
 }
 
@@ -1166,33 +1174,36 @@
 		  PyObject *locals, int closeit, PyCompilerFlags *flags)
 {
 	PyObject *ret;
+        PyArena *arena = PyArena_New();
 	mod_ty mod = PyParser_ASTFromFile(fp, filename, start, 0, 0,
-					  flags, NULL);
-	if (mod == NULL)
+					  flags, NULL, arena);
+	if (mod == NULL) {
+                PyArena_Free(arena);
 		return NULL;
+        }
 	if (closeit)
 		fclose(fp);
-	ret = run_err_mod(mod, filename, globals, locals, flags);
-	free_mod(mod);
+	ret = run_err_mod(mod, filename, globals, locals, flags, arena);
+        PyArena_Free(arena);
 	return ret;
 }
 
 static PyObject *
 run_err_mod(mod_ty mod, const char *filename, PyObject *globals, 
-	    PyObject *locals, PyCompilerFlags *flags)
+	    PyObject *locals, PyCompilerFlags *flags, PyArena *arena)
 {
 	if (mod == NULL)
 		return  NULL;
-	return run_mod(mod, filename, globals, locals, flags);
+	return run_mod(mod, filename, globals, locals, flags, arena);
 }
 
 static PyObject *
 run_mod(mod_ty mod, const char *filename, PyObject *globals, PyObject *locals,
-	 PyCompilerFlags *flags)
+	 PyCompilerFlags *flags, PyArena *arena)
 {
 	PyCodeObject *co;
 	PyObject *v;
-	co = PyAST_Compile(mod, filename, flags);
+	co = PyAST_Compile(mod, filename, flags, arena);
 	if (co == NULL)
 		return NULL;
 	v = PyEval_EvalCode(co, globals, locals);
@@ -1236,43 +1247,45 @@
 Py_CompileStringFlags(const char *str, const char *filename, int start,
 		      PyCompilerFlags *flags)
 {
-	mod_ty mod;
 	PyCodeObject *co;
-	mod = PyParser_ASTFromString(str, filename, start, flags);
-	if (mod == NULL)
+        PyArena *arena = PyArena_New();
+	mod_ty mod = PyParser_ASTFromString(str, filename, start, flags, arena);
+	if (mod == NULL) {
+                PyArena_Free(arena);
 		return NULL;
-	co = PyAST_Compile(mod, filename, flags);
-	free_mod(mod);
+        }
+	co = PyAST_Compile(mod, filename, flags, arena);
+        PyArena_Free(arena);
 	return (PyObject *)co;
 }
 
 struct symtable *
 Py_SymtableString(const char *str, const char *filename, int start)
 {
-	mod_ty mod;
 	struct symtable *st;
-
-	mod = PyParser_ASTFromString(str, filename, start, NULL);
-	if (mod == NULL)
+        PyArena *arena = PyArena_New();
+	mod_ty mod = PyParser_ASTFromString(str, filename, start, NULL, arena);
+	if (mod == NULL) {
+                PyArena_Free(arena);
 		return NULL;
+        }
 	st = PySymtable_Build(mod, filename, 0);
-	free_mod(mod);
+        PyArena_Free(arena);
 	return st;
 }
 
 /* Preferred access to parser is through AST. */
 mod_ty
 PyParser_ASTFromString(const char *s, const char *filename, int start, 
-		       PyCompilerFlags *flags)
+		       PyCompilerFlags *flags, PyArena *arena)
 {
-	node *n;
 	mod_ty mod;
 	perrdetail err;
-	n = PyParser_ParseStringFlagsFilename(s, filename, &_PyParser_Grammar,
-					      start, &err, 
-					      PARSER_FLAGS(flags));
+	node *n = PyParser_ParseStringFlagsFilename(s, filename,
+					&_PyParser_Grammar, start, &err, 
+					PARSER_FLAGS(flags));
 	if (n) {
-		mod = PyAST_FromNode(n, flags, filename);
+		mod = PyAST_FromNode(n, flags, filename, arena);
 		PyNode_Free(n);
 		return mod;
 	}
@@ -1284,15 +1297,15 @@
 
 mod_ty
 PyParser_ASTFromFile(FILE *fp, const char *filename, int start, char *ps1, 
-		     char *ps2, PyCompilerFlags *flags, int *errcode)
+		     char *ps2, PyCompilerFlags *flags, int *errcode,
+                     PyArena *arena)
 {
-	node *n;
 	mod_ty mod;
 	perrdetail err;
-	n = PyParser_ParseFileFlags(fp, filename, &_PyParser_Grammar, start, 
-				    ps1, ps2, &err, PARSER_FLAGS(flags));
+	node *n = PyParser_ParseFileFlags(fp, filename, &_PyParser_Grammar,
+				start, ps1, ps2, &err, PARSER_FLAGS(flags));
 	if (n) {
-		mod = PyAST_FromNode(n, flags, filename);
+		mod = PyAST_FromNode(n, flags, filename, arena);
 		PyNode_Free(n);
 		return mod;
 	}
@@ -1309,10 +1322,9 @@
 node *
 PyParser_SimpleParseFileFlags(FILE *fp, const char *filename, int start, int flags)
 {
-	node *n;
 	perrdetail err;
-	n = PyParser_ParseFileFlags(fp, filename, &_PyParser_Grammar, start,
-					(char *)0, (char *)0, &err, flags);
+	node *n = PyParser_ParseFileFlags(fp, filename, &_PyParser_Grammar,
+					  start, NULL, NULL, &err, flags);
 	if (n == NULL)
 		err_input(&err);
 		
@@ -1324,10 +1336,9 @@
 node *
 PyParser_SimpleParseStringFlags(const char *str, int start, int flags)
 {
-	node *n;
 	perrdetail err;
-	n = PyParser_ParseStringFlags(str, &_PyParser_Grammar, start, &err,
-				      flags);
+	node *n = PyParser_ParseStringFlags(str, &_PyParser_Grammar,
+					    start, &err, flags);
 	if (n == NULL)
 		err_input(&err);
 	return n;
@@ -1337,12 +1348,9 @@
 PyParser_SimpleParseStringFlagsFilename(const char *str, const char *filename,
 					int start, int flags)
 {
-	node *n;
 	perrdetail err;
-
-	n = PyParser_ParseStringFlagsFilename(str, filename,
-					      &_PyParser_Grammar,
-					      start, &err, flags);
+	node *n = PyParser_ParseStringFlagsFilename(str, filename,
+				&_PyParser_Grammar, start, &err, flags);
 	if (n == NULL)
 		err_input(&err);
 	return n;
@@ -1351,8 +1359,7 @@
 node *
 PyParser_SimpleParseStringFilename(const char *str, const char *filename, int start)
 {
-	return PyParser_SimpleParseStringFlagsFilename(str, filename,
-						       start, 0);
+	return PyParser_SimpleParseStringFlagsFilename(str, filename, start, 0);
 }
 
 /* May want to move a more generalized form of this to parsetok.c or


More information about the Python-checkins mailing list