[pypy-svn] r54067 - in pypy/branch/io-improvements/pypy/rpython/lltypesystem: . test

fijal at codespeak.net fijal at codespeak.net
Wed Apr 23 20:02:12 CEST 2008


Author: fijal
Date: Wed Apr 23 20:02:10 2008
New Revision: 54067

Modified:
   pypy/branch/io-improvements/pypy/rpython/lltypesystem/ll2ctypes.py
   pypy/branch/io-improvements/pypy/rpython/lltypesystem/test/test_ll2ctypes.py
Log:
Shady support for varsized structs. Just enough to get strings running


Modified: pypy/branch/io-improvements/pypy/rpython/lltypesystem/ll2ctypes.py
==============================================================================
--- pypy/branch/io-improvements/pypy/rpython/lltypesystem/ll2ctypes.py	(original)
+++ pypy/branch/io-improvements/pypy/rpython/lltypesystem/ll2ctypes.py	Wed Apr 23 20:02:10 2008
@@ -241,9 +241,12 @@
         carray = cls._malloc(container.getlength())
     add_storage(container, _array_mixin, carray)
     if not isinstance(ARRAY.OF, lltype.ContainerType):
+        # fish that we have enough space
+        ctypes_array = ctypes.cast(carray.items,
+                                   ctypes.POINTER(carray.items._type_))
         for i in range(container.getlength()):
             item_value = container.items[i]    # fish fish
-            carray.items[i] = lltype2ctypes(item_value)
+            ctypes_array[i] = lltype2ctypes(item_value)
         remove_regular_array_content(container)
     else:
         assert isinstance(ARRAY.OF, lltype.Struct)
@@ -262,7 +265,10 @@
     remove_regular_struct_content(container)
     for field_name in STRUCT._names:
         FIELDTYPE = getattr(STRUCT, field_name)
-        if isinstance(FIELDTYPE, lltype.ContainerType):
+        if isinstance(FIELDTYPE, lltype.Array):
+            convert_array(getattr(container, field_name),
+                          getattr(ctypes_storage, field_name))
+        elif isinstance(FIELDTYPE, lltype.ContainerType):
             struct_use_ctypes_storage(getattr(container, field_name),
                                       getattr(ctypes_storage, field_name))
 
@@ -498,8 +504,10 @@
             return lltype.nullptr(T.TO)
         if isinstance(T.TO, lltype.Struct):
             if T.TO._arrayfld is not None:
-                raise NotImplementedError("XXX var-sized structs")
-            container = lltype._struct(T.TO)
+                lgt = getattr(cobj.contents, T.TO._arrayfld).length
+                container = lltype._struct(T.TO, lgt)
+            else:
+                container = lltype._struct(T.TO)
             struct_use_ctypes_storage(container, cobj.contents)
         elif isinstance(T.TO, lltype.Array):
             if T.TO._hints.get('nolength', False):

Modified: pypy/branch/io-improvements/pypy/rpython/lltypesystem/test/test_ll2ctypes.py
==============================================================================
--- pypy/branch/io-improvements/pypy/rpython/lltypesystem/test/test_ll2ctypes.py	(original)
+++ pypy/branch/io-improvements/pypy/rpython/lltypesystem/test/test_ll2ctypes.py	Wed Apr 23 20:02:10 2008
@@ -6,7 +6,7 @@
 from pypy.rpython.lltypesystem.ll2ctypes import lltype2ctypes, ctypes2lltype
 from pypy.rpython.lltypesystem.ll2ctypes import standard_c_lib
 from pypy.rpython.lltypesystem.ll2ctypes import uninitialized2ctypes
-from pypy.rpython.lltypesystem.ll2ctypes import ALLOCATED
+from pypy.rpython.lltypesystem.ll2ctypes import ALLOCATED, force_cast
 from pypy.rpython.annlowlevel import llhelper
 from pypy.rlib import rposix
 from pypy.translator.tool.cbuild import ExternalCompilationInfo
@@ -817,3 +817,13 @@
         c1 = lltype2ctypes(a1)
         c2 = lltype2ctypes(a2)
         assert type(c1) is type(c2)
+
+    def test_varsized_struct(self): 
+        STR = lltype.Struct('rpy_string', ('hash',  lltype.Signed),
+                            ('chars', lltype.Array(lltype.Char, hints={'immutable': True})))
+        s = lltype.malloc(STR, 3, flavor='raw')
+        one = force_cast(rffi.VOIDP, s)
+        # sanity check
+        #assert lltype2ctypes(one).contents.items._length_ > 0
+        two = force_cast(lltype.Ptr(STR), one)
+        assert s == two



More information about the Pypy-commit mailing list