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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit