[pypy-svn] r6880 - in pypy/trunk/src/pypy/translator: . test
arigo at codespeak.net
arigo at codespeak.net
Sun Oct 10 11:15:45 CEST 2004
Author: arigo
Date: Sun Oct 10 11:15:44 2004
New Revision: 6880
Modified:
pypy/trunk/src/pypy/translator/genc.h
pypy/trunk/src/pypy/translator/genc.py
pypy/trunk/src/pypy/translator/test/test_ctrans.py
Log:
Enabled all tests again (without type annotations), and made them pass:
* added most numeric operations to genc.h
* support for classes, implemented as regular Python heap types,
with instances storing attributes as usual in their __dict__
* tuple constants
The short genc.{py,h} together with the flow objspace now implement most of
the equivalent of the old Python2C: translating Python bytecode to C code
calling the abstract.h functions, without any type-based optimizations.
Modified: pypy/trunk/src/pypy/translator/genc.h
==============================================================================
--- pypy/trunk/src/pypy/translator/genc.h (original)
+++ pypy/trunk/src/pypy/translator/genc.h Sun Oct 10 11:15:44 2004
@@ -22,12 +22,50 @@
} \
Py_INCREF(r);
+#define OP_NEG(x,r,err) if (!(r=PyNumber_Negative(x))) goto err;
+#define OP_POS(x,r,err) if (!(r=PyNumber_Positive(x))) goto err;
+#define OP_INVERT(x,r,err) if (!(r=PyNumber_Invert(x))) goto err;
+
#define OP_ADD(x,y,r,err) if (!(r=PyNumber_Add(x,y))) goto err;
#define OP_SUB(x,y,r,err) if (!(r=PyNumber_Subtract(x,y))) goto err;
#define OP_MUL(x,y,r,err) if (!(r=PyNumber_Multiply(x,y))) goto err;
+#define OP_TRUEDIV(x,y,r,err) if (!(r=PyNumber_TrueDivide(x,y))) goto err;
+#define OP_FLOORDIV(x,y,r,err) if (!(r=PyNumber_FloorDivide(x,y)))goto err;
#define OP_DIV(x,y,r,err) if (!(r=PyNumber_Divide(x,y))) goto err;
#define OP_MOD(x,y,r,err) if (!(r=PyNumber_Remainder(x,y))) goto err;
-#define OP_INPLACE_ADD(x,y,r,err) if(!(r=PyNumber_InPlaceAdd(x,y))) goto err;
+#define OP_POW(x,y,r,err) if (!(r=PyNumber_Power(x,y,Py_None)))goto err;
+#define OP_LSHIFT(x,y,r,err) if (!(r=PyNumber_Lshift(x,y))) goto err;
+#define OP_RSHIFT(x,y,r,err) if (!(r=PyNumber_Rshift(x,y))) goto err;
+#define OP_AND_(x,y,r,err) if (!(r=PyNumber_And(x,y))) goto err;
+#define OP_OR_(x,y,r,err) if (!(r=PyNumber_Or(x,y))) goto err;
+#define OP_XOR(x,y,r,err) if (!(r=PyNumber_Xor(x,y))) goto err;
+
+#define OP_INPLACE_ADD(x,y,r,err) if (!(r=PyNumber_InPlaceAdd(x,y))) \
+ goto err;
+#define OP_INPLACE_SUB(x,y,r,err) if (!(r=PyNumber_InPlaceSubtract(x,y))) \
+ goto err;
+#define OP_INPLACE_MUL(x,y,r,err) if (!(r=PyNumber_InPlaceMultiply(x,y))) \
+ goto err;
+#define OP_INPLACE_TRUEDIV(x,y,r,err) if (!(r=PyNumber_InPlaceTrueDivide(x,y)))\
+ goto err;
+#define OP_INPLACE_FLOORDIV(x,y,r,err)if(!(r=PyNumber_InPlaceFloorDivide(x,y)))\
+ goto err;
+#define OP_INPLACE_DIV(x,y,r,err) if (!(r=PyNumber_InPlaceDivide(x,y))) \
+ goto err;
+#define OP_INPLACE_MOD(x,y,r,err) if (!(r=PyNumber_InPlaceRemainder(x,y))) \
+ goto err;
+#define OP_INPLACE_POW(x,y,r,err) if (!(r=PyNumber_InPlacePower(x,y,Py_None))) \
+ goto err;
+#define OP_INPLACE_LSHIFT(x,y,r,err) if (!(r=PyNumber_InPlaceLshift(x,y))) \
+ goto err;
+#define OP_INPLACE_RSHIFT(x,y,r,err) if (!(r=PyNumber_InPlaceRshift(x,y))) \
+ goto err;
+#define OP_INPLACE_AND(x,y,r,err) if (!(r=PyNumber_InPlaceAnd(x,y))) \
+ goto err;
+#define OP_INPLACE_OR(x,y,r,err) if (!(r=PyNumber_InPlaceOr(x,y))) \
+ goto err;
+#define OP_INPLACE_XOR(x,y,r,err) if (!(r=PyNumber_InPlaceXor(x,y))) \
+ goto err;
#define OP_GETITEM(x,y,r,err) if (!(r=PyObject_GetItem(x,y))) goto err;
#define OP_SETITEM(x,y,z,r,err) if ((PyObject_SetItem(x,y,z))<0) goto err; \
@@ -57,6 +95,69 @@
#define MOVE(x, y) y = x;
+#define INITCHK(expr) if (!(expr)) return;
+
+
+/*** classes ***/
+
+#define SETUP_CLASS(t, name, base) \
+ t = PyObject_CallFunction((PyObject*) &PyType_Type, \
+ "s(O){}", name, base)
+
+#define SETUP_CLASS_ATTR(t, attr, value) \
+ (PyObject_SetAttrString(t, attr, value) >= 0)
+
+/* we need a subclass of 'builtin_function_or_method' which can be used
+ as methods: builtin function objects that can be bound on instances */
+static PyObject *
+gencfunc_descr_get(PyObject *func, PyObject *obj, PyObject *type)
+{
+ if (obj == Py_None)
+ obj = NULL;
+ return PyMethod_New(func, obj, type);
+}
+static PyTypeObject PyGenCFunction_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0,
+ "pypy_generated_function",
+ sizeof(PyCFunctionObject),
+ 0,
+ 0, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ /*&PyCFunction_Type set below*/ 0, /* tp_base */
+ 0, /* tp_dict */
+ gencfunc_descr_get, /* tp_descr_get */
+ 0, /* tp_descr_set */
+};
+
+#define SETUP_MODULE \
+ PyGenCFunction_Type.tp_base = &PyCFunction_Type; \
+ PyType_Ready(&PyGenCFunction_Type);
+
/*** operations with a variable number of arguments ***/
Modified: pypy/trunk/src/pypy/translator/genc.py
==============================================================================
--- pypy/trunk/src/pypy/translator/genc.py (original)
+++ pypy/trunk/src/pypy/translator/genc.py Sun Oct 10 11:15:44 2004
@@ -69,7 +69,8 @@
else:
name = 'gint_minus%d' % abs(value)
self.globaldecl.append('static PyObject* %s;' % name)
- self.initcode.append('%s = PyInt_FromLong(%d);' % (name, value))
+ self.initcode.append('INITCHK(%s = '
+ 'PyInt_FromLong(%d))' % (name, value))
return name
def nameof_str(self, value):
@@ -87,15 +88,16 @@
else:
# printable string
s = '"%s"' % value
- self.initcode.append('%s = PyString_FromStringAndSize(%s, %d);' % (
- name, s, len(value)))
+ self.initcode.append('INITCHK(%s = PyString_FromStringAndSize('
+ '%s, %d))' % (name, s, len(value)))
return name
def nameof_function(self, func):
name = self.uniquename('gfunc_' + func.__name__)
self.globaldecl.append('static PyObject* %s;' % name)
- self.initcode.append('%s = PyCFunction_New(&ml_%s, NULL);' % (name,
- name))
+ self.initcode.append('INITCHK(%s = PyCFunction_New('
+ '&ml_%s, NULL))' % (name, name))
+ self.initcode.append('\t%s->ob_type = &PyGenCFunction_Type;' % name)
self.pendingfunctions.append(func)
return name
@@ -105,11 +107,50 @@
'%r is not from __builtin__' % (func,))
name = self.uniquename('gbltin_' + func.__name__)
self.globaldecl.append('static PyObject* %s;' % name)
- self.initcode.append('%s = PyMapping_GetItemString('
- 'PyEval_GetBuiltins(), "%s");' % (
+ self.initcode.append('INITCHK(%s = PyMapping_GetItemString('
+ 'PyEval_GetBuiltins(), "%s"))' % (
name, func.__name__))
return name
+ def nameof_classobj(self, cls):
+ name = self.uniquename('gcls_' + cls.__name__)
+ bases = [base for base in cls.__bases__ if base is not object]
+ assert len(bases) <= 1, "%r needs multiple inheritance" % (cls,)
+ if bases:
+ base = self.nameof(bases[0])
+ else:
+ base = '(PyObject*) &PyBaseObject_Type'
+ content = cls.__dict__.items()
+ content.sort()
+ lines = []
+ for key, value in content:
+ if key.startswith('__'):
+ continue
+ lines.append('INITCHK(SETUP_CLASS_ATTR(%s, "%s", %s))' % (
+ name, key, self.nameof(value)))
+ self.globaldecl.append('static PyObject* %s;' % name)
+ self.initcode.append('INITCHK(SETUP_CLASS(%s, "%s", %s))' % (
+ name, cls.__name__, base))
+ self.initcode.extend(lines)
+ return name
+
+ def nameof_type(self, cls):
+ assert hasattr(cls, '__weakref__'), (
+ "%r is not a user-defined class" % (cls,))
+ return self.nameof_classobj(cls)
+
+ def nameof_tuple(self, tup):
+ name = self.uniquename('g%dtuple' % len(tup))
+ lines = []
+ for i in range(len(tup)):
+ item = self.nameof(tup[i])
+ lines.append('\tPy_INCREF(%s);' % item)
+ lines.append('\tPyTuple_SET_ITEM(%s, %d, %s);' % (name, i, item))
+ self.globaldecl.append('static PyObject* %s;' % name)
+ self.initcode.append('INITCHK(%s = PyTuple_New(%d))' % (name, len(tup)))
+ self.initcode.extend(lines)
+ return name
+
def gen_source(self):
f = self.f
info = {
@@ -245,7 +286,7 @@
if len(block.exits) == 0:
yield 'return %s;' % expr(block.inputargs[0])
continue
- if block.exitswitch is not None:
+ if len(block.exits) > 1:
for link in block.exits[:-1]:
yield 'if (EQ_%s(%s)) {' % (link.exitcase,
block.exitswitch.name)
@@ -277,6 +318,7 @@
void init%(modname)s(void)
{
\tPyObject* m = Py_InitModule("%(modname)s", NULL);
+\tSETUP_MODULE
'''
C_INIT_FOOTER = '''
Modified: pypy/trunk/src/pypy/translator/test/test_ctrans.py
==============================================================================
--- pypy/trunk/src/pypy/translator/test/test_ctrans.py (original)
+++ pypy/trunk/src/pypy/translator/test/test_ctrans.py Sun Oct 10 11:15:44 2004
@@ -84,21 +84,20 @@
self.assertEquals(sand(0, 6), "no")
self.assertEquals(sand(0, 0), "no")
-if 0:
- class TypedTestCase(testit.IntTestCase):
+class TypedTestCase(testit.IntTestCase):
def getcompiled(self, func):
t = Translator(func)
t.simplify()
- # builds starting-types from func_defs
- argstypelist = []
- if func.func_defaults:
- for spec in func.func_defaults:
- if isinstance(spec, tuple):
- spec = spec[0] # use the first type only for the tests
- argstypelist.append(spec)
- a = t.annotate(argstypelist)
- a.simplify()
+## # builds starting-types from func_defs
+## argstypelist = []
+## if func.func_defaults:
+## for spec in func.func_defaults:
+## if isinstance(spec, tuple):
+## spec = spec[0] # use the first type only for the tests
+## argstypelist.append(spec)
+## a = t.annotate(argstypelist)
+## a.simplify()
return t.ccompile()
def test_set_attr(self):
@@ -132,10 +131,10 @@
def test_call_five(self):
call_five = self.getcompiled(snippet.call_five)
result = call_five()
- #self.assertEquals(result, [5])
+ self.assertEquals(result, [5])
# -- currently result isn't a real list, but a pseudo-array
# that can't be inspected from Python.
- self.assertEquals(result.__class__.__name__[:8], "list of ")
+ #self.assertEquals(result.__class__.__name__[:8], "list of ")
def test_call_unpack_56(self):
call_unpack_56 = self.getcompiled(snippet.call_unpack_56)
More information about the Pypy-commit
mailing list