Add a Notification Settings Button to all web notifications behind the web platform...
[chromium-blink-merge.git] / third_party / pycoverage / coverage / bytecode.py
blob85360638528e6bece33b1f5a1e4dd08e5c2ac3d0
1 """Bytecode manipulation for coverage.py"""
3 import opcode, types
5 from coverage.backward import byte_to_int
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
13 # The opcode, defined in the `opcode` module.
14 self.op = -1
16 # The argument, a small integer, whose meaning depends on the opcode.
17 self.arg = -1
19 # The offset in the code object of the next bytecode.
20 self.next_offset = -1
22 # The offset to jump to.
23 self.jump_to = -1
26 class ByteCodes(object):
27 """Iterator over byte codes in `code`.
29 Returns `ByteCode` objects.
31 """
32 # pylint: disable=R0924
33 def __init__(self, code):
34 self.code = code
36 def __getitem__(self, i):
37 return byte_to_int(self.code[i])
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
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
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
58 bc.next_offset = offset = next_offset
59 yield bc
62 class CodeObjects(object):
63 """Iterate over all the code objects in `code`."""
64 def __init__(self, code):
65 self.stack = [code]
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