[pypy-commit] pypy py3.6: copy slightly lengthy test from cpython to find the (crashing) bug in set_lineno

cfbolz pypy.commits at gmail.com
Thu Feb 21 05:35:09 EST 2019


Author: Carl Friedrich Bolz-Tereick <cfbolz at gmx.de>
Branch: py3.6
Changeset: r96120:1d06586fec74
Date: 2019-02-21 11:26 +0100
http://bitbucket.org/pypy/pypy/changeset/1d06586fec74/

Log:	copy slightly lengthy test from cpython to find the (crashing) bug
	in set_lineno

diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py
--- a/pypy/interpreter/pyframe.py
+++ b/pypy/interpreter/pyframe.py
@@ -739,6 +739,7 @@
         delta_iblock = min_delta_iblock = 0    # see below for comment
         addr = min_addr
         while addr < max_addr:
+            assert addr & 1 == 0
             op = ord(code[addr])
 
             if op in (SETUP_LOOP, SETUP_EXCEPT, SETUP_FINALLY, SETUP_WITH,
@@ -749,10 +750,7 @@
                 if delta_iblock < min_delta_iblock:
                     min_delta_iblock = delta_iblock
 
-            if op >= HAVE_ARGUMENT:
-                addr += 3
-            else:
-                addr += 1
+            addr += 2
 
         # 'min_delta_iblock' is <= 0; its absolute value is the number of
         # blocks we exit.  'go_iblock' is the delta number of blocks
diff --git a/pypy/interpreter/test/test_pyframe.py b/pypy/interpreter/test/test_pyframe.py
--- a/pypy/interpreter/test/test_pyframe.py
+++ b/pypy/interpreter/test/test_pyframe.py
@@ -179,6 +179,61 @@
                         ('return', 5)]
         """
 
+    def test_set_lineno_jump_out_of_block(self):
+        import sys
+        class JumpTracer:
+            def __init__(self, function):
+                self.function = function
+                self.jumpFrom = function.jump[0]
+                self.jumpTo = function.jump[1]
+                self.done = False
+
+            def trace(self, frame, event, arg):
+                if not self.done and frame.f_code == self.function.__code__:
+                    firstLine = frame.f_code.co_firstlineno
+                    if event == 'line' and frame.f_lineno == firstLine + self.jumpFrom:
+                        # Cope with non-integer self.jumpTo (because of
+                        # no_jump_to_non_integers below).
+                        try:
+                            frame.f_lineno = firstLine + self.jumpTo
+                        except TypeError:
+                            frame.f_lineno = self.jumpTo
+                        self.done = True
+                return self.trace
+
+        def run_test(func):
+            tracer = JumpTracer(func)
+            sys.settrace(tracer.trace)
+            output = []
+            func(output)
+            sys.settrace(None)
+            assert func.output == output
+
+        # copied from cpython test suite
+        def jump_out_of_block_forwards(output):
+            for i in 1, 2:
+                output.append(2)
+                for j in [3]:  # Also tests jumping over a block
+                    output.append(4)
+            output.append(5)
+
+        jump_out_of_block_forwards.jump = (3, 5)
+        jump_out_of_block_forwards.output = [2, 5]
+        #run_test(jump_out_of_block_forwards)
+
+        def jump_out_of_block_backwards(output):
+            output.append(1)
+            for i in [1]:
+                output.append(3)
+                for j in [2]:  # Also tests jumping over a block
+                    output.append(5)
+                output.append(6)
+            output.append(7)
+
+        jump_out_of_block_backwards.jump = (6, 1)
+        jump_out_of_block_backwards.output = [1, 3, 5, 1, 3, 5, 6, 7]
+        run_test(jump_out_of_block_backwards)
+
     def test_f_back(self):
         import sys
         def f():


More information about the pypy-commit mailing list