[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