[pypy-commit] pypy ffistruct: add support for reading nested structures

antocuni noreply at buildbot.pypy.org
Tue May 15 17:00:52 CEST 2012


Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: ffistruct
Changeset: r55105:691b846e85b6
Date: 2012-05-15 16:24 +0200
http://bitbucket.org/pypy/pypy/changeset/691b846e85b6/

Log:	add support for reading nested structures

diff --git a/pypy/module/_ffi/interp_funcptr.py b/pypy/module/_ffi/interp_funcptr.py
--- a/pypy/module/_ffi/interp_funcptr.py
+++ b/pypy/module/_ffi/interp_funcptr.py
@@ -203,8 +203,9 @@
     def get_singlefloat(self, w_ffitype):
         return self.func.call(self.argchain, rffi.FLOAT)
 
-    def get_struct(self, w_datashape):
-        return self.func.call(self.argchain, rffi.LONG, is_struct=True)
+    def get_struct(self, w_ffitype, w_datashape):
+        addr = self.func.call(self.argchain, rffi.LONG, is_struct=True)
+        return w_datashape.fromaddress(self.space, addr)
 
     def get_void(self, w_ffitype):
         return self.func.call(self.argchain, lltype.Void)
diff --git a/pypy/module/_ffi/interp_struct.py b/pypy/module/_ffi/interp_struct.py
--- a/pypy/module/_ffi/interp_struct.py
+++ b/pypy/module/_ffi/interp_struct.py
@@ -245,8 +245,13 @@
         return libffi.struct_getfield_singlefloat(w_ffitype.get_ffitype(),
                                                   self.rawmem, self.offset)
 
-    ## def get_struct(self, w_datashape):
-    ##     ...
+    def get_struct(self, w_ffitype, w_datashape):
+        assert isinstance(w_datashape, W__StructDescr)
+        innermem = rffi.ptradd(self.rawmem, self.offset)
+        # we return a reference to the inner struct, not a copy
+        # autofree=False because it's still owned by the parent struct
+        return W__StructInstance(w_datashape, allocate=False, autofree=False,
+                                 rawmem=innermem)
 
     ## def get_void(self, w_ffitype):
     ##     ...
diff --git a/pypy/module/_ffi/test/test_struct.py b/pypy/module/_ffi/test/test_struct.py
--- a/pypy/module/_ffi/test/test_struct.py
+++ b/pypy/module/_ffi/test/test_struct.py
@@ -264,7 +264,6 @@
         assert types.Pointer(descr.ffitype) is foo_p
 
     def test_nested_structure(self):
-        skip('in-progress')
         from _ffi import _StructDescr, Field, types
         longsize = types.slong.sizeof()
         foo_fields = [
diff --git a/pypy/module/_ffi/type_converter.py b/pypy/module/_ffi/type_converter.py
--- a/pypy/module/_ffi/type_converter.py
+++ b/pypy/module/_ffi/type_converter.py
@@ -224,8 +224,7 @@
         elif w_ffitype.is_struct():
             w_datashape = w_ffitype.w_datashape
             assert isinstance(w_datashape, W__StructDescr)
-            addr = self.get_struct(w_datashape) # this is the ptr to the struct
-            return w_datashape.fromaddress(space, addr)
+            return self.get_struct(w_ffitype, w_datashape)
         elif w_ffitype.is_void():
             voidval = self.get_void(w_ffitype)
             assert voidval is None
@@ -325,7 +324,7 @@
         """
         self.error(w_ffitype)
 
-    def get_struct(self, w_datashape):
+    def get_struct(self, w_ffitype, w_datashape):
         """
         Return type: lltype.Unsigned
         (the address of the structure)


More information about the pypy-commit mailing list