[pypy-svn] r78175 - in pypy/trunk/pypy: interpreter objspace/flow

afa at codespeak.net afa at codespeak.net
Thu Oct 21 17:01:39 CEST 2010


Author: afa
Date: Thu Oct 21 17:01:37 2010
New Revision: 78175

Modified:
   pypy/trunk/pypy/interpreter/pyopcode.py
   pypy/trunk/pypy/objspace/flow/flowcontext.py
Log:
Implement the SETUP_WITH opcode for the flow object space running on code compiled by cpython 2.7.
Now all previous tests run on top of cpython 2.5 to 2.7.

The implementation was borrowed from the fast-forward branch, and slightly simplified
to adapt to the RPython type system, which has virtual methods but no __mro__ or special descriptors.
This is why this code is not in pyopcode.py


Modified: pypy/trunk/pypy/interpreter/pyopcode.py
==============================================================================
--- pypy/trunk/pypy/interpreter/pyopcode.py	(original)
+++ pypy/trunk/pypy/interpreter/pyopcode.py	Thu Oct 21 17:01:37 2010
@@ -874,10 +874,9 @@
     def WITH_CLEANUP(self, oparg, next_instr):
         # see comment in END_FINALLY for stack state
         # This opcode changed a lot between CPython versions
-        if self.pycode.magic >= 0xa0df2ef:
+        if (self.pycode.magic >= 0xa0df2ef
             # Implementation since 2.7a0: 62191 (introduce SETUP_WITH)
-            raise NotImplementedError("WITH_CLEANUP for CPython 2.7")
-        elif self.pycode.magic >= 0xa0df2d1:
+            or self.pycode.magic >= 0xa0df2d1):
             # implementation since 2.6a1: 62161 (WITH_CLEANUP optimization)
             self.popvalue()
             self.popvalue()
@@ -1249,10 +1248,18 @@
         frame.pushvalue(frame.space.w_None)
         return self.handlerposition   # jump to the handler
 
+class WithBlock(FinallyBlock):
+
+    def really_handle(self, frame, unroller):
+        if (frame.space.full_exceptions and
+            isinstance(unroller, SApplicationException)):
+            unroller.operr.normalize_exception(frame.space)
+        return FinallyBlock.really_handle(self, frame, unroller)
 
 block_classes = {'SETUP_LOOP': LoopBlock,
                  'SETUP_EXCEPT': ExceptBlock,
-                 'SETUP_FINALLY': FinallyBlock}
+                 'SETUP_FINALLY': FinallyBlock,
+                 'SETUP_WITH': WithBlock}
 
 ### helpers written at the application-level ###
 # Some of these functions are expected to be generally useful if other

Modified: pypy/trunk/pypy/objspace/flow/flowcontext.py
==============================================================================
--- pypy/trunk/pypy/objspace/flow/flowcontext.py	(original)
+++ pypy/trunk/pypy/objspace/flow/flowcontext.py	Thu Oct 21 17:01:37 2010
@@ -478,10 +478,19 @@
 
     # `with` statement
 
-    def SETUP_WITH(self, oparg, next_instr):
-        raise NotImplementedError("SETUP_WITH")
+    def SETUP_WITH(self, offsettoend, next_instr):
+        # A simpler version than the 'real' 2.7 one:
+        # directly call manager.__enter__(), don't use special lookup functions
+        # which are too complex for the flow object space.
+        from pypy.interpreter.pyopcode import WithBlock
+        w_manager = self.peekvalue()
+        w_exit = self.space.getattr(w_manager, self.space.wrap("__exit__"))
+        self.settopvalue(w_exit)
+        w_result = self.space.call_method(w_manager, "__enter__")
+        block = WithBlock(self, next_instr + offsettoend)
+        self.append_block(block)
+        self.pushvalue(w_result)
 
-    
     def make_arguments(self, nargs):
         return ArgumentsForTranslation(self.space, self.peekvalues(nargs))
     def argument_factory(self, *args):



More information about the Pypy-commit mailing list