Skip to content

Commit 1535786

Browse files
committed
Tidy up compile.c
1 parent fc35844 commit 1535786

File tree

3 files changed

+2810
-2807
lines changed

3 files changed

+2810
-2807
lines changed

Python/compile.c

Lines changed: 49 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1520,17 +1520,29 @@ fblock_unwind_finally_try(struct compiler *c, struct fblockinfo *info, int prese
15201520
return 1;
15211521
}
15221522

1523+
static int
1524+
compiler_call_exit_with_nones(struct compiler *c) {
1525+
PyObject *three_nones = PyTuple_Pack(3, Py_None, Py_None, Py_None);
1526+
if (three_nones == NULL) {
1527+
return 0;
1528+
}
1529+
ADDOP_O(c, LOAD_CONST, three_nones, consts);
1530+
ADDOP_I(c, CALL_FUNCTION_EX, 0);
1531+
Py_DECREF(three_nones);
1532+
return 1;
1533+
}
1534+
1535+
15231536
static int
15241537
fblock_unwind_async_with(struct compiler *c, struct fblockinfo *info, int preserve_tos)
15251538
{
15261539
ADDOP(c, POP_BLOCK);
15271540
if (preserve_tos)
15281541
ADDOP(c, ROT_TWO);
15291542
/* await __exit__(None, None, None) */
1530-
ADDOP_O(c, LOAD_CONST, Py_None, consts);
1531-
ADDOP(c, DUP_TOP);
1532-
ADDOP(c, DUP_TOP);
1533-
ADDOP_I(c, CALL_FUNCTION, 3);
1543+
if (!compiler_call_exit_with_nones(c)) {
1544+
return 0;
1545+
}
15341546
ADDOP(c, GET_AWAITABLE);
15351547
ADDOP_O(c, LOAD_CONST, Py_None, consts);
15361548
ADDOP(c, YIELD_FROM);
@@ -1569,10 +1581,9 @@ fblock_unwind_with(struct compiler *c, struct fblockinfo *info, int preserve_tos
15691581
if (preserve_tos)
15701582
ADDOP(c, ROT_TWO);
15711583
/* call __exit__(None, None, None) */
1572-
ADDOP_O(c, LOAD_CONST, Py_None, consts);
1573-
ADDOP(c, DUP_TOP);
1574-
ADDOP(c, DUP_TOP);
1575-
ADDOP_I(c, CALL_FUNCTION, 3);
1584+
if (!compiler_call_exit_with_nones(c)) {
1585+
return 0;
1586+
}
15761587
ADDOP(c, POP_TOP);
15771588
return 1;
15781589
}
@@ -2658,14 +2669,16 @@ compiler_continue(struct compiler *c)
26582669

26592670
/* Code generated for "try: <body> finally: <finalbody>" is as follows:
26602671
2661-
SETUP_EXCEPT F2
2672+
SETUP_EXCEPT F1
26622673
<code for body>
26632674
POP_BLOCK
2664-
F1:
2665-
<code for finalbody>
2666-
JUMP_ABSOLUTE EXIT
2675+
LOAD_ADDR EXIT
2676+
JUMP_FORWARD F2
2677+
F1: LOAD_ADDR R
26672678
F2:
26682679
<code for finalbody>
2680+
END_FINALLY
2681+
R:
26692682
RERAISE
26702683
EXIT:
26712684
@@ -2681,6 +2694,10 @@ compiler_continue(struct compiler *c)
26812694
Pops en entry from the block stack, and pops the value
26822695
stack until its level is the same as indicated on the
26832696
block stack. (The label is ignored.)
2697+
LOAD_ADDR:
2698+
Pushes the given address (as an integer) to the value stack.
2699+
END_FINALLY:
2700+
Jumps to the address currently on the top of the value stack.
26842701
RERAISE:
26852702
Pops 3 entries from the *value* stack and re-raises the exception
26862703
they specify.
@@ -2725,13 +2742,12 @@ compiler_try_finally(struct compiler *c, stmt_ty s)
27252742
compiler_use_next_block(c, final1);
27262743

27272744
ADDOP_JREL(c, LOAD_ADDR, exit);
2728-
ADDOP_JABS(c, JUMP_ABSOLUTE, finalbody);
2745+
ADDOP_JREL(c, JUMP_FORWARD, finalbody);
27292746

27302747
/* Jump to `finally` block for exceptional outcome */
27312748
compiler_use_next_block(c, final2);
27322749
c->u->u_lineno_set = 0;
27332750
ADDOP_JREL(c, LOAD_ADDR, reraise);
2734-
ADDOP_JABS(c, JUMP_ABSOLUTE, finalbody);
27352751

27362752
/* Actual code for `finally` block */
27372753
if (!compiler_push_finally_end(c, finalbody))
@@ -2858,8 +2874,7 @@ compiler_try_except(struct compiler *c, stmt_ty s)
28582874
compiler_nameop(c, handler->v.ExceptHandler.name, Del);
28592875
ADDOP_JREL(c, JUMP_FORWARD, end);
28602876

2861-
/* finally: */
2862-
ADDOP_O(c, LOAD_CONST, Py_None, consts);
2877+
/* cleanup: */
28632878
compiler_use_next_block(c, cleanup_end);
28642879
if (!compiler_push_finally_end(c, cleanup_end))
28652880
return 0;
@@ -4390,18 +4405,6 @@ expr_constant(expr_ty e)
43904405
return -1;
43914406
}
43924407

4393-
static int
4394-
compiler_call_exit_with_nones(struct compiler *c) {
4395-
PyObject *three_nones = PyTuple_Pack(3, Py_None, Py_None, Py_None);
4396-
if (three_nones == NULL) {
4397-
return 0;
4398-
}
4399-
ADDOP_O(c, LOAD_CONST, three_nones, consts);
4400-
ADDOP_I(c, CALL_FUNCTION_EX, 0);
4401-
Py_DECREF(three_nones);
4402-
return 1;
4403-
}
4404-
44054408
static int
44064409
compiler_with_except_finish(struct compiler *c) {
44074410
basicblock *exit;
@@ -4529,25 +4532,27 @@ compiler_async_with(struct compiler *c, stmt_ty s, int pos)
45294532
/*
45304533
Implements the with statement from PEP 343.
45314534
4532-
The semantics outlined in that PEP are as follows:
4533-
45344535
with EXPR as VAR:
45354536
BLOCK
45364537
4537-
It is implemented roughly as:
4538+
is implemented as:
4539+
4540+
<code for EXPR>
4541+
ENTER_WITH
4542+
SETUP_WITH E
4543+
<code to store to VAR> or POP_TOP
4544+
<code for BLOCK>
4545+
LOAD_CONST (None, None, None)
4546+
CALL_FUNCTION_EX 0
4547+
JUMP_FORWARD EXIT
4548+
E: WITH_EXCEPT_START (calls EXPR.__exit__)
4549+
POP_JUMP_IF_TRUE T:
4550+
RERAISE
4551+
T: POP_TOP * 3 (remove exception from stack)
4552+
POP_EXCEPT
4553+
POP_TOP
4554+
EXIT:
45384555
4539-
context = EXPR
4540-
exit = context.__exit__ # not calling it
4541-
value = context.__enter__()
4542-
try:
4543-
VAR = value # if VAR present in the syntax
4544-
BLOCK
4545-
finally:
4546-
if an exception was raised:
4547-
exc = copy of (exception, instance, traceback)
4548-
else:
4549-
exc = (None, None, None)
4550-
exit(*exc)
45514556
*/
45524557

45534558
static int
@@ -4604,7 +4609,7 @@ compiler_with(struct compiler *c, stmt_ty s, int pos)
46044609
return 0;
46054610
ADDOP(c, POP_TOP);
46064611
compiler_pop_fblock(c, FINALLY_END, final1);
4607-
ADDOP_JABS(c, JUMP_ABSOLUTE, exit);
4612+
ADDOP_JREL(c, JUMP_FORWARD, exit);
46084613

46094614
/* `finally` block for exceptional outcome */
46104615
compiler_use_next_block(c, final2);

0 commit comments

Comments
 (0)