Author: Antonio Cuni <[email protected]>
Branch: py3k
Changeset: r55008:f9ef9c856d38
Date: 2012-05-09 11:02 +0200
http://bitbucket.org/pypy/pypy/changeset/f9ef9c856d38/
Log: generate the very same code as cpython for try/except blocks. In
particular, make sure to delete the local variable which contains
the exception after we exit the except: block
diff --git a/pypy/interpreter/astcompiler/codegen.py
b/pypy/interpreter/astcompiler/codegen.py
--- a/pypy/interpreter/astcompiler/codegen.py
+++ b/pypy/interpreter/astcompiler/codegen.py
@@ -576,12 +576,50 @@
self.emit_jump(ops.POP_JUMP_IF_FALSE, next_except, True)
self.emit_op(ops.POP_TOP)
if handler.name:
- self.name_op(handler.name, ast.Store);
+ ## generate the equivalent of:
+ ##
+ ## try:
+ ## # body
+ ## except type as name:
+ ## try:
+ ## # body
+ ## finally:
+ ## name = None
+ ## del name
+ #
+ cleanup_end = self.new_block()
+ self.name_op(handler.name, ast.Store)
+ self.emit_op(ops.POP_TOP)
+ # second try
+ self.emit_jump(ops.SETUP_FINALLY, cleanup_end)
+ cleanup_body = self.use_next_block()
+ self.push_frame_block(F_BLOCK_FINALLY, cleanup_body)
+ # second # body
+ self.visit_sequence(handler.body)
+ self.emit_op(ops.POP_BLOCK)
+ self.emit_op(ops.POP_EXCEPT)
+ self.pop_frame_block(F_BLOCK_FINALLY, cleanup_body)
+ # finally
+ self.load_const(self.space.w_None)
+ self.use_next_block(cleanup_end)
+ self.push_frame_block(F_BLOCK_FINALLY_END, cleanup_end)
+ # name = None
+ self.load_const(self.space.w_None)
+ self.name_op(handler.name, ast.Store)
+ # del name
+ self.name_op(handler.name, ast.Del)
+ #
+ self.emit_op(ops.END_FINALLY)
+ self.pop_frame_block(F_BLOCK_FINALLY_END, cleanup_end)
else:
self.emit_op(ops.POP_TOP)
- self.emit_op(ops.POP_TOP)
- self.visit_sequence(handler.body)
- self.emit_op(ops.POP_EXCEPT)
+ self.emit_op(ops.POP_TOP)
+ cleanup_body = self.use_next_block()
+ self.push_frame_block(F_BLOCK_FINALLY, cleanup_body)
+ self.visit_sequence(handler.body)
+ self.emit_op(ops.POP_EXCEPT)
+ self.pop_frame_block(F_BLOCK_FINALLY, cleanup_body)
+ #
self.emit_jump(ops.JUMP_FORWARD, end)
self.use_next_block(next_except)
self.emit_op(ops.END_FINALLY)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit