diff options
author | Irit Katriel <iritkatriel@yahoo.com> | 2020-11-17 19:31:55 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-17 19:31:55 (GMT) |
commit | 48a9c0eb2a3304ea64d1b32fdf9db853d5d8c429 (patch) | |
tree | f6ae1333bc97f35c514718d82baf1409cdb22f52 /Python/compile.c | |
parent | 05a5d697f4f097f37c5c1e2ed0e2338a33c3fb6a (diff) | |
download | cpython-48a9c0eb2a3304ea64d1b32fdf9db853d5d8c429.zip cpython-48a9c0eb2a3304ea64d1b32fdf9db853d5d8c429.tar.gz cpython-48a9c0eb2a3304ea64d1b32fdf9db853d5d8c429.tar.bz2 |
[3.9] bpo-39934: Account for control blocks in 'except' in compiler. (GH-22395) (GH-23303)
* bpo-39934: backport PR 22395 to 3.9
Diffstat (limited to 'Python/compile.c')
-rw-r--r-- | Python/compile.c | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/Python/compile.c b/Python/compile.c index 51af28b..722d52d 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -84,8 +84,8 @@ It's called a frame block to distinguish it from a basic block in the compiler IR. */ -enum fblocktype { WHILE_LOOP, FOR_LOOP, EXCEPT, FINALLY_TRY, FINALLY_END, - WITH, ASYNC_WITH, HANDLER_CLEANUP, POP_VALUE }; +enum fblocktype { WHILE_LOOP, FOR_LOOP, TRY_EXCEPT, FINALLY_TRY, FINALLY_END, + WITH, ASYNC_WITH, HANDLER_CLEANUP, POP_VALUE, EXCEPTION_HANDLER }; struct fblockinfo { enum fblocktype fb_type; @@ -1624,9 +1624,7 @@ compiler_push_fblock(struct compiler *c, enum fblocktype t, basicblock *b, { struct fblockinfo *f; if (c->u->u_nfblocks >= CO_MAXBLOCKS) { - PyErr_SetString(PyExc_SyntaxError, - "too many statically nested blocks"); - return 0; + return compiler_error(c, "too many statically nested blocks"); } f = &c->u->u_fblock[c->u->u_nfblocks++]; f->fb_type = t; @@ -1666,6 +1664,7 @@ compiler_unwind_fblock(struct compiler *c, struct fblockinfo *info, { switch (info->fb_type) { case WHILE_LOOP: + case EXCEPTION_HANDLER: return 1; case FOR_LOOP: @@ -1676,7 +1675,7 @@ compiler_unwind_fblock(struct compiler *c, struct fblockinfo *info, ADDOP(c, POP_TOP); return 1; - case EXCEPT: + case TRY_EXCEPT: ADDOP(c, POP_BLOCK); return 1; @@ -3064,14 +3063,17 @@ compiler_try_except(struct compiler *c, stmt_ty s) return 0; ADDOP_JREL(c, SETUP_FINALLY, except); compiler_use_next_block(c, body); - if (!compiler_push_fblock(c, EXCEPT, body, NULL, NULL)) + if (!compiler_push_fblock(c, TRY_EXCEPT, body, NULL, NULL)) return 0; VISIT_SEQ(c, stmt, s->v.Try.body); ADDOP(c, POP_BLOCK); - compiler_pop_fblock(c, EXCEPT, body); + compiler_pop_fblock(c, TRY_EXCEPT, body); ADDOP_JREL(c, JUMP_FORWARD, orelse); n = asdl_seq_LEN(s->v.Try.handlers); compiler_use_next_block(c, except); + /* Runtime will push a block here, so we need to account for that */ + if (!compiler_push_fblock(c, EXCEPTION_HANDLER, NULL, NULL, NULL)) + return 0; for (i = 0; i < n; i++) { excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET( s->v.Try.handlers, i); @@ -3156,6 +3158,7 @@ compiler_try_except(struct compiler *c, stmt_ty s) } compiler_use_next_block(c, except); } + compiler_pop_fblock(c, EXCEPTION_HANDLER, NULL); ADDOP(c, RERAISE); compiler_use_next_block(c, orelse); VISIT_SEQ(c, stmt, s->v.Try.orelse); |