]> git.proxmox.com Git - mirror_edk2.git/blame - AppPkg/Applications/Python/Python-2.7.2/Lib/test/test_peepholer.py
EmbeddedPkg: Extend NvVarStoreFormattedLib LIBRARY_CLASS
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.2 / Lib / test / test_peepholer.py
CommitLineData
4710c53d 1import dis\r
2import sys\r
3from cStringIO import StringIO\r
4import unittest\r
5\r
6def disassemble(func):\r
7 f = StringIO()\r
8 tmp = sys.stdout\r
9 sys.stdout = f\r
10 dis.dis(func)\r
11 sys.stdout = tmp\r
12 result = f.getvalue()\r
13 f.close()\r
14 return result\r
15\r
16def dis_single(line):\r
17 return disassemble(compile(line, '', 'single'))\r
18\r
19class TestTranforms(unittest.TestCase):\r
20\r
21 def test_unot(self):\r
22 # UNARY_NOT POP_JUMP_IF_FALSE --> POP_JUMP_IF_TRUE\r
23 def unot(x):\r
24 if not x == 2:\r
25 del x\r
26 asm = disassemble(unot)\r
27 for elem in ('UNARY_NOT', 'POP_JUMP_IF_FALSE'):\r
28 self.assertNotIn(elem, asm)\r
29 self.assertIn('POP_JUMP_IF_TRUE', asm)\r
30\r
31 def test_elim_inversion_of_is_or_in(self):\r
32 for line, elem in (\r
33 ('not a is b', '(is not)',),\r
34 ('not a in b', '(not in)',),\r
35 ('not a is not b', '(is)',),\r
36 ('not a not in b', '(in)',),\r
37 ):\r
38 asm = dis_single(line)\r
39 self.assertIn(elem, asm)\r
40\r
41 def test_none_as_constant(self):\r
42 # LOAD_GLOBAL None --> LOAD_CONST None\r
43 def f(x):\r
44 None\r
45 return x\r
46 asm = disassemble(f)\r
47 for elem in ('LOAD_GLOBAL',):\r
48 self.assertNotIn(elem, asm)\r
49 for elem in ('LOAD_CONST', '(None)'):\r
50 self.assertIn(elem, asm)\r
51 def f():\r
52 'Adding a docstring made this test fail in Py2.5.0'\r
53 return None\r
54 self.assertIn('LOAD_CONST', disassemble(f))\r
55 self.assertNotIn('LOAD_GLOBAL', disassemble(f))\r
56\r
57 def test_while_one(self):\r
58 # Skip over: LOAD_CONST trueconst POP_JUMP_IF_FALSE xx\r
59 def f():\r
60 while 1:\r
61 pass\r
62 return list\r
63 asm = disassemble(f)\r
64 for elem in ('LOAD_CONST', 'POP_JUMP_IF_FALSE'):\r
65 self.assertNotIn(elem, asm)\r
66 for elem in ('JUMP_ABSOLUTE',):\r
67 self.assertIn(elem, asm)\r
68\r
69 def test_pack_unpack(self):\r
70 for line, elem in (\r
71 ('a, = a,', 'LOAD_CONST',),\r
72 ('a, b = a, b', 'ROT_TWO',),\r
73 ('a, b, c = a, b, c', 'ROT_THREE',),\r
74 ):\r
75 asm = dis_single(line)\r
76 self.assertIn(elem, asm)\r
77 self.assertNotIn('BUILD_TUPLE', asm)\r
78 self.assertNotIn('UNPACK_TUPLE', asm)\r
79\r
80 def test_folding_of_tuples_of_constants(self):\r
81 for line, elem in (\r
82 ('a = 1,2,3', '((1, 2, 3))'),\r
83 ('("a","b","c")', "(('a', 'b', 'c'))"),\r
84 ('a,b,c = 1,2,3', '((1, 2, 3))'),\r
85 ('(None, 1, None)', '((None, 1, None))'),\r
86 ('((1, 2), 3, 4)', '(((1, 2), 3, 4))'),\r
87 ):\r
88 asm = dis_single(line)\r
89 self.assertIn(elem, asm)\r
90 self.assertNotIn('BUILD_TUPLE', asm)\r
91\r
92 # Bug 1053819: Tuple of constants misidentified when presented with:\r
93 # . . . opcode_with_arg 100 unary_opcode BUILD_TUPLE 1 . . .\r
94 # The following would segfault upon compilation\r
95 def crater():\r
96 (~[\r
97 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,\r
98 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,\r
99 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,\r
100 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,\r
101 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,\r
102 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,\r
103 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,\r
104 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,\r
105 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,\r
106 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,\r
107 ],)\r
108\r
109 def test_folding_of_binops_on_constants(self):\r
110 for line, elem in (\r
111 ('a = 2+3+4', '(9)'), # chained fold\r
112 ('"@"*4', "('@@@@')"), # check string ops\r
113 ('a="abc" + "def"', "('abcdef')"), # check string ops\r
114 ('a = 3**4', '(81)'), # binary power\r
115 ('a = 3*4', '(12)'), # binary multiply\r
116 ('a = 13//4', '(3)'), # binary floor divide\r
117 ('a = 14%4', '(2)'), # binary modulo\r
118 ('a = 2+3', '(5)'), # binary add\r
119 ('a = 13-4', '(9)'), # binary subtract\r
120 ('a = (12,13)[1]', '(13)'), # binary subscr\r
121 ('a = 13 << 2', '(52)'), # binary lshift\r
122 ('a = 13 >> 2', '(3)'), # binary rshift\r
123 ('a = 13 & 7', '(5)'), # binary and\r
124 ('a = 13 ^ 7', '(10)'), # binary xor\r
125 ('a = 13 | 7', '(15)'), # binary or\r
126 ):\r
127 asm = dis_single(line)\r
128 self.assertIn(elem, asm, asm)\r
129 self.assertNotIn('BINARY_', asm)\r
130\r
131 # Verify that unfoldables are skipped\r
132 asm = dis_single('a=2+"b"')\r
133 self.assertIn('(2)', asm)\r
134 self.assertIn("('b')", asm)\r
135\r
136 # Verify that large sequences do not result from folding\r
137 asm = dis_single('a="x"*1000')\r
138 self.assertIn('(1000)', asm)\r
139\r
140 def test_binary_subscr_on_unicode(self):\r
141 # valid code get optimized\r
142 asm = dis_single('u"foo"[0]')\r
143 self.assertIn("(u'f')", asm)\r
144 self.assertNotIn('BINARY_SUBSCR', asm)\r
145 asm = dis_single('u"\u0061\uffff"[1]')\r
146 self.assertIn("(u'\\uffff')", asm)\r
147 self.assertNotIn('BINARY_SUBSCR', asm)\r
148\r
149 # invalid code doesn't get optimized\r
150 # out of range\r
151 asm = dis_single('u"fuu"[10]')\r
152 self.assertIn('BINARY_SUBSCR', asm)\r
153 # non-BMP char (see #5057)\r
154 asm = dis_single('u"\U00012345"[0]')\r
155 self.assertIn('BINARY_SUBSCR', asm)\r
156\r
157\r
158 def test_folding_of_unaryops_on_constants(self):\r
159 for line, elem in (\r
160 ('`1`', "('1')"), # unary convert\r
161 ('-0.5', '(-0.5)'), # unary negative\r
162 ('~-2', '(1)'), # unary invert\r
163 ):\r
164 asm = dis_single(line)\r
165 self.assertIn(elem, asm, asm)\r
166 self.assertNotIn('UNARY_', asm)\r
167\r
168 # Verify that unfoldables are skipped\r
169 for line, elem in (\r
170 ('-"abc"', "('abc')"), # unary negative\r
171 ('~"abc"', "('abc')"), # unary invert\r
172 ):\r
173 asm = dis_single(line)\r
174 self.assertIn(elem, asm, asm)\r
175 self.assertIn('UNARY_', asm)\r
176\r
177 def test_elim_extra_return(self):\r
178 # RETURN LOAD_CONST None RETURN --> RETURN\r
179 def f(x):\r
180 return x\r
181 asm = disassemble(f)\r
182 self.assertNotIn('LOAD_CONST', asm)\r
183 self.assertNotIn('(None)', asm)\r
184 self.assertEqual(asm.split().count('RETURN_VALUE'), 1)\r
185\r
186 def test_elim_jump_to_return(self):\r
187 # JUMP_FORWARD to RETURN --> RETURN\r
188 def f(cond, true_value, false_value):\r
189 return true_value if cond else false_value\r
190 asm = disassemble(f)\r
191 self.assertNotIn('JUMP_FORWARD', asm)\r
192 self.assertNotIn('JUMP_ABSOLUTE', asm)\r
193 self.assertEqual(asm.split().count('RETURN_VALUE'), 2)\r
194\r
195 def test_elim_jump_after_return1(self):\r
196 # Eliminate dead code: jumps immediately after returns can't be reached\r
197 def f(cond1, cond2):\r
198 if cond1: return 1\r
199 if cond2: return 2\r
200 while 1:\r
201 return 3\r
202 while 1:\r
203 if cond1: return 4\r
204 return 5\r
205 return 6\r
206 asm = disassemble(f)\r
207 self.assertNotIn('JUMP_FORWARD', asm)\r
208 self.assertNotIn('JUMP_ABSOLUTE', asm)\r
209 self.assertEqual(asm.split().count('RETURN_VALUE'), 6)\r
210\r
211 def test_elim_jump_after_return2(self):\r
212 # Eliminate dead code: jumps immediately after returns can't be reached\r
213 def f(cond1, cond2):\r
214 while 1:\r
215 if cond1: return 4\r
216 asm = disassemble(f)\r
217 self.assertNotIn('JUMP_FORWARD', asm)\r
218 # There should be one jump for the while loop.\r
219 self.assertEqual(asm.split().count('JUMP_ABSOLUTE'), 1)\r
220 self.assertEqual(asm.split().count('RETURN_VALUE'), 2)\r
221\r
222\r
223def test_main(verbose=None):\r
224 import sys\r
225 from test import test_support\r
226 test_classes = (TestTranforms,)\r
227\r
228 with test_support.check_py3k_warnings(\r
229 ("backquote not supported", SyntaxWarning)):\r
230 test_support.run_unittest(*test_classes)\r
231\r
232 # verify reference counting\r
233 if verbose and hasattr(sys, "gettotalrefcount"):\r
234 import gc\r
235 counts = [None] * 5\r
236 for i in xrange(len(counts)):\r
237 test_support.run_unittest(*test_classes)\r
238 gc.collect()\r
239 counts[i] = sys.gettotalrefcount()\r
240 print counts\r
241\r
242if __name__ == "__main__":\r
243 test_main(verbose=True)\r