| 
									
										
										
										
											2013-11-23 14:49:22 -08:00
										 |  |  | import dis | 
					
						
							| 
									
										
										
										
											2015-04-13 15:00:43 -05:00
										 |  |  | from test.support import import_module | 
					
						
							| 
									
										
										
										
											2013-11-23 14:49:22 -08:00
										 |  |  | import unittest | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-23 16:11:17 -08:00
										 |  |  | _opcode = import_module("_opcode") | 
					
						
							| 
									
										
										
										
											2018-09-18 09:54:26 +03:00
										 |  |  | from _opcode import stack_effect | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-23 16:11:17 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-23 14:49:22 -08:00
										 |  |  | class OpcodeTests(unittest.TestCase): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_stack_effect(self): | 
					
						
							| 
									
										
										
										
											2018-09-18 09:54:26 +03:00
										 |  |  |         self.assertEqual(stack_effect(dis.opmap['POP_TOP']), -1) | 
					
						
							|  |  |  |         self.assertEqual(stack_effect(dis.opmap['DUP_TOP_TWO']), 2) | 
					
						
							|  |  |  |         self.assertEqual(stack_effect(dis.opmap['BUILD_SLICE'], 0), -1) | 
					
						
							|  |  |  |         self.assertEqual(stack_effect(dis.opmap['BUILD_SLICE'], 1), -1) | 
					
						
							|  |  |  |         self.assertEqual(stack_effect(dis.opmap['BUILD_SLICE'], 3), -2) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, stack_effect, 30000) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, stack_effect, dis.opmap['BUILD_SLICE']) | 
					
						
							|  |  |  |         self.assertRaises(ValueError, stack_effect, dis.opmap['POP_TOP'], 0) | 
					
						
							| 
									
										
										
										
											2018-04-25 22:04:06 +03:00
										 |  |  |         # All defined opcodes | 
					
						
							|  |  |  |         for name, code in dis.opmap.items(): | 
					
						
							|  |  |  |             with self.subTest(opname=name): | 
					
						
							|  |  |  |                 if code < dis.HAVE_ARGUMENT: | 
					
						
							| 
									
										
										
										
											2018-09-18 09:54:26 +03:00
										 |  |  |                     stack_effect(code) | 
					
						
							|  |  |  |                     self.assertRaises(ValueError, stack_effect, code, 0) | 
					
						
							| 
									
										
										
										
											2018-04-25 22:04:06 +03:00
										 |  |  |                 else: | 
					
						
							| 
									
										
										
										
											2018-09-18 09:54:26 +03:00
										 |  |  |                     stack_effect(code, 0) | 
					
						
							|  |  |  |                     self.assertRaises(ValueError, stack_effect, code) | 
					
						
							| 
									
										
										
										
											2018-04-25 22:04:06 +03:00
										 |  |  |         # All not defined opcodes | 
					
						
							|  |  |  |         for code in set(range(256)) - set(dis.opmap.values()): | 
					
						
							|  |  |  |             with self.subTest(opcode=code): | 
					
						
							| 
									
										
										
										
											2018-09-18 09:54:26 +03:00
										 |  |  |                 self.assertRaises(ValueError, stack_effect, code) | 
					
						
							|  |  |  |                 self.assertRaises(ValueError, stack_effect, code, 0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_stack_effect_jump(self): | 
					
						
							|  |  |  |         JUMP_IF_TRUE_OR_POP = dis.opmap['JUMP_IF_TRUE_OR_POP'] | 
					
						
							|  |  |  |         self.assertEqual(stack_effect(JUMP_IF_TRUE_OR_POP, 0), 0) | 
					
						
							|  |  |  |         self.assertEqual(stack_effect(JUMP_IF_TRUE_OR_POP, 0, jump=True), 0) | 
					
						
							|  |  |  |         self.assertEqual(stack_effect(JUMP_IF_TRUE_OR_POP, 0, jump=False), -1) | 
					
						
							|  |  |  |         FOR_ITER = dis.opmap['FOR_ITER'] | 
					
						
							|  |  |  |         self.assertEqual(stack_effect(FOR_ITER, 0), 1) | 
					
						
							|  |  |  |         self.assertEqual(stack_effect(FOR_ITER, 0, jump=True), -1) | 
					
						
							|  |  |  |         self.assertEqual(stack_effect(FOR_ITER, 0, jump=False), 1) | 
					
						
							|  |  |  |         JUMP_FORWARD = dis.opmap['JUMP_FORWARD'] | 
					
						
							|  |  |  |         self.assertEqual(stack_effect(JUMP_FORWARD, 0), 0) | 
					
						
							|  |  |  |         self.assertEqual(stack_effect(JUMP_FORWARD, 0, jump=True), 0) | 
					
						
							|  |  |  |         self.assertEqual(stack_effect(JUMP_FORWARD, 0, jump=False), 0) | 
					
						
							|  |  |  |         # All defined opcodes | 
					
						
							|  |  |  |         has_jump = dis.hasjabs + dis.hasjrel | 
					
						
							|  |  |  |         for name, code in dis.opmap.items(): | 
					
						
							|  |  |  |             with self.subTest(opname=name): | 
					
						
							|  |  |  |                 if code < dis.HAVE_ARGUMENT: | 
					
						
							|  |  |  |                     common = stack_effect(code) | 
					
						
							|  |  |  |                     jump = stack_effect(code, jump=True) | 
					
						
							|  |  |  |                     nojump = stack_effect(code, jump=False) | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     common = stack_effect(code, 0) | 
					
						
							|  |  |  |                     jump = stack_effect(code, 0, jump=True) | 
					
						
							|  |  |  |                     nojump = stack_effect(code, 0, jump=False) | 
					
						
							|  |  |  |                 if code in has_jump: | 
					
						
							|  |  |  |                     self.assertEqual(common, max(jump, nojump)) | 
					
						
							|  |  |  |                 else: | 
					
						
							|  |  |  |                     self.assertEqual(jump, common) | 
					
						
							|  |  |  |                     self.assertEqual(nojump, common) | 
					
						
							| 
									
										
										
										
											2018-04-25 22:04:06 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-23 14:49:22 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | if __name__ == "__main__": | 
					
						
							| 
									
										
										
										
											2015-04-13 15:00:43 -05:00
										 |  |  |     unittest.main() |