[pypy-svn] r46547 - in pypy/dist/pypy/rpython: . lltypesystem ootypesystem ootypesystem/test test
antocuni at codespeak.net
antocuni at codespeak.net
Thu Sep 13 19:08:07 CEST 2007
Author: antocuni
Date: Thu Sep 13 19:08:07 2007
New Revision: 46547
Modified:
pypy/dist/pypy/rpython/lltypesystem/rbuiltin.py
pypy/dist/pypy/rpython/ootypesystem/ootype.py
pypy/dist/pypy/rpython/ootypesystem/rbuiltin.py
pypy/dist/pypy/rpython/ootypesystem/test/test_ootype.py
pypy/dist/pypy/rpython/rbuiltin.py
pypy/dist/pypy/rpython/rweakref.py
pypy/dist/pypy/rpython/test/test_rweakref.py
Log:
implement rweakref for ootype.
Modified: pypy/dist/pypy/rpython/lltypesystem/rbuiltin.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/rbuiltin.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/rbuiltin.py Thu Sep 13 19:08:07 2007
@@ -66,3 +66,40 @@
BUILTIN_TYPER[hasattr] = rtype_builtin_hasattr
BUILTIN_TYPER[__import__] = rtype_builtin___import__
BUILTIN_TYPER[objectmodel.r_dict] = rtype_r_dict
+
+# _________________________________________________________________
+# weakrefs
+
+import weakref
+from pypy.rpython.lltypesystem import llmemory
+
+def rtype_weakref_create(hop):
+ # Note: this code also works for the RPython-level calls 'weakref.ref(x)'.
+ vlist = hop.inputargs(hop.args_r[0])
+ hop.exception_cannot_occur()
+ return hop.genop('weakref_create', vlist, resulttype=llmemory.WeakRefPtr)
+
+def rtype_weakref_deref(hop):
+ c_ptrtype, v_wref = hop.inputargs(lltype.Void, hop.args_r[1])
+ assert v_wref.concretetype == llmemory.WeakRefPtr
+ hop.exception_cannot_occur()
+ return hop.genop('weakref_deref', [v_wref], resulttype=c_ptrtype.value)
+
+def rtype_cast_ptr_to_weakrefptr(hop):
+ vlist = hop.inputargs(hop.args_r[0])
+ hop.exception_cannot_occur()
+ return hop.genop('cast_ptr_to_weakrefptr', vlist,
+ resulttype=llmemory.WeakRefPtr)
+
+def rtype_cast_weakrefptr_to_ptr(hop):
+ c_ptrtype, v_wref = hop.inputargs(lltype.Void, hop.args_r[1])
+ assert v_wref.concretetype == llmemory.WeakRefPtr
+ hop.exception_cannot_occur()
+ return hop.genop('cast_weakrefptr_to_ptr', [v_wref],
+ resulttype=c_ptrtype.value)
+
+BUILTIN_TYPER[weakref.ref] = rtype_weakref_create
+BUILTIN_TYPER[llmemory.weakref_create] = rtype_weakref_create
+BUILTIN_TYPER[llmemory.weakref_deref ] = rtype_weakref_deref
+BUILTIN_TYPER[llmemory.cast_ptr_to_weakrefptr] = rtype_cast_ptr_to_weakrefptr
+BUILTIN_TYPER[llmemory.cast_weakrefptr_to_ptr] = rtype_cast_weakrefptr_to_ptr
Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/ootype.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/ootype.py Thu Sep 13 19:08:07 2007
@@ -381,6 +381,25 @@
def _specialize(self, generic_types):
return self
+# WARNING: the name WeakReference is rebound at the end of file
+class WeakReference(BuiltinADTType):
+ def __init__(self):
+ self._null = _null_weak_reference(self)
+ self._GENERIC_METHODS = frozendict({
+ "ll_set": Meth([ROOT], Void),
+ "ll_deref": Meth([], ROOT),
+ })
+ self._setup_methods({})
+
+ def _defl(self):
+ return self._null
+
+ def _get_interp_class(self):
+ return _weak_reference
+
+ def _specialize(self, generic_types):
+ return self
+
class List(BuiltinADTType):
# placeholders for types
# make sure that each derived class has his own SELFTYPE_T
@@ -787,6 +806,9 @@
_enforce = _upcast
def _downcast(self, INSTANCE):
+ if not self._inst:
+ assert isSubclass(INSTANCE, self._TYPE) or isSubclass(self._TYPE, INSTANCE)
+ return null(INSTANCE)
assert isSubclass(INSTANCE, self._TYPE)
return _view(INSTANCE, self._inst)
@@ -1133,6 +1155,37 @@
def __init__(self, STRING_BUILDER):
self.__dict__["_TYPE"] = STRING_BUILDER
+import weakref
+
+class _weak_reference(_builtin_type):
+ def __init__(self, WEAK_REFERENCE):
+ self._TYPE = WEAK_REFERENCE
+ self._ref = None
+
+ def _unwrap_view(self, obj):
+ # we can't store directly the view inside the weakref because
+ # the view can be a temp object that is not referenced
+ # anywhere else.
+ while isinstance(obj, _view):
+ obj = obj._inst
+ return obj
+
+ def ll_set(self, target):
+ assert isinstance(typeOf(target), Instance)
+ target = self._unwrap_view(target)
+ self._ref = weakref.ref(target)
+
+ def ll_deref(self):
+ if self._ref is None:
+ return null(ROOT)
+ result = self._ref()
+ if result is None:
+ return null(ROOT)
+ return _view(ROOT, result)
+
+class _null_weak_reference(_null_mixin(_weak_reference), _weak_reference):
+ def __init__(self, WEAK_REFERENCE):
+ self.__dict__["_TYPE"] = WEAK_REFERENCE
class _list(_builtin_type):
def __init__(self, LIST):
@@ -1475,6 +1528,13 @@
def hasDictTypes(DICT):
return DICT._is_initialized()
+def ooweakref_create(obj):
+ ref = new(WeakReference)
+ ref.ll_set(obj)
+ return ref
+
+ROOT = Instance('Root', None, _is_root=True)
String = String()
StringBuilder = StringBuilder()
-ROOT = Instance('Root', None, _is_root=True)
+WeakReference = WeakReference()
+dead_wref = new(WeakReference)
Modified: pypy/dist/pypy/rpython/ootypesystem/rbuiltin.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/rbuiltin.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/rbuiltin.py Thu Sep 13 19:08:07 2007
@@ -101,3 +101,18 @@
BUILTIN_TYPER[isinstance] = rtype_builtin_isinstance
BUILTIN_TYPER[objectmodel.r_dict] = rtype_r_dict
BUILTIN_TYPER[objectmodel.instantiate] = rtype_instantiate
+
+
+# _________________________________________________________________
+# weakrefs
+
+import weakref
+from pypy.rpython.lltypesystem import llmemory
+
+def rtype_weakref_create(hop):
+ # Note: this code also works for the RPython-level calls 'weakref.ref(x)'.
+ vlist = hop.inputargs(hop.args_r[0])
+ hop.exception_cannot_occur()
+ return hop.gendirectcall(ootype.ooweakref_create, *vlist)
+
+BUILTIN_TYPER[weakref.ref] = rtype_weakref_create
Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ootype.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/test/test_ootype.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/test/test_ootype.py Thu Sep 13 19:08:07 2007
@@ -451,3 +451,27 @@
DT = DictItemsIterator(String, Signed)
_, meth = DT._lookup('ll_go_next')
assert meth._can_raise == True
+
+def test_cast_null():
+ A = Instance("A", ROOT)
+ B = Instance("B", ROOT)
+ rootnull = null(ROOT)
+ anull = oodowncast(A, rootnull)
+ assert typeOf(anull) is A
+ assert ooupcast(ROOT, anull) == rootnull
+ py.test.raises(AssertionError, oodowncast, B, anull)
+
+def test_weak_reference():
+ import gc
+ A = Instance("A", ROOT)
+ obj = new(A)
+ ref = new(WeakReference)
+ ref.ll_set(obj)
+ assert oodowncast(A, ref.ll_deref()) == obj
+ del obj
+ gc.collect()
+ assert ref.ll_deref() is null(ROOT)
+
+def test_dead_wref():
+ ref = new(WeakReference)
+ assert ref.ll_deref() is null(ROOT)
Modified: pypy/dist/pypy/rpython/rbuiltin.py
==============================================================================
--- pypy/dist/pypy/rpython/rbuiltin.py (original)
+++ pypy/dist/pypy/rpython/rbuiltin.py Thu Sep 13 19:08:07 2007
@@ -594,42 +594,6 @@
BUILTIN_TYPER[llmemory.offsetof] = rtype_offsetof
# _________________________________________________________________
-# weakrefs
-
-import weakref
-
-def rtype_weakref_create(hop):
- # Note: this code also works for the RPython-level calls 'weakref.ref(x)'.
- vlist = hop.inputargs(hop.args_r[0])
- hop.exception_cannot_occur()
- return hop.genop('weakref_create', vlist, resulttype=llmemory.WeakRefPtr)
-
-def rtype_weakref_deref(hop):
- c_ptrtype, v_wref = hop.inputargs(lltype.Void, hop.args_r[1])
- assert v_wref.concretetype == llmemory.WeakRefPtr
- hop.exception_cannot_occur()
- return hop.genop('weakref_deref', [v_wref], resulttype=c_ptrtype.value)
-
-def rtype_cast_ptr_to_weakrefptr(hop):
- vlist = hop.inputargs(hop.args_r[0])
- hop.exception_cannot_occur()
- return hop.genop('cast_ptr_to_weakrefptr', vlist,
- resulttype=llmemory.WeakRefPtr)
-
-def rtype_cast_weakrefptr_to_ptr(hop):
- c_ptrtype, v_wref = hop.inputargs(lltype.Void, hop.args_r[1])
- assert v_wref.concretetype == llmemory.WeakRefPtr
- hop.exception_cannot_occur()
- return hop.genop('cast_weakrefptr_to_ptr', [v_wref],
- resulttype=c_ptrtype.value)
-
-BUILTIN_TYPER[weakref.ref] = rtype_weakref_create
-BUILTIN_TYPER[llmemory.weakref_create] = rtype_weakref_create
-BUILTIN_TYPER[llmemory.weakref_deref ] = rtype_weakref_deref
-BUILTIN_TYPER[llmemory.cast_ptr_to_weakrefptr] = rtype_cast_ptr_to_weakrefptr
-BUILTIN_TYPER[llmemory.cast_weakrefptr_to_ptr] = rtype_cast_weakrefptr_to_ptr
-
-# _________________________________________________________________
# non-gc objects
def rtype_free_non_gc_object(hop):
Modified: pypy/dist/pypy/rpython/rweakref.py
==============================================================================
--- pypy/dist/pypy/rpython/rweakref.py (original)
+++ pypy/dist/pypy/rpython/rweakref.py Thu Sep 13 19:08:07 2007
@@ -5,6 +5,7 @@
from pypy.rpython.rmodel import Repr
from pypy.rpython.rclass import getinstancerepr
from pypy.rpython.lltypesystem import lltype, llmemory
+from pypy.rpython.ootypesystem import ootype
# ____________________________________________________________
#
@@ -12,13 +13,14 @@
class __extend__(annmodel.SomeWeakRef):
def rtyper_makerepr(self, rtyper):
- return WeakRefRepr(rtyper)
+ if rtyper.type_system.name == 'lltypesystem':
+ return LLWeakRefRepr(rtyper)
+ else:
+ return OOWeakRefRepr(rtyper)
def rtyper_makekey(self):
return self.__class__,
-
-class WeakRefRepr(Repr):
- lowleveltype = llmemory.WeakRefPtr
+class BaseWeakRefRepr(Repr):
def __init__(self, rtyper):
self.rtyper = rtyper
@@ -26,11 +28,6 @@
raise TyperError("RPython-level weakrefs are not supported by "
"this backend or GC policy")
- 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.ReferenceType)
instance = value()
@@ -38,8 +35,37 @@
# 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.dead_wref
+ return self.dead_wref
else:
repr = self.rtyper.bindingrepr(Constant(instance))
llinstance = repr.convert_const(instance)
- return llmemory.weakref_create(llinstance)
+ return self._weakref_create(llinstance)
+
+ def _weakref_create(self, llinstance):
+ raise NotImplementedError
+
+class LLWeakRefRepr(BaseWeakRefRepr):
+ lowleveltype = llmemory.WeakRefPtr
+ dead_wref = llmemory.dead_wref
+
+ 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 _weakref_create(self, llinstance):
+ return llmemory.weakref_create(llinstance)
+
+class OOWeakRefRepr(BaseWeakRefRepr):
+ lowleveltype = ootype.WeakReference
+ dead_wref = ootype.dead_wref
+
+ def rtype_simple_call(self, hop):
+ 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)
+
+ 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 Thu Sep 13 19:08:07 2007
@@ -1,89 +1,95 @@
import py, weakref
from pypy.rlib import rgc
from pypy.rpython.lltypesystem import lltype, llmemory
-from pypy.rpython.test.test_llinterp import interpret
+from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin
+class BaseTestRweakref(BaseRtypingTest):
-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()
+ def test_weakref_simple(self):
+ class A:
+ pass
+ class B(A):
+ pass
+ class C(A):
+ pass
+
+ def f(n):
+ if n:
+ x = B()
+ x.hello = 42
+ r = weakref.ref(x)
+ else:
+ x = C()
+ x.hello = 64
+ r = weakref.ref(x)
+ return r().hello, x # returns 'x' too, to keep it alive
+ res = self.interpret(f, [1])
+ assert res.item0 == 42
+ res = self.interpret(f, [0])
+ assert res.item0 == 64
+
+ def test_prebuilt_weakref(self):
+ 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 = self.interpret(f, [1])
+ assert res == 5
+ res = self.interpret(f, [0])
+ assert res == 8
+
+ def test_prebuilt_dead_weakref(self):
+ class A:
+ pass
+ a1 = A()
+ w1 = weakref.ref(a1)
+ a2 = A()
+ w2 = weakref.ref(a2)
+
+ del a1
rgc.collect()
- return llmemory.weakref_deref(lltype.Ptr(S), w)
+ assert w1() is None
+
+ def f(n):
+ if n:
+ r = w1
+ else:
+ r = w2
+ return r() is not None
+ res = self.interpret(f, [1])
+ assert res == False
+ res = self.interpret(f, [0])
+ assert res == True
+
+
+class TestLLtype(BaseTestRweakref, LLRtypeMixin):
+ def test_ll_weakref(self):
+ 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)
+ res = self.interpret(f, [])
+ assert res == lltype.nullptr(S)
-def test_weakref_simple():
- class A:
- pass
- class B(A):
- pass
- class C(A):
- pass
-
- def f(n):
- if n:
- x = B()
- x.hello = 42
- r = weakref.ref(x)
- else:
- x = C()
- 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():
- 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
+class TestOOtype(BaseTestRweakref, OORtypeMixin):
+ pass
More information about the pypy-svn
mailing list