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

arigo at codespeak.net arigo at codespeak.net
Wed Jul 25 12:12:18 CEST 2007


Author: arigo
Date: Wed Jul 25 12:12:17 2007
New Revision: 45317

Modified:
   pypy/dist/pypy/rpython/lltypesystem/ll2ctypes.py
   pypy/dist/pypy/rpython/lltypesystem/test/test_ll2ctypes.py
Log:
ll2ctypes support for inlined substructures.


Modified: pypy/dist/pypy/rpython/lltypesystem/ll2ctypes.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/ll2ctypes.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/ll2ctypes.py	Wed Jul 25 12:12:17 2007
@@ -150,20 +150,40 @@
         return cls
 
 
-def convert_struct(container):
+def convert_struct(container, cstruct=None):
     STRUCT = container._TYPE
-    cls = get_ctypes_type(STRUCT)
-    cstruct = cls._malloc()
+    if cstruct is None:
+        # if 'container' is an inlined substructure, convert the whole
+        # bigger structure at once
+        parent, parentindex = lltype.parentlink(container)
+        if parent is not None:
+            convert_struct(parent)
+            return
+        # regular case: allocate a new ctypes Structure of the proper type
+        cls = get_ctypes_type(STRUCT)
+        cstruct = cls._malloc()
     add_storage(container, _struct_mixin, cstruct)
     for field_name in STRUCT._names:
+        FIELDTYPE = getattr(STRUCT, field_name)
         field_value = getattr(container, field_name)
-        setattr(cstruct, field_name, lltype2ctypes(field_value))
+        if not isinstance(FIELDTYPE, lltype.ContainerType):
+            # regular field
+            setattr(cstruct, field_name, lltype2ctypes(field_value))
+        else:
+            # inlined substructure/subarray
+            if isinstance(FIELDTYPE, lltype.Struct):
+                csubstruct = getattr(cstruct, field_name)
+                convert_struct(field_value, csubstruct)
+            else:
+                raise NotImplementedError('inlined field', FIELDTYPE)
     remove_regular_struct_content(container)
 
 def remove_regular_struct_content(container):
     STRUCT = container._TYPE
     for field_name in STRUCT._names:
-        delattr(container, field_name)
+        FIELDTYPE = getattr(STRUCT, field_name)
+        if not isinstance(FIELDTYPE, lltype.ContainerType):
+            delattr(container, field_name)
 
 def convert_array(container):
     ARRAY = container._TYPE

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	Wed Jul 25 12:12:17 2007
@@ -371,4 +371,36 @@
         checkval(sc.contents.y, 'l')
 
     def test_substructures(self):
-        py.test.skip("XXX test and implement substructures")
+        S1  = lltype.Struct('S1', ('x', lltype.Signed))
+        BIG = lltype.Struct('BIG', ('s1a', S1), ('s1b', S1))
+        s = lltype.malloc(BIG, flavor='raw')
+        s.s1a.x = 123
+        s.s1b.x = 456
+        sc = lltype2ctypes(s)
+        assert sc.contents.s1a.x == 123
+        assert sc.contents.s1b.x == 456
+        sc.contents.s1a.x += 1
+        sc.contents.s1b.x += 10
+        assert s.s1a.x == 124
+        assert s.s1b.x == 466
+        s.s1a.x += 3
+        s.s1b.x += 30
+        assert sc.contents.s1a.x == 127
+        assert sc.contents.s1b.x == 496
+        lltype.free(s, flavor='raw')
+
+        s = lltype.malloc(BIG, flavor='raw')
+        s1ac = lltype2ctypes(s.s1a)
+        s1ac.contents.x = 53
+        sc = lltype2ctypes(s)
+        assert sc.contents.s1a.x == 53
+        sc.contents.s1a.x += 1
+        assert s1ac.contents.x == 54
+        assert s.s1a.x == 54
+        s.s1a.x += 2
+        assert s1ac.contents.x == 56
+        assert sc.contents.s1a.x == 56
+        sc.contents.s1a.x += 3
+        assert s1ac.contents.x == 59
+        assert s.s1a.x == 59
+        lltype.free(s, flavor='raw')



More information about the Pypy-commit mailing list