From: Andreas Löscher on
Hi,
I am not sure if this is the right newsgroup, so if not don't hesitate
to tell me.

I am developed a Python to C compiler, so that Byte Code files
automatically can be translated into C Extension Modules. (And it works
pretty well --> http://www.coremountains.com/products/bytecoat/)

While developing, I found something strange concerning the YIELD_VALUE
OpCode.

Since Python Version 2.5 it behaves the following:
1. pop yield value from stack and return it to
a former gen_send_ex() call from Objects/genobject.c

2. push the yield value on the stack in gen_send_ex() and return it

3. when the generator is executed again, the yield value is
'poped' from the stack again with the POP_TOP opcode

Now I found that a little strange:
1. why is the value removed from the stack, than pushed on the
stack to remove it finally again? the combination of
YIELD_VALUE and TOP_POP seems hard coded in compile.c
which means that a TOP_POP follows every YIELD_VALUE
TOP_POP

2. If the semantic of the YIELD_VALUE OpCode has changed, why
is this reached by using another function? Such thing
should be done in the OpCode.

(e.a.: instead of retval = POP()
--> retval = TOP(); Py_INCREF(retval); )


I am a little confused about this.

Best,
Andreas

From: Terry Reedy on
Andreas Löscher wrote:
> Hi,
> I am not sure if this is the right newsgroup, so if not don't hesitate
> to tell me.

Since there is no CPython internals list, this is the right place to
start, even though you might end up having to post a slightly off-topic
query to python-devel just to get the attention of whoever has the
answer. But there are a few deveoopers who read and post here also.

> I am developed a Python to C compiler, so that Byte Code files
> automatically can be translated into C Extension Modules. (And it works
> pretty well --> http://www.coremountains.com/products/bytecoat/)
>
> While developing, I found something strange concerning the YIELD_VALUE
> OpCode.
>
> Since Python Version 2.5 it behaves the following:
> 1. pop yield value from stack and return it to
> a former gen_send_ex() call from Objects/genobject.c
>
> 2. push the yield value on the stack in gen_send_ex() and return it
>
> 3. when the generator is executed again, the yield value is
> 'poped' from the stack again with the POP_TOP opcode
>
> Now I found that a little strange:
> 1. why is the value removed from the stack, than pushed on the
> stack to remove it finally again? the combination of
> YIELD_VALUE and TOP_POP seems hard coded in compile.c
> which means that a TOP_POP follows every YIELD_VALUE
> TOP_POP
>
> 2. If the semantic of the YIELD_VALUE OpCode has changed, why
> is this reached by using another function? Such thing
> should be done in the OpCode.
>
> (e.a.: instead of retval = POP()
> --> retval = TOP(); Py_INCREF(retval); )
>
> I am a little confused about this.

I suspect that what you see reflects the 2.5 change of 'yield x' from a
statement to an expression to enable gen.send(). It is possible that
someone did the simplest thing that worked, rather than properly
rewriting the code. Or maybe the trickery is needed. You can always try
a simplyfing patch against the test suite and even submit it if it passes.

Terry Jan Reedy


From: greg on
Andreas Löscher wrote:
> Since Python Version 2.5 it behaves the following:
> 1. pop yield value from stack and return it to
> a former gen_send_ex() call from Objects/genobject.c
>
> 2. push the yield value on the stack in gen_send_ex() and return

Are you sure about that? I would expect the value pushed to
be the one sent back into the generator using a send() call
if any, or None if the generator is resumed using next()
rather than send().

> 3. when the generator is executed again, the yield value is
> 'poped' from the stack again with the POP_TOP opcode

This will happen if the result of the yield expression is
not used for anything in the Python code.

--
Greg
 | 
Pages: 1
Prev: mySQL access speed
Next: ast manipulation