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.
This commit is contained in:
Serhiy Storchaka 2018-03-23 14:34:35 +02:00 committed by GitHub
parent c65bf3fe4a
commit 702f8f3611
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 276 additions and 226 deletions

View file

@ -1944,6 +1944,26 @@ main_loop:
}
}
TARGET(END_ASYNC_FOR) {
PyObject *exc = POP();
assert(PyExceptionClass_Check(exc));
if (PyErr_GivenExceptionMatches(exc, PyExc_StopAsyncIteration)) {
PyTryBlock *b = PyFrame_BlockPop(f);
assert(b->b_type == EXCEPT_HANDLER);
Py_DECREF(exc);
UNWIND_EXCEPT_HANDLER(b);
Py_DECREF(POP());
JUMPBY(oparg);
FAST_DISPATCH();
}
else {
PyObject *val = POP();
PyObject *tb = POP();
PyErr_Restore(exc, val, tb);
goto exception_unwind;
}
}
TARGET(LOAD_BUILD_CLASS) {
_Py_IDENTIFIER(__build_class__);