From adb69fcdffdc50ee3e1d33b00cd874020197b445 Mon Sep 17 00:00:00 2001 From: Neal Norwitz Date: Sat, 17 Dec 2005 20:54:49 +0000 Subject: [PATCH] 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. --- Include/Python-ast.h | 134 ++++---- Include/Python.h | 1 + Include/asdl.h | 2 +- Include/ast.h | 2 +- Include/compile.h | 2 +- Include/pyarena.h | 42 +++ Include/pythonrun.h | 6 +- Makefile.pre.in | 2 + Parser/asdl_c.py | 15 +- Python/Python-ast.c | 667 +++++++----------------------------- Python/asdl.c | 7 +- Python/ast.c | 791 ++++++++++++++----------------------------- Python/compile.c | 25 +- Python/import.c | 8 +- Python/pyarena.c | 133 ++++++++ Python/pythonrun.c | 109 +++--- 16 files changed, 704 insertions(+), 1242 deletions(-) create mode 100644 Include/pyarena.h create mode 100644 Python/pyarena.c diff --git a/Include/Python-ast.h b/Include/Python-ast.h index 2484bb13d40..4dfaef81410 100644 --- a/Include/Python-ast.h +++ b/Include/Python-ast.h @@ -328,81 +328,79 @@ struct _alias { }; -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); diff --git a/Include/Python.h b/Include/Python.h index f941cbad229..8df7dbc3e84 100644 --- a/Include/Python.h +++ b/Include/Python.h @@ -113,6 +113,7 @@ #include "pystate.h" +#include "pyarena.h" #include "modsupport.h" #include "pythonrun.h" #include "ceval.h" diff --git a/Include/asdl.h b/Include/asdl.h index cf059672a7c..a2c86c8dd45 100644 --- a/Include/asdl.h +++ b/Include/asdl.h @@ -23,7 +23,7 @@ typedef struct { 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 diff --git a/Include/ast.h b/Include/ast.h index b1a93882374..cc14b7fd762 100644 --- a/Include/ast.h +++ b/Include/ast.h @@ -5,7 +5,7 @@ extern "C" { #endif PyAPI_FUNC(mod_ty) PyAST_FromNode(const node *, PyCompilerFlags *flags, - const char *); + const char *, PyArena *); #ifdef __cplusplus } diff --git a/Include/compile.h b/Include/compile.h index 5c6a7c766c7..029cb17ab2d 100644 --- a/Include/compile.h +++ b/Include/compile.h @@ -25,7 +25,7 @@ typedef struct { 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 \ diff --git a/Include/pyarena.h b/Include/pyarena.h new file mode 100644 index 00000000000..6f191a1aa15 --- /dev/null +++ b/Include/pyarena.h @@ -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 */ diff --git a/Include/pythonrun.h b/Include/pythonrun.h index 514d3bc8870..e309078a691 100644 --- a/Include/pythonrun.h +++ b/Include/pythonrun.h @@ -37,10 +37,12 @@ PyAPI_FUNC(int) PyRun_InteractiveOneFlags(FILE *, const char *, PyCompilerFlags 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) \ diff --git a/Makefile.pre.in b/Makefile.pre.in index bae425063ac..ab01deb3873 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -254,6 +254,7 @@ PYTHON_OBJS= \ 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 @@ PYTHON_HEADERS= \ Include/object.h \ Include/objimpl.h \ Include/patchlevel.h \ + Include/pyarena.h \ Include/pydebug.h \ Include/pyerrors.h \ Include/pyfpe.h \ diff --git a/Parser/asdl_c.py b/Parser/asdl_c.py index f45bee450ca..b1fc77da288 100755 --- a/Parser/asdl_c.py +++ b/Parser/asdl_c.py @@ -249,8 +249,9 @@ class PrototypeVisitor(EmitVisitor): 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 @@ class FunctionVisitor(PrototypeVisitor): 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 @@ class FunctionVisitor(PrototypeVisitor): 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 @@ def main(srcfile): c = ChainOfVisitors(TypeDefVisitor(f), StructVisitor(f), PrototypeVisitor(f), - FreePrototypeVisitor(f), +## FreePrototypeVisitor(f), ) c.visit(mod) f.close() @@ -671,8 +676,8 @@ def main(srcfile): print >> f v = ChainOfVisitors(MarshalPrototypeVisitor(f), FunctionVisitor(f), - FreeUtilVisitor(f), - FreeVisitor(f), +## FreeUtilVisitor(f), +## FreeVisitor(f), MarshalUtilVisitor(f), MarshalFunctionVisitor(f), ) diff --git a/Python/Python-ast.c b/Python/Python-ast.c index b2766251b18..445049dfb51 100644 --- a/Python/Python-ast.c +++ b/Python/Python-ast.c @@ -19,10 +19,10 @@ static int marshal_write_keyword(PyObject **, int *, keyword_ty); 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 @@ Module(asdl_seq * body) } 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 @@ Interactive(asdl_seq * body) } mod_ty -Expression(expr_ty body) +Expression(expr_ty body, PyArena *arena) { mod_ty p; if (!body) { @@ -55,7 +55,7 @@ Expression(expr_ty body) "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 @@ Expression(expr_ty body) } 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 @@ Suite(asdl_seq * body) 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 @@ FunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq * "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 @@ FunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq * } 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 @@ ClassDef(identifier name, asdl_seq * bases, asdl_seq * body, int lineno) "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 @@ ClassDef(identifier name, asdl_seq * bases, asdl_seq * body, int lineno) } 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 @@ Return(expr_ty value, int lineno) } 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 @@ Delete(asdl_seq * targets, int lineno) } 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 @@ Assign(asdl_seq * targets, expr_ty value, int lineno) "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 @@ Assign(asdl_seq * targets, expr_ty value, int lineno) } 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 @@ AugAssign(expr_ty target, operator_ty op, expr_ty value, int lineno) "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 @@ 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) +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 @@ Print(expr_ty dest, asdl_seq * values, bool nl, int lineno) 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 @@ For(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * orelse, int "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 @@ For(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * orelse, int } 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 @@ While(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno) "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 @@ 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) +If(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, PyArena *arena) { stmt_ty p; if (!test) { @@ -290,7 +293,7 @@ If(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno) "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 @@ 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) +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 @@ Raise(expr_ty type, expr_ty inst, expr_ty tback, int lineno) } 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 @@ TryExcept(asdl_seq * body, asdl_seq * handlers, asdl_seq * orelse, int lineno) } 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 @@ TryFinally(asdl_seq * body, asdl_seq * finalbody, int lineno) } 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 @@ Assert(expr_ty test, expr_ty msg, int lineno) "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 @@ Assert(expr_ty test, expr_ty msg, int lineno) } 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 @@ Import(asdl_seq * names, int lineno) } 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 @@ ImportFrom(identifier module, asdl_seq * names, int lineno) "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 @@ ImportFrom(identifier module, asdl_seq * names, int lineno) } 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 @@ Exec(expr_ty body, expr_ty globals, expr_ty locals, int lineno) "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 @@ Exec(expr_ty body, expr_ty globals, expr_ty locals, int lineno) } 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 @@ Global(asdl_seq * names, int lineno) } 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 @@ Expr(expr_ty value, int lineno) "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 @@ Expr(expr_ty value, int lineno) } 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 @@ Pass(int lineno) } 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 @@ Break(int lineno) } 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 @@ Continue(int lineno) } 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 @@ BoolOp(boolop_ty op, asdl_seq * values, int lineno) "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 @@ BoolOp(boolop_ty op, asdl_seq * values, int lineno) } 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 @@ BinOp(expr_ty left, operator_ty op, expr_ty right, int lineno) "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 @@ BinOp(expr_ty left, operator_ty op, expr_ty right, int lineno) } 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 @@ UnaryOp(unaryop_ty op, expr_ty operand, int lineno) "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 @@ UnaryOp(unaryop_ty op, expr_ty operand, int lineno) } 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 @@ Lambda(arguments_ty args, expr_ty body, int lineno) "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 @@ Lambda(arguments_ty args, expr_ty body, int lineno) } 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 @@ Dict(asdl_seq * keys, asdl_seq * values, int lineno) } 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 @@ ListComp(expr_ty elt, asdl_seq * generators, int lineno) "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 @@ ListComp(expr_ty elt, asdl_seq * generators, int lineno) } 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 @@ GeneratorExp(expr_ty elt, asdl_seq * generators, int lineno) "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 @@ GeneratorExp(expr_ty elt, asdl_seq * generators, int lineno) } 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 @@ Yield(expr_ty value, int lineno) } 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 @@ Compare(expr_ty left, asdl_seq * ops, asdl_seq * comparators, int lineno) "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 @@ Compare(expr_ty left, asdl_seq * ops, asdl_seq * comparators, int lineno) 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 @@ Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, expr_ty starargs, "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 @@ Call(expr_ty func, asdl_seq * args, asdl_seq * keywords, expr_ty starargs, } 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 @@ Repr(expr_ty value, int lineno) "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 @@ Repr(expr_ty value, int lineno) } expr_ty -Num(object n, int lineno) +Num(object n, int lineno, PyArena *arena) { expr_ty p; if (!n) { @@ -763,7 +768,7 @@ Num(object n, int lineno) "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 @@ Num(object n, int lineno) } expr_ty -Str(string s, int lineno) +Str(string s, int lineno, PyArena *arena) { expr_ty p; if (!s) { @@ -783,7 +788,7 @@ Str(string s, int lineno) "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 @@ Str(string s, int lineno) } 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 @@ Attribute(expr_ty value, identifier attr, expr_context_ty ctx, int lineno) "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 @@ Attribute(expr_ty value, identifier attr, expr_context_ty ctx, int lineno) } 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 @@ Subscript(expr_ty value, slice_ty slice, expr_context_ty ctx, int lineno) "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 @@ Subscript(expr_ty value, slice_ty slice, expr_context_ty ctx, int lineno) } 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 @@ Name(identifier id, expr_context_ty ctx, int lineno) "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 @@ Name(identifier id, expr_context_ty ctx, int lineno) } 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 @@ List(asdl_seq * elts, expr_context_ty ctx, int lineno) "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 @@ List(asdl_seq * elts, expr_context_ty ctx, int lineno) } 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 @@ Tuple(asdl_seq * elts, expr_context_ty ctx, int lineno) "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 @@ Tuple(asdl_seq * elts, expr_context_ty ctx, int lineno) } 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 @@ Ellipsis() } 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(expr_ty lower, expr_ty upper, expr_ty step) } 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 @@ ExtSlice(asdl_seq * dims) } slice_ty -Index(expr_ty value) +Index(expr_ty value, PyArena *arena) { slice_ty p; if (!value) { @@ -978,7 +985,7 @@ Index(expr_ty value) "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 @@ Index(expr_ty value) } 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 @@ comprehension(expr_ty target, expr_ty iter, asdl_seq * ifs) "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 @@ comprehension(expr_ty target, expr_ty iter, asdl_seq * ifs) } 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 @@ excepthandler(expr_ty type, expr_ty name, asdl_seq * body) 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 @@ arguments(asdl_seq * args, identifier vararg, identifier kwarg, asdl_seq * } 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 @@ keyword(identifier arg, expr_ty value) "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 @@ keyword(identifier arg, expr_ty value) } alias_ty -alias(identifier name, identifier asname) +alias(identifier name, identifier asname, PyArena *arena) { alias_ty p; if (!name) { @@ -1078,7 +1085,7 @@ alias(identifier name, identifier asname) "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 @@ alias(identifier name, identifier asname) } -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; \ diff --git a/Python/asdl.c b/Python/asdl.c index 07ad4b3ea4f..ccd8714d026 100644 --- a/Python/asdl.c +++ b/Python/asdl.c @@ -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 @@ asdl_seq_new(int size) void asdl_seq_free(asdl_seq *seq) { - PyObject_Free(seq); } - diff --git a/Python/ast.c b/Python/ast.c index 04b2b3e5f66..6585c8fa8f6 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -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 @@ static PyObject *parsestrplus(struct compiling *, const node *n); #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 @@ num_stmts(const node *n) */ 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 @@ PyAST_FromNode(const node *n, PyCompilerFlags *flags, const char *filename) 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 @@ PyAST_FromNode(const node *n, PyCompilerFlags *flags, const char *filename) } } } - return Module(stmts); + return Module(stmts, arena); case eval_input: { expr_ty testlist_ast; @@ -322,20 +235,20 @@ PyAST_FromNode(const node *n, PyCompilerFlags *flags, const char *filename) 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 @@ PyAST_FromNode(const node *n, PyCompilerFlags *flags, const char *filename) } } - 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 @@ seq_for_testlist(struct compiling *c, const node *n) || 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 @@ seq_for_testlist(struct compiling *c, const node *n) 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 @@ seq_for_testlist(struct compiling *c, const node *n) } 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 @@ compiler_complex_args(const node *n) 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 @@ ast_for_arguments(struct compiling *c, const node *n) 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 @@ ast_for_arguments(struct compiling *c, const node *n) 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 @@ ast_for_arguments(struct compiling *c, const node *n) 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 @@ ast_for_arguments(struct compiling *c, const node *n) 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 @@ ast_for_arguments(struct compiling *c, const node *n) } } - 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 @@ ast_for_dotted_name(struct compiling *c, const node *n) 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 @@ ast_for_decorator(struct compiling *c, const node *n) 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 @@ ast_for_decorators(struct compiling *c, const node *n) 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 @@ ast_for_funcdef(struct compiling *c, const node *n) 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 @@ ast_for_funcdef(struct compiling *c, const node *n) 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 NULL; - return FunctionDef(name, args, body, decorator_seq, LINENO(n)); - -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 @@ ast_for_lambdef(struct compiling *c, const node *n) 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 @@ ast_for_listcomp(struct compiling *c, const node *n) 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 @@ ast_for_listcomp(struct compiling *c, const node *n) 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 @@ ast_for_listcomp(struct compiling *c, const node *n) 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 @@ ast_for_listcomp(struct compiling *c, const node *n) asdl_seq_APPEND(listcomps, lc); } - return ListComp(elt, listcomps, LINENO(n)); + return ListComp(elt, listcomps, LINENO(n), c->c_arena); } /* @@ -1198,13 +1055,11 @@ ast_for_genexp(struct compiling *c, const node *n) 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 @@ ast_for_genexp(struct compiling *c, const node *n) 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 @@ ast_for_genexp(struct compiling *c, const node *n) 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 @@ ast_for_genexp(struct compiling *c, const node *n) 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 @@ ast_for_atom(struct compiling *c, const node *n) 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 @@ ast_for_atom(struct compiling *c, const node *n) 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 @@ ast_for_atom(struct compiling *c, const node *n) 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 @@ ast_for_slice(struct compiling *c, const node *n) */ 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 @@ ast_for_slice(struct compiling *c, const node *n) if (!step) return NULL; - return Index(step); + return Index(step, c->c_arena); } if (TYPE(ch) == test) { @@ -1477,7 +1293,7 @@ ast_for_slice(struct compiling *c, const node *n) } } - return Slice(lower, upper, step); + return Slice(lower, upper, step, c->c_arena); } static expr_ty @@ -1504,7 +1320,7 @@ ast_for_binop(struct compiling *c, const node *n) 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 @@ ast_for_binop(struct compiling *c, const node *n) 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 @@ ast_for_trailer(struct compiling *c, const node *n, expr_ty left_expr) 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 @@ ast_for_trailer(struct compiling *c, const node *n, expr_ty left_expr) 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 @@ ast_for_power(struct compiling *c, const node *n) 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 @@ ast_for_expr(struct compiling *c, const node *n) 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 @@ ast_for_expr(struct compiling *c, const node *n) 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 @@ ast_for_expr(struct compiling *c, const node *n) 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 @@ ast_for_expr(struct compiling *c, const node *n) 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 @@ ast_for_expr(struct compiling *c, const node *n) 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 @@ ast_for_expr(struct compiling *c, const node *n) } 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 @@ ast_for_expr(struct compiling *c, const node *n) 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 @@ ast_for_expr(struct compiling *c, const node *n) 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 @@ ast_for_expr(struct compiling *c, const node *n) 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 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func) 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 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func) 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 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func) /* 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 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func) */ 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 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func) } } - 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 @@ ast_for_testlist(struct compiling *c, const node* n) 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 @@ ast_for_class_bases(struct compiling *c, const node* n) 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 @@ ast_for_expr_stmt(struct compiling *c, const node *n) 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 @@ ast_for_expr_stmt(struct compiling *c, const node *n) 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 @@ ast_for_expr_stmt(struct compiling *c, const node *n) 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 @@ ast_for_expr_stmt(struct compiling *c, const node *n) 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 @@ ast_for_expr_stmt(struct compiling *c, const node *n) /* 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 @@ ast_for_expr_stmt(struct compiling *c, const node *n) 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 @@ ast_for_expr_stmt(struct compiling *c, const node *n) 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 @@ ast_for_print_stmt(struct compiling *c, const node *n) 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 @@ ast_for_exprlist(struct compiling *c, const node *n, int context) 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 @@ ast_for_del_stmt(struct compiling *c, const node *n) 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 @@ ast_for_flow_stmt(struct compiling *c, const node *n) 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 @@ ast_for_flow_stmt(struct compiling *c, const node *n) 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 @@ ast_for_flow_stmt(struct compiling *c, const node *n) 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 @@ ast_for_flow_stmt(struct compiling *c, const node *n) } 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 @@ alias_for_import_name(const node *n) 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 @@ alias_for_import_name(const node *n) 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 @@ alias_for_import_name(const node *n) --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 @@ ast_for_import_stmt(struct compiling *c, const node *n) 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 @@ ast_for_import_stmt(struct compiling *c, const node *n) 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 @@ ast_for_import_stmt(struct compiling *c, const node *n) 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 @@ ast_for_import_stmt(struct compiling *c, const node *n) 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 @@ ast_for_global_stmt(struct compiling *c, const node *n) 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 @@ ast_for_exec_stmt(struct compiling *c, const node *n) 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 @@ ast_for_assert_stmt(struct compiling *c, const node *n) 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 @@ ast_for_assert_stmt(struct compiling *c, const node *n) 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 @@ ast_for_suite(struct compiling *c, const node *n) 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 @@ ast_for_suite(struct compiling *c, const node *n) 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 @@ ast_for_suite(struct compiling *c, const node *n) /* 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 @@ ast_for_suite(struct compiling *c, const node *n) 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 @@ ast_for_suite(struct compiling *c, const node *n) } assert(pos == seq->size); return seq; - error: - if (seq) - asdl_stmt_seq_free(seq); - return NULL; } static stmt_ty @@ -2602,11 +2353,10 @@ ast_for_if_stmt(struct compiling *c, const node *n) 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 @@ ast_for_if_stmt(struct compiling *c, const node *n) 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 @@ ast_for_if_stmt(struct compiling *c, const node *n) 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 @@ ast_for_if_stmt(struct compiling *c, const node *n) 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 @@ ast_for_while_stmt(struct compiling *c, const node *n) 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 @@ ast_for_while_stmt(struct compiling *c, const node *n) 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 @@ ast_for_for_stmt(struct compiling *c, const node *n) _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 @@ ast_for_except_clause(struct compiling *c, const node *exc, node *body) 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 @@ ast_for_except_clause(struct compiling *c, const node *exc, node *body) 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 @@ ast_for_except_clause(struct compiling *c, const node *exc, node *body) 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 @@ ast_for_try_stmt(struct compiling *c, const node *n) 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 @@ ast_for_try_stmt(struct compiling *c, const node *n) 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 @@ ast_for_try_stmt(struct compiling *c, const node *n) 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 @@ ast_for_try_stmt(struct compiling *c, const node *n) 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 @@ ast_for_classdef(struct compiling *c, const node *n) 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 @@ ast_for_classdef(struct compiling *c, const node *n) 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 @@ ast_for_stmt(struct compiling *c, const node *n) 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 @@ decode_unicode(const char *s, size_t len, int rawmode, const char *encoding) static PyObject * parsestr(const char *s, const char *encoding) { - PyObject *v; size_t len; int quote = *s; int rawmode = 0; @@ -3259,7 +2970,7 @@ parsestr(const char *s, const char *encoding) 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 @@ parsestr(const char *s, const char *encoding) } } - 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 @@ parsestrplus(struct compiling *c, const node *n) } #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 } diff --git a/Python/compile.c b/Python/compile.c index 4ad17b3d0a3..accd3b70bc0 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -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 { 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 @@ compiler_init(struct compiler *c) } 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 @@ PyAST_Compile(mod_ty mod, const char *filename, PyCompilerFlags *flags) 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 @@ PyAST_Compile(mod_ty mod, const char *filename, PyCompilerFlags *flags) 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 @@ compiler_augassign(struct compiler *c, stmt_ty s) 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 @@ compiler_augassign(struct compiler *c, stmt_ty s) 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 @@ compiler_augassign(struct compiler *c, stmt_ty s) 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); diff --git a/Python/import.c b/Python/import.c index daa8f8d660d..f284ff4d211 100644 --- a/Python/import.c +++ b/Python/import.c @@ -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 @@ parse_source_module(const char *pathname, FILE *fp) { 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; } diff --git a/Python/pyarena.c b/Python/pyarena.c new file mode 100644 index 00000000000..d67753215e1 --- /dev/null +++ b/Python/pyarena.c @@ -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; +} diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 0b14f8bfbc4..a7f4fe7ceed 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -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 @@ extern grammar _PyParser_Grammar; /* From graminit.c */ 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 @@ PyRun_InteractiveOneFlags(FILE *fp, const char *filename, PyCompilerFlags *flags { PyObject *m, *d, *v, *w; mod_ty mod; + PyArena *arena; char *ps1 = "", *ps2 = ""; int errcode = 0; @@ -716,12 +718,14 @@ PyRun_InteractiveOneFlags(FILE *fp, const char *filename, PyCompilerFlags *flags 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 @@ PyRun_InteractiveOneFlags(FILE *fp, const char *filename, PyCompilerFlags *flags 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 @@ PyRun_StringFlags(const char *str, int start, PyObject *globals, PyObject *locals, PyCompilerFlags *flags) { PyObject *ret; - mod_ty mod = PyParser_ASTFromString(str, "", start, flags); - ret = run_err_mod(mod, "", globals, locals, flags); - free_mod(mod); + PyArena *arena = PyArena_New(); + mod_ty mod = PyParser_ASTFromString(str, "", start, flags, + arena); + ret = run_err_mod(mod, "", globals, locals, flags, arena); + PyArena_Free(arena); return ret; } @@ -1166,33 +1174,36 @@ PyRun_FileExFlags(FILE *fp, const char *filename, int start, PyObject *globals, 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 @@ PyObject * 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 @@ PyParser_ASTFromString(const char *s, const char *filename, int start, 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 @@ PyParser_ASTFromFile(FILE *fp, const char *filename, int start, char *ps1, 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 @@ PyParser_SimpleParseFileFlags(FILE *fp, const char *filename, int start, int fla 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 @@ node * 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 @@ PyParser_SimpleParseStringFlagsFilename(const char *str, const char *filename, 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