[pypy-svn] r6390 - pypy/trunk/src/pypy/translator

arigo at codespeak.net arigo at codespeak.net
Sat Sep 11 12:33:51 CEST 2004


Author: arigo
Date: Sat Sep 11 12:33:50 2004
New Revision: 6390

Modified:
   pypy/trunk/src/pypy/translator/genc.h
   pypy/trunk/src/pypy/translator/genc_op.py
   pypy/trunk/src/pypy/translator/genc_typeset.py
   pypy/trunk/src/pypy/translator/typer.py
Log:
Uniformly generates macro calls in the function bodies.  It simplifies a bit
genc_op.py and more importantly it produces more readable C files.  (suggested
by Holger)


Modified: pypy/trunk/src/pypy/translator/genc.h
==============================================================================
--- pypy/trunk/src/pypy/translator/genc.h	(original)
+++ pypy/trunk/src/pypy/translator/genc.h	Sat Sep 11 12:33:50 2004
@@ -61,9 +61,9 @@
 
 /*** conversions ***/
 
-#define convert_io(x,r,err)   if (!(r=PyInt_FromLong(x))) goto err;
-#define convert_so(c,l,r,err) if (!(r=PyString_FromStringAndSize(c,l)))goto err;
-#define convert_vo(r)         r = Py_None; Py_INCREF(r);
+#define CONVERT_io(x,r,err)   if (!(r=PyInt_FromLong(x))) goto err;
+#define CONVERT_so(c,l,r,err) if (!(r=PyString_FromStringAndSize(c,l)))goto err;
+#define CONVERT_vo(r)         r = Py_None; Py_INCREF(r);
 
 /*#define convert_oi(x,r,err)   if ((r=PyInt_AsLong(x)) == -1             \
  *                                  && PyErr_Occurred()) goto err;
@@ -71,15 +71,15 @@
 
 /*** tests ***/
 
-#define caseFalse_i(n, err)    if (n) goto err;
-#define caseTrue_i(n, err)     if (!n) goto err;
-#define case0_i(n, err)        if (n != 0) goto err;
-#define case1_i(n, err)        if (n != 1) goto err;
-
-#define caseFalse_o(o, err)    if (!(PyInt_Check(o) && !PyInt_AS_LONG(o))) goto err;
-#define caseTrue_o(o, err)     if (!(PyInt_Check(o) && PyInt_AS_LONG(o))) goto err;
-#define case0_o(o, err) if (!(PyInt_Check(o) && PyInt_AS_LONG(o)==0)) goto err;
-#define case1_o(o, err) if (!(PyInt_Check(o) && PyInt_AS_LONG(o)==1)) goto err;
+#define CASE_False_i(n, err)    if (n) goto err;
+#define CASE_True_i(n, err)     if (!n) goto err;
+#define CASE_0_i(n, err)        if (n != 0) goto err;
+#define CASE_1_i(n, err)        if (n != 1) goto err;
+
+#define CASE_False_o(o, err)    if (!(PyInt_Check(o) && !PyInt_AS_LONG(o))) goto err;
+#define CASE_True_o(o, err)     if (!(PyInt_Check(o) && PyInt_AS_LONG(o))) goto err;
+#define CASE_0_o(o, err) if (!(PyInt_Check(o) && PyInt_AS_LONG(o)==0)) goto err;
+#define CASE_1_o(o, err) if (!(PyInt_Check(o) && PyInt_AS_LONG(o)==1)) goto err;
 
 
 /*** misc ***/
@@ -95,25 +95,51 @@
 		}                                       \
 	}
 
-#define INSTANTIATE(cls, r, err)    if (!(r=cls##_new())) goto err;
+/* a few built-in functions */
+
+#define CALL_len_oi(o,r,err)  if ((r=PyObject_Size(o))<0) goto err;
+#define CALL_pow_iii(x,y,r)   { int i=y; r=1; while (--i>=0) r*=x; } /*slow*/
+
+
+/*** macros used directly by genc_op.py ***/
+
+#define OP_NEWLIST(len, r, err)        if (!(r=PyList_New(len))) goto err;
+#define OP_NEWLIST_SET(r, i, o)        PyList_SET_ITEM(r, i, o); Py_INCREF(o);
+#define OP_NEWTUPLE(len, r, err)       if (!(r=PyTuple_New(len))) goto err;
+#define OP_NEWTUPLE_SET(r, i, o)       PyTuple_SET_ITEM(r, i, o); Py_INCREF(o);
+
+#define OP_CALL_PYOBJ(args, r, err)    if (!(r=PyObject_CallFunction args)) \
+						goto err;
+
+#define OP_INSTANTIATE(cls, r, err)    if (!(r=cls##_new())) goto err;
 #define ALLOC_INSTANCE(cls, r, err)                             \
 		if (!(r=PyType_GenericAlloc(&cls##_Type.type, 0))) goto err;
 #define SETUP_TYPE(cls)                         \
 		PyType_Ready(&cls##_Type.type); \
 		cls##_typenew();
 
-#define GET_ATTR_py(fld, r)   r=fld; Py_INCREF(r);
-#define SET_ATTR_py(fld, v)   { PyObject* o=fld; fld=v;         \
-                                Py_INCREF(v); Py_XDECREF(o); }
-
-#define GET_ATTR_cls(fld, r)  r=fld; Py_INCREF(r);
-#define SET_ATTR_cls(fld, v)  fld=v; Py_INCREF(v);  /* initialization only */
-
-/* a few built-in functions */
-
-#define CALL_len_oi(o,r,err)  if ((r=PyObject_Size(o))<0) goto err;
-#define CALL_pow_iii(x,y,r)   { int i=y; r=1; while (--i>=0) r*=x; } /*slow*/
-
+#define OP_GETINSTATTR(cls, o, f, r)    r=((cls##_Object*) o)->f;
+#define OP_GETINSTATTR_o(cls, o, f, r)  r=((cls##_Object*) o)->f; Py_INCREF(r);
+#define OP_GETCLASSATTR(cls, o, f, r)   r=((cls##_TypeObject*)(o->ob_type))->f;
+#define OP_GETCLASSATTR_o(cls, o, f, r) r=((cls##_TypeObject*)(o->ob_type))->f;\
+								  Py_INCREF(r);
+#define OP_SETINSTATTR(cls, o, f, v)    ((cls##_Object*) o)->f=v;
+#define OP_SETINSTATTR_o(cls, o, f, v)  { PyObject* tmp;                    \
+					  OP_GETINSTATTR(cls, o, f, tmp)    \
+					  OP_SETINSTATTR(cls, o, f, v)      \
+					  Py_INCREF(v); Py_XDECREF(tmp);    \
+					}
+#define OP_INITCLASSATTR(cls, f, v)     cls##_Type.f=v;
+#define OP_INITCLASSATTR_o(cls, f, v)   cls##_Type.f=v; Py_INCREF(v);
+
+#define OP_DUMMYREF(r)                  r = Py_None; Py_INCREF(r);
+
+#define MOVE(x, y)                      y = x;
+
+#define OP_CCALL_v(fn, args, err)       if (fn args < 0) goto err;
+#define OP_CCALL(fn, args, r, err)      if ((r=fn args) == NULL) goto err;
+#define OP_CCALL_i(fn, args, r, err)    if ((r=fn args) == -1 &&            \
+                                            PyErr_Occurred()) goto err;
 
 /************************************************************/
  /***  The rest is produced by genc.py                     ***/

Modified: pypy/trunk/src/pypy/translator/genc_op.py
==============================================================================
--- pypy/trunk/src/pypy/translator/genc_op.py	(original)
+++ pypy/trunk/src/pypy/translator/genc_op.py	Sat Sep 11 12:33:50 2004
@@ -81,21 +81,6 @@
     def optimized_result(self, typer):
         return self.known_answer
 
-class LoNewList(LoC):
-    can_fail = True
-    cost     = 3
-    # self.args: [input PyObjects.., output PyObject]
-    def writestr(self, *stuff):
-        content = stuff[:-2]
-        result = stuff[-2]
-        err = stuff[-1]
-        ls = ['if (!(%s = PyList_New(%d))) goto %s;' % (
-            result, len(content), err)]
-        for i in range(len(content)):
-            ls.append('PyList_SET_ITEM(%s, %d, %s); Py_INCREF(%s);' % (
-                result, i, content[i], content[i]))
-        return '\n'.join(ls)
-
 class LoCallFunction(LoC):
     can_fail = True
     cost     = 3
@@ -106,24 +91,21 @@
         err = stuff[-1]
         format = '"' + 'O' * len(args) + '"'
         args = (func, format) + args
-        return ('if (!(%s = PyObject_CallFunction(%s)))'
-                ' goto %s;' % (result, ', '.join(args), err))
+        return ('OP_CALL_PYOBJ((%s), %s, %s)' % (', '.join(args), result, err))
 
 class LoInstantiate(LoC):
     can_fail = True
     llclass  = PARAMETER
     # self.args: [output PyObject instance]
     def writestr(self, res, err):
-        return 'INSTANTIATE(%s, %s, %s)' % (
-            self.llclass.name, res, err)
+        return 'OP_INSTANTIATE(%s, %s, %s)' % (self.llclass.name, res, err)
 
 class LoAllocInstance(LoC):
     can_fail = True
     llclass  = PARAMETER
     # self.args: [output PyObject instance]
     def writestr(self, res, err):
-        return 'ALLOC_INSTANCE(%s, %s, %s)' % (
-            self.llclass.name, res, err)
+        return 'ALLOC_INSTANCE(%s, %s, %s)' % (self.llclass.name, res, err)
 
 class LoConvertTupleItem(LoOptimized):
     source_r = PARAMETER   # tuple-of-hltypes, one per item of the input tuple
@@ -159,41 +141,39 @@
 class LoNewTuple(LoC):
     can_fail = True
     cost     = 3
+    macro    = 'OP_NEWTUPLE'
     # self.args: [input PyObjects.., output PyObject]
     def writestr(self, *stuff):
         args   = stuff[:-2]
         result = stuff[-2]
         err    = stuff[-1]
-        ls = ['if (!(%s = PyTuple_New(%d))) goto %s;' %
-              (result, len(args), err)]
-        for i, a in zip(range(len(args)), args):
-            ls.append('PyTuple_SET_ITEM(%s, %d, %s); Py_INCREF(%s);' %
-                      (result, i, a, a))
+        ls = ['%s(%d, %s, %s)' % (self.macro, len(args), result, err)]
+        for i in range(len(args)):
+            ls.append('%s_SET(%s, %d, %s)' % (self.macro, result, i, args[i]))
         return '\n'.join(ls)
 
+class LoNewList(LoNewTuple):
+    macro    = 'OP_NEWLIST'
+    # self.args: [input PyObjects.., output PyObject]
+
 class LoGetAttr(LoC):
     cost = 1
     fld  = PARAMETER
     # self.args: [PyObject instance, result..]
     def writestr(self, inst, *result):
         ls = []
-        llclass = self.fld.llclass
         if self.fld.is_class_attr:
-            for src, dstname in zip(self.fld.llvars, result):
-                fldexpr = '((%s_TypeObject*)(%s->ob_type))->%s' % (
-                    llclass.name, inst, src.name)
-                if src.type == 'PyObject*':
-                    ls.append('GET_ATTR_cls(%s, %s)' % (fldexpr, dstname))
-                else:
-                    ls.append('%s = %s;' % (dstname, fldexpr))
+            macro = 'OP_GETCLASSATTR'
         else:
-            for src, dstname in zip(self.fld.llvars, result):
-                fldexpr = '((%s_Object*) %s)->%s' % (llclass.name, inst,
-                                                     src.name)
-                if src.type == 'PyObject*':
-                    ls.append('GET_ATTR_py(%s, %s)' % (fldexpr, dstname))
-                else:
-                    ls.append('%s = %s;' % (dstname, fldexpr))
+            macro = 'OP_GETINSTATTR'
+        llclass = self.fld.llclass
+        for src, dstname in zip(self.fld.llvars, result):
+            if src.type == 'PyObject*':
+                typecode = '_o'
+            else:
+                typecode = ''
+            ls.append('%s%s(%s, %s, %s, %s)' % (
+                macro, typecode, llclass.name, inst, src.name, dstname))
         return '\n'.join(ls)
 
 class LoGetAttrMethod(LoGetAttr):
@@ -215,12 +195,12 @@
         assert len(value) == len(self.fld.llvars)
         ls = []
         for srcname, dst in zip(value, self.fld.llvars):
-            fldexpr = '((%s_Object*) %s)->%s' % (self.llclass.name, inst,
-                                                 dst.name)
             if dst.type == 'PyObject*':
-                ls.append('SET_ATTR_py(%s, %s)' % (fldexpr, srcname))
+                typecode = '_o'
             else:
-                ls.append('%s = %s;' % (fldexpr, srcname))
+                typecode = ''
+            ls.append('OP_SETINSTATTR%s(%s, %s, %s, %s)' % (
+                typecode, self.llclass.name, inst, dst.name, srcname))
         return '\n'.join(ls)
 
 class LoInitClassAttr(LoC):
@@ -233,11 +213,12 @@
         ls = []
         # setting class attributes is only used for initialization
         for srcname, dst in zip(value, self.fld.llvars):
-            fldexpr = '%s_Type.%s' % (self.llclass.name, dst.name)
             if dst.type == 'PyObject*':
-                ls.append('SET_ATTR_cls(%s, %s)' % (fldexpr, srcname))
+                typecode = '_o'
             else:
-                ls.append('%s = %s;' % (fldexpr, srcname))
+                typecode = ''
+            ls.append('OP_INITCLASSATTR%s(%s, %s, %s)' % (
+                typecode, self.llclass.name, dst.name, srcname))
         return '\n'.join(ls)
 
 class LoConvertBoundMethod(LoOptimized):
@@ -277,8 +258,7 @@
         ls = []
         for a in self.args:
             if a.type == 'PyObject*':
-                ls.append('%s = Py_None; Py_INCREF(%s); /* dummy */' % (
-                    a.name, a.name))
+                ls.append('OP_DUMMYREF(%s)' % a.name)
         return '\n'.join(ls)
 
 # ____________________________________________________________
@@ -287,7 +267,7 @@
     cost = 1
     # self.args: [input LLVar, output LLVar]
     def writestr(self, x, y):
-        return '%s = %s;' % (y, x)
+        return 'MOVE(%s, %s)' % (x, y)
 
 class LoGoto(LoC):
     cost = 0
@@ -335,11 +315,6 @@
     'int':       '-1',
     }
 
-ERROR_CHECK = {
-    None:        '< 0',
-    'int':       '== -1 && PyErr_Occurred()',
-    }
-
 class LoCallPyFunction(LoC):
     can_fail  = True
     hlrettype = PARAMETER
@@ -351,17 +326,19 @@
         args = [a.name for a in self.args[1:R]]
         err = self.errtarget
         if L == 0:  # no return value
-            return 'if (%s(%s) %s) goto %s;' % (
-                funcptr, ', '.join(args), ERROR_CHECK[None], err)
+            return 'OP_CCALL_v(%s, (%s), %s)' % (funcptr, ', '.join(args), err)
         else:
             # the return value is the first return LLVar:
             retvar = self.args[R]
             # if there are several return LLVars, the extra ones are passed
             # in by reference as output arguments
             args += ['&%s' % a.name for a in self.args[R+1:]]
-            return ('if ((%s = %s(%s)) %s) goto %s;' % (
-                retvar.name, funcptr, ', '.join(args),
-                ERROR_CHECK.get(retvar.type, '== NULL'), err))
+            if retvar.type == 'int':
+                typecode = '_i'
+            else:
+                typecode = ''
+            return 'OP_CCALL%s(%s, (%s), %s, %s)' % (
+                typecode, funcptr, ', '.join(args), retvar.name, err)
 
 class LoReturn(LoC):
     cost = 1

Modified: pypy/trunk/src/pypy/translator/genc_typeset.py
==============================================================================
--- pypy/trunk/src/pypy/translator/genc_typeset.py	(original)
+++ pypy/trunk/src/pypy/translator/genc_typeset.py	Sat Sep 11 12:33:50 2004
@@ -39,7 +39,7 @@
         self.bindings = bindings
         self.conversion_cache = {}
         self.conversion_errors = {}
-        self.lloperations = {'convert': self.conversion_cache}
+        self.lloperations = {'CONVERT': self.conversion_cache}
         self.parse_operation_templates()
 
     # __________ methods required by LLFunction __________

Modified: pypy/trunk/src/pypy/translator/typer.py
==============================================================================
--- pypy/trunk/src/pypy/translator/typer.py	(original)
+++ pypy/trunk/src/pypy/translator/typer.py	Sat Sep 11 12:33:50 2004
@@ -59,7 +59,7 @@
 #       ...}
 #       This dict contains the known signatures of each space operation.
 #       Special opnames:
-#         'caseXXX'    v : fails (i.e. jump to errlabel) if v is not XXX
+#         'CASE_XXX'    v : fails (i.e. jump to errlabel) if v is not XXX
 #
 #   rawoperations = {
 #       'opname': subclass-of-LLOp,
@@ -189,12 +189,12 @@
         # exits
         if block.exits:
             for exit in block.exits[:-1]:
-                # generate | caseXXX v elselabel
+                # generate | CASE_XXX v elselabel
                 #          |   copy output vars to next block's input vars
                 #          |   jump to next block
                 #          | elselabel:
                 elselabel = '%s_not%s' % (self.blockname[block], exit.exitcase)
-                self.operation('case%s' % exit.exitcase,
+                self.operation('CASE_%s' % exit.exitcase,
                                [block.exitswitch],
                                errlabel = elselabel)
                 self.goto(exit)



More information about the Pypy-commit mailing list