summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Include/Python-ast.h134
-rw-r--r--Include/Python.h1
-rw-r--r--Include/asdl.h2
-rw-r--r--Include/ast.h2
-rw-r--r--Include/compile.h2
-rw-r--r--Include/pyarena.h42
-rw-r--r--Include/pythonrun.h6
-rw-r--r--Makefile.pre.in2
-rwxr-xr-xParser/asdl_c.py15
-rw-r--r--Python/Python-ast.c667
-rw-r--r--Python/asdl.c7
-rw-r--r--Python/ast.c791
-rw-r--r--Python/compile.c25
-rw-r--r--Python/import.c8
-rw-r--r--Python/pyarena.c133
-rw-r--r--Python/pythonrun.c109
16 files changed, 704 insertions, 1242 deletions
diff --git a/Include/Python-ast.h b/Include/Python-ast.h
index 2484bb1..4dfaef8 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 f941cba..8df7dbc 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 cf05967..a2c86c8 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 b1a9388..cc14b7f 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 5c6a7c7..029cb17 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 0000000..6f191a1
--- /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 514d3bc..e309078 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 bae4250..ab01deb 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 f45bee4..b1fc77d 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 b276625..445049d 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 07ad4b3..ccd8714 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 04b2b3e..6585c8f 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 FunctionDef(name, args, body, decorator_seq, LINENO(n));
+ return NULL;
-error:
- asdl_stmt_seq_free(body);
- asdl_expr_seq_free(decorator_seq);
- free_arguments(args);
- Py_XDECREF(name);
- return NULL;
+ return FunctionDef(name, args, body, decorator_seq, LINENO(n), c->c_arena);
}
static expr_ty
@@ -919,27 +805,23 @@ 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 4ad17b3..accd3b7 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 daa8f8d..f284ff4 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 0000000..d677532
--- /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 0b14f8b..a7f4fe7 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, "<string>", start, flags);
- ret = run_err_mod(mod, "<string>", globals, locals, flags);
- free_mod(mod);
+ PyArena *arena = PyArena_New();
+ mod_ty mod = PyParser_ASTFromString(str, "<string>", start, flags,
+ arena);
+ ret = run_err_mod(mod, "<string>", globals, locals, flags, arena);
+ PyArena_Free(arena);
return ret;
}
@@ -1166,33 +1174,36 @@ 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