Skip to content

Commit a239d48

Browse files
committed
Remove DO_NOT_EMIT_BYTECODE macros, so that while loops and if statements conform to PEP 626.
1 parent f5e97b7 commit a239d48

8 files changed

+3485
-3533
lines changed

Lib/test/test_compile.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -728,10 +728,10 @@ def unused_block_while_else():
728728

729729
for func in funcs:
730730
opcodes = list(dis.get_instructions(func))
731-
self.assertEqual(2, len(opcodes))
732-
self.assertEqual('LOAD_CONST', opcodes[0].opname)
733-
self.assertEqual(None, opcodes[0].argval)
734-
self.assertEqual('RETURN_VALUE', opcodes[1].opname)
731+
self.assertLessEqual(len(opcodes), 3)
732+
self.assertEqual('LOAD_CONST', opcodes[-2].opname)
733+
self.assertEqual(None, opcodes[-2].argval)
734+
self.assertEqual('RETURN_VALUE', opcodes[-1].opname)
735735

736736
def test_false_while_loop(self):
737737
def break_in_while():

Lib/test/test_dis.py

Lines changed: 71 additions & 66 deletions
Large diffs are not rendered by default.

Lib/test/test_peepholer.py

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -409,21 +409,6 @@ def f(cond1, cond2):
409409
self.assertLessEqual(len(returns), 6)
410410
self.check_lnotab(f)
411411

412-
def test_elim_jump_after_return2(self):
413-
# Eliminate dead code: jumps immediately after returns can't be reached
414-
def f(cond1, cond2):
415-
while 1:
416-
if cond1: return 4
417-
self.assertNotInBytecode(f, 'JUMP_FORWARD')
418-
# There should be one jump for the while loop.
419-
jumps = [instr for instr in dis.get_instructions(f)
420-
if 'JUMP' in instr.opname]
421-
self.assertEqual(len(jumps), 1)
422-
returns = [instr for instr in dis.get_instructions(f)
423-
if instr.opname == 'RETURN_VALUE']
424-
self.assertLessEqual(len(returns), 2)
425-
self.check_lnotab(f)
426-
427412
def test_make_function_doesnt_bail(self):
428413
def f():
429414
def g()->1+1:

Lib/test/test_sys_settrace.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,8 @@ def basic():
5353
# following that clause?
5454

5555

56-
# Some constructs like "while 0:", "if 0:" or "if 1:...else:..." are optimized
57-
# away. No code # exists for them, so the line numbers skip directly from
58-
# "del x" to "x = 1".
56+
# Some constructs like "while 0:", "if 0:" or "if 1:...else:..." could be optimized
57+
# away. Make sure that those lines aren't skipped.
5958
def arigo_example0():
6059
x = 1
6160
del x
@@ -66,6 +65,7 @@ def arigo_example0():
6665
arigo_example0.events = [(0, 'call'),
6766
(1, 'line'),
6867
(2, 'line'),
68+
(3, 'line'),
6969
(5, 'line'),
7070
(5, 'return')]
7171

@@ -79,6 +79,7 @@ def arigo_example1():
7979
arigo_example1.events = [(0, 'call'),
8080
(1, 'line'),
8181
(2, 'line'),
82+
(3, 'line'),
8283
(5, 'line'),
8384
(5, 'return')]
8485

@@ -94,6 +95,7 @@ def arigo_example2():
9495
arigo_example2.events = [(0, 'call'),
9596
(1, 'line'),
9697
(2, 'line'),
98+
(3, 'line'),
9799
(4, 'line'),
98100
(7, 'line'),
99101
(7, 'return')]
@@ -236,9 +238,13 @@ def tightloop_example():
236238
(1, 'line'),
237239
(2, 'line'),
238240
(3, 'line'),
241+
(4, 'line'),
239242
(5, 'line'),
243+
(4, 'line'),
240244
(5, 'line'),
245+
(4, 'line'),
241246
(5, 'line'),
247+
(4, 'line'),
242248
(5, 'line'),
243249
(5, 'exception'),
244250
(6, 'line'),

Python/compile.c

Lines changed: 26 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ static int compiler_slice(struct compiler *, expr_ty);
228228

229229
static int inplace_binop(operator_ty);
230230
static int are_all_items_const(asdl_expr_seq *, Py_ssize_t, Py_ssize_t);
231-
static int expr_constant(expr_ty);
231+
232232

233233
static int compiler_with(struct compiler *, stmt_ty, int);
234234
static int compiler_async_with(struct compiler *, stmt_ty, int);
@@ -2704,48 +2704,28 @@ static int
27042704
compiler_if(struct compiler *c, stmt_ty s)
27052705
{
27062706
basicblock *end, *next;
2707-
int constant;
27082707
assert(s->kind == If_kind);
27092708
end = compiler_new_block(c);
2710-
if (end == NULL)
2709+
if (end == NULL) {
27112710
return 0;
2712-
2713-
constant = expr_constant(s->v.If.test);
2714-
/* constant = 0: "if 0"
2715-
* constant = 1: "if 1", "if 2", ...
2716-
* constant = -1: rest */
2717-
if (constant == 0) {
2718-
BEGIN_DO_NOT_EMIT_BYTECODE
2719-
VISIT_SEQ(c, stmt, s->v.If.body);
2720-
END_DO_NOT_EMIT_BYTECODE
2721-
if (s->v.If.orelse) {
2722-
VISIT_SEQ(c, stmt, s->v.If.orelse);
2723-
}
2724-
} else if (constant == 1) {
2725-
VISIT_SEQ(c, stmt, s->v.If.body);
2726-
if (s->v.If.orelse) {
2727-
BEGIN_DO_NOT_EMIT_BYTECODE
2728-
VISIT_SEQ(c, stmt, s->v.If.orelse);
2729-
END_DO_NOT_EMIT_BYTECODE
2730-
}
2731-
} else {
2732-
if (asdl_seq_LEN(s->v.If.orelse)) {
2733-
next = compiler_new_block(c);
2734-
if (next == NULL)
2735-
return 0;
2736-
}
2737-
else {
2738-
next = end;
2739-
}
2740-
if (!compiler_jump_if(c, s->v.If.test, next, 0)) {
2711+
}
2712+
if (asdl_seq_LEN(s->v.If.orelse)) {
2713+
next = compiler_new_block(c);
2714+
if (next == NULL) {
27412715
return 0;
27422716
}
2743-
VISIT_SEQ(c, stmt, s->v.If.body);
2744-
if (asdl_seq_LEN(s->v.If.orelse)) {
2745-
ADDOP_JUMP(c, JUMP_FORWARD, end);
2746-
compiler_use_next_block(c, next);
2747-
VISIT_SEQ(c, stmt, s->v.If.orelse);
2748-
}
2717+
}
2718+
else {
2719+
next = end;
2720+
}
2721+
if (!compiler_jump_if(c, s->v.If.test, next, 0)) {
2722+
return 0;
2723+
}
2724+
VISIT_SEQ(c, stmt, s->v.If.body);
2725+
if (asdl_seq_LEN(s->v.If.orelse)) {
2726+
ADDOP_JUMP(c, JUMP_FORWARD, end);
2727+
compiler_use_next_block(c, next);
2728+
VISIT_SEQ(c, stmt, s->v.If.orelse);
27492729
}
27502730
compiler_use_next_block(c, end);
27512731
return 1;
@@ -2842,25 +2822,6 @@ static int
28422822
compiler_while(struct compiler *c, stmt_ty s)
28432823
{
28442824
basicblock *loop, *body, *end, *anchor = NULL;
2845-
int constant = expr_constant(s->v.While.test);
2846-
2847-
if (constant == 0) {
2848-
BEGIN_DO_NOT_EMIT_BYTECODE
2849-
// Push a dummy block so the VISIT_SEQ knows that we are
2850-
// inside a while loop so it can correctly evaluate syntax
2851-
// errors.
2852-
if (!compiler_push_fblock(c, WHILE_LOOP, NULL, NULL, NULL)) {
2853-
return 0;
2854-
}
2855-
VISIT_SEQ(c, stmt, s->v.While.body);
2856-
// Remove the dummy block now that is not needed.
2857-
compiler_pop_fblock(c, WHILE_LOOP, NULL);
2858-
END_DO_NOT_EMIT_BYTECODE
2859-
if (s->v.While.orelse) {
2860-
VISIT_SEQ(c, stmt, s->v.While.orelse);
2861-
}
2862-
return 1;
2863-
}
28642825
loop = compiler_new_block(c);
28652826
body = compiler_new_block(c);
28662827
anchor = compiler_new_block(c);
@@ -2872,15 +2833,16 @@ compiler_while(struct compiler *c, stmt_ty s)
28722833
if (!compiler_push_fblock(c, WHILE_LOOP, loop, end, NULL)) {
28732834
return 0;
28742835
}
2875-
if (constant == -1) {
2876-
if (!compiler_jump_if(c, s->v.While.test, anchor, 0)) {
2877-
return 0;
2878-
}
2836+
if (!compiler_jump_if(c, s->v.While.test, anchor, 0)) {
2837+
return 0;
28792838
}
28802839

28812840
compiler_use_next_block(c, body);
28822841
VISIT_SEQ(c, stmt, s->v.While.body);
2883-
ADDOP_JUMP(c, JUMP_ABSOLUTE, loop);
2842+
SET_LOC(c, s);
2843+
if (!compiler_jump_if(c, s->v.While.test, body, 1)) {
2844+
return 0;
2845+
}
28842846

28852847
compiler_pop_fblock(c, WHILE_LOOP, loop);
28862848

@@ -4791,15 +4753,6 @@ compiler_visit_keyword(struct compiler *c, keyword_ty k)
47914753
Return values: 1 for true, 0 for false, -1 for non-constant.
47924754
*/
47934755

4794-
static int
4795-
expr_constant(expr_ty e)
4796-
{
4797-
if (e->kind == Constant_kind) {
4798-
return PyObject_IsTrue(e->v.Constant.value);
4799-
}
4800-
return -1;
4801-
}
4802-
48034756
static int
48044757
compiler_with_except_finish(struct compiler *c) {
48054758
basicblock *exit;
@@ -6317,8 +6270,8 @@ optimize_basic_block(basicblock *bb, PyObject *consts)
63176270
}
63186271
if (inst->i_target->b_exit && inst->i_target->b_iused <= MAX_COPY_SIZE) {
63196272
basicblock *to_copy = inst->i_target;
6320-
*inst = to_copy->b_instr[0];
6321-
for (i = 1; i < to_copy->b_iused; i++) {
6273+
inst->i_opcode = NOP;
6274+
for (i = 0; i < to_copy->b_iused; i++) {
63226275
int index = compiler_next_instr(bb);
63236276
if (index < 0) {
63246277
return -1;

0 commit comments

Comments
 (0)