[pypy-svn] r75534 - in pypy/branch/fast-forward/pypy/interpreter: . astcompiler

benjamin at codespeak.net benjamin at codespeak.net
Wed Jun 23 21:30:34 CEST 2010


Author: benjamin
Date: Wed Jun 23 21:30:30 2010
New Revision: 75534

Modified:
   pypy/branch/fast-forward/pypy/interpreter/astcompiler/assemble.py
   pypy/branch/fast-forward/pypy/interpreter/astcompiler/codegen.py
   pypy/branch/fast-forward/pypy/interpreter/pyopcode.py
Log:
implement SETUP_WITH opcode

Modified: pypy/branch/fast-forward/pypy/interpreter/astcompiler/assemble.py
==============================================================================
--- pypy/branch/fast-forward/pypy/interpreter/astcompiler/assemble.py	(original)
+++ pypy/branch/fast-forward/pypy/interpreter/astcompiler/assemble.py	Wed Jun 23 21:30:30 2010
@@ -314,7 +314,8 @@
                 if jump_op == ops.FOR_ITER:
                     target_depth -= 2
                 elif (jump_op == ops.SETUP_FINALLY or
-                      jump_op == ops.SETUP_EXCEPT):
+                      jump_op == ops.SETUP_EXCEPT or
+                      jump_op == ops.SETUP_WITH):
                     target_depth += 3
                     if target_depth > max_depth:
                         max_depth = target_depth
@@ -500,6 +501,7 @@
     ops.WITH_CLEANUP : -1,
     ops.POP_BLOCK : 0,
     ops.END_FINALLY : -3,
+    ops.SETUP_WITH : 1,
     ops.SETUP_FINALLY : 0,
     ops.SETUP_EXCEPT : 0,
 

Modified: pypy/branch/fast-forward/pypy/interpreter/astcompiler/codegen.py
==============================================================================
--- pypy/branch/fast-forward/pypy/interpreter/astcompiler/codegen.py	(original)
+++ pypy/branch/fast-forward/pypy/interpreter/astcompiler/codegen.py	Wed Jun 23 21:30:30 2010
@@ -707,35 +707,20 @@
         self.update_position(wih.lineno, True)
         body_block = self.new_block()
         cleanup = self.new_block()
-        exit_storage = self.current_temporary_name()
-        temp_result = None
-        if wih.optional_vars:
-            temp_result = self.current_temporary_name()
         wih.context_expr.walkabout(self)
-        self.emit_op(ops.DUP_TOP)
-        self.emit_op_name(ops.LOAD_ATTR, self.names, "__exit__")
-        self.name_op(exit_storage, ast.Store)
-        self.emit_op_name(ops.LOAD_ATTR, self.names, "__enter__")
-        self.emit_op_arg(ops.CALL_FUNCTION, 0)
-        if wih.optional_vars:
-            self.name_op(temp_result, ast.Store)
-        else:
-            self.emit_op(ops.POP_TOP)
-        self.emit_jump(ops.SETUP_FINALLY, cleanup)
+        self.emit_jump(ops.SETUP_WITH, cleanup)
         self.use_next_block(body_block)
         self.push_frame_block(F_BLOCK_FINALLY, body_block)
         if wih.optional_vars:
-            self.name_op(temp_result, ast.Load)
-            self.name_op(temp_result, ast.Del)
             wih.optional_vars.walkabout(self)
+        else:
+            self.emit_op(ops.POP_TOP)
         self.visit_sequence(wih.body)
         self.emit_op(ops.POP_BLOCK)
         self.pop_frame_block(F_BLOCK_FINALLY, body_block)
         self.load_const(self.space.w_None)
         self.use_next_block(cleanup)
         self.push_frame_block(F_BLOCK_FINALLY_END, cleanup)
-        self.name_op(exit_storage, ast.Load)
-        self.name_op(exit_storage, ast.Del)
         self.emit_op(ops.WITH_CLEANUP)
         self.emit_op(ops.END_FINALLY)
         self.pop_frame_block(F_BLOCK_FINALLY_END, cleanup)

Modified: pypy/branch/fast-forward/pypy/interpreter/pyopcode.py
==============================================================================
--- pypy/branch/fast-forward/pypy/interpreter/pyopcode.py	(original)
+++ pypy/branch/fast-forward/pypy/interpreter/pyopcode.py	Wed Jun 23 21:30:30 2010
@@ -874,25 +874,47 @@
         block = FinallyBlock(self, next_instr + offsettoend)
         self.append_block(block)
 
+    def SETUP_WITH(self, offsettoend, next_instr):
+        w_manager = self.peekvalue()
+        w_descr = self.space.lookup(w_manager, "__exit__")
+        if w_descr is None:
+            raise OperationError(self.space.w_AttributeError,
+                                 self.space.wrap("__exit__"))
+        w_exit = self.space.get(w_descr, w_manager)
+        self.settopvalue(w_exit)
+        w_enter = self.space.lookup(w_manager, "__enter__")
+        if w_enter is None:
+            raise OperationError(self.space.w_AttributeError,
+                                 self.space.wrap("__enter__"))
+        w_result = self.space.get_and_call_function(w_enter, w_manager)
+        block = FinallyBlock(self, next_instr + offsettoend)
+        self.append_block(block)
+        self.pushvalue(w_result)
+
     def WITH_CLEANUP(self, oparg, next_instr):
-        # see comment in END_FINALLY for stack state
-        w_exitfunc = self.popvalue()
-        w_unroller = self.peekvalue(2)
+        self.dropvalues(2)
+        w_unroller = self.popvalue()
         unroller = self.space.interpclass_w(w_unroller)
-        if isinstance(unroller, SApplicationException):
+        w_exit = self.popvalue()
+        is_app_exc = (unroller is not None and
+                      isinstance(unroller, SApplicationException))
+        if is_app_exc:
             operr = unroller.operr
-            w_result = self.space.call_function(w_exitfunc,
-                                                operr.w_type,
-                                                operr.get_w_value(self.space),
-                                                operr.application_traceback)
-            if self.space.is_true(w_result):
-                # __exit__() returned True -> Swallow the exception.
-                self.settopvalue(self.space.w_None, 2)
-        else:
-            self.space.call_function(w_exitfunc,
-                                     self.space.w_None,
-                                     self.space.w_None,
-                                     self.space.w_None)
+            w_type = operr.w_type
+            w_value = operr.get_w_value(self.space)
+            w_tb = self.space.wrap(operr.application_traceback)
+        else:
+            w_type = w_value = w_tb = self.space.w_None
+        w_suppress = self.space.call_function(w_exit, w_type, w_value, w_tb)
+        if is_app_exc and self.space.is_true(w_suppress):
+            self.pushvalue(self.space.w_None)
+            self.pushvalue(self.space.w_None)
+            self.pushvalue(self.space.w_None)
+        else:
+            self.pushvalue(w_unroller)
+            self.pushvalue(w_value)
+            self.pushvalue(w_type)
+        print self.valuestack_w
 
     @jit.unroll_safe
     def call_function(self, oparg, w_star=None, w_starstar=None):



More information about the Pypy-commit mailing list