However, this is not necessarily true and causes the column table to become out-of-sync with the linetable and actual instructions when opcodes that have extended argument get used. One such example that showed up test_traceback.py is JUMP_IF_NOT_EXC_MATCH which can be prepended with EXTENDED_ARG if the target/oparg is bigger than 255.
After adding a print out to the assemble_cnotab method we find:
Instruction idx 560 -- line 33, i_col_offset=0, i_end_col_offset=1, opcode=LOAD_CONST
Instruction idx 562 -- line 33, i_col_offset=4, i_end_col_offset=5, opcode=LOAD_CONST
Instruction idx 564 -- line 33, i_col_offset=0, i_end_col_offset=5, opcode=BINARY_TRUE_DIVIDE
Instruction idx 566 -- line 33, i_col_offset=0, i_end_col_offset=5, opcode=POP_TOP
Notice that the actual instruction idx 568 corresponding to the true divide has become desynced with the column table thinking it instruction 564. We need to take instrsize into account when emitting the column table.
Currently we are assuming in compile.c that each instruction object turns into one bytecode:
https://github.com/colnotab/cpython/blob/44138dcca2b3d391c154c2fd5ec89cd1e2d0e9fc/Python/compile.c#L7012-L7014
However, this is not necessarily true and causes the column table to become out-of-sync with the linetable and actual instructions when opcodes that have extended argument get used. One such example that showed up
test_traceback.py
isJUMP_IF_NOT_EXC_MATCH
which can be prepended withEXTENDED_ARG
if the target/oparg is bigger than255
.For example in this program:
The error printed is:
This seems to correspond to the
LOAD_CONST
of1
instead of the full division operation. If we look at the disassembly:After adding a print out to the
assemble_cnotab
method we find:Notice that the actual instruction idx
568
corresponding to the true divide has become desynced with the column table thinking it instruction564
. We need to takeinstrsize
into account when emitting the column table.