diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2018-03-23 12:34:35 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-03-23 12:34:35 (GMT) |
commit | 702f8f3611bc49b73772cce2b9b041bd11ff9b35 (patch) | |
tree | f712f53a42dc54831e7daf7e3686bc9c875b37b3 /Objects/frameobject.c | |
parent | c65bf3fe4a2bde424b79e350f36b7aaa3f6476f6 (diff) | |
download | cpython-702f8f3611bc49b73772cce2b9b041bd11ff9b35.zip cpython-702f8f3611bc49b73772cce2b9b041bd11ff9b35.tar.gz cpython-702f8f3611bc49b73772cce2b9b041bd11ff9b35.tar.bz2 |
bpo-33041: Rework compiling an "async for" loop. (#6142)
* Added new opcode END_ASYNC_FOR.
* Setting global StopAsyncIteration no longer breaks "async for" loops.
* Jumping into an "async for" loop is now disabled.
* Jumping out of an "async for" loop no longer corrupts the stack.
* Simplify the compiler.
Diffstat (limited to 'Objects/frameobject.c')
-rw-r--r-- | Objects/frameobject.c | 21 |
1 files changed, 9 insertions, 12 deletions
diff --git a/Objects/frameobject.c b/Objects/frameobject.c index 643be08..9d37935 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -100,8 +100,7 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno) int line = 0; /* (ditto) */ int addr = 0; /* (ditto) */ int delta_iblock = 0; /* Scanning the SETUPs and POPs */ - int for_loop_delta = 0; /* (ditto) */ - int delta; + int delta = 0; int blockstack[CO_MAXBLOCKS]; /* Walking the 'finally' blocks */ int blockstack_top = 0; /* (ditto) */ @@ -256,14 +255,16 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno) return -1; } if (first_in && !second_in) { - if (op == FOR_ITER && !delta_iblock) { - for_loop_delta++; - } - if (op != FOR_ITER) { + if (op != FOR_ITER && code[target_addr] != END_ASYNC_FOR) { delta_iblock++; } + else if (!delta_iblock) { + /* Pop the iterators of any 'for' and 'async for' loop + * we're jumping out of. */ + delta++; + } } - if (op != FOR_ITER) { + if (op != FOR_ITER && code[target_addr] != END_ASYNC_FOR) { blockstack[blockstack_top++] = target_addr; } break; @@ -289,11 +290,10 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno) assert(blockstack_top == 0); /* Pop any blocks that we're jumping out of. */ - delta = 0; if (delta_iblock > 0) { f->f_iblock -= delta_iblock; PyTryBlock *b = &f->f_blockstack[f->f_iblock]; - delta = (f->f_stacktop - f->f_valuestack) - b->b_level; + delta += (f->f_stacktop - f->f_valuestack) - b->b_level; if (b->b_type == SETUP_FINALLY && code[b->b_handler] == WITH_CLEANUP_START) { @@ -301,9 +301,6 @@ frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno) delta++; } } - /* Pop the iterators of any 'for' loop we're jumping out of. */ - delta += for_loop_delta; - while (delta > 0) { PyObject *v = (*--f->f_stacktop); Py_DECREF(v); |