1 """Bytecode manipulation for coverage.py"""
5 from coverage
.backward
import byte_to_int
7 class ByteCode(object):
8 """A single bytecode."""
10 # The offset of this bytecode in the code object.
13 # The opcode, defined in the `opcode` module.
16 # The argument, a small integer, whose meaning depends on the opcode.
19 # The offset in the code object of the next bytecode.
22 # The offset to jump to.
26 class ByteCodes(object):
27 """Iterator over byte codes in `code`.
29 Returns `ByteCode` objects.
32 # pylint: disable=R0924
33 def __init__(self
, code
):
36 def __getitem__(self
, i
):
37 return byte_to_int(self
.code
[i
])
41 while offset
< len(self
.code
):
46 next_offset
= offset
+1
47 if bc
.op
>= opcode
.HAVE_ARGUMENT
:
48 bc
.arg
= self
[offset
+1] + 256*self
[offset
+2]
52 if bc
.op
in opcode
.hasjrel
:
53 label
= next_offset
+ bc
.arg
54 elif bc
.op
in opcode
.hasjabs
:
58 bc
.next_offset
= offset
= next_offset
62 class CodeObjects(object):
63 """Iterate over all the code objects in `code`."""
64 def __init__(self
, code
):
69 # We're going to return the code object on the stack, but first
70 # push its children for later returning.
71 code
= self
.stack
.pop()
72 for c
in code
.co_consts
:
73 if isinstance(c
, types
.CodeType
):