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

arigo at codespeak.net arigo at codespeak.net
Tue Sep 11 12:17:50 CEST 2007


Author: arigo
Date: Tue Sep 11 12:17:49 2007
New Revision: 46466

Modified:
   pypy/dist/pypy/rpython/rweakref.py
   pypy/dist/pypy/rpython/test/test_rweakref.py
Log:
Prebuilt non-dead RPython-level weakrefs...


Modified: pypy/dist/pypy/rpython/rweakref.py
==============================================================================
--- pypy/dist/pypy/rpython/rweakref.py	(original)
+++ pypy/dist/pypy/rpython/rweakref.py	Tue Sep 11 12:17:49 2007
@@ -1,5 +1,8 @@
+import weakref
 from pypy.annotation import model as annmodel
+from pypy.objspace.flow.model import Constant
 from pypy.rpython.rmodel import Repr
+from pypy.rpython.rclass import getinstancerepr
 from pypy.rpython.lltypesystem import lltype, llmemory
 
 
@@ -18,7 +21,7 @@
 
 class __extend__(annmodel.SomeWeakRef):
     def rtyper_makerepr(self, rtyper):
-        return WeakRefRepr()
+        return WeakRefRepr(rtyper)
     def rtyper_makekey(self):
         return self.__class__,
 
@@ -26,7 +29,23 @@
 class WeakRefRepr(Repr):
     lowleveltype = llmemory.WeakRef
 
+    def __init__(self, rtyper):
+        self.rtyper = rtyper
+
     def rtype_simple_call(self, hop):
         v_wref, = hop.inputargs(self)
         hop.exception_cannot_occur()
         return hop.genop('weakref_deref', [v_wref], resulttype=hop.r_result)
+
+    def convert_const(self, value):
+        assert isinstance(value, weakref.ref)
+        instance = value()
+        bk = self.rtyper.annotator.bookkeeper
+        # obscure!  if the annotator hasn't seen this object before,
+        # we don't want to look at it now (confusion tends to result).
+        if instance is None or not bk.have_seen(instance):
+            return llmemory.WeakRef._defl()
+        else:
+            repr = self.rtyper.bindingrepr(Constant(instance))
+            llinstance = repr.convert_const(instance)
+            return llmemory.weakref_create(llinstance)

Modified: pypy/dist/pypy/rpython/test/test_rweakref.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_rweakref.py	(original)
+++ pypy/dist/pypy/rpython/test/test_rweakref.py	Tue Sep 11 12:17:49 2007
@@ -1,4 +1,4 @@
-import weakref
+import py, weakref
 from pypy.rlib import rgc
 from pypy.rpython.lltypesystem import lltype, llmemory
 from pypy.rpython.test.test_llinterp import interpret
@@ -39,9 +39,52 @@
             x.hello = 64
             r = weakref.ref(x)
         return r().hello, x      # returns 'x' too, to keep it alive
-
     res = interpret(f, [1])
     assert res.item0 == 42
-
     res = interpret(f, [0])
     assert res.item0 == 64
+
+def test_prebuilt_weakref():
+    class A:
+        pass
+    a1 = A()
+    a1.hello = 5
+    w1 = weakref.ref(a1)
+    a2 = A()
+    a2.hello = 8
+    w2 = weakref.ref(a2)
+
+    def f(n):
+        if n:
+            r = w1
+        else:
+            r = w2
+        return r().hello
+    res = interpret(f, [1])
+    assert res == 5
+    res = interpret(f, [0])
+    assert res == 8
+
+def test_prebuilt_dead_weakref():
+    py.test.skip("in-progress")
+    class A:
+        pass
+    a1 = A()
+    w1 = weakref.ref(a1)
+    a2 = A()
+    w2 = weakref.ref(a2)
+
+    del a1
+    rgc.collect()
+    assert w1() is None
+
+    def f(n):
+        if n:
+            r = w1
+        else:
+            r = w2
+        return r() is not None
+    res = interpret(f, [1])
+    assert res == False
+    res = interpret(f, [0])
+    assert res == True



More information about the Pypy-commit mailing list