DebugClients/Python/coverage/bytecode.py

changeset 4491
0d8612e24fef
parent 4489
d0d6e4ad31bd
child 5051
3586ebd9fac8
equal deleted inserted replaced
4487:4ba7a8ab24f2 4491:0d8612e24fef
1 # Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
2 # For details: https://bitbucket.org/ned/coveragepy/src/default/NOTICE.txt
3
1 """Bytecode manipulation for coverage.py""" 4 """Bytecode manipulation for coverage.py"""
2 5
3 import opcode, types 6 import opcode
7 import types
4 8
5 from .backward import byte_to_int 9 from coverage.backward import byte_to_int
10
6 11
7 class ByteCode(object): 12 class ByteCode(object):
8 """A single bytecode.""" 13 """A single bytecode."""
9 def __init__(self): 14 def __init__(self):
10 # The offset of this bytecode in the code object. 15 # The offset of this bytecode in the code object.
24 29
25 30
26 class ByteCodes(object): 31 class ByteCodes(object):
27 """Iterator over byte codes in `code`. 32 """Iterator over byte codes in `code`.
28 33
34 This handles the logic of EXTENDED_ARG byte codes internally. Those byte
35 codes are not returned by this iterator.
36
29 Returns `ByteCode` objects. 37 Returns `ByteCode` objects.
30 38
31 """ 39 """
32 # pylint: disable=R0924
33 def __init__(self, code): 40 def __init__(self, code):
34 self.code = code 41 self.code = code
35 42
36 def __getitem__(self, i): 43 def __getitem__(self, i):
37 return byte_to_int(self.code[i]) 44 return byte_to_int(self.code[i])
38 45
39 def __iter__(self): 46 def __iter__(self):
40 offset = 0 47 offset = 0
48 ext_arg = 0
41 while offset < len(self.code): 49 while offset < len(self.code):
42 bc = ByteCode() 50 bc = ByteCode()
43 bc.op = self[offset] 51 bc.op = self[offset]
44 bc.offset = offset 52 bc.offset = offset
45 53
46 next_offset = offset+1 54 next_offset = offset+1
47 if bc.op >= opcode.HAVE_ARGUMENT: 55 if bc.op >= opcode.HAVE_ARGUMENT:
48 bc.arg = self[offset+1] + 256*self[offset+2] 56 bc.arg = ext_arg + self[offset+1] + 256*self[offset+2]
49 next_offset += 2 57 next_offset += 2
50 58
51 label = -1 59 label = -1
52 if bc.op in opcode.hasjrel: 60 if bc.op in opcode.hasjrel:
53 label = next_offset + bc.arg 61 label = next_offset + bc.arg
54 elif bc.op in opcode.hasjabs: 62 elif bc.op in opcode.hasjabs:
55 label = bc.arg 63 label = bc.arg
56 bc.jump_to = label 64 bc.jump_to = label
57 65
58 bc.next_offset = offset = next_offset 66 bc.next_offset = offset = next_offset
59 yield bc 67 if bc.op == opcode.EXTENDED_ARG:
68 ext_arg = bc.arg * 256*256
69 else:
70 ext_arg = 0
71 yield bc
60 72
61 73
62 class CodeObjects(object): 74 class CodeObjects(object):
63 """Iterate over all the code objects in `code`.""" 75 """Iterate over all the code objects in `code`."""
64 def __init__(self, code): 76 def __init__(self, code):

eric ide

mercurial