Don't store yield expressions list as yields can be copied
authorVitja Makarov <vitja.makarov@gmail.com>
Sun, 9 Jan 2011 11:02:48 +0000 (14:02 +0300)
committerVitja Makarov <vitja.makarov@gmail.com>
Sun, 9 Jan 2011 11:02:48 +0000 (14:02 +0300)
Cython/Compiler/Nodes.py
Cython/Compiler/ParseTreeTransforms.py

index 8aedbde4eacdaabbe09b852ecbcf4a33c2ab0759..01ce116dc8c0b791a790368bb62c6b679698f3c7 100644 (file)
@@ -2944,11 +2944,10 @@ class GeneratorBodyDefNode(DefNode):
 
     child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
 
-    def __init__(self, pos=None, name=None, body=None, yields=None):
+    def __init__(self, pos=None, name=None, body=None):
         super(GeneratorBodyDefNode, self).__init__(pos=pos, body=body, name=name, doc=None,
                                                    args=[],
                                                    star_arg=None, starstar_arg=None)
-        self.yields = yields
 
     def declare_generator_body(self, env):
         prefix = env.next_id(env.scope_prefix)
@@ -3030,7 +3029,11 @@ class GeneratorBodyDefNode(DefNode):
         # ----- Generator resume code
         resume_code.putln("switch (%s->%s.resume_label) {" % (Naming.cur_scope_cname, Naming.obj_base_cname));
         resume_code.putln("case 0: goto %s;" % first_run_label)
-        for yield_expr in self.yields:
+
+        from ParseTreeTransforms import YieldNodeCollector
+        collector = YieldNodeCollector()
+        collector.visitchildren(self)
+        for yield_expr in collector.yields:
             resume_code.putln("case %d: goto %s;" % (yield_expr.label_num, yield_expr.label_name));
         resume_code.putln("default: /* CPython raises the right error here */");
         resume_code.put_finish_refcount_context()
index dd038388204137428db27e9410908195277273cf..aeb2c65ffb14377dfc9d66d2d9efc30fe15f8544 100644 (file)
@@ -1332,7 +1332,6 @@ class YieldNodeCollector(TreeVisitor):
         if self.has_return_value:
             error(node.pos, "'yield' outside function")
         self.yields.append(node)
-        node.label_num = len(self.yields)
 
     def visit_ReturnStatNode(self, node):
         if node.value:
@@ -1370,10 +1369,12 @@ class MarkClosureVisitor(CythonTransform):
         collector.visitchildren(node)
 
         if collector.yields:
+            for i, yield_expr in enumerate(collector.yields):
+                yield_expr.label_num = i + 1
+
             gbody = Nodes.GeneratorBodyDefNode(pos=node.pos,
                                                name=node.name,
-                                               body=node.body,
-                                               yields=collector.yields)
+                                               body=node.body)
             generator = Nodes.GeneratorDefNode(pos=node.pos,
                                                name=node.name,
                                                args=node.args,