mirror of
https://github.com/python/cpython.git
synced 2025-08-30 05:35:08 +00:00
Produce cleaner bytecode for 'with' and 'async with' by generating separate code for normal and exceptional paths. (#6641)
Remove BEGIN_FINALLY, END_FINALLY, CALL_FINALLY and POP_FINALLY bytecodes. Implement finally blocks by code duplication. Reimplement frame.lineno setter using line numbers rather than bytecode offsets.
This commit is contained in:
parent
5dcc06f6e0
commit
fee552669f
15 changed files with 4789 additions and 4754 deletions
|
@ -198,7 +198,6 @@ markblocks(_Py_CODEUNIT *code, Py_ssize_t len)
|
|||
case SETUP_FINALLY:
|
||||
case SETUP_WITH:
|
||||
case SETUP_ASYNC_WITH:
|
||||
case CALL_FINALLY:
|
||||
j = GETJUMPTGT(code, i);
|
||||
assert(j < len);
|
||||
blocks[j] = 1;
|
||||
|
@ -432,14 +431,10 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
|
|||
/* Remove unreachable ops after RETURN */
|
||||
case RETURN_VALUE:
|
||||
h = i + 1;
|
||||
/* END_FINALLY should be kept since it denotes the end of
|
||||
the 'finally' block in frame_setlineno() in frameobject.c.
|
||||
SETUP_FINALLY should be kept for balancing.
|
||||
*/
|
||||
while (h < codelen && ISBASICBLOCK(blocks, i, h) &&
|
||||
_Py_OPCODE(codestr[h]) != END_FINALLY)
|
||||
while (h < codelen && ISBASICBLOCK(blocks, i, h))
|
||||
{
|
||||
if (_Py_OPCODE(codestr[h]) == SETUP_FINALLY) {
|
||||
/* Leave SETUP_FINALLY and RERAISE in place to help find block limits. */
|
||||
if (_Py_OPCODE(codestr[h]) == SETUP_FINALLY || _Py_OPCODE(codestr[h]) == RERAISE) {
|
||||
while (h > i + 1 &&
|
||||
_Py_OPCODE(codestr[h - 1]) == EXTENDED_ARG)
|
||||
{
|
||||
|
@ -506,7 +501,6 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
|
|||
case SETUP_FINALLY:
|
||||
case SETUP_WITH:
|
||||
case SETUP_ASYNC_WITH:
|
||||
case CALL_FINALLY:
|
||||
j = blocks[j / sizeof(_Py_CODEUNIT) + i + 1] - blocks[i] - 1;
|
||||
j *= sizeof(_Py_CODEUNIT);
|
||||
break;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue