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

arigo at codespeak.net arigo at codespeak.net
Tue Sep 21 22:06:08 CEST 2004


Author: arigo
Date: Tue Sep 21 22:06:07 2004
New Revision: 6634

Modified:
   pypy/trunk/src/pypy/translator/genc.h
   pypy/trunk/src/pypy/translator/genc.py
   pypy/trunk/src/pypy/translator/genc_op.py
   pypy/trunk/src/pypy/translator/genc_typeset.py
Log:
Array concatenation (+=) done but probably wrong.  We need to concatenate
arrays of different types, e.g. in 'lst += [5]' the '[5]' is an array of
constants, whereas 'lst' typically is not.

One remaining test fails because it returns an array and there is no provision 
for converting it to a PyObject* (i.e. to a regular PyListObject*).



Modified: pypy/trunk/src/pypy/translator/genc.h
==============================================================================
--- pypy/trunk/src/pypy/translator/genc.h	(original)
+++ pypy/trunk/src/pypy/translator/genc.h	Tue Sep 21 22:06:07 2004
@@ -154,6 +154,8 @@
 					  OP_SETARRAYITEM(name,a,i,f,v)     \
 					  Py_INCREF(v); Py_DECREF(tmp);     \
 					}
+#define OP_ARRAYLEN(name,a,r)          r=((PyList_##name*) a)->ob_size;
+#define OP_CONCATARRAY(name,a1,a2,err) if (concatlist_##name(a1,a2)) goto err;
 
 /************************************************************/
  /***  The rest is produced by genc.py                     ***/

Modified: pypy/trunk/src/pypy/translator/genc.py
==============================================================================
--- pypy/trunk/src/pypy/translator/genc.py	(original)
+++ pypy/trunk/src/pypy/translator/genc.py	Tue Sep 21 22:06:07 2004
@@ -348,8 +348,16 @@
         print >> f, self.C_LIST_DEALLOC_FOOTER % info
 
         print >> f, self.C_LIST_TYPEOBJECT % info
-        return name
 
+        print >> f, self.C_LIST_CONCAT_HEADER % info
+        for j in range(len(lltypes)):
+            print >> f, '\t\tdest->a%d = src->a%d;' % (j, j),
+            if lltypes[j] == 'PyObject*':
+                print >> f, 'Py_INCREF(dest->a%d);' % j,
+            print >> f
+        print >> f, self.C_LIST_CONCAT_FOOTER % info
+
+        return name
 
 # ____________________________________________________________
 
@@ -543,4 +551,32 @@
 }
 '''
 
+    C_LIST_CONCAT_HEADER = (
+'''static int concatlist_%(name)s(PyObject* a1, PyObject* a2)
+{
+	PyList_%(name)s* o1 = (PyList_%(name)s*) a1;
+	PyList_%(name)s* o2 = (PyList_%(name)s*) a2;
+	int l1 = o1->ob_size;
+	int l2 = o2->ob_size;
+	ListItem_%(name)s* src;
+	ListItem_%(name)s* dest;
+	void* buffer = PyMem_Realloc(o1->ob_item,
+				     (l1+l2)*sizeof(ListItem_%(name)s));
+	if (buffer == NULL) {
+		PyErr_NoMemory();
+		return -1;
+	}
+	o1->ob_item = (ListItem_%(name)s*) buffer;
+	src = o2->ob_item;
+	dest = o1->ob_item + l1;
+	while (--l2 >= 0) {''')
+
+    C_LIST_CONCAT_FOOTER = (
+'''		src++;
+		dest++;
+	}
+	return 0;
+}
+''')
+
 # ____________________________________________________________

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	Tue Sep 21 22:06:07 2004
@@ -230,6 +230,21 @@
     macro = 'OP_SETARRAYITEM'
     # self.args: [PyObject, int_index, input_item..]
 
+class LoConcatArray(LoC):
+    can_fail = True
+    typename = PARAMETER   # the name of the PyList_Xxx type in the C source
+    lltypes  = PARAMETER   # the C types needed to represent each array item
+    # self.args: [PyObject, PyObject, output-PyObject]
+    def writestr(self, array1, array2, output_array, err):
+        return 'OP_CONCATARRAY(%s, %s, %s, %s)' % (
+            self.typename, array1, array2, err)
+    def optimize(self, typer, llresult):
+        # the result of the concatenation is the same array as the first
+        # input argument.
+        array1 = self.args[0]
+        llresult[-1] = array1  # patch to do the copy statically
+        return False  # proceed with the normal writestr()
+
 class LoGetAttr(LoC):
     cost = 1
     fld  = PARAMETER

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	Tue Sep 21 22:06:07 2004
@@ -379,6 +379,18 @@
                 lltypes  = r.r_item.impl,
                 )
 
+    def extend_OP_INPLACE_ADD(self, hltypes):
+        if len(hltypes) != 3:
+            return
+        r1, r2, r_result = hltypes
+        # concatenating CLists of the same type
+        if isinstance(r1, CList) and r1 == r2:
+            sig = (r1, r1, r1)
+            yield sig, genc_op.LoConcatArray.With(
+                typename = r1.typename,
+                lltypes  = r1.r_item.impl,
+                )
+
     # ____________________________________________________________
 
     def parse_operation_templates(self):



More information about the Pypy-commit mailing list