◐ Shell
clean mode source ↗

bpo-17611: Move unwinding of stack from interpreter to compiler by nascheme · Pull Request #4682 · python/cpython

and others added 22 commits

December 2, 2017 14:06

@nascheme

Behavior is still the same after the bytecode and compiler
changes.
The bytecode changes cause the number of expected returns
to go from 6 to 5.  The last return in the function now gets
eliminated, as it is unreachable.  I believe the SETUP_LOOP
opcode was defeating the peephole optimizer previously.  That's just
a guess though, I don't understand how the peephole optimizer works.

@serhiy-storchaka @nascheme

The argument is not actually used for anything but it makes
more sense to pass 'final' rather than passing 'body'.
If the finally body contains an exit (break or return), don't unwind
the finally body a second time.  That would cause an infinite loop
in the compiler.  We temporarily pop the top block, emit code for
the finally clause and then push the block back on.

At some (hopefully correct) comments explaining what's going on.
When there is a 'return' inside the finally body of a try/finally,
we need to clear the current exception.  If the final body was
entered due to an exception, we also need to pop the EXCEPT_HANDLER
fbock.

pitrou

This is slightly more efficient.  For computing the stack effect
of opcodes, consider PUSH_NO_EXCEPT to use six stack slots so that
the stack will be large enough to handle an exception.

Update dis.rst (with content from PR 5006 by Serhiy).
Fixes problem pointed out by Serhiy:

There is a gap between calling the __enter__ method and the
SETUP_FINALLY instruction. If the exception is raised in the gap,
the __exit__ method will be never called. For example:

    a = []
    with CM() as a[0]: # IndexError
        ...