[pypy-svn] r46827 - in pypy/dist/pypy/rpython/lltypesystem: . test

arigo at codespeak.net arigo at codespeak.net
Sat Sep 22 17:53:14 CEST 2007


Author: arigo
Date: Sat Sep 22 17:53:14 2007
New Revision: 46827

Modified:
   pypy/dist/pypy/rpython/lltypesystem/ll2ctypes.py
   pypy/dist/pypy/rpython/lltypesystem/test/test_ll2ctypes.py
Log:
ll2ctypes support for arrays of structures.


Modified: pypy/dist/pypy/rpython/lltypesystem/ll2ctypes.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/ll2ctypes.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/ll2ctypes.py	Sat Sep 22 17:53:14 2007
@@ -118,7 +118,10 @@
             else:
                 items = self._indexable(index)
             cobj = items[index]
-            return ctypes2lltype(ITEM, cobj)
+            if isinstance(ITEM, lltype.ContainerType):
+                return ctypes2lltype(lltype.Ptr(ITEM), ctypes.pointer(cobj))
+            else:
+                return ctypes2lltype(ITEM, cobj)
 
         def _setitem(self, index, value, boundscheck=True):
             if boundscheck:
@@ -220,10 +223,16 @@
     cls = get_ctypes_type(ARRAY)
     carray = cls._malloc(container.getlength())
     add_storage(container, _array_mixin, carray)
-    for i in range(container.getlength()):
-        item_value = container.items[i]    # fish fish
-        carray.items[i] = lltype2ctypes(item_value)
-    remove_regular_array_content(container)
+    if not isinstance(ARRAY.OF, lltype.ContainerType):
+        for i in range(container.getlength()):
+            item_value = container.items[i]    # fish fish
+            carray.items[i] = lltype2ctypes(item_value)
+        remove_regular_array_content(container)
+    else:
+        assert isinstance(ARRAY.OF, lltype.Struct)
+        for i in range(container.getlength()):
+            item_ptr = container.items[i]    # fish fish
+            convert_struct(item_ptr, carray.items[i])
 
 def remove_regular_array_content(container):
     for i in range(container.getlength()):

Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_ll2ctypes.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/test/test_ll2ctypes.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/test/test_ll2ctypes.py	Sat Sep 22 17:53:14 2007
@@ -517,6 +517,31 @@
         lltype.free(a2, flavor='raw')
         lltype.free(s2, flavor='raw')
 
+    def test_arrayofstruct(self):
+        S1 = lltype.Struct('S1', ('x', lltype.Signed))
+        A = lltype.Array(S1, hints={'nolength': True})
+        a = lltype.malloc(A, 5, flavor='raw')
+        a[0].x = 100
+        a[1].x = 101
+        a[2].x = 102
+        a[3].x = 103
+        a[4].x = 104
+        ac = lltype2ctypes(a, normalize=False)
+        assert ac.contents.items[0].x == 100
+        assert ac.contents.items[2].x == 102
+        ac.contents.items[3].x += 500
+        assert a[3].x == 603
+        a[4].x += 600
+        assert ac.contents.items[4].x == 704
+        a1 = ctypes2lltype(lltype.Ptr(A), ac)
+        assert a1 == a
+        assert a1[2].x == 102
+        aitem1 = ctypes2lltype(lltype.Ptr(S1),
+                               ctypes.pointer(ac.contents.items[1]))
+        assert aitem1.x == 101
+        assert aitem1 == a1[1]
+        lltype.free(a, flavor='raw')
+
     def test_get_errno(self):
         if sys.platform.startswith('win'):
             underscore_on_windows = '_'



More information about the Pypy-commit mailing list