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

arigo at codespeak.net arigo at codespeak.net
Tue Sep 11 11:41:59 CEST 2007


Author: arigo
Date: Tue Sep 11 11:41:58 2007
New Revision: 46461

Modified:
   pypy/dist/pypy/rpython/lltypesystem/llmemory.py
   pypy/dist/pypy/rpython/lltypesystem/test/test_llmemory.py
Log:
Fix fakeweakaddress to resist to pointer casts.
This fixes fakeweakref too.


Modified: pypy/dist/pypy/rpython/lltypesystem/llmemory.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/llmemory.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/llmemory.py	Tue Sep 11 11:41:58 2007
@@ -491,8 +491,11 @@
 # ____________________________________________________________
 
 class fakeweakaddress(object):
+    # XXX convoluted code to support both lltype._ptr and simulatorptr
     def __init__(self, ob):
         if ob is not None:
+            if isinstance(ob, lltype._ptr):
+                ob = lltype.normalizeptr(ob)._obj
             self.ref = weakref.ref(ob)
             # umpf
             from pypy.rpython.memory import lltypesimulation
@@ -509,6 +512,8 @@
         # xxx stop-gap
         #if ob is None:
         #    raise DanglingPointerError
+        if isinstance(ob, lltype._container):
+            ob = ob._as_ptr()
         return ob
     def __repr__(self):
         if self.ref is None:
@@ -525,7 +530,6 @@
                                  fakeweakaddress(None))
 
 def cast_ptr_to_weakadr(obj):
-    # XXX this is missing the normalizations done by _ptr._cast_to_adr()
     assert isinstance(lltype.typeOf(obj), lltype.Ptr)
     return fakeweakaddress(obj)
 
@@ -533,7 +537,8 @@
     result = adr.get()
     if result is None:
         return lltype.nullptr(EXPECTED_TYPE.TO)
-    return result
+    else:
+        return lltype.cast_pointer(EXPECTED_TYPE, result)
 
 fakeweakaddress._TYPE = WeakGcAddress
 WEAKNULL = fakeweakaddress(None)
@@ -549,7 +554,7 @@
     PTRTYPE = lltype.typeOf(obj)
     assert isinstance(PTRTYPE, lltype.Ptr)
     assert PTRTYPE.TO._gckind == 'gc'
-    return fakeweakref(lltype.normalizeptr(obj))
+    return fakeweakref(obj)
 
 def weakref_deref(PTRTYPE, wref):
     assert isinstance(PTRTYPE, lltype.Ptr)

Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_llmemory.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/test/test_llmemory.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/test/test_llmemory.py	Tue Sep 11 11:41:58 2007
@@ -169,6 +169,23 @@
     res = interpret(f, [])
     assert res
 
+def test_weak_casts_lifetime():
+    T = lltype.GcStruct("T", ("x", lltype.Signed))
+    S = lltype.GcStruct("S", ("t", T))
+    Sptr = lltype.Ptr(S)
+    def g():
+        s1 = lltype.malloc(S)
+        adr = cast_ptr_to_weakadr(s1)
+        s2 = cast_weakadr_to_ptr(adr, Sptr)
+        assert s1 == s2
+        return adr, lltype.cast_pointer(lltype.Ptr(T), s2)   # s1, s2 go away
+    def f():
+        adr, t = g()
+        t2 = cast_weakadr_to_ptr(adr, lltype.Ptr(T))
+        return t2 == t
+    res = interpret(f, [])
+    assert res
+
 def test_fakeaccessor():
     S = lltype.GcStruct("S", ("x", lltype.Signed), ("y", lltype.Signed))
     s = lltype.malloc(S)
@@ -574,14 +591,23 @@
     # release(start)
 
 def test_weakref():
-    S = lltype.GcStruct('S', ('x',lltype.Signed))
+    S1 = lltype.GcStruct('S1', ('x',lltype.Signed))
+    S = lltype.GcStruct('S', ('s1', S1))
     s = lltype.malloc(S)
+    s1 = lltype.cast_pointer(lltype.Ptr(S1), s)
     w = weakref_create(s)
     assert weakref_deref(lltype.Ptr(S), w) == s
-    assert weakref_deref(lltype.Ptr(S), w) == s
+    assert weakref_deref(lltype.Ptr(S1), w) == s1
+    # check that the weakref stays alive even if there are only
+    # cast_pointer'ed references around
     del s
     import gc; gc.collect()
+    assert weakref_deref(lltype.Ptr(S1), w) == s1
+    # now really kill the structure
+    del s1
+    import gc; gc.collect()
     assert weakref_deref(lltype.Ptr(S), w) == lltype.nullptr(S)
+    assert weakref_deref(lltype.Ptr(S1), w) == lltype.nullptr(S1)
 
 class TestWeakAddressLLinterp(object):
     def test_null(self):



More information about the Pypy-commit mailing list