Implement better handling for async for.

Instead of ignoring boilerplate when decompiling `async for`, build the loop semantically by deconstructing the BLK_WHILE -> BLK_CONTAINER -> BLK_TRY that python generates when compiling an `async for` (see https://www.python.org/dev/peps/pep-0492/#asynchronous-iterators-and-async-for).
When reading GET_AITER, convert the BLK_WHILE into a BLK_ASYNCFOR in the same way as a `for` loop.
Ignore GET_ANEXT.
Use END_FINALLY as the trigger to finish building the BLK_ASYNCFOR:
-> Extract the loop variable from the contents of the BLK_TRY.
-> Throw away the BLK_TRY and BLK_CONTAINER, leave the BLK_ASYNCFOR on top of the stack.
This commit is contained in:
Aralox
2020-10-21 19:32:20 +11:00
parent 8933c9a4a9
commit 91a23f914d
5 changed files with 67 additions and 128 deletions

View File

@@ -514,17 +514,9 @@ private:
bool m_negative;
};
namespace Pyc { enum Opcode : int; }
class ASTIterBlock : public ASTBlock {
public:
static const std::vector<Pyc::Opcode> ASYNCFOR_BOILERPLATE;
static const int ASYNCFOR_BOILER_READLOOPINDEX;
static const int ASYNCFOR_BOILER_READLOOPCONTENTS;
static const int ASYNCFOR_BOILER_OFFSETFROMEND;
static const int ASYNCFOR_BOILER_FIRSTJUMP;
static const Pyc::Opcode ASYNCFOR_BOILER_ALTJUMPOP;
ASTIterBlock(ASTBlock::BlkType blktype, int end, PycRef<ASTNode> iter)
: ASTBlock(blktype, end), m_iter(std::move(iter)), m_idx(), m_comp() { }