[pypy-svn] r53913 - pypy/dist/pypy/interpreter

fijal at codespeak.net fijal at codespeak.net
Sun Apr 20 17:33:10 CEST 2008


Author: fijal
Date: Sun Apr 20 17:33:09 2008
New Revision: 53913

Modified:
   pypy/dist/pypy/interpreter/pyopcode.py
Log:
use one class instead of many.


Modified: pypy/dist/pypy/interpreter/pyopcode.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyopcode.py	(original)
+++ pypy/dist/pypy/interpreter/pyopcode.py	Sun Apr 20 17:33:09 2008
@@ -818,15 +818,16 @@
         raise BytecodeCorruption, "old opcode, no longer in use"
 
     def SETUP_LOOP(f, offsettoend, next_instr, *ignored):
-        block = LoopBlock(f, next_instr + offsettoend)
+        #block = LoopBlock(f, next_instr + offsettoend)
+        block = FrameBlock(LOOP, f, next_instr + offsettoend)
         f.blockstack.append(block)
 
     def SETUP_EXCEPT(f, offsettoend, next_instr, *ignored):
-        block = ExceptBlock(f, next_instr + offsettoend)
+        block = FrameBlock(EXCEPT, f, next_instr + offsettoend)
         f.blockstack.append(block)
 
     def SETUP_FINALLY(f, offsettoend, next_instr, *ignored):
-        block = FinallyBlock(f, next_instr + offsettoend)
+        block = FrameBlock(FINALLY, f, next_instr + offsettoend)
         f.blockstack.append(block)
 
     def WITH_CLEANUP(f, *ignored):
@@ -1066,15 +1067,23 @@
         return SContinueLoop(space.int_w(w_jump_to))
     state_pack_variables = staticmethod(state_pack_variables)
 
+LOOP = 0
+EXCEPT = 1
+FINALLY = 2
+
+HANDLING_MASKS = [SBreakLoop.kind | SContinueLoop.kind,
+                  SApplicationException.kind, -1]
 
 class FrameBlock:
 
     """Abstract base class for frame blocks from the blockstack,
     used by the SETUP_XXX and POP_BLOCK opcodes."""
 
-    def __init__(self, frame, handlerposition):
+    def __init__(self, tp, frame, handlerposition):
+        self.tp = tp
         self.handlerposition = handlerposition
         self.valuestackdepth = frame.valuestackdepth
+        self.handling_mask = HANDLING_MASKS[tp]
 
     def __eq__(self, other):
         return (self.__class__ is other.__class__ and
@@ -1093,6 +1102,9 @@
     def cleanup(self, frame):
         "Clean up a frame when we normally exit the block."
         self.cleanupstack(frame)
+        if self.tp == FINALLY:
+            frame.pushvalue(frame.space.w_None)
+            frame.pushvalue(frame.space.w_None)
 
     # internal pickling interface, not using the standard protocol
     def _get_state_(self, space):
@@ -1105,9 +1117,46 @@
         return hint(next_instr, promote=True)
 
     def really_handle(self, frame, unroller):
-        """ Purely abstract method
-        """
-        raise NotImplementedError
+        if self.tp == LOOP:
+            if isinstance(unroller, SContinueLoop):
+                # re-push the loop block without cleaning up the value stack,
+                # and jump to the beginning of the loop, stored in the
+                # exception's argument
+                frame.blockstack.append(self)
+                return unroller.jump_to
+            else:
+                # jump to the end of the loop
+                self.cleanupstack(frame)
+                return self.handlerposition
+        elif self.tp == EXCEPT:
+            # push the exception to the value stack for inspection by the
+            # exception handler (the code after the except:)
+            self.cleanupstack(frame)
+            assert isinstance(unroller, SApplicationException)
+            operationerr = unroller.operr
+            if frame.space.full_exceptions:
+                operationerr.normalize_exception(frame.space)
+            # the stack setup is slightly different than in CPython:
+            # instead of the traceback, we store the unroller object,
+            # wrapped.
+            frame.pushvalue(frame.space.wrap(unroller))
+            frame.pushvalue(operationerr.w_value)
+            frame.pushvalue(operationerr.w_type)
+            return self.handlerposition   # jump to the handler
+        else:
+            # any abnormal reason for unrolling a finally: triggers the end of
+            # the block unrolling and the entering the finally: handler.
+            # see comments in cleanup().
+            self.cleanupstack(frame)
+            frame.pushvalue(frame.space.wrap(unroller))
+            frame.pushvalue(frame.space.w_None)
+            frame.pushvalue(frame.space.w_None)
+            return self.handlerposition   # jump to the handler            
+
+    #def really_handle(self, frame, unroller):
+    #    """ Purely abstract method
+    #    """
+    #    raise NotImplementedError
 
 class LoopBlock(FrameBlock):
     """A loop block.  Stores the end-of-loop pointer in case of 'break'."""



More information about the Pypy-commit mailing list