Author: fijal
Branch: 
Changeset: r83486:56c0228015a1
Date: 2016-04-01 12:01 +0200
http://bitbucket.org/pypy/pypy/changeset/56c0228015a1/

Log:    backout the merge of the branch we need to think more about

diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py
--- a/pypy/interpreter/error.py
+++ b/pypy/interpreter/error.py
@@ -277,9 +277,18 @@
         raise NotImplementedError
 
     def get_traceback(self):
-        """Get the PyTraceback object, for app-level Python code.
+        """Calling this marks the PyTraceback as escaped, i.e. it becomes
+        accessible and inspectable by app-level Python code.  For the JIT.
+        Note that this has no effect if there are already several traceback
+        frames recorded, because in this case they are already marked as
+        escaping by executioncontext.leave() being called with
+        got_exception=True.
         """
-        return self._application_traceback
+        from pypy.interpreter.pytraceback import PyTraceback
+        tb = self._application_traceback
+        if tb is not None and isinstance(tb, PyTraceback):
+            tb.frame.mark_as_escaped()
+        return tb
 
     def set_traceback(self, traceback):
         """Set the current traceback."""
diff --git a/pypy/interpreter/executioncontext.py 
b/pypy/interpreter/executioncontext.py
--- a/pypy/interpreter/executioncontext.py
+++ b/pypy/interpreter/executioncontext.py
@@ -74,6 +74,15 @@
         finally:
             frame_vref = self.topframeref
             self.topframeref = frame.f_backref
+            if frame.escaped or got_exception:
+                # if this frame escaped to applevel, we must ensure that also
+                # f_back does
+                f_back = frame.f_backref()
+                if f_back:
+                    f_back.mark_as_escaped()
+                # force the frame (from the JIT point of view), so that it can
+                # be accessed also later
+                frame_vref()
             jit.virtual_ref_finish(frame_vref, frame)
 
     # ________________________________________________________________
diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py
--- a/pypy/interpreter/pyframe.py
+++ b/pypy/interpreter/pyframe.py
@@ -65,6 +65,7 @@
     last_exception           = None
     f_backref                = jit.vref_None
     
+    escaped                  = False  # see mark_as_escaped()
     debugdata                = None
 
     pycode = None # code object executed by that frame
@@ -151,6 +152,15 @@
         assert isinstance(cell, Cell)
         return cell
 
+    def mark_as_escaped(self):
+        """
+        Must be called on frames that are exposed to applevel, e.g. by
+        sys._getframe().  This ensures that the virtualref holding the frame
+        is properly forced by ec.leave(), and thus the frame will be still
+        accessible even after the corresponding C stack died.
+        """
+        self.escaped = True
+
     def append_block(self, block):
         assert block.previous is self.lastblock
         self.lastblock = block
diff --git a/pypy/module/sys/vm.py b/pypy/module/sys/vm.py
--- a/pypy/module/sys/vm.py
+++ b/pypy/module/sys/vm.py
@@ -37,6 +37,7 @@
             raise OperationError(space.w_ValueError,
                                  space.wrap("call stack is not deep enough"))
         if depth == 0:
+            f.mark_as_escaped()
             return space.wrap(f)
         depth -= 1
         f = ec.getnextframe_nohidden(f)
diff --git a/rpython/rlib/jit.py b/rpython/rlib/jit.py
--- a/rpython/rlib/jit.py
+++ b/rpython/rlib/jit.py
@@ -475,6 +475,8 @@
     def __call__(self):
         if self._state == 'non-forced':
             self._state = 'forced'
+        elif self._state == 'invalid':
+            raise InvalidVirtualRef
         return self._x
 
     @property
@@ -485,7 +487,7 @@
 
     def _finish(self):
         if self._state == 'non-forced':
-            self._state = 'forgotten'
+            self._state = 'invalid'
 
 class DirectJitVRef(DirectVRef):
     def __init__(self, x):
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to