OLD | NEW |
(Empty) | |
| 1 """Bytecode manipulation for coverage.py""" |
| 2 |
| 3 import opcode, types |
| 4 |
| 5 from coverage.backward import byte_to_int |
| 6 |
| 7 class ByteCode(object): |
| 8 """A single bytecode.""" |
| 9 def __init__(self): |
| 10 # The offset of this bytecode in the code object. |
| 11 self.offset = -1 |
| 12 |
| 13 # The opcode, defined in the `opcode` module. |
| 14 self.op = -1 |
| 15 |
| 16 # The argument, a small integer, whose meaning depends on the opcode. |
| 17 self.arg = -1 |
| 18 |
| 19 # The offset in the code object of the next bytecode. |
| 20 self.next_offset = -1 |
| 21 |
| 22 # The offset to jump to. |
| 23 self.jump_to = -1 |
| 24 |
| 25 |
| 26 class ByteCodes(object): |
| 27 """Iterator over byte codes in `code`. |
| 28 |
| 29 Returns `ByteCode` objects. |
| 30 |
| 31 """ |
| 32 # pylint: disable=R0924 |
| 33 def __init__(self, code): |
| 34 self.code = code |
| 35 |
| 36 def __getitem__(self, i): |
| 37 return byte_to_int(self.code[i]) |
| 38 |
| 39 def __iter__(self): |
| 40 offset = 0 |
| 41 while offset < len(self.code): |
| 42 bc = ByteCode() |
| 43 bc.op = self[offset] |
| 44 bc.offset = offset |
| 45 |
| 46 next_offset = offset+1 |
| 47 if bc.op >= opcode.HAVE_ARGUMENT: |
| 48 bc.arg = self[offset+1] + 256*self[offset+2] |
| 49 next_offset += 2 |
| 50 |
| 51 label = -1 |
| 52 if bc.op in opcode.hasjrel: |
| 53 label = next_offset + bc.arg |
| 54 elif bc.op in opcode.hasjabs: |
| 55 label = bc.arg |
| 56 bc.jump_to = label |
| 57 |
| 58 bc.next_offset = offset = next_offset |
| 59 yield bc |
| 60 |
| 61 |
| 62 class CodeObjects(object): |
| 63 """Iterate over all the code objects in `code`.""" |
| 64 def __init__(self, code): |
| 65 self.stack = [code] |
| 66 |
| 67 def __iter__(self): |
| 68 while self.stack: |
| 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): |
| 74 self.stack.append(c) |
| 75 yield code |
OLD | NEW |