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

arigo at codespeak.net arigo at codespeak.net
Tue Sep 11 11:11:56 CEST 2007


Author: arigo
Date: Tue Sep 11 11:11:55 2007
New Revision: 46460

Added:
   pypy/dist/pypy/rpython/rweakref.py   (contents, props changed)
   pypy/dist/pypy/rpython/test/test_rweakref.py   (contents, props changed)
Modified:
   pypy/dist/pypy/annotation/builtin.py
   pypy/dist/pypy/annotation/model.py
   pypy/dist/pypy/rpython/llinterp.py
   pypy/dist/pypy/rpython/lltypesystem/lloperation.py
   pypy/dist/pypy/rpython/rbuiltin.py
   pypy/dist/pypy/rpython/rtyper.py
Log:
Annotation and rtyping for low-level WeakRefs.


Modified: pypy/dist/pypy/annotation/builtin.py
==============================================================================
--- pypy/dist/pypy/annotation/builtin.py	(original)
+++ pypy/dist/pypy/annotation/builtin.py	Tue Sep 11 11:11:55 2007
@@ -8,7 +8,8 @@
 from pypy.annotation.model import SomeUnicodeCodePoint, SomeAddress
 from pypy.annotation.model import SomeFloat, SomeWeakGcAddress, unionof
 from pypy.annotation.model import SomePBC, SomeInstance, SomeDict
-from pypy.annotation.model import SomeExternalObject, SomeWeakRef
+from pypy.annotation.model import SomeExternalObject
+from pypy.annotation.model import SomeWeakRef, SomeLLWeakRef
 from pypy.annotation.model import annotation_to_lltype, lltype_to_annotation, ll_to_annotation
 from pypy.annotation.model import add_knowntypedata
 from pypy.annotation.model import s_ImpossibleValue
@@ -580,6 +581,28 @@
 
 BUILTIN_ANALYZERS[weakref.ref] = weakref_ref
 
+def llweakref_create(s_obj):
+    if (not isinstance(s_obj, SomePtr) or
+        s_obj.ll_ptrtype.TO._gckind != 'gc'):
+        raise Exception("bad type for argument to weakref_create(): %r" % (
+            s_obj,))
+    return SomeLLWeakRef()
+
+def llweakref_deref(s_ptrtype, s_wref):
+    if not (s_ptrtype.is_constant() and
+            isinstance(s_ptrtype.const, lltype.Ptr) and
+            s_ptrtype.const.TO._gckind == 'gc'):
+        raise Exception("weakref_deref() arg 1 must be a constant "
+                        "ptr type, got %s" % (s_ptrtype,))
+    if not isinstance(s_wref, SomeLLWeakRef):
+        raise Exception("weakref_deref() arg 2 must be a llweakref, "
+                        "got %s" % (s_wref,))
+    return SomePtr(s_ptrtype.const)
+
+from pypy.rpython.lltypesystem import llmemory
+BUILTIN_ANALYZERS[llmemory.weakref_create] = llweakref_create
+BUILTIN_ANALYZERS[llmemory.weakref_deref ] = llweakref_deref
+
 #________________________________
 # non-gc objects
 

Modified: pypy/dist/pypy/annotation/model.py
==============================================================================
--- pypy/dist/pypy/annotation/model.py	(original)
+++ pypy/dist/pypy/annotation/model.py	Tue Sep 11 11:11:55 2007
@@ -33,7 +33,7 @@
 from pypy.annotation.pairtype import pair, extendabletype
 from pypy.tool.tls import tlsobject
 from pypy.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong, base_int
-import inspect
+import inspect, weakref
 from sys import maxint
 from pypy.annotation.description import FunctionDesc
 
@@ -495,6 +495,7 @@
 # weakrefs
 
 class SomeWeakRef(SomeObject):
+    knowntype = weakref.ref
     immutable = True
     def __init__(self, classdef):
         self.classdef = classdef
@@ -502,6 +503,12 @@
     def can_be_none(self):
         return False
 
+class SomeLLWeakRef(SomeObject):
+    immutable = True
+
+    def can_be_none(self):
+        return False
+
 # ____________________________________________________________
 # memory addresses
 
@@ -583,6 +590,7 @@
     (SomeUnicodeCodePoint(), lltype.UniChar),
     (SomeAddress(), llmemory.Address),
     (SomeWeakGcAddress(), llmemory.WeakGcAddress),
+    (SomeLLWeakRef(), llmemory.WeakRef),
 ]
 
 def annotation_to_lltype(s_val, info=None):

Modified: pypy/dist/pypy/rpython/llinterp.py
==============================================================================
--- pypy/dist/pypy/rpython/llinterp.py	(original)
+++ pypy/dist/pypy/rpython/llinterp.py	Tue Sep 11 11:11:55 2007
@@ -702,6 +702,13 @@
         return lltype.cast_opaque_ptr(RESTYPE, obj)
     op_cast_opaque_ptr.need_result_type = True
 
+    def op_weakref_create(self, obj):
+        return llmemory.weakref_create(obj)
+
+    def op_weakref_deref(self, PTRTYPE, obj):
+        return llmemory.weakref_deref(PTRTYPE, obj)
+    op_weakref_deref.need_result_type = True
+
     def op_gc__collect(self):
         import gc
         gc.collect()

Modified: pypy/dist/pypy/rpython/lltypesystem/lloperation.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/lloperation.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/lloperation.py	Tue Sep 11 11:11:55 2007
@@ -366,6 +366,8 @@
     'cast_weakadr_to_int':  LLOp(canfold=True),
     'cast_adr_to_int':      LLOp(canfold=True),
     'cast_int_to_adr':      LLOp(canfold=True),   # not implemented in llinterp
+    'weakref_create':       LLOp(sideeffects=False),
+    'weakref_deref':        LLOp(sideeffects=False),
 
     # __________ used by the JIT ________
 

Modified: pypy/dist/pypy/rpython/rbuiltin.py
==============================================================================
--- pypy/dist/pypy/rpython/rbuiltin.py	(original)
+++ pypy/dist/pypy/rpython/rbuiltin.py	Tue Sep 11 11:11:55 2007
@@ -594,6 +594,22 @@
 BUILTIN_TYPER[llmemory.offsetof] = rtype_offsetof
 
 # _________________________________________________________________
+# weakrefs
+
+def rtype_weakref_create(hop):
+    vlist = hop.inputargs(hop.args_r[0])
+    hop.exception_cannot_occur()
+    return hop.genop('weakref_create', vlist, resulttype=llmemory.WeakRef)
+
+def rtype_weakref_deref(hop):
+    c_ptrtype, v_wref = hop.inputargs(lltype.Void, llmemory.WeakRef)
+    hop.exception_cannot_occur()
+    return hop.genop('weakref_deref', [v_wref], resulttype=c_ptrtype.value)
+
+BUILTIN_TYPER[llmemory.weakref_create] = rtype_weakref_create
+BUILTIN_TYPER[llmemory.weakref_deref ] = rtype_weakref_deref
+
+# _________________________________________________________________
 # non-gc objects
 
 def rtype_free_non_gc_object(hop):

Modified: pypy/dist/pypy/rpython/rtyper.py
==============================================================================
--- pypy/dist/pypy/rpython/rtyper.py	(original)
+++ pypy/dist/pypy/rpython/rtyper.py	Tue Sep 11 11:11:55 2007
@@ -947,5 +947,6 @@
 from pypy.rpython import rexternalobj
 from pypy.rpython import rptr
 from pypy.rpython import rgeneric
+from pypy.rpython import rweakref
 from pypy.rpython import raddress # memory addresses
 from pypy.rpython.ootypesystem import rootype

Added: pypy/dist/pypy/rpython/rweakref.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/rweakref.py	Tue Sep 11 11:11:55 2007
@@ -0,0 +1,14 @@
+from pypy.annotation import model as annmodel
+from pypy.rpython.rmodel import Repr
+from pypy.rpython.lltypesystem import lltype, llmemory
+
+
+class __extend__(annmodel.SomeLLWeakRef):
+    def rtyper_makerepr(self, rtyper):
+        return LLWeakRefRepr()
+    def rtyper_makekey(self):
+        return self.__class__,
+
+
+class LLWeakRefRepr(Repr):
+    lowleveltype = llmemory.WeakRef

Added: pypy/dist/pypy/rpython/test/test_rweakref.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/test/test_rweakref.py	Tue Sep 11 11:11:55 2007
@@ -0,0 +1,20 @@
+from pypy.rlib import rgc
+from pypy.rpython.lltypesystem import lltype, llmemory
+from pypy.rpython.test.test_llinterp import interpret
+
+
+def test_ll_weakref():
+    S = lltype.GcStruct('S', ('x',lltype.Signed))
+    def g():
+        s = lltype.malloc(S)
+        w = llmemory.weakref_create(s)
+        assert llmemory.weakref_deref(lltype.Ptr(S), w) == s
+        assert llmemory.weakref_deref(lltype.Ptr(S), w) == s
+        return w   # 's' is forgotten here
+    def f():
+        w = g()
+        rgc.collect()
+        return llmemory.weakref_deref(lltype.Ptr(S), w)
+
+    res = interpret(f, [])
+    assert res == lltype.nullptr(S)



More information about the Pypy-commit mailing list