Skip to content

Commit 70dbabe

Browse files
Allow fusing TryBegin with an unknown stack size when converting from CFG to bytecode (#120)
* cfg: forget about seen TryEnd if we encounter an already seen TryEnd * cfg: ensure we remove dead TryEnd when fusing TryBegin/TryEnd pairs when going from CFG to bytecode * doc: update release notes
1 parent 8cbb501 commit 70dbabe

2 files changed

Lines changed: 19 additions & 6 deletions

File tree

doc/changelog.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
ChangeLog
22
=========
33

4+
unreleased: Version 0.14.2
5+
--------------------------
6+
7+
Bugfixes:
8+
9+
- allow to convert a CFG, for which stack sizes have not been computed, to Bytecode
10+
even in the presence of mergeable TryBegin/TryEnd PR #120
11+
- remove spurious TryEnd leftover when going from CFG to Bytecode PR #120
12+
13+
414
2023-04-04: Version 0.14.1
515
--------------------------
616

src/bytecode/cfg.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -819,8 +819,8 @@ def from_bytecode(bytecode: _bytecode.Bytecode) -> "ControlFlowGraph":
819819
# - if the current instruction is a TryEnd and if the last instruction
820820
# is final in which case we insert the TryEnd in the old block.
821821
# - if we have a currently active TryBegin for which we may need to
822-
# create a TryEnd in the previous and a new TryBegin in the new one
823-
# because the blocks are not connected.
822+
# create a TryEnd in the previous block and a new TryBegin in the
823+
# new one because the blocks are not connected.
824824
if old_block is not None:
825825
temp = try_begin_inserted_in_block
826826
try_begin_inserted_in_block = False
@@ -981,23 +981,26 @@ def to_bytecode(self) -> _bytecode.Bytecode:
981981

982982
# If the TryBegin share the target and push_lasti of the
983983
# entry of an adjacent TryEnd, omit the new TryBegin that
984-
# was inserted to allow analysis of the CFG
984+
# was inserted to allow analysis of the CFG and remove
985+
# the already inserted TryEnd.
985986
if last_try_end is not None:
986987
cfg_te, byt_te = last_try_end
987988
entry = cfg_te.entry
988989
if (
989990
entry.target is instr.target
990991
and entry.push_lasti == instr.push_lasti
991992
):
992-
# If the exception table is in a dead code portion
993-
# simply use a size of zero
993+
# If we did not yet compute the required stack depth
994+
# keep the value as UNSET
994995
if entry.stack_depth is UNSET:
995-
byt_te.entry.stack_depth = 0
996+
assert instr.stack_depth is UNSET
997+
byt_te.entry.stack_depth = UNSET
996998
else:
997999
byt_te.entry.stack_depth = min(
9981000
entry.stack_depth, instr.stack_depth
9991001
)
10001002
try_begins[instr] = byt_te.entry
1003+
instructions.remove(byt_te)
10011004
continue
10021005
assert isinstance(new, TryBegin)
10031006
try_begins[instr] = new

0 commit comments

Comments
 (0)