[pypy-svn] r46574 - in pypy/dist/pypy: annotation rpython rpython/test

arigo at codespeak.net arigo at codespeak.net
Fri Sep 14 12:15:27 CEST 2007


Author: arigo
Date: Fri Sep 14 12:15:26 2007
New Revision: 46574

Modified:
   pypy/dist/pypy/annotation/binaryop.py
   pypy/dist/pypy/annotation/bookkeeper.py
   pypy/dist/pypy/annotation/model.py
   pypy/dist/pypy/annotation/unaryop.py
   pypy/dist/pypy/rpython/rweakref.py
   pypy/dist/pypy/rpython/test/test_rweakref.py
Log:
Replace SomeDeadWeakRef() with SomeWeakRef(classdef=None).
Proper support for known-to-be-dead weakrefs in rweakref.


Modified: pypy/dist/pypy/annotation/binaryop.py
==============================================================================
--- pypy/dist/pypy/annotation/binaryop.py	(original)
+++ pypy/dist/pypy/annotation/binaryop.py	Fri Sep 14 12:15:26 2007
@@ -11,8 +11,7 @@
 from pypy.annotation.model import SomeTuple, SomeImpossibleValue, s_ImpossibleValue
 from pypy.annotation.model import SomeInstance, SomeBuiltin, SomeIterator
 from pypy.annotation.model import SomePBC, SomeSlice, SomeFloat, s_None
-from pypy.annotation.model import SomeExternalObject
-from pypy.annotation.model import SomeWeakRef, SomeDeadWeakRef
+from pypy.annotation.model import SomeExternalObject, SomeWeakRef
 from pypy.annotation.model import SomeAddress, SomeTypedAddressAccess
 from pypy.annotation.model import SomeCTypesObject
 from pypy.annotation.model import unionof, UnionError, set, missing_operation, TLS
@@ -766,7 +765,6 @@
 _make_none_union('SomeDict',          'obj.dictdef')
 _make_none_union('SomeExternalObject', 'obj.knowntype')
 _make_none_union('SomeWeakRef',         'obj.classdef')
-_make_none_union('SomeDeadWeakRef',      '')
 
 # getitem on SomePBCs, in particular None fails
 
@@ -873,23 +871,16 @@
 
 class __extend__(pairtype(SomeWeakRef, SomeWeakRef)):
     def union((s_wrf1, s_wrf2)):
-        basedef = s_wrf1.classdef.commonbase(s_wrf2.classdef)
-        if basedef is None:
-            return SomeObject()
+        if s_wrf1.classdef is None:
+            basedef = s_wrf2.classdef   # s_wrf1 is known to be dead
+        elif s_wrf2.classdef is None:
+            basedef = s_wrf1.classdef   # s_wrf2 is known to be dead
+        else:
+            basedef = s_wrf1.classdef.commonbase(s_wrf2.classdef)
+            if basedef is None:    # no common base class! complain...
+                return SomeObject()
         return SomeWeakRef(basedef)
 
-class __extend__(pairtype(SomeWeakRef, SomeDeadWeakRef)):
-    def union((s_wrf1, s_wrf2)):
-        return SomeWeakRef(s_wrf1.classdef)
-
-class __extend__(pairtype(SomeDeadWeakRef, SomeWeakRef)):
-    def union((s_wrf1, s_wrf2)):
-        return SomeWeakRef(s_wrf2.classdef)
-
-class __extend__(pairtype(SomeDeadWeakRef, SomeDeadWeakRef)):
-    def union((s_wrf1, s_wrf2)):
-        return SomeDeadWeakRef()
-
 #_________________________________________
 # memory addresses
 

Modified: pypy/dist/pypy/annotation/bookkeeper.py
==============================================================================
--- pypy/dist/pypy/annotation/bookkeeper.py	(original)
+++ pypy/dist/pypy/annotation/bookkeeper.py	Fri Sep 14 12:15:26 2007
@@ -11,7 +11,7 @@
      SomeInteger, SomeExternalObject, SomeOOInstance, TLS, SomeAddress, \
      SomeUnicodeCodePoint, SomeOOStaticMeth, s_None, s_ImpossibleValue, \
      SomeLLADTMeth, SomeBool, SomeTuple, SomeOOClass, SomeImpossibleValue, \
-     SomeList, SomeObject, HarmlesslyBlocked, SomeWeakRef, SomeDeadWeakRef
+     SomeList, SomeObject, HarmlesslyBlocked, SomeWeakRef
 from pypy.annotation.classdef import ClassDef, InstanceSource
 from pypy.annotation.listdef import ListDef, MOST_GENERAL_LISTDEF
 from pypy.annotation.dictdef import DictDef, MOST_GENERAL_DICTDEF
@@ -391,7 +391,7 @@
         elif tp is weakref.ReferenceType:
             x1 = x()
             if x1 is None:
-                result = SomeDeadWeakRef()
+                result = SomeWeakRef(None)    # dead weakref
             else:
                 s1 = self.immutablevalue(x1)
                 assert isinstance(s1, SomeInstance)

Modified: pypy/dist/pypy/annotation/model.py
==============================================================================
--- pypy/dist/pypy/annotation/model.py	(original)
+++ pypy/dist/pypy/annotation/model.py	Fri Sep 14 12:15:26 2007
@@ -498,12 +498,9 @@
     knowntype = weakref.ReferenceType
     immutable = True
     def __init__(self, classdef):
+        # 'classdef' is None for known-to-be-dead weakrefs.
         self.classdef = classdef
 
-class SomeDeadWeakRef(SomeObject):
-    knowntype = weakref.ReferenceType
-    immutable = True
-
 # ____________________________________________________________
 # memory addresses
 

Modified: pypy/dist/pypy/annotation/unaryop.py
==============================================================================
--- pypy/dist/pypy/annotation/unaryop.py	(original)
+++ pypy/dist/pypy/annotation/unaryop.py	Fri Sep 14 12:15:26 2007
@@ -9,7 +9,7 @@
      SomeExternalObject, SomeTypedAddressAccess, SomeAddress, \
      SomeCTypesObject, s_ImpossibleValue, s_Bool, s_None, \
      unionof, set, missing_operation, add_knowntypedata, HarmlesslyBlocked, \
-     SomeGenericCallable, SomeWeakRef, SomeDeadWeakRef
+     SomeGenericCallable, SomeWeakRef
 from pypy.annotation.bookkeeper import getbookkeeper
 from pypy.annotation import builtin
 from pypy.annotation.binaryop import _clone ## XXX where to put this?
@@ -755,11 +755,10 @@
 
 class __extend__(SomeWeakRef):
     def simple_call(s_wrf):
-        return SomeInstance(s_wrf.classdef, can_be_None=True)
-
-class __extend__(SomeDeadWeakRef):
-    def simple_call(s_wrf):
-        return s_None
+        if s_wrf.classdef is None:
+            return s_None   # known to be a dead weakref
+        else:
+            return SomeInstance(s_wrf.classdef, can_be_None=True)
 
 #_________________________________________
 # memory addresses

Modified: pypy/dist/pypy/rpython/rweakref.py
==============================================================================
--- pypy/dist/pypy/rpython/rweakref.py	(original)
+++ pypy/dist/pypy/rpython/rweakref.py	Fri Sep 14 12:15:26 2007
@@ -55,7 +55,11 @@
     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)
+        if hop.r_result.lowleveltype is lltype.Void: # known-to-be-dead weakref
+            return hop.inputconst(lltype.Void, None)
+        else:
+            return hop.genop('weakref_deref', [v_wref],
+                             resulttype=hop.r_result)
 
     def _weakref_create(self, llinstance):
         return llmemory.weakref_create(llinstance)
@@ -69,8 +73,12 @@
         v_wref, = hop.inputargs(self)
         cname = hop.inputconst(ootype.Void, 'll_deref')
         hop.exception_cannot_occur()
-        v_deref = hop.genop('oosend', [cname, v_wref], resulttype=ootype.ROOT)
-        return hop.genop('oodowncast', [v_deref], resulttype=hop.r_result)
+        if hop.r_result.lowleveltype is lltype.Void: # known-to-be-dead weakref
+            return hop.inputconst(lltype.Void, None)
+        else:
+            v_deref = hop.genop('oosend', [cname, v_wref],
+                                resulttype=ootype.ROOT)
+            return hop.genop('oodowncast', [v_deref], resulttype=hop.r_result)
 
     def _weakref_create(self, llinstance):
         return ootype.ooweakref_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	Fri Sep 14 12:15:26 2007
@@ -72,6 +72,46 @@
         res = self.interpret(f, [0])
         assert res == True
 
+    def test_multiple_prebuilt_dead_weakrefs(self):
+        class A:
+            pass
+        a1 = A()
+        w1 = weakref.ref(a1)
+        a2 = A()
+        w2 = weakref.ref(a2)
+        a3 = A()
+        w3 = weakref.ref(a3)
+        a4 = A()
+        w4 = weakref.ref(a4)
+
+        del a1, a3
+        rgc.collect()
+        assert w1() is None
+        assert w3() is None
+
+        def f(n):
+            if n > 0:
+                if n > 5:
+                    r = w1
+                else:
+                    r = w3
+                assert r() is None
+            else:
+                if n < -5:
+                    r = w2
+                else:
+                    r = w4
+                assert r() is not None
+            return r() is not None
+        res = self.interpret(f, [1])
+        assert res == False
+        res = self.interpret(f, [0])
+        assert res == True
+        res = self.interpret(f, [100])
+        assert res == False
+        res = self.interpret(f, [-100])
+        assert res == True
+
     def test_pbc_null_weakref(self):
         class A:
             pass



More information about the Pypy-commit mailing list