[pypy-svn] r26530 - in pypy/dist/pypy/rpython/rctypes: . test

arigo at codespeak.net arigo at codespeak.net
Fri Apr 28 18:58:21 CEST 2006


Author: arigo
Date: Fri Apr 28 18:58:21 2006
New Revision: 26530

Modified:
   pypy/dist/pypy/rpython/rctypes/rpointer.py
   pypy/dist/pypy/rpython/rctypes/test/test_rstruct.py
Log:
Fixed the recursive ctypes structure problem.  The rpointers are now
lazily following the type of what they point to.



Modified: pypy/dist/pypy/rpython/rctypes/rpointer.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/rpointer.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/rpointer.py	Fri Apr 28 18:58:21 2006
@@ -9,20 +9,27 @@
 
 class PointerRepr(CTypesValueRepr):
     def __init__(self, rtyper, s_pointer):
-        ptr_ctype = s_pointer.knowntype
-        ref_ctype = ptr_ctype._type_
+        # For recursive types, getting the r_contents is delayed until
+        # _setup_repr().
+        ll_contents = lltype.Ptr(lltype.ForwardReference())
+        self.keepalive_box_type = lltype.GcForwardReference()
+        super(PointerRepr, self).__init__(rtyper, s_pointer, ll_contents)
 
+    def _setup_repr(self):
         # Find the repr and low-level type of the contents from its ctype
+        rtyper = self.rtyper
+        ref_ctype = self.ctype._type_
         self.r_contents = rtyper.getrepr(SomeCTypesObject(ref_ctype,
                                                SomeCTypesObject.MEMORYALIAS))
-
-        ll_contents = lltype.Ptr(self.r_contents.c_data_type)
-
-        super(PointerRepr, self).__init__(rtyper, s_pointer, ll_contents)
+        if isinstance(self.ll_type.TO, lltype.ForwardReference):
+            self.ll_type.TO.become(self.r_contents.c_data_type)
+        if isinstance(self.keepalive_box_type, lltype.GcForwardReference):
+            self.keepalive_box_type.become(
+                self.r_contents.r_memoryowner.lowleveltype.TO)
 
     def get_content_keepalive_type(self):
         "Keepalive for the box that holds the data that 'self' points to."
-        return self.r_contents.r_memoryowner.lowleveltype
+        return lltype.Ptr(self.keepalive_box_type)
 
     def setkeepalive(self, llops, v_box, v_owner):
         inputargs = [v_box, inputconst(lltype.Void, 'keepalive'),

Modified: pypy/dist/pypy/rpython/rctypes/test/test_rstruct.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/test/test_rstruct.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/test/test_rstruct.py	Fri Apr 28 18:58:21 2006
@@ -152,7 +152,6 @@
         assert res == 121
 
     def test_struct_with_pointer_to_self(self):
-        py.test.skip('In-preogress')
         PS = POINTER('S')
         class S(Structure):
             _fields_ = [('l', PS), ('r', PS)]
@@ -160,11 +159,12 @@
 
         def func():
             s0 = S()
-            s0.r = s0
-            s0.l = pointer(S())
-            s0.l.r = s0
+            s0.r.contents = s0
+            s0.l.contents = S()
+            s0.l.contents.r.contents = s0
 
-            return bool(s0.r.contents.l.contents.r)
+            return bool(s0.r.contents.l.contents.l)
+        assert not func()
         res = interpret(func, [])
         assert res is False
         



More information about the Pypy-commit mailing list