[pypy-commit] pypy framestate: Replace CONTINUE_LOOP and BREAK_LOOP with jumps in simple cases

rlamy noreply at buildbot.pypy.org
Thu Feb 12 20:27:38 CET 2015


Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: framestate
Changeset: r75839:ed696843831a
Date: 2015-02-12 05:10 +0000
http://bitbucket.org/pypy/pypy/changeset/ed696843831a/

Log:	Replace CONTINUE_LOOP and BREAK_LOOP with jumps in simple cases

diff --git a/rpython/flowspace/bytecode.py b/rpython/flowspace/bytecode.py
--- a/rpython/flowspace/bytecode.py
+++ b/rpython/flowspace/bytecode.py
@@ -221,12 +221,6 @@
             for exit in block._exits:
                 exit.set_blockstack(self.blockstack)
 
-    def unroll(self, signal):
-        while self.blockstack:
-            block = self.blockstack.pop()
-            if isinstance(signal, block.handles):
-                return block
-
     def check_graph(self):
         for b in self.blocks:
             if not b._exits:
@@ -537,9 +531,24 @@
         reader.end_block()
 
     def do_signals(self, reader):
-        from rpython.flowspace.flowcontext import Break
-        frameblock = reader.unroll(Break())
-        reader.curr_block.set_exits([frameblock.handler])
+        block = reader.curr_block
+        assert block.operations[-1] is self
+        del block.operations[-1]
+        from rpython.flowspace.flowcontext import ExceptBlock, FinallyBlock
+        while reader.blockstack:
+            context = reader.blockstack.pop()
+            if isinstance(context, ExceptBlock):
+                block.operations.append(POP_BLOCK(-1, self.offset))
+            elif isinstance(context, FinallyBlock):
+                block.operations.append(self)
+                block.set_exits([context.handler])
+                return
+            else:  # LoopBlock
+                block.operations.append(POP_BLOCK(-1, self.offset))
+                block.set_exits([context.handler])
+                return
+        raise BytecodeCorruption(
+            "A break statement should not escape from the function")
 
     def eval(self, ctx):
         from rpython.flowspace.flowcontext import Break
@@ -550,6 +559,27 @@
     def bc_flow(self, reader):
         reader.curr_block.operations.append(self)
         self.target = reader.get_block_at(self.arg)
+        reader.end_block()
+
+    def do_signals(self, reader):
+        block = reader.curr_block
+        assert block.operations[-1] is self
+        del block.operations[-1]
+        from rpython.flowspace.flowcontext import ExceptBlock, FinallyBlock
+        while reader.blockstack:
+            context = reader.blockstack.pop()
+            if isinstance(context, ExceptBlock):
+                block.operations.append(POP_BLOCK(-1, self.offset))
+            elif isinstance(context, FinallyBlock):
+                block.operations.append(self)
+                block.set_exits([context.handler])
+                return
+            else:  # LoopBlock
+                block.operations.append(POP_BLOCK(-1, self.offset))
+                block.set_exits([self.target])
+                return
+        raise BytecodeCorruption(
+            "A continue statement should not escape from the function")
 
     def eval(self, ctx):
         from rpython.flowspace.flowcontext import Continue


More information about the pypy-commit mailing list