|
24 | 24 | )
|
25 | 25 |
|
26 | 26 | from coverage import env
|
27 |
| -from coverage.bytecode import TBranchTrails, branch_trails |
| 27 | +from coverage.bytecode import TBranchTrails, always_jumps, branch_trails |
28 | 28 | from coverage.debug import short_filename, short_stack
|
29 | 29 | from coverage.misc import isolate_module
|
30 | 30 | from coverage.types import (
|
@@ -184,6 +184,10 @@ class CodeInfo:
|
184 | 184 | # Two possible trails from the branch point, left and right.
|
185 | 185 | branch_trails: TBranchTrails
|
186 | 186 |
|
| 187 | + # Always-jumps are bytecode offsets that do no work but move |
| 188 | + # to another offset. |
| 189 | + always_jumps: dict[TOffset, TOffset] |
| 190 | + |
187 | 191 |
|
188 | 192 | def bytes_to_lines(code: CodeType) -> dict[TOffset, TLineNo]:
|
189 | 193 | """Make a dict mapping byte code offsets to line numbers."""
|
@@ -348,6 +352,7 @@ def sysmon_py_start(
|
348 | 352 | file_data=file_data,
|
349 | 353 | byte_to_line=b2l,
|
350 | 354 | branch_trails={},
|
| 355 | + always_jumps={}, |
351 | 356 | )
|
352 | 357 | self.code_infos[id(code)] = code_info
|
353 | 358 | self.code_objects.append(code)
|
@@ -431,15 +436,23 @@ def sysmon_branch_either(
|
431 | 436 | if self.stats is not None:
|
432 | 437 | self.stats["branch_trails"] += 1
|
433 | 438 | code_info.branch_trails = branch_trails(code)
|
| 439 | + code_info.always_jumps = always_jumps(code) |
434 | 440 | # log(f"branch_trails for {code}:\n {code_info.branch_trails}")
|
435 | 441 | added_arc = False
|
436 | 442 | dest_info = code_info.branch_trails.get(instruction_offset)
|
| 443 | + |
| 444 | + # Re-map the destination offset through always-jumps to deal with NOP etc. |
| 445 | + dests = {destination_offset} |
| 446 | + while (dest := code_info.always_jumps.get(destination_offset)) is not None: |
| 447 | + destination_offset = dest |
| 448 | + dests.add(destination_offset) |
| 449 | + |
437 | 450 | # log(f"{dest_info = }")
|
438 | 451 | if dest_info is not None:
|
439 | 452 | for offsets, arc in dest_info:
|
440 | 453 | if arc is None:
|
441 | 454 | continue
|
442 |
| - if destination_offset in offsets: |
| 455 | + if dests & offsets: |
443 | 456 | code_info.file_data.add(arc) # type: ignore
|
444 | 457 | # log(f"adding {arc=}")
|
445 | 458 | added_arc = True
|
|
0 commit comments