Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8473cf8

Browse files
authored
bpo-42246: Remove DO_NOT_EMIT_BYTECODE macros, so that while loops and if statements conform to PEP 626. (GH-23743)
1 parent 6f79e60 commit 8473cf8

8 files changed

+3486
-3545
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: 27 additions & 85 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);
@@ -1572,17 +1572,6 @@ compiler_addop_j(struct compiler *c, int opcode, basicblock *b)
15721572
} \
15731573
}
15741574

1575-
/* These macros allows to check only for errors and not emmit bytecode
1576-
* while visiting nodes.
1577-
*/
1578-
1579-
#define BEGIN_DO_NOT_EMIT_BYTECODE { \
1580-
c->c_do_not_emit_bytecode++;
1581-
1582-
#define END_DO_NOT_EMIT_BYTECODE \
1583-
c->c_do_not_emit_bytecode--; \
1584-
}
1585-
15861575
/* Search if variable annotations are present statically in a block. */
15871576

15881577
static int
@@ -2704,48 +2693,28 @@ static int
27042693
compiler_if(struct compiler *c, stmt_ty s)
27052694
{
27062695
basicblock *end, *next;
2707-
int constant;
27082696
assert(s->kind == If_kind);
27092697
end = compiler_new_block(c);
2710-
if (end == NULL)
2698+
if (end == NULL) {
27112699
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)) {
2700+
}
2701+
if (asdl_seq_LEN(s->v.If.orelse)) {
2702+
next = compiler_new_block(c);
2703+
if (next == NULL) {
27412704
return 0;
27422705
}
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-
}
2706+
}
2707+
else {
2708+
next = end;
2709+
}
2710+
if (!compiler_jump_if(c, s->v.If.test, next, 0)) {
2711+
return 0;
2712+
}
2713+
VISIT_SEQ(c, stmt, s->v.If.body);
2714+
if (asdl_seq_LEN(s->v.If.orelse)) {
2715+
ADDOP_JUMP(c, JUMP_FORWARD, end);
2716+
compiler_use_next_block(c, next);
2717+
VISIT_SEQ(c, stmt, s->v.If.orelse);
27492718
}
27502719
compiler_use_next_block(c, end);
27512720
return 1;
@@ -2842,25 +2811,6 @@ static int
28422811
compiler_while(struct compiler *c, stmt_ty s)
28432812
{
28442813
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-
}
28642814
loop = compiler_new_block(c);
28652815
body = compiler_new_block(c);
28662816
anchor = compiler_new_block(c);
@@ -2872,15 +2822,16 @@ compiler_while(struct compiler *c, stmt_ty s)
28722822
if (!compiler_push_fblock(c, WHILE_LOOP, loop, end, NULL)) {
28732823
return 0;
28742824
}
2875-
if (constant == -1) {
2876-
if (!compiler_jump_if(c, s->v.While.test, anchor, 0)) {
2877-
return 0;
2878-
}
2825+
if (!compiler_jump_if(c, s->v.While.test, anchor, 0)) {
2826+
return 0;
28792827
}
28802828

28812829
compiler_use_next_block(c, body);
28822830
VISIT_SEQ(c, stmt, s->v.While.body);
2883-
ADDOP_JUMP(c, JUMP_ABSOLUTE, loop);
2831+
SET_LOC(c, s);
2832+
if (!compiler_jump_if(c, s->v.While.test, body, 1)) {
2833+
return 0;
2834+
}
28842835

28852836
compiler_pop_fblock(c, WHILE_LOOP, loop);
28862837

@@ -4791,15 +4742,6 @@ compiler_visit_keyword(struct compiler *c, keyword_ty k)
47914742
Return values: 1 for true, 0 for false, -1 for non-constant.
47924743
*/
47934744

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-
48034745
static int
48044746
compiler_with_except_finish(struct compiler *c) {
48054747
basicblock *exit;
@@ -6304,7 +6246,7 @@ optimize_basic_block(basicblock *bb, PyObject *consts)
63046246
case JUMP_FORWARD:
63056247
if (inst->i_target != target->i_target) {
63066248
inst->i_target = target->i_target;
6307-
--i;
6249+
// --i;
63086250
}
63096251
break;
63106252
case JUMP_ABSOLUTE:
@@ -6317,8 +6259,8 @@ optimize_basic_block(basicblock *bb, PyObject *consts)
63176259
}
63186260
if (inst->i_target->b_exit && inst->i_target->b_iused <= MAX_COPY_SIZE) {
63196261
basicblock *to_copy = inst->i_target;
6320-
*inst = to_copy->b_instr[0];
6321-
for (i = 1; i < to_copy->b_iused; i++) {
6262+
inst->i_opcode = NOP;
6263+
for (i = 0; i < to_copy->b_iused; i++) {
63226264
int index = compiler_next_instr(bb);
63236265
if (index < 0) {
63246266
return -1;

0 commit comments

Comments
 (0)