Author: Armin Rigo <[email protected]>
Branch: invalidate-virtualrefs
Changeset: r44551:ce4527cbcb3d
Date: 2011-05-27 15:42 +0200
http://bitbucket.org/pypy/pypy/changeset/ce4527cbcb3d/

Log:    merge heads

diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py
--- a/pypy/interpreter/error.py
+++ b/pypy/interpreter/error.py
@@ -261,8 +261,7 @@
         """
         from pypy.interpreter.pytraceback import PyTraceback
         tb = self._application_traceback
-        if tb is not None:
-            assert isinstance(tb, PyTraceback)
+        if tb is not None and isinstance(tb, PyTraceback):
             tb.frame.mark_as_escaped()
         return tb
 
diff --git a/pypy/jit/metainterp/optimizeopt/virtualize.py 
b/pypy/jit/metainterp/optimizeopt/virtualize.py
--- a/pypy/jit/metainterp/optimizeopt/virtualize.py
+++ b/pypy/jit/metainterp/optimizeopt/virtualize.py
@@ -330,18 +330,24 @@
         vrefvalue.setfield(descr_virtual_token, self.getvalue(tokenbox))
 
     def optimize_VIRTUAL_REF_FINISH(self, op):
-        # Set the 'forced' field of the virtual_ref.
-        # In good cases, this is all virtual, so has no effect.
-        # Otherwise, this forces the real object -- but only now, as
-        # opposed to much earlier.  This is important because the object is
-        # typically a PyPy PyFrame, and now is the end of its execution, so
-        # forcing it now does not have catastrophic effects.
+        # This operation is used in two cases.  In normal cases, it
+        # is the end of the frame, and op.getarg(1) is NULL.  In this
+        # case we just clear the vref.virtual_token, because it contains
+        # a stack frame address and we are about to leave the frame.
+        # In that case vref.forced should still be NULL, and remains
+        # NULL; and accessing the frame through the vref later is
+        # *forbidden* and will raise InvalidVirtualRef.
+        #
+        # In the other (uncommon) case, the operation is produced
+        # earlier, because the vref was forced during tracing already.
+        # In this case, op.getarg(1) is the virtual to force, and we
+        # have to store it in vref.forced.
+        #
         vrefinfo = self.optimizer.metainterp_sd.virtualref_info
-        # op.getarg(1) should really never point to null here
-        # - set 'forced' to point to the real object
         seo = self.optimizer.send_extra_operation
 
-        vrefbox, objbox = op.getarglist()
+        # - set 'forced' to point to the real object
+        objbox = op.getarg(1)
         if not self.optimizer.cpu.ts.CONST_NULL.same_constant(objbox):
             seo(ResOperation(rop.SETFIELD_GC, op.getarglist(), None,
                              descr = vrefinfo.descr_forced))
diff --git a/pypy/objspace/trace.py b/pypy/objspace/trace.py
--- a/pypy/objspace/trace.py
+++ b/pypy/objspace/trace.py
@@ -110,10 +110,10 @@
         self.result.append(EnterFrame(frame))
         self.ec.enter(frame)
 
-    def leave(self, frame, w_exitvalue):
+    def leave(self, frame, w_exitvalue, got_exception):
         """ called just after evaluating of a frame is suspended/finished. """
         self.result.append(LeaveFrame(frame))
-        self.ec.leave(frame, w_exitvalue)
+        self.ec.leave(frame, w_exitvalue, got_exception)
 
     def bytecode_trace(self, frame):
         """ called just before execution of a bytecode. """
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to