| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -502,6 +502,33 @@ def test_compile_invalid_namedexpr(self): | |||
| 502 | 502 | with self.assertRaisesRegex(TypeError, "NamedExpr target must be a Name"): | |
| 503 | 503 | compile(ast.fix_missing_locations(m), "<file>", "exec") | |
| 504 | 504 | ||
| 505 | + def test_compile_redundant_jumps_and_nops_after_moving_cold_blocks(self): | ||
| 506 | + # See gh-120367 | ||
| 507 | + code=textwrap.dedent(""" | ||
| 508 | + try: | ||
| 509 | + pass | ||
| 510 | + except: | ||
| 511 | + pass | ||
| 512 | + else: | ||
| 513 | + match name_2: | ||
| 514 | + case b'': | ||
| 515 | + pass | ||
| 516 | + finally: | ||
| 517 | + something | ||
| 518 | + """) | ||
| 519 | + | ||
| 520 | + tree = ast.parse(code) | ||
| 521 | + | ||
| 522 | + # make all instructions locations the same to create redundancies | ||
| 523 | + for node in ast.walk(tree): | ||
| 524 | + if hasattr(node,"lineno"): | ||
| 525 | + del node.lineno | ||
| 526 | + del node.end_lineno | ||
| 527 | + del node.col_offset | ||
| 528 | + del node.end_col_offset | ||
| 529 | + | ||
| 530 | + compile(ast.fix_missing_locations(tree), "<file>", "exec") | ||
| 531 | + | ||
| 505 | 532 | def test_compile_ast(self): | |
| 506 | 533 | fname = __file__ | |
| 507 | 534 | if fname.lower().endswith('pyc'): | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,2 @@ | |||
| 1 | + Fix crash in compiler on code with redundant NOPs and JUMPs which show up | ||
| 2 | + after exception handlers are moved to the end of the code. | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1857,6 +1857,22 @@ optimize_basic_block(PyObject *const_cache, basicblock *bb, PyObject *consts) | |||
| 1857 | 1857 | ||
| 1858 | 1858 | static int resolve_line_numbers(cfg_builder *g, int firstlineno); | |
| 1859 | 1859 | ||
| 1860 | + static int | ||
| 1861 | + remove_redundant_nops_and_jumps(cfg_builder *g) | ||
| 1862 | + { | ||
| 1863 | + int removed_nops, removed_jumps; | ||
| 1864 | + do { | ||
| 1865 | + /* Convergence is guaranteed because the number of | ||
| 1866 | + * redundant jumps and nops only decreases. | ||
| 1867 | + */ | ||
| 1868 | + removed_nops = remove_redundant_nops(g); | ||
| 1869 | + RETURN_IF_ERROR(removed_nops); | ||
| 1870 | + removed_jumps = remove_redundant_jumps(g); | ||
| 1871 | + RETURN_IF_ERROR(removed_jumps); | ||
| 1872 | + } while(removed_nops + removed_jumps > 0); | ||
| 1873 | + return SUCCESS; | ||
| 1874 | + } | ||
| 1875 | + | ||
| 1860 | 1876 | /* Perform optimizations on a control flow graph. | |
| 1861 | 1877 | The consts object should still be in list form to allow new constants | |
| 1862 | 1878 | to be appended. | |
@@ -1878,17 +1894,7 @@ optimize_cfg(cfg_builder *g, PyObject *consts, PyObject *const_cache, int firstl | |||
| 1878 | 1894 | } | |
| 1879 | 1895 | RETURN_IF_ERROR(remove_redundant_nops_and_pairs(g->g_entryblock)); | |
| 1880 | 1896 | RETURN_IF_ERROR(remove_unreachable(g->g_entryblock)); | |
| 1881 | - | ||
| 1882 | - int removed_nops, removed_jumps; | ||
| 1883 | - do { | ||
| 1884 | - /* Convergence is guaranteed because the number of | ||
| 1885 | - * redundant jumps and nops only decreases. | ||
| 1886 | - */ | ||
| 1887 | - removed_nops = remove_redundant_nops(g); | ||
| 1888 | - RETURN_IF_ERROR(removed_nops); | ||
| 1889 | - removed_jumps = remove_redundant_jumps(g); | ||
| 1890 | - RETURN_IF_ERROR(removed_jumps); | ||
| 1891 | - } while(removed_nops + removed_jumps > 0); | ||
| 1897 | + RETURN_IF_ERROR(remove_redundant_nops_and_jumps(g)); | ||
| 1892 | 1898 | assert(no_redundant_jumps(g)); | |
| 1893 | 1899 | return SUCCESS; | |
| 1894 | 1900 | } | |
@@ -2358,7 +2364,7 @@ push_cold_blocks_to_end(cfg_builder *g) { | |||
| 2358 | 2364 | b->b_next = cold_blocks; | |
| 2359 | 2365 | ||
| 2360 | 2366 | if (cold_blocks != NULL) { | |
| 2361 | - RETURN_IF_ERROR(remove_redundant_jumps(g)); | ||
| 2367 | + RETURN_IF_ERROR(remove_redundant_nops_and_jumps(g)); | ||
| 2362 | 2368 | } | |
| 2363 | 2369 | return SUCCESS; | |
| 2364 | 2370 | } | |
| Back | FazBrowse Home | New Git URL |
0 commit comments