Thu, 10 Apr 2014 23:02:20 +0200
updated coverage to 3.7.1
31
744cd0b4b8cd
Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
1 | """Bytecode manipulation for coverage.py""" |
744cd0b4b8cd
Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
2 | |
3495
fac17a82b431
updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
790
diff
changeset
|
3 | import opcode, types |
fac17a82b431
updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
790
diff
changeset
|
4 | |
fac17a82b431
updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
790
diff
changeset
|
5 | from .backward import byte_to_int |
31
744cd0b4b8cd
Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
6 | |
744cd0b4b8cd
Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
7 | class ByteCode(object): |
744cd0b4b8cd
Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
8 | """A single bytecode.""" |
744cd0b4b8cd
Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
9 | def __init__(self): |
3495
fac17a82b431
updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
790
diff
changeset
|
10 | # The offset of this bytecode in the code object. |
31
744cd0b4b8cd
Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
11 | self.offset = -1 |
3495
fac17a82b431
updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
790
diff
changeset
|
12 | |
fac17a82b431
updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
790
diff
changeset
|
13 | # The opcode, defined in the `opcode` module. |
31
744cd0b4b8cd
Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
14 | self.op = -1 |
3495
fac17a82b431
updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
790
diff
changeset
|
15 | |
fac17a82b431
updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
790
diff
changeset
|
16 | # The argument, a small integer, whose meaning depends on the opcode. |
31
744cd0b4b8cd
Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
17 | self.arg = -1 |
3495
fac17a82b431
updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
790
diff
changeset
|
18 | |
fac17a82b431
updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
790
diff
changeset
|
19 | # The offset in the code object of the next bytecode. |
31
744cd0b4b8cd
Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
20 | self.next_offset = -1 |
3495
fac17a82b431
updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
790
diff
changeset
|
21 | |
fac17a82b431
updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
790
diff
changeset
|
22 | # The offset to jump to. |
31
744cd0b4b8cd
Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
23 | self.jump_to = -1 |
744cd0b4b8cd
Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
24 | |
744cd0b4b8cd
Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
25 | |
744cd0b4b8cd
Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
26 | class ByteCodes(object): |
744cd0b4b8cd
Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
27 | """Iterator over byte codes in `code`. |
744cd0b4b8cd
Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
28 | |
744cd0b4b8cd
Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
29 | Returns `ByteCode` objects. |
744cd0b4b8cd
Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
30 | |
744cd0b4b8cd
Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
31 | """ |
3495
fac17a82b431
updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
790
diff
changeset
|
32 | # pylint: disable=R0924 |
31
744cd0b4b8cd
Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
33 | def __init__(self, code): |
744cd0b4b8cd
Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
34 | self.code = code |
744cd0b4b8cd
Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
35 | |
3495
fac17a82b431
updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
790
diff
changeset
|
36 | def __getitem__(self, i): |
fac17a82b431
updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
790
diff
changeset
|
37 | return byte_to_int(self.code[i]) |
31
744cd0b4b8cd
Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
38 | |
744cd0b4b8cd
Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
39 | def __iter__(self): |
3495
fac17a82b431
updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
790
diff
changeset
|
40 | offset = 0 |
fac17a82b431
updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
790
diff
changeset
|
41 | while offset < len(self.code): |
fac17a82b431
updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
790
diff
changeset
|
42 | bc = ByteCode() |
fac17a82b431
updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
790
diff
changeset
|
43 | bc.op = self[offset] |
fac17a82b431
updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
790
diff
changeset
|
44 | bc.offset = offset |
31
744cd0b4b8cd
Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
45 | |
3495
fac17a82b431
updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
790
diff
changeset
|
46 | next_offset = offset+1 |
fac17a82b431
updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
790
diff
changeset
|
47 | if bc.op >= opcode.HAVE_ARGUMENT: |
fac17a82b431
updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
790
diff
changeset
|
48 | bc.arg = self[offset+1] + 256*self[offset+2] |
fac17a82b431
updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
790
diff
changeset
|
49 | next_offset += 2 |
31
744cd0b4b8cd
Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
50 | |
3495
fac17a82b431
updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
790
diff
changeset
|
51 | label = -1 |
fac17a82b431
updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
790
diff
changeset
|
52 | if bc.op in opcode.hasjrel: |
fac17a82b431
updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
790
diff
changeset
|
53 | label = next_offset + bc.arg |
fac17a82b431
updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
790
diff
changeset
|
54 | elif bc.op in opcode.hasjabs: |
fac17a82b431
updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
790
diff
changeset
|
55 | label = bc.arg |
fac17a82b431
updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
790
diff
changeset
|
56 | bc.jump_to = label |
31
744cd0b4b8cd
Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
57 | |
3495
fac17a82b431
updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
790
diff
changeset
|
58 | bc.next_offset = offset = next_offset |
fac17a82b431
updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
790
diff
changeset
|
59 | yield bc |
31
744cd0b4b8cd
Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
60 | |
744cd0b4b8cd
Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
61 | |
744cd0b4b8cd
Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
62 | class CodeObjects(object): |
744cd0b4b8cd
Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
63 | """Iterate over all the code objects in `code`.""" |
744cd0b4b8cd
Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
64 | def __init__(self, code): |
744cd0b4b8cd
Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
65 | self.stack = [code] |
744cd0b4b8cd
Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
66 | |
744cd0b4b8cd
Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
67 | def __iter__(self): |
3495
fac17a82b431
updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
790
diff
changeset
|
68 | while self.stack: |
31
744cd0b4b8cd
Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
69 | # We're going to return the code object on the stack, but first |
744cd0b4b8cd
Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
70 | # push its children for later returning. |
744cd0b4b8cd
Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
71 | code = self.stack.pop() |
744cd0b4b8cd
Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
72 | for c in code.co_consts: |
744cd0b4b8cd
Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
73 | if isinstance(c, types.CodeType): |
744cd0b4b8cd
Updated coverage.py to version 3.2.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
74 | self.stack.append(c) |
3495
fac17a82b431
updated coverage to 3.7.1
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
790
diff
changeset
|
75 | yield code |