Author: Antonio Cuni <[email protected]>
Branch: invalidate-virtualrefs
Changeset: r44478:da62de19afc8
Date: 2011-05-25 14:27 +0200
http://bitbucket.org/pypy/pypy/changeset/da62de19afc8/

Log:    refactor the untranslated version of vrefs: now they can be in the
        non-forced, forced or invalid state

diff --git a/pypy/rlib/jit.py b/pypy/rlib/jit.py
--- a/pypy/rlib/jit.py
+++ b/pypy/rlib/jit.py
@@ -183,7 +183,6 @@
 # VRefs
 
 def virtual_ref(x):
-
     """Creates a 'vref' object that contains a reference to 'x'.  Calls
     to virtual_ref/virtual_ref_finish must be properly nested.  The idea
     is that the object 'x' is supposed to be JITted as a virtual between
@@ -194,10 +193,9 @@
     return DirectJitVRef(x)
 virtual_ref.oopspec = 'virtual_ref(x)'
 
-def virtual_ref_finish(x):
-    """See docstring in virtual_ref(x).  Note that virtual_ref_finish
-    takes as argument the real object, not the vref."""
-    keepalive_until_here(x)   # otherwise the whole function call is removed
+def virtual_ref_finish(vref, x):
+    """See docstring in virtual_ref(x)"""
+    _virtual_ref_finish(vref, x)
 virtual_ref_finish.oopspec = 'virtual_ref_finish(x)'
 
 def non_virtual_ref(x):
@@ -205,19 +203,39 @@
     Used for None or for frames outside JIT scope."""
     return DirectVRef(x)
 
+class InvalidVirtualRef(Exception):
+    """
+    Raised if we try to call a non-forced virtualref after the call to
+    virtual_ref_finish
+    """
+
 # ---------- implementation-specific ----------
 
 class DirectVRef(object):
     def __init__(self, x):
         self._x = x
+        self._state = 'non-forced'
+
     def __call__(self):
+        if self._state == 'non-forced':
+            self._state = 'forced'
+        elif self._state == 'invalid':
+            raise InvalidVirtualRef
         return self._x
 
+    def _finish(self):
+        if self._state == 'non-forced':
+            self._state = 'invalid'
+
 class DirectJitVRef(DirectVRef):
     def __init__(self, x):
         assert x is not None, "virtual_ref(None) is not allowed"
         DirectVRef.__init__(self, x)
 
+def _virtual_ref_finish(vref, x):
+    assert vref._x is x, "Invalid call to virtual_ref_finish"
+    vref._finish()
+
 class Entry(ExtRegistryEntry):
     _about_ = (non_virtual_ref, DirectJitVRef)
 
diff --git a/pypy/rlib/test/test__jit_vref.py b/pypy/rlib/test/test__jit_vref.py
--- a/pypy/rlib/test/test__jit_vref.py
+++ b/pypy/rlib/test/test__jit_vref.py
@@ -1,6 +1,6 @@
 import py
 from pypy.rlib.jit import virtual_ref, virtual_ref_finish
-from pypy.rlib.jit import vref_None, non_virtual_ref
+from pypy.rlib.jit import vref_None, non_virtual_ref, InvalidVirtualRef
 from pypy.rlib._jit_vref import SomeVRef
 from pypy.annotation import model as annmodel
 from pypy.annotation.annrpython import RPythonAnnotator
@@ -23,18 +23,23 @@
     pass
 
 
-def test_direct_1():
+def test_direct_forced():
     x1 = X()
     vref = virtual_ref(x1)
+    assert vref._state == 'non-forced'
     assert vref() is x1
-    virtual_ref_finish(x1)
+    assert vref._state == 'forced'
+    virtual_ref_finish(vref, x1)
+    assert vref._state == 'forced'
     assert vref() is x1
 
-def test_direct_2():
+def test_direct_invalid():
     x1 = X()
     vref = virtual_ref(x1)
-    virtual_ref_finish(x1)
-    assert vref() is x1
+    assert vref._state == 'non-forced'
+    virtual_ref_finish(vref, x1)
+    assert vref._state == 'invalid'
+    py.test.raises(InvalidVirtualRef, "vref()")
 
 def test_annotate_1():
     def f():
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to