[pypy-commit] pypy py3.5-async: Implement visit_AsyncFor in codegen

raffael_t pypy.commits at gmail.com
Thu Jul 7 15:40:10 EDT 2016


Author: Raffael Tfirst <raffael.tfirst at gmail.com>
Branch: py3.5-async
Changeset: r85604:d67ac6d8fc48
Date: 2016-07-07 21:39 +0200
http://bitbucket.org/pypy/pypy/changeset/d67ac6d8fc48/

Log:	Implement visit_AsyncFor in codegen

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
@@ -565,6 +565,60 @@
         self.pop_frame_block(F_BLOCK_LOOP, start)
         self.visit_sequence(fr.orelse)
         self.use_next_block(end)
+    
+    def visit_AsyncFor(self, fr):
+        self.update_position(fr.lineno, True)
+        b_try = self.new_block()
+        b_except = self.new_block()
+        b_end = self.new_block()
+        b_after_try = self.new_block()
+        b_try_cleanup = self.new_block()
+        b_after_loop = self.new_block()
+        b_after_loop_else = self.new_block()
+        self.emit_jump(ops.SETUP_LOOP, b_after_loop)
+        self.push_frame_block(F_BLOCK_LOOP, b_try)
+        fr.iter.walkabout(self)
+        self.emit_op(ops.GET_AITER)
+        self.load_const(self.space.w_None)
+        self.emit_op(ops.YIELD_FROM)
+        self.use_next_block(b_try)
+        # This adds another line, so each for iteration can be traced.
+        self.lineno_set = False
+        self.emit_jump(ops.SETUP_EXCEPT, b_except)
+        self.push_frame_block(F_BLOCK_EXCEPT, b_try)
+        self.emit_op(ops.GET_ANEXT)
+        self.load_const(self.space.w_None)
+        self.emit_op(ops.YIELD_FROM)
+        fr.target.walkabout(self)
+        self.emit_op(ops.POP_BLOCK)
+        self.pop_frame_block(F_BLOCK_EXCEPT, b_try)
+        self.emit_jump(ops.JUMP_FORWARD, b_after_try)
+        self.use_next_block(b_except)
+        self.emit_op(ops.POP_TOP)
+        self.emit_op_name(ops.LOAD_GLOBAL, self.names, "StopIterError")
+        self.emit_op_arg(ops.COMPARE_OP, 10)
+        self.emit_jump(ops.POP_JUMP_IF_FALSE, b_try_cleanup, True)
+        
+        self.emit_op(ops.POP_TOP)
+        self.emit_op(ops.POP_TOP)
+        self.emit_op(ops.POP_TOP)
+        self.emit_op(ops.POP_EXCEPT) # for SETUP_EXCEPT
+        self.emit_op(ops.POP_BLOCK) # for SETUP_LOOP
+        self.emit_jump(ops.JUMP_ABSOLUTE, b_after_loop_else, True)
+        
+        self.use_next_block(b_try_cleanup)
+        self.emit_op(ops.END_FINALLY)
+        self.use_next_block(b_after_try)
+        self.visit_sequence(fr.body)
+        self.emit_jump(ops.JUMP_ABSOLUTE, b_try, True)
+        self.emit_op(ops.POP_BLOCK) # for SETUP_LOOP
+        self.pop_frame_block(F_BLOCK_LOOP, b_try)
+        self.use_next_block(b_after_loop)
+        self.emit_jump(ops.JUMP_ABSOLUTE, b_end, True)
+        self.use_next_block(b_after_loop_else)
+        self.visit_sequence(fr.orelse)
+        
+        self.use_next_block(b_end)
 
     def visit_While(self, wh):
         self.update_position(wh.lineno, True)


More information about the pypy-commit mailing list