[Python-checkins] r62706 - in python/branches/tlee-ast-optimize: Include/Python-ast.h Lib/test/test_optimizer.py Parser/asdl_c.py Python/Python-ast.c Python/compile.c Python/optimize.c Python/peephole.c
thomas.lee
python-checkins at python.org
Sun May 4 18:57:45 CEST 2008
Author: thomas.lee
Date: Sun May 4 18:57:45 2008
New Revision: 62706
Log:
Implementing very, very rough initial implementation of annotated ASTs. Got one or two extra optimizations ported from the peepholer (most notably, folding tuples of constants). Tests are somewhat incomplete, and refleaks are likely to be present.
Modified:
python/branches/tlee-ast-optimize/Include/Python-ast.h
python/branches/tlee-ast-optimize/Lib/test/test_optimizer.py
python/branches/tlee-ast-optimize/Parser/asdl_c.py
python/branches/tlee-ast-optimize/Python/Python-ast.c
python/branches/tlee-ast-optimize/Python/compile.c
python/branches/tlee-ast-optimize/Python/optimize.c
python/branches/tlee-ast-optimize/Python/peephole.c
Modified: python/branches/tlee-ast-optimize/Include/Python-ast.h
==============================================================================
--- python/branches/tlee-ast-optimize/Include/Python-ast.h (original)
+++ python/branches/tlee-ast-optimize/Include/Python-ast.h Sun May 4 18:57:45 2008
@@ -57,6 +57,7 @@
} Suite;
} v;
+ PyObject* annotations;
};
enum _stmt_kind {FunctionDef_kind=1, ClassDef_kind=2, Return_kind=3,
@@ -182,6 +183,7 @@
} v;
int lineno;
int col_offset;
+ PyObject* annotations;
};
enum _expr_kind {BoolOp_kind=1, BinOp_kind=2, UnaryOp_kind=3, Lambda_kind=4,
@@ -295,6 +297,7 @@
} v;
int lineno;
int col_offset;
+ PyObject* annotations;
};
enum _slice_kind {Ellipsis_kind=1, Slice_kind=2, ExtSlice_kind=3, Index_kind=4};
@@ -316,6 +319,7 @@
} Index;
} v;
+ PyObject* annotations;
};
struct _comprehension {
@@ -337,6 +341,7 @@
} v;
int lineno;
int col_offset;
+ PyObject* annotations;
};
struct _arguments {
Modified: python/branches/tlee-ast-optimize/Lib/test/test_optimizer.py
==============================================================================
--- python/branches/tlee-ast-optimize/Lib/test/test_optimizer.py (original)
+++ python/branches/tlee-ast-optimize/Lib/test/test_optimizer.py Sun May 4 18:57:45 2008
@@ -97,7 +97,7 @@
for code, expected in tests:
ast = self.compileast(code)
- actual = getattr(ast.body[0].value, attrmap[type(expected)])
+ actual = ast.body[0].value.annotations['const']
self.assertEqual(expected, actual)
def test_binop_fold_num_with_variable(self):
@@ -118,8 +118,8 @@
self.assertEqual(_ast.Expr, ast.body[1].__class__)
self.assertEqual(_ast.BinOp, ast.body[1].value.__class__)
self.assertEqual(_ast.Name, ast.body[1].value.left.__class__)
- self.assertEqual(_ast.Num, ast.body[1].value.right.__class__)
- self.assertEqual(6, ast.body[1].value.right.n)
+ self.assertEqual(_ast.BinOp, ast.body[1].value.right.__class__)
+ self.assertEqual(6, ast.body[1].value.right.annotations['const'])
def test_binop_failure_left_until_runtime(self):
ast = self.compileast("5 + '3'")
@@ -134,13 +134,22 @@
except TypeError:
pass
+ def assertConstant(self, expected, code):
+ ast = self.compileast(code).body[0].value
+ if type(ast) is _ast.Str:
+ self.assertEqual(expected, ast.s)
+ elif type(ast) is _ast.Num:
+ self.assertEqual(expected, ast.n)
+ else:
+ self.assertEqual(expected, ast.annotations['const'])
+
def test_unary_fold_num(self):
# check unary constant folding for numeric values
- self.assertNum(-5, "-5")
- self.assertNum(True, "not 0")
- self.assertNum(-3, "-+3")
- self.assertNum(False, "not True")
- self.assertNum(True, "not None")
+ self.assertConstant(-5, '-5')
+ self.assertConstant(True, "not 0")
+ self.assertConstant(-3, "-+3")
+ self.assertConstant(False, "not True")
+ self.assertConstant(True, "not None")
def test_unary_failure_left_until_runtime(self):
ast = self.compileast("~'bad!'")
@@ -188,6 +197,13 @@
self.assertEqual(3, len(ast.body[0].body))
self.assertEqual(_ast.Pass, ast.body[0].body[2].__class__)
+ def test_fold_tuple_of_constants(self):
+ ast = self.compileast('(1, 2, 3)')
+ self.assertEqual((1, 2, 3), ast.body[0].value.annotations['const'])
+
+ ast = self.compileast('((1, 2), 3)')
+ self.assertEqual(((1, 2), 3), ast.body[0].value.annotations['const'])
+
def test_main():
test_support.run_unittest(AstOptimizerTest)
Modified: python/branches/tlee-ast-optimize/Parser/asdl_c.py
==============================================================================
--- python/branches/tlee-ast-optimize/Parser/asdl_c.py (original)
+++ python/branches/tlee-ast-optimize/Parser/asdl_c.py Sun May 4 18:57:45 2008
@@ -170,6 +170,7 @@
type = str(field.type)
assert type in asdl.builtin_types, type
emit("%s %s;" % (type, field.name), depth + 1);
+ emit("PyObject* annotations;", depth + 1)
emit("};")
emit("")
@@ -321,6 +322,7 @@
emit("p->v.%s.%s = %s;" % (name, argname, argname), 1)
for argtype, argname, opt in attrs:
emit("p->%s = %s;" % (argname, argname), 1)
+ emit("p->annotations = NULL;", 1)
def emit_body_struct(self, name, args, attrs):
def emit(s, depth=0, reflow=1):
@@ -417,6 +419,9 @@
args = [f.name.value for f in t.fields] + [a.name.value for a in sum.attributes]
self.emit("*out = %s(%s);" % (t.name, self.buildArgs(args)), 2)
self.emit("if (*out == NULL) goto failed;", 2)
+ self.emit('(*out)->annotations = PyObject_GetAttrString(obj, "annotations");', 2)
+ self.emit('if ((*out)->annotations == NULL)', 2)
+ self.emit('PyErr_Clear();', 3)
self.emit("return 0;", 2)
self.emit("}", 1)
self.sumTrailer(name)
@@ -980,6 +985,9 @@
self.emit('if (PyObject_SetAttrString(result, "%s", value) < 0)' % a.name, 1)
self.emit('goto failed;', 2)
self.emit('Py_DECREF(value);', 1)
+ if not is_simple(sum):
+ self.emit('if (o->annotations && PyObject_SetAttrString(result, "annotations", o->annotations) < 0)', 1)
+ self.emit('goto failed;', 2)
self.func_end()
def simpleSum(self, sum, name):
Modified: python/branches/tlee-ast-optimize/Python/Python-ast.c
==============================================================================
--- python/branches/tlee-ast-optimize/Python/Python-ast.c (original)
+++ python/branches/tlee-ast-optimize/Python/Python-ast.c Sun May 4 18:57:45 2008
@@ -936,6 +936,7 @@
return NULL;
p->kind = Module_kind;
p->v.Module.body = body;
+ p->annotations = NULL;
return p;
}
@@ -948,6 +949,7 @@
return NULL;
p->kind = Interactive_kind;
p->v.Interactive.body = body;
+ p->annotations = NULL;
return p;
}
@@ -965,6 +967,7 @@
return NULL;
p->kind = Expression_kind;
p->v.Expression.body = body;
+ p->annotations = NULL;
return p;
}
@@ -977,6 +980,7 @@
return NULL;
p->kind = Suite_kind;
p->v.Suite.body = body;
+ p->annotations = NULL;
return p;
}
@@ -1005,6 +1009,7 @@
p->v.FunctionDef.decorator_list = decorator_list;
p->lineno = lineno;
p->col_offset = col_offset;
+ p->annotations = NULL;
return p;
}
@@ -1028,6 +1033,7 @@
p->v.ClassDef.decorator_list = decorator_list;
p->lineno = lineno;
p->col_offset = col_offset;
+ p->annotations = NULL;
return p;
}
@@ -1042,6 +1048,7 @@
p->v.Return.value = value;
p->lineno = lineno;
p->col_offset = col_offset;
+ p->annotations = NULL;
return p;
}
@@ -1056,6 +1063,7 @@
p->v.Delete.targets = targets;
p->lineno = lineno;
p->col_offset = col_offset;
+ p->annotations = NULL;
return p;
}
@@ -1077,6 +1085,7 @@
p->v.Assign.value = value;
p->lineno = lineno;
p->col_offset = col_offset;
+ p->annotations = NULL;
return p;
}
@@ -1109,6 +1118,7 @@
p->v.AugAssign.value = value;
p->lineno = lineno;
p->col_offset = col_offset;
+ p->annotations = NULL;
return p;
}
@@ -1126,6 +1136,7 @@
p->v.Print.nl = nl;
p->lineno = lineno;
p->col_offset = col_offset;
+ p->annotations = NULL;
return p;
}
@@ -1154,6 +1165,7 @@
p->v.For.orelse = orelse;
p->lineno = lineno;
p->col_offset = col_offset;
+ p->annotations = NULL;
return p;
}
@@ -1176,6 +1188,7 @@
p->v.While.orelse = orelse;
p->lineno = lineno;
p->col_offset = col_offset;
+ p->annotations = NULL;
return p;
}
@@ -1198,6 +1211,7 @@
p->v.If.orelse = orelse;
p->lineno = lineno;
p->col_offset = col_offset;
+ p->annotations = NULL;
return p;
}
@@ -1220,6 +1234,7 @@
p->v.With.body = body;
p->lineno = lineno;
p->col_offset = col_offset;
+ p->annotations = NULL;
return p;
}
@@ -1237,6 +1252,7 @@
p->v.Raise.tback = tback;
p->lineno = lineno;
p->col_offset = col_offset;
+ p->annotations = NULL;
return p;
}
@@ -1254,6 +1270,7 @@
p->v.TryExcept.orelse = orelse;
p->lineno = lineno;
p->col_offset = col_offset;
+ p->annotations = NULL;
return p;
}
@@ -1270,6 +1287,7 @@
p->v.TryFinally.finalbody = finalbody;
p->lineno = lineno;
p->col_offset = col_offset;
+ p->annotations = NULL;
return p;
}
@@ -1290,6 +1308,7 @@
p->v.Assert.msg = msg;
p->lineno = lineno;
p->col_offset = col_offset;
+ p->annotations = NULL;
return p;
}
@@ -1304,6 +1323,7 @@
p->v.Import.names = names;
p->lineno = lineno;
p->col_offset = col_offset;
+ p->annotations = NULL;
return p;
}
@@ -1326,6 +1346,7 @@
p->v.ImportFrom.level = level;
p->lineno = lineno;
p->col_offset = col_offset;
+ p->annotations = NULL;
return p;
}
@@ -1348,6 +1369,7 @@
p->v.Exec.locals = locals;
p->lineno = lineno;
p->col_offset = col_offset;
+ p->annotations = NULL;
return p;
}
@@ -1362,6 +1384,7 @@
p->v.Global.names = names;
p->lineno = lineno;
p->col_offset = col_offset;
+ p->annotations = NULL;
return p;
}
@@ -1381,6 +1404,7 @@
p->v.Expr.value = value;
p->lineno = lineno;
p->col_offset = col_offset;
+ p->annotations = NULL;
return p;
}
@@ -1394,6 +1418,7 @@
p->kind = Pass_kind;
p->lineno = lineno;
p->col_offset = col_offset;
+ p->annotations = NULL;
return p;
}
@@ -1407,6 +1432,7 @@
p->kind = Break_kind;
p->lineno = lineno;
p->col_offset = col_offset;
+ p->annotations = NULL;
return p;
}
@@ -1420,6 +1446,7 @@
p->kind = Continue_kind;
p->lineno = lineno;
p->col_offset = col_offset;
+ p->annotations = NULL;
return p;
}
@@ -1441,6 +1468,7 @@
p->v.BoolOp.values = values;
p->lineno = lineno;
p->col_offset = col_offset;
+ p->annotations = NULL;
return p;
}
@@ -1473,6 +1501,7 @@
p->v.BinOp.right = right;
p->lineno = lineno;
p->col_offset = col_offset;
+ p->annotations = NULL;
return p;
}
@@ -1499,6 +1528,7 @@
p->v.UnaryOp.operand = operand;
p->lineno = lineno;
p->col_offset = col_offset;
+ p->annotations = NULL;
return p;
}
@@ -1525,6 +1555,7 @@
p->v.Lambda.body = body;
p->lineno = lineno;
p->col_offset = col_offset;
+ p->annotations = NULL;
return p;
}
@@ -1557,6 +1588,7 @@
p->v.IfExp.orelse = orelse;
p->lineno = lineno;
p->col_offset = col_offset;
+ p->annotations = NULL;
return p;
}
@@ -1573,6 +1605,7 @@
p->v.Dict.values = values;
p->lineno = lineno;
p->col_offset = col_offset;
+ p->annotations = NULL;
return p;
}
@@ -1594,6 +1627,7 @@
p->v.ListComp.generators = generators;
p->lineno = lineno;
p->col_offset = col_offset;
+ p->annotations = NULL;
return p;
}
@@ -1615,6 +1649,7 @@
p->v.GeneratorExp.generators = generators;
p->lineno = lineno;
p->col_offset = col_offset;
+ p->annotations = NULL;
return p;
}
@@ -1629,6 +1664,7 @@
p->v.Yield.value = value;
p->lineno = lineno;
p->col_offset = col_offset;
+ p->annotations = NULL;
return p;
}
@@ -1651,6 +1687,7 @@
p->v.Compare.comparators = comparators;
p->lineno = lineno;
p->col_offset = col_offset;
+ p->annotations = NULL;
return p;
}
@@ -1675,6 +1712,7 @@
p->v.Call.kwargs = kwargs;
p->lineno = lineno;
p->col_offset = col_offset;
+ p->annotations = NULL;
return p;
}
@@ -1694,6 +1732,7 @@
p->v.Repr.value = value;
p->lineno = lineno;
p->col_offset = col_offset;
+ p->annotations = NULL;
return p;
}
@@ -1713,6 +1752,7 @@
p->v.Num.n = n;
p->lineno = lineno;
p->col_offset = col_offset;
+ p->annotations = NULL;
return p;
}
@@ -1732,6 +1772,7 @@
p->v.Str.s = s;
p->lineno = lineno;
p->col_offset = col_offset;
+ p->annotations = NULL;
return p;
}
@@ -1764,6 +1805,7 @@
p->v.Attribute.ctx = ctx;
p->lineno = lineno;
p->col_offset = col_offset;
+ p->annotations = NULL;
return p;
}
@@ -1796,6 +1838,7 @@
p->v.Subscript.ctx = ctx;
p->lineno = lineno;
p->col_offset = col_offset;
+ p->annotations = NULL;
return p;
}
@@ -1822,6 +1865,7 @@
p->v.Name.ctx = ctx;
p->lineno = lineno;
p->col_offset = col_offset;
+ p->annotations = NULL;
return p;
}
@@ -1843,6 +1887,7 @@
p->v.List.ctx = ctx;
p->lineno = lineno;
p->col_offset = col_offset;
+ p->annotations = NULL;
return p;
}
@@ -1864,6 +1909,7 @@
p->v.Tuple.ctx = ctx;
p->lineno = lineno;
p->col_offset = col_offset;
+ p->annotations = NULL;
return p;
}
@@ -1875,6 +1921,7 @@
if (!p)
return NULL;
p->kind = Ellipsis_kind;
+ p->annotations = NULL;
return p;
}
@@ -1889,6 +1936,7 @@
p->v.Slice.lower = lower;
p->v.Slice.upper = upper;
p->v.Slice.step = step;
+ p->annotations = NULL;
return p;
}
@@ -1901,6 +1949,7 @@
return NULL;
p->kind = ExtSlice_kind;
p->v.ExtSlice.dims = dims;
+ p->annotations = NULL;
return p;
}
@@ -1918,6 +1967,7 @@
return NULL;
p->kind = Index_kind;
p->v.Index.value = value;
+ p->annotations = NULL;
return p;
}
@@ -1958,6 +2008,7 @@
p->v.ExceptHandler.body = body;
p->lineno = lineno;
p->col_offset = col_offset;
+ p->annotations = NULL;
return p;
}
@@ -2064,6 +2115,9 @@
Py_DECREF(value);
break;
}
+ if (o->annotations && PyObject_SetAttrString(result, "annotations",
+ o->annotations) < 0)
+ goto failed;
return result;
failed:
Py_XDECREF(value);
@@ -2441,6 +2495,9 @@
if (PyObject_SetAttrString(result, "col_offset", value) < 0)
goto failed;
Py_DECREF(value);
+ if (o->annotations && PyObject_SetAttrString(result, "annotations",
+ o->annotations) < 0)
+ goto failed;
return result;
failed:
Py_XDECREF(value);
@@ -2764,6 +2821,9 @@
if (PyObject_SetAttrString(result, "col_offset", value) < 0)
goto failed;
Py_DECREF(value);
+ if (o->annotations && PyObject_SetAttrString(result, "annotations",
+ o->annotations) < 0)
+ goto failed;
return result;
failed:
Py_XDECREF(value);
@@ -2851,6 +2911,9 @@
Py_DECREF(value);
break;
}
+ if (o->annotations && PyObject_SetAttrString(result, "annotations",
+ o->annotations) < 0)
+ goto failed;
return result;
failed:
Py_XDECREF(value);
@@ -3053,6 +3116,9 @@
if (PyObject_SetAttrString(result, "col_offset", value) < 0)
goto failed;
Py_DECREF(value);
+ if (o->annotations && PyObject_SetAttrString(result, "annotations",
+ o->annotations) < 0)
+ goto failed;
return result;
failed:
Py_XDECREF(value);
@@ -3198,6 +3264,10 @@
}
*out = Module(body, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)Interactive_type)) {
@@ -3230,6 +3300,10 @@
}
*out = Interactive(body, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)Expression_type)) {
@@ -3249,6 +3323,10 @@
}
*out = Expression(body, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)Suite_type)) {
@@ -3281,6 +3359,10 @@
}
*out = Suite(body, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
@@ -3411,6 +3493,10 @@
*out = FunctionDef(name, args, body, decorator_list, lineno,
col_offset, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)ClassDef_type)) {
@@ -3509,6 +3595,10 @@
*out = ClassDef(name, bases, body, decorator_list, lineno,
col_offset, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)Return_type)) {
@@ -3527,6 +3617,10 @@
}
*out = Return(value, lineno, col_offset, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)Delete_type)) {
@@ -3559,6 +3653,10 @@
}
*out = Delete(targets, lineno, col_offset, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)Assign_type)) {
@@ -3604,6 +3702,10 @@
}
*out = Assign(targets, value, lineno, col_offset, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)AugAssign_type)) {
@@ -3649,6 +3751,10 @@
}
*out = AugAssign(target, op, value, lineno, col_offset, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)Print_type)) {
@@ -3706,6 +3812,10 @@
}
*out = Print(dest, values, nl, lineno, col_offset, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)For_type)) {
@@ -3791,6 +3901,10 @@
*out = For(target, iter, body, orelse, lineno, col_offset,
arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)While_type)) {
@@ -3862,6 +3976,10 @@
}
*out = While(test, body, orelse, lineno, col_offset, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)If_type)) {
@@ -3933,6 +4051,10 @@
}
*out = If(test, body, orelse, lineno, col_offset, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)With_type)) {
@@ -3991,6 +4113,10 @@
*out = With(context_expr, optional_vars, body, lineno,
col_offset, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)Raise_type)) {
@@ -4033,6 +4159,10 @@
}
*out = Raise(type, inst, tback, lineno, col_offset, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)TryExcept_type)) {
@@ -4118,6 +4248,10 @@
*out = TryExcept(body, handlers, orelse, lineno, col_offset,
arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)TryFinally_type)) {
@@ -4176,6 +4310,10 @@
}
*out = TryFinally(body, finalbody, lineno, col_offset, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)Assert_type)) {
@@ -4207,6 +4345,10 @@
}
*out = Assert(test, msg, lineno, col_offset, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)Import_type)) {
@@ -4239,6 +4381,10 @@
}
*out = Import(names, lineno, col_offset, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)ImportFrom_type)) {
@@ -4297,6 +4443,10 @@
*out = ImportFrom(module, names, level, lineno, col_offset,
arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)Exec_type)) {
@@ -4340,6 +4490,10 @@
}
*out = Exec(body, globals, locals, lineno, col_offset, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)Global_type)) {
@@ -4372,6 +4526,10 @@
}
*out = Global(names, lineno, col_offset, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)Expr_type)) {
@@ -4391,24 +4549,40 @@
}
*out = Expr(value, lineno, col_offset, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)Pass_type)) {
*out = Pass(lineno, col_offset, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)Break_type)) {
*out = Break(lineno, col_offset, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)Continue_type)) {
*out = Continue(lineno, col_offset, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
@@ -4499,6 +4673,10 @@
}
*out = BoolOp(op, values, lineno, col_offset, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)BinOp_type)) {
@@ -4544,6 +4722,10 @@
}
*out = BinOp(left, op, right, lineno, col_offset, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)UnaryOp_type)) {
@@ -4576,6 +4758,10 @@
}
*out = UnaryOp(op, operand, lineno, col_offset, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)Lambda_type)) {
@@ -4608,6 +4794,10 @@
}
*out = Lambda(args, body, lineno, col_offset, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)IfExp_type)) {
@@ -4653,6 +4843,10 @@
}
*out = IfExp(test, body, orelse, lineno, col_offset, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)Dict_type)) {
@@ -4711,6 +4905,10 @@
}
*out = Dict(keys, values, lineno, col_offset, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)ListComp_type)) {
@@ -4756,6 +4954,10 @@
}
*out = ListComp(elt, generators, lineno, col_offset, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)GeneratorExp_type)) {
@@ -4801,6 +5003,10 @@
}
*out = GeneratorExp(elt, generators, lineno, col_offset, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)Yield_type)) {
@@ -4819,6 +5025,10 @@
}
*out = Yield(value, lineno, col_offset, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)Compare_type)) {
@@ -4891,6 +5101,10 @@
*out = Compare(left, ops, comparators, lineno, col_offset,
arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)Call_type)) {
@@ -4987,6 +5201,10 @@
*out = Call(func, args, keywords, starargs, kwargs, lineno,
col_offset, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)Repr_type)) {
@@ -5006,6 +5224,10 @@
}
*out = Repr(value, lineno, col_offset, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)Num_type)) {
@@ -5025,6 +5247,10 @@
}
*out = Num(n, lineno, col_offset, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)Str_type)) {
@@ -5044,6 +5270,10 @@
}
*out = Str(s, lineno, col_offset, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)Attribute_type)) {
@@ -5089,6 +5319,10 @@
}
*out = Attribute(value, attr, ctx, lineno, col_offset, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)Subscript_type)) {
@@ -5134,6 +5368,10 @@
}
*out = Subscript(value, slice, ctx, lineno, col_offset, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)Name_type)) {
@@ -5166,6 +5404,10 @@
}
*out = Name(id, ctx, lineno, col_offset, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)List_type)) {
@@ -5211,6 +5453,10 @@
}
*out = List(elts, ctx, lineno, col_offset, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)Tuple_type)) {
@@ -5256,6 +5502,10 @@
}
*out = Tuple(elts, ctx, lineno, col_offset, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
@@ -5319,6 +5569,10 @@
*out = Ellipsis(arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)Slice_type)) {
@@ -5361,6 +5615,10 @@
}
*out = Slice(lower, upper, step, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)ExtSlice_type)) {
@@ -5393,6 +5651,10 @@
}
*out = ExtSlice(dims, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
if (PyObject_IsInstance(obj, (PyObject*)Index_type)) {
@@ -5412,6 +5674,10 @@
}
*out = Index(value, arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
@@ -5746,6 +6012,10 @@
*out = ExceptHandler(type, name, body, lineno, col_offset,
arena);
if (*out == NULL) goto failed;
+ (*out)->annotations = PyObject_GetAttrString(obj,
+ "annotations");
+ if ((*out)->annotations == NULL)
+ PyErr_Clear();
return 0;
}
Modified: python/branches/tlee-ast-optimize/Python/compile.c
==============================================================================
--- python/branches/tlee-ast-optimize/Python/compile.c (original)
+++ python/branches/tlee-ast-optimize/Python/compile.c Sun May 4 18:57:45 2008
@@ -2831,6 +2831,11 @@
return ! Py_OptimizeFlag;
/* fall through */
default:
+ if (e->annotations != NULL) {
+ PyObject* constant = PyDict_GetItemString(e->annotations, "const");
+ if (constant != NULL)
+ return PyObject_IsTrue(constant);
+ }
return -1;
}
}
@@ -2972,6 +2977,16 @@
c->u->u_lineno = e->lineno;
c->u->u_lineno_set = false;
}
+
+ /* if the expression is annotated with a constant value, use that instead */
+ if (e->annotations != NULL) {
+ PyObject* constant = PyDict_GetItemString(e->annotations, "const");
+ if (constant != NULL) {
+ ADDOP_O(c, LOAD_CONST, constant, consts);
+ return 1;
+ }
+ }
+
switch (e->kind) {
case BoolOp_kind:
return compiler_boolop(c, e);
@@ -3580,7 +3595,9 @@
d_lineno = i->i_lineno - a->a_lineno;
assert(d_bytecode >= 0);
- assert(d_lineno >= 0);
+#if 0
+ assert(d_lineno >= 0);
+#endif
if(d_bytecode == 0 && d_lineno == 0)
return 1;
Modified: python/branches/tlee-ast-optimize/Python/optimize.c
==============================================================================
--- python/branches/tlee-ast-optimize/Python/optimize.c (original)
+++ python/branches/tlee-ast-optimize/Python/optimize.c Sun May 4 18:57:45 2008
@@ -14,111 +14,51 @@
static int optimize_slice(slice_ty* slice_ptr, PyArena* arena);
/**
- * Determine the constant value of a given expression. It's assumed that
- * constants have been folded.
+ * Annotate a constant expression with its value.
*/
-static PyObject*
-_expr_constant_value(expr_ty expr)
+static int
+_annotate_constant(expr_ty expr, PyObject* v, PyArena* arena)
{
- if (expr->kind == Str_kind) {
- return expr->v.Str.s;
- }
- else if (expr->kind == Num_kind) {
- return expr->v.Num.n;
- }
- else if (expr->kind == Name_kind) {
- const char* name = PyString_AS_STRING(expr->v.Name.id);
- if (strcmp(name, "True") == 0)
- return Py_True;
- else if (strcmp(name, "False") == 0)
- return Py_False;
- else if (strcmp(name, "None") == 0)
- return Py_None;
+ if (expr->annotations == NULL) {
+ expr->annotations = PyDict_New();
+ if (expr->annotations == NULL)
+ return 0;
+ if (PyArena_AddPyObject(arena, expr->annotations) == -1)
+ return 0;
}
- return NULL;
-}
-/**
- * Determine whether or not the given expression represents a constant value.
- * This makes the assumption that constants have already been folded.
- */
-static int
-_expr_is_constant(expr_ty expr)
-{
- return _expr_constant_value(expr) != NULL;
-}
+ if (PyDict_SetItemString(expr->annotations, "const", v) == -1)
+ return 0;
-/*
- * builds a Name() node with a Load context from the given id.
- */
-static expr_ty
-_make_name(PyObject* id, int lineno, int col_offset, PyArena* arena)
-{
- expr_ty expr;
- if (id == NULL)
- return NULL;
- expr = Name(id, Load, lineno, col_offset, arena);
- if (expr == NULL)
- return NULL;
- return expr;
+ return 1;
}
/**
- * Builds an expr from the given constant value. Constant values can be
- * any Str or Num, or any one of True/False/None.
+ * Determine the constant value of a given expression. It's assumed that
+ * constants have been folded.
*/
-static expr_ty
-_expr_from_object(PyObject* object, int lineno, int col_offset, PyArena* arena)
+static PyObject*
+_expr_constant_value(expr_ty expr)
{
- expr_ty expr = NULL;
-
- if (PyString_Check(object) || PyUnicode_Check(object)) {
- Py_INCREF(object);
- expr = Str(object, lineno, col_offset, arena);
- }
- else if (PyNumber_Check(object)) {
- Py_INCREF(object);
- expr = Num(object, lineno, col_offset, arena);
- }
- else if (object == Py_None) {
- object = PyString_FromString("None");
- expr = _make_name(object, lineno, col_offset, arena);
- }
- else if (object == Py_True) {
- object = PyString_FromString("True");
- expr = _make_name(object, lineno, col_offset, arena);
+ PyObject* obj;
+
+ if (expr->kind == Str_kind) {
+ return expr->v.Str.s;
}
- else if (object == Py_False) {
- object = PyString_FromString("False");
- expr = _make_name(object, lineno, col_offset, arena);
+ else if (expr->kind == Num_kind) {
+ return expr->v.Num.n;
}
else {
- PyErr_Format(PyExc_TypeError, "unknown constant value");
- return NULL;
- }
-
- if (expr == NULL)
- return NULL;
+ if (expr->annotations == NULL)
+ return NULL;
- if (PyArena_AddPyObject(arena, object) == -1) {
- /* exception will be set in PyArena_AddPyObject */
- Py_DECREF(object);
- return NULL;
- }
+ obj = PyDict_GetItemString(expr->annotations, "const");
- /* PyArena_AddPyObject decrements the refcount for us */
- return expr;
-}
+ if (obj == NULL)
+ PyErr_Clear();
-/**
- * Returns 1 if the given expression evaluates to a true value. Otherwise,
- * returns 0. This function assumes that the given expr is constant.
- */
-static int
-_expr_is_true(expr_ty expr)
-{
- assert(_expr_is_constant(expr));
- return PyObject_IsTrue(_expr_constant_value(expr));
+ return obj;
+ }
}
/**
@@ -181,17 +121,13 @@
_asdl_seq_replace_with_pass(asdl_seq* seq, int n, int lineno, int col_offset, PyArena* arena)
{
stmt_ty pass;
- asdl_seq* new;
pass = Pass(lineno, col_offset, arena);
if (pass == NULL)
return NULL;
- new = asdl_seq_new(1, arena);
- if (new == NULL)
- return NULL;
- asdl_seq_SET(new, 0, pass);
-
- return _asdl_seq_replace(seq, n, new, arena);
+ asdl_seq_SET(seq, n, pass);
+
+ return seq;
}
/**
@@ -203,14 +139,17 @@
int n;
asdl_seq* seq = *seq_ptr;
for (n = 0; n < asdl_seq_LEN(seq); n++) {
- stmt_ty stmt = asdl_seq_GET(seq, n);
+ stmt_ty stmt;
if (!optimize_stmt((stmt_ty*)&asdl_seq_GET(seq, n), arena))
return 0;
+ stmt = asdl_seq_GET(seq, n);
+
if (stmt->kind == If_kind) {
+ PyObject* test = _expr_constant_value(stmt->v.If.test);
/* eliminate branches that can never be reached */
- if (_expr_is_constant(stmt->v.If.test)) {
- if (_expr_is_true(stmt->v.If.test))
+ if (test != NULL) {
+ if (PyObject_IsTrue(test))
seq = _asdl_seq_replace(seq, n, stmt->v.If.body, arena);
else {
if (stmt->v.If.orelse == NULL) {
@@ -228,7 +167,7 @@
*seq_ptr = seq;
}
}
- else if (stmt->kind == Return_kind) {
+ else if (stmt->kind == Return_kind && n < (asdl_seq_LEN(seq) - 1)) {
/* eliminate all nodes after a return */
seq = _asdl_seq_replace_with_pass(seq, n + 1,
stmt->lineno, stmt->col_offset, arena);
@@ -458,14 +397,13 @@
return 1;
}
- expr = _expr_from_object(res, expr->lineno, expr->col_offset, arena);
- if (expr == NULL) {
+ if (!_annotate_constant(expr, res, arena)) {
Py_DECREF(res);
return 0;
}
- *expr_ptr = expr;
- Py_DECREF(res);
+ /* XXX: is this necessary? */
+ /* Py_DECREF(res); */
}
return 1;
@@ -474,20 +412,14 @@
static int
optimize_unary_op(expr_ty* expr_ptr, PyArena* arena)
{
+ PyObject* operand;
expr_ty expr = *expr_ptr;
if (!optimize_expr(&expr->v.UnaryOp.operand, arena))
return 0;
- if (_expr_is_constant(expr->v.UnaryOp.operand)) {
- PyObject* operand;
- PyObject* res;
- operand = _expr_constant_value(expr->v.UnaryOp.operand);
- if (operand == NULL) {
- /* XXX this should never happen ... */
- PyErr_Format(PyExc_ValueError, "unknown constant type: %d",
- expr->v.UnaryOp.operand->kind);
- return 0;
- }
+ operand = _expr_constant_value(expr->v.UnaryOp.operand);
+ if (operand != NULL) {
+ PyObject* res;
switch (expr->v.UnaryOp.op) {
case Invert:
@@ -533,14 +465,13 @@
return 1;
}
- expr = _expr_from_object(res, expr->lineno, expr->col_offset, arena);
- if (!expr) {
+ if (!_annotate_constant(expr, res, arena)) {
Py_DECREF(res);
return 0;
}
- *expr_ptr = expr;
- Py_DECREF(res);
+ /* XXX: is this necessary? */
+ /* Py_DECREF(res); */
}
return 1;
}
@@ -747,6 +678,50 @@
return 1;
}
+static PyObject*
+_make_constant_tuple(asdl_seq* values, PyArena* arena)
+{
+ expr_ty expr;
+ int i;
+ PyObject* tuple;
+
+ tuple = PyTuple_New(asdl_seq_LEN(values));
+ if (tuple == NULL)
+ return NULL;
+
+ if (PyArena_AddPyObject(arena, tuple) == -1) {
+ Py_DECREF(tuple);
+ return NULL;
+ }
+
+ /* don't *think* we need to add the constant values to the arena */
+ for (i = 0; i < asdl_seq_LEN(values); i++) {
+ PyObject* value;
+ expr = (expr_ty)asdl_seq_GET(values, i);
+ value = _expr_constant_value(expr);
+ Py_INCREF(value);
+ if (PyTuple_SetItem(tuple, i, value) == -1)
+ return NULL;
+ }
+
+ return tuple;
+}
+
+static int
+_is_constant_seq(asdl_seq* values)
+{
+ expr_ty expr;
+ int i;
+
+ for (i = 0; i < asdl_seq_LEN(values); i++) {
+ expr = (expr_ty)asdl_seq_GET(values, i);
+ if (_expr_constant_value(expr) == NULL)
+ return 0;
+ }
+
+ return 1;
+}
+
static int
optimize_expr(expr_ty* expr_ptr, PyArena* arena)
{
@@ -810,21 +785,56 @@
}
case List_kind:
{
+ /* TODO: optimize lists used in "in"/"not in" as per original
+ * peephole optimization code */
return optimize_expr_seq(&expr->v.List.elts, arena);
}
case Tuple_kind:
{
- return optimize_expr_seq(&expr->v.Tuple.elts, arena);
+ if (!optimize_expr_seq(&expr->v.Tuple.elts, arena))
+ return 0;
+
+ if (_is_constant_seq(expr->v.Tuple.elts)) {
+ PyObject* value = _make_constant_tuple(expr->v.Tuple.elts,
+ arena);
+ if (value == NULL)
+ return 0;
+ if (!_annotate_constant(expr, value, arena))
+ return 0;
+ }
+
+ return 1;
}
case Num_kind:
case Str_kind:
+ {
+ return 1;
+ }
case Name_kind:
{
+ PyObject* v;
+ const char* id;
+
+ id = PyString_AS_STRING(expr->v.Name.id);
+ v = NULL;
+
+ if (strcmp(id, "None") == 0)
+ v = Py_None;
+ else if (strcmp(id, "True") == 0)
+ v = Py_True;
+ else if (strcmp(id, "False") == 0)
+ v = Py_False;
+
+ if (v != NULL) {
+ if (!_annotate_constant(expr, v, arena))
+ return 0;
+ }
+
return 1;
}
default:
PyErr_Format(PyExc_ValueError, "unknown expr_ty kind: %d",
- expr->kind);
+ expr->kind);
return 0;
}
}
@@ -925,6 +935,16 @@
return 0;
if (!optimize_expr(&stmt->v.For.iter, arena))
return 0;
+ if (stmt->v.For.iter->kind == List_kind) {
+ if (_is_constant_seq(stmt->v.For.iter->v.List.elts)) {
+ PyObject* constant = _make_constant_tuple(
+ stmt->v.For.iter->v.List.elts, arena);
+ if (constant == NULL)
+ return 0;
+ if (!_annotate_constant(stmt->v.For.iter, constant, arena))
+ return 0;
+ }
+ }
if (!optimize_stmt_seq(&stmt->v.For.body, arena))
return 0;
if (!optimize_stmt_seq(&stmt->v.For.orelse, arena))
@@ -1204,6 +1224,8 @@
int
PyAST_Optimize(mod_ty* mod_ptr, PyArena* arena)
{
- return optimize_mod(mod_ptr, arena);
+ int res;
+ res = optimize_mod(mod_ptr, arena);
+ return res;
}
Modified: python/branches/tlee-ast-optimize/Python/peephole.c
==============================================================================
--- python/branches/tlee-ast-optimize/Python/peephole.c (original)
+++ python/branches/tlee-ast-optimize/Python/peephole.c Sun May 4 18:57:45 2008
@@ -201,34 +201,11 @@
codestr[i+3] = NOP;
break;
- /* Replace LOAD_GLOBAL/LOAD_NAME None
- with LOAD_CONST None */
- case LOAD_NAME:
- case LOAD_GLOBAL:
- j = GETARG(codestr, i);
- name = PyString_AsString(PyTuple_GET_ITEM(names, j));
- if (name == NULL || strcmp(name, "None") != 0)
- continue;
- for (j=0 ; j < PyList_GET_SIZE(consts) ; j++) {
- if (PyList_GET_ITEM(consts, j) == Py_None)
- break;
- }
- if (j == PyList_GET_SIZE(consts)) {
- if (PyList_Append(consts, Py_None) == -1)
- goto exitUnchanged;
- }
- assert(PyList_GET_ITEM(consts, j) == Py_None);
- codestr[i] = LOAD_CONST;
- SETARG(codestr, i, j);
- cumlc = lastlc + 1;
- break;
-
/* Try to fold tuples of constants (includes a case for lists
which are only used for "in" and "not in" tests).
Skip over BUILD_SEQN 1 UNPACK_SEQN 1.
Replace BUILD_SEQN 2 UNPACK_SEQN 2 with ROT2.
Replace BUILD_SEQN 3 UNPACK_SEQN 3 with ROT3 ROT2. */
- case BUILD_TUPLE:
case BUILD_LIST:
j = GETARG(codestr, i);
h = i - 3 * j;
More information about the Python-checkins
mailing list