| 
									
										
										
										
											2023-09-07 20:53:38 +03:00
										 |  |  | import contextlib | 
					
						
							| 
									
										
										
										
											2023-09-12 04:30:07 +02:00
										 |  |  | import os | 
					
						
							|  |  |  | import sys | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  | import tempfile | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  | import unittest | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-07 20:53:38 +03:00
										 |  |  | from test import support | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  | from test import test_tools | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-12 04:30:07 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | def skip_if_different_mount_drives(): | 
					
						
							| 
									
										
										
										
											2024-01-13 01:30:27 +08:00
										 |  |  |     if sys.platform != "win32": | 
					
						
							| 
									
										
										
										
											2023-09-12 04:30:07 +02:00
										 |  |  |         return | 
					
						
							|  |  |  |     ROOT = os.path.dirname(os.path.dirname(__file__)) | 
					
						
							|  |  |  |     root_drive = os.path.splitroot(ROOT)[0] | 
					
						
							|  |  |  |     cwd_drive = os.path.splitroot(os.getcwd())[0] | 
					
						
							|  |  |  |     if root_drive != cwd_drive: | 
					
						
							| 
									
										
										
										
											2023-12-21 12:46:28 +00:00
										 |  |  |         # May raise ValueError if ROOT and the current working | 
					
						
							|  |  |  |         # different have different mount drives (on Windows). | 
					
						
							| 
									
										
										
										
											2023-09-12 04:30:07 +02:00
										 |  |  |         raise unittest.SkipTest( | 
					
						
							|  |  |  |             f"the current working directory and the Python source code " | 
					
						
							|  |  |  |             f"directory have different mount drives " | 
					
						
							|  |  |  |             f"({cwd_drive} and {root_drive})" | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2024-01-13 01:30:27 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-12 04:30:07 +02:00
										 |  |  | skip_if_different_mount_drives() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-13 01:30:27 +08:00
										 |  |  | test_tools.skip_if_missing("cases_generator") | 
					
						
							|  |  |  | with test_tools.imports_under_tool("cases_generator"): | 
					
						
							| 
									
										
										
										
											2023-12-21 12:46:28 +00:00
										 |  |  |     from analyzer import StackItem | 
					
						
							|  |  |  |     import parser | 
					
						
							|  |  |  |     from stack import Stack | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |     import tier1_generator | 
					
						
							| 
									
										
										
										
											2024-02-26 08:42:53 -08:00
										 |  |  |     import optimizer_generator | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-07 20:53:38 +03:00
										 |  |  | def handle_stderr(): | 
					
						
							|  |  |  |     if support.verbose > 1: | 
					
						
							|  |  |  |         return contextlib.nullcontext() | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         return support.captured_stderr() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-13 01:30:27 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  | class TestEffects(unittest.TestCase): | 
					
						
							|  |  |  |     def test_effect_sizes(self): | 
					
						
							| 
									
										
										
										
											2023-12-21 12:46:28 +00:00
										 |  |  |         stack = Stack() | 
					
						
							|  |  |  |         inputs = [ | 
					
						
							| 
									
										
										
										
											2024-01-13 01:30:27 +08:00
										 |  |  |             x := StackItem("x", None, "", "1"), | 
					
						
							|  |  |  |             y := StackItem("y", None, "", "oparg"), | 
					
						
							|  |  |  |             z := StackItem("z", None, "", "oparg*2"), | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         ] | 
					
						
							| 
									
										
										
										
											2023-12-21 12:46:28 +00:00
										 |  |  |         outputs = [ | 
					
						
							|  |  |  |             StackItem("x", None, "", "1"), | 
					
						
							|  |  |  |             StackItem("b", None, "", "oparg*4"), | 
					
						
							|  |  |  |             StackItem("c", None, "", "1"), | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         ] | 
					
						
							| 
									
										
										
										
											2023-12-21 12:46:28 +00:00
										 |  |  |         stack.pop(z) | 
					
						
							|  |  |  |         stack.pop(y) | 
					
						
							|  |  |  |         stack.pop(x) | 
					
						
							|  |  |  |         for out in outputs: | 
					
						
							|  |  |  |             stack.push(out) | 
					
						
							|  |  |  |         self.assertEqual(stack.base_offset.to_c(), "-1 - oparg*2 - oparg") | 
					
						
							|  |  |  |         self.assertEqual(stack.top_offset.to_c(), "1 - oparg*2 - oparg + oparg*4") | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TestGeneratedCases(unittest.TestCase): | 
					
						
							|  |  |  |     def setUp(self) -> None: | 
					
						
							|  |  |  |         super().setUp() | 
					
						
							| 
									
										
										
										
											2023-08-04 09:35:56 -07:00
										 |  |  |         self.maxDiff = None | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         self.temp_dir = tempfile.gettempdir() | 
					
						
							|  |  |  |         self.temp_input_filename = os.path.join(self.temp_dir, "input.txt") | 
					
						
							|  |  |  |         self.temp_output_filename = os.path.join(self.temp_dir, "output.txt") | 
					
						
							|  |  |  |         self.temp_metadata_filename = os.path.join(self.temp_dir, "metadata.txt") | 
					
						
							|  |  |  |         self.temp_pymetadata_filename = os.path.join(self.temp_dir, "pymetadata.txt") | 
					
						
							|  |  |  |         self.temp_executor_filename = os.path.join(self.temp_dir, "executor.txt") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def tearDown(self) -> None: | 
					
						
							|  |  |  |         for filename in [ | 
					
						
							|  |  |  |             self.temp_input_filename, | 
					
						
							|  |  |  |             self.temp_output_filename, | 
					
						
							|  |  |  |             self.temp_metadata_filename, | 
					
						
							|  |  |  |             self.temp_pymetadata_filename, | 
					
						
							|  |  |  |             self.temp_executor_filename, | 
					
						
							|  |  |  |         ]: | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 os.remove(filename) | 
					
						
							|  |  |  |             except: | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  |         super().tearDown() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def run_cases_test(self, input: str, expected: str): | 
					
						
							|  |  |  |         with open(self.temp_input_filename, "w+") as temp_input: | 
					
						
							| 
									
										
										
										
											2023-12-21 12:46:28 +00:00
										 |  |  |             temp_input.write(parser.BEGIN_MARKER) | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |             temp_input.write(input) | 
					
						
							| 
									
										
										
										
											2023-12-21 12:46:28 +00:00
										 |  |  |             temp_input.write(parser.END_MARKER) | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |             temp_input.flush() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-07 20:53:38 +03:00
										 |  |  |         with handle_stderr(): | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |             tier1_generator.generate_tier1_from_files( | 
					
						
							| 
									
										
										
										
											2024-01-13 01:30:27 +08:00
										 |  |  |                 [self.temp_input_filename], self.temp_output_filename, False | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |             ) | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |         with open(self.temp_output_filename) as temp_output: | 
					
						
							|  |  |  |             lines = temp_output.readlines() | 
					
						
							| 
									
										
										
										
											2023-11-01 13:13:02 -07:00
										 |  |  |             while lines and lines[0].startswith(("// ", "#", "    #", "\n")): | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |                 lines.pop(0) | 
					
						
							| 
									
										
										
										
											2023-11-01 13:13:02 -07:00
										 |  |  |             while lines and lines[-1].startswith(("#", "\n")): | 
					
						
							|  |  |  |                 lines.pop(-1) | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         actual = "".join(lines) | 
					
						
							| 
									
										
										
										
											2023-11-01 13:13:02 -07:00
										 |  |  |         # if actual.strip() != expected.strip(): | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         #     print("Actual:") | 
					
						
							|  |  |  |         #     print(actual) | 
					
						
							|  |  |  |         #     print("Expected:") | 
					
						
							|  |  |  |         #     print(expected) | 
					
						
							|  |  |  |         #     print("End") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-01 13:13:02 -07:00
										 |  |  |         self.assertEqual(actual.strip(), expected.strip()) | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_inst_no_args(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |         inst(OP, (--)) { | 
					
						
							|  |  |  |             spam(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         output = """
 | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |         TARGET(OP) { | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |             spam(); | 
					
						
							|  |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         self.run_cases_test(input, output) | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |     def test_inst_one_pop(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |         inst(OP, (value --)) { | 
					
						
							|  |  |  |             spam(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         output = """
 | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |         TARGET(OP) { | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							| 
									
										
										
										
											2023-08-04 09:35:56 -07:00
										 |  |  |             PyObject *value; | 
					
						
							|  |  |  |             value = stack_pointer[-1]; | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |             spam(); | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |             stack_pointer += -1; | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         self.run_cases_test(input, output) | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |     def test_inst_one_push(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |         inst(OP, (-- res)) { | 
					
						
							|  |  |  |             spam(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         output = """
 | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |         TARGET(OP) { | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |             PyObject *res; | 
					
						
							|  |  |  |             spam(); | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |             stack_pointer[0] = res; | 
					
						
							|  |  |  |             stack_pointer += 1; | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         self.run_cases_test(input, output) | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |     def test_inst_one_push_one_pop(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |         inst(OP, (value -- res)) { | 
					
						
							|  |  |  |             spam(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         output = """
 | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |         TARGET(OP) { | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							| 
									
										
										
										
											2023-08-04 09:35:56 -07:00
										 |  |  |             PyObject *value; | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |             PyObject *res; | 
					
						
							| 
									
										
										
										
											2023-08-04 09:35:56 -07:00
										 |  |  |             value = stack_pointer[-1]; | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |             spam(); | 
					
						
							| 
									
										
										
										
											2023-06-12 14:55:15 -07:00
										 |  |  |             stack_pointer[-1] = res; | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         self.run_cases_test(input, output) | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |     def test_binary_op(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |         inst(OP, (left, right -- res)) { | 
					
						
							|  |  |  |             spam(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         output = """
 | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |         TARGET(OP) { | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							| 
									
										
										
										
											2023-08-04 09:35:56 -07:00
										 |  |  |             PyObject *right; | 
					
						
							|  |  |  |             PyObject *left; | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |             PyObject *res; | 
					
						
							| 
									
										
										
										
											2023-08-04 09:35:56 -07:00
										 |  |  |             right = stack_pointer[-1]; | 
					
						
							|  |  |  |             left = stack_pointer[-2]; | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |             spam(); | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |             stack_pointer[-2] = res; | 
					
						
							|  |  |  |             stack_pointer += -1; | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         self.run_cases_test(input, output) | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |     def test_overlap(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							| 
									
										
										
										
											2023-01-17 15:59:19 -08:00
										 |  |  |         inst(OP, (left, right -- left, result)) { | 
					
						
							|  |  |  |             spam(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         output = """
 | 
					
						
							| 
									
										
										
										
											2023-01-17 15:59:19 -08:00
										 |  |  |         TARGET(OP) { | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							| 
									
										
										
										
											2023-08-04 09:35:56 -07:00
										 |  |  |             PyObject *right; | 
					
						
							|  |  |  |             PyObject *left; | 
					
						
							| 
									
										
										
										
											2023-01-17 15:59:19 -08:00
										 |  |  |             PyObject *result; | 
					
						
							| 
									
										
										
										
											2023-08-04 09:35:56 -07:00
										 |  |  |             right = stack_pointer[-1]; | 
					
						
							|  |  |  |             left = stack_pointer[-2]; | 
					
						
							| 
									
										
										
										
											2023-01-17 15:59:19 -08:00
										 |  |  |             spam(); | 
					
						
							| 
									
										
										
										
											2023-06-12 14:55:15 -07:00
										 |  |  |             stack_pointer[-1] = result; | 
					
						
							| 
									
										
										
										
											2023-01-17 15:59:19 -08:00
										 |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         self.run_cases_test(input, output) | 
					
						
							| 
									
										
										
										
											2023-01-17 15:59:19 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |     def test_predictions_and_eval_breaker(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							| 
									
										
										
										
											2023-10-03 10:13:50 -07:00
										 |  |  |         inst(OP1, (arg -- rest)) { | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-02-07 20:03:22 -08:00
										 |  |  |         inst(OP3, (arg -- res)) { | 
					
						
							| 
									
										
										
										
											2023-10-03 10:13:50 -07:00
										 |  |  |             DEOPT_IF(xxx); | 
					
						
							| 
									
										
										
										
											2023-02-07 20:03:22 -08:00
										 |  |  |             CHECK_EVAL_BREAKER(); | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-10-03 10:13:50 -07:00
										 |  |  |         family(OP1, INLINE_CACHE_ENTRIES_OP1) = { OP3 }; | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         output = """
 | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |         TARGET(OP1) { | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP1); | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |             PREDICTED(OP1); | 
					
						
							| 
									
										
										
										
											2023-10-03 10:13:50 -07:00
										 |  |  |             PyObject *arg; | 
					
						
							|  |  |  |             PyObject *rest; | 
					
						
							|  |  |  |             arg = stack_pointer[-1]; | 
					
						
							|  |  |  |             stack_pointer[-1] = rest; | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         TARGET(OP3) { | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP3); | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |             static_assert(INLINE_CACHE_ENTRIES_OP1 == 0, "incorrect cache size"); | 
					
						
							| 
									
										
										
										
											2023-08-04 09:35:56 -07:00
										 |  |  |             PyObject *arg; | 
					
						
							| 
									
										
										
										
											2023-02-07 20:03:22 -08:00
										 |  |  |             PyObject *res; | 
					
						
							| 
									
										
										
										
											2023-08-04 09:35:56 -07:00
										 |  |  |             arg = stack_pointer[-1]; | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |             DEOPT_IF(xxx, OP1); | 
					
						
							| 
									
										
										
										
											2023-06-12 14:55:15 -07:00
										 |  |  |             stack_pointer[-1] = res; | 
					
						
							| 
									
										
										
										
											2023-02-07 20:03:22 -08:00
										 |  |  |             CHECK_EVAL_BREAKER(); | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         self.run_cases_test(input, output) | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |     def test_error_if_plain(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |         inst(OP, (--)) { | 
					
						
							|  |  |  |             ERROR_IF(cond, label); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         output = """
 | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |         TARGET(OP) { | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |             if (cond) goto label; | 
					
						
							|  |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         self.run_cases_test(input, output) | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |     def test_error_if_plain_with_comment(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							| 
									
										
										
										
											2023-01-24 22:39:13 +00:00
										 |  |  |         inst(OP, (--)) { | 
					
						
							|  |  |  |             ERROR_IF(cond, label);  // Comment is ok | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         output = """
 | 
					
						
							| 
									
										
										
										
											2023-01-24 22:39:13 +00:00
										 |  |  |         TARGET(OP) { | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							| 
									
										
										
										
											2023-01-24 22:39:13 +00:00
										 |  |  |             if (cond) goto label; | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |             // Comment is ok | 
					
						
							| 
									
										
										
										
											2023-01-24 22:39:13 +00:00
										 |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         self.run_cases_test(input, output) | 
					
						
							| 
									
										
										
										
											2023-01-24 22:39:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |     def test_error_if_pop(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |         inst(OP, (left, right -- res)) { | 
					
						
							|  |  |  |             ERROR_IF(cond, label); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         output = """
 | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |         TARGET(OP) { | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							| 
									
										
										
										
											2023-08-04 09:35:56 -07:00
										 |  |  |             PyObject *right; | 
					
						
							|  |  |  |             PyObject *left; | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |             PyObject *res; | 
					
						
							| 
									
										
										
										
											2023-08-04 09:35:56 -07:00
										 |  |  |             right = stack_pointer[-1]; | 
					
						
							|  |  |  |             left = stack_pointer[-2]; | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |             if (cond) goto pop_2_label; | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |             stack_pointer[-2] = res; | 
					
						
							|  |  |  |             stack_pointer += -1; | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         self.run_cases_test(input, output) | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |     def test_cache_effect(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |         inst(OP, (counter/1, extra/2, value --)) { | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         output = """
 | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |         TARGET(OP) { | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; | 
					
						
							| 
									
										
										
										
											2024-02-29 18:53:32 -08:00
										 |  |  |             (void)this_instr; | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             next_instr += 4; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							| 
									
										
										
										
											2023-08-04 09:35:56 -07:00
										 |  |  |             PyObject *value; | 
					
						
							|  |  |  |             value = stack_pointer[-1]; | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             uint16_t counter = read_u16(&this_instr[1].cache); | 
					
						
							| 
									
										
										
										
											2024-02-29 18:53:32 -08:00
										 |  |  |             (void)counter; | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             uint32_t extra = read_u32(&this_instr[2].cache); | 
					
						
							| 
									
										
										
										
											2024-02-29 18:53:32 -08:00
										 |  |  |             (void)extra; | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |             stack_pointer += -1; | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         self.run_cases_test(input, output) | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |     def test_suppress_dispatch(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |         inst(OP, (--)) { | 
					
						
							|  |  |  |             goto somewhere; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         output = """
 | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |         TARGET(OP) { | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |             goto somewhere; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         self.run_cases_test(input, output) | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |     def test_macro_instruction(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							| 
									
										
										
										
											2023-01-30 11:23:57 -08:00
										 |  |  |         inst(OP1, (counter/1, left, right -- left, right)) { | 
					
						
							|  |  |  |             op1(left, right); | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-01-30 11:23:57 -08:00
										 |  |  |         op(OP2, (extra/2, arg2, left, right -- res)) { | 
					
						
							|  |  |  |             res = op2(arg2, left, right); | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |         } | 
					
						
							|  |  |  |         macro(OP) = OP1 + cache/2 + OP2; | 
					
						
							| 
									
										
										
										
											2023-01-30 11:23:57 -08:00
										 |  |  |         inst(OP3, (unused/5, arg2, left, right -- res)) { | 
					
						
							|  |  |  |             res = op3(arg2, left, right); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-07-16 11:16:34 -04:00
										 |  |  |         family(OP, INLINE_CACHE_ENTRIES_OP) = { OP3 }; | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         output = """
 | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |         TARGET(OP) { | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 6; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							| 
									
										
										
										
											2023-10-03 10:13:50 -07:00
										 |  |  |             PREDICTED(OP); | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             _Py_CODEUNIT *this_instr = next_instr - 6; | 
					
						
							| 
									
										
										
										
											2024-02-29 18:53:32 -08:00
										 |  |  |             (void)this_instr; | 
					
						
							| 
									
										
										
										
											2023-08-04 09:35:56 -07:00
										 |  |  |             PyObject *right; | 
					
						
							|  |  |  |             PyObject *left; | 
					
						
							|  |  |  |             PyObject *arg2; | 
					
						
							|  |  |  |             PyObject *res; | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |             // _OP1 | 
					
						
							| 
									
										
										
										
											2023-08-04 09:35:56 -07:00
										 |  |  |             right = stack_pointer[-1]; | 
					
						
							|  |  |  |             left = stack_pointer[-2]; | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |             { | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |                 uint16_t counter = read_u16(&this_instr[1].cache); | 
					
						
							| 
									
										
										
										
											2024-02-29 18:53:32 -08:00
										 |  |  |                 (void)counter; | 
					
						
							| 
									
										
										
										
											2023-01-30 11:23:57 -08:00
										 |  |  |                 op1(left, right); | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |             /* Skip 2 cache entries */ | 
					
						
							| 
									
										
										
										
											2023-08-04 09:35:56 -07:00
										 |  |  |             // OP2 | 
					
						
							|  |  |  |             arg2 = stack_pointer[-3]; | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |             { | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |                 uint32_t extra = read_u32(&this_instr[4].cache); | 
					
						
							| 
									
										
										
										
											2024-02-29 18:53:32 -08:00
										 |  |  |                 (void)extra; | 
					
						
							| 
									
										
										
										
											2023-01-30 11:23:57 -08:00
										 |  |  |                 res = op2(arg2, left, right); | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |             stack_pointer[-3] = res; | 
					
						
							|  |  |  |             stack_pointer += -2; | 
					
						
							| 
									
										
										
										
											2023-01-30 11:23:57 -08:00
										 |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-22 15:19:50 +00:00
										 |  |  |         TARGET(OP1) { | 
					
						
							|  |  |  |             _Py_CODEUNIT *this_instr = frame->instr_ptr = next_instr; | 
					
						
							| 
									
										
										
										
											2024-02-29 18:53:32 -08:00
										 |  |  |             (void)this_instr; | 
					
						
							| 
									
										
										
										
											2023-11-22 15:19:50 +00:00
										 |  |  |             next_instr += 2; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP1); | 
					
						
							|  |  |  |             PyObject *right; | 
					
						
							|  |  |  |             PyObject *left; | 
					
						
							|  |  |  |             right = stack_pointer[-1]; | 
					
						
							|  |  |  |             left = stack_pointer[-2]; | 
					
						
							|  |  |  |             uint16_t counter = read_u16(&this_instr[1].cache); | 
					
						
							| 
									
										
										
										
											2024-02-29 18:53:32 -08:00
										 |  |  |             (void)counter; | 
					
						
							| 
									
										
										
										
											2023-11-22 15:19:50 +00:00
										 |  |  |             op1(left, right); | 
					
						
							|  |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-30 11:23:57 -08:00
										 |  |  |         TARGET(OP3) { | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 6; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP3); | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |             static_assert(INLINE_CACHE_ENTRIES_OP == 5, "incorrect cache size"); | 
					
						
							| 
									
										
										
										
											2023-08-04 09:35:56 -07:00
										 |  |  |             PyObject *right; | 
					
						
							|  |  |  |             PyObject *left; | 
					
						
							|  |  |  |             PyObject *arg2; | 
					
						
							| 
									
										
										
										
											2023-01-30 11:23:57 -08:00
										 |  |  |             PyObject *res; | 
					
						
							| 
									
										
										
										
											2023-12-18 13:16:45 +00:00
										 |  |  |             /* Skip 5 cache entries */ | 
					
						
							| 
									
										
										
										
											2023-08-04 09:35:56 -07:00
										 |  |  |             right = stack_pointer[-1]; | 
					
						
							|  |  |  |             left = stack_pointer[-2]; | 
					
						
							|  |  |  |             arg2 = stack_pointer[-3]; | 
					
						
							| 
									
										
										
										
											2023-01-30 11:23:57 -08:00
										 |  |  |             res = op3(arg2, left, right); | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |             stack_pointer[-3] = res; | 
					
						
							|  |  |  |             stack_pointer += -2; | 
					
						
							|  |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |         self.run_cases_test(input, output) | 
					
						
							| 
									
										
										
										
											2023-12-18 13:16:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |     def test_unused_caches(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         inst(OP, (unused/1, unused/2 --)) { | 
					
						
							|  |  |  |             body(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         TARGET(OP) { | 
					
						
							|  |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 4; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							| 
									
										
										
										
											2023-12-18 13:16:45 +00:00
										 |  |  |             /* Skip 1 cache entry */ | 
					
						
							|  |  |  |             /* Skip 2 cache entries */ | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |             body(); | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         self.run_cases_test(input, output) | 
					
						
							| 
									
										
										
										
											2023-01-17 15:59:19 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-30 11:03:30 +00:00
										 |  |  |     def test_pseudo_instruction_no_flags(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         pseudo(OP) = { | 
					
						
							|  |  |  |             OP1, | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         inst(OP1, (--)) { | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         TARGET(OP1) { | 
					
						
							|  |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP1); | 
					
						
							|  |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |         self.run_cases_test(input, output) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_pseudo_instruction_with_flags(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         pseudo(OP, (HAS_ARG, HAS_JUMP)) = { | 
					
						
							|  |  |  |             OP1, | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         inst(OP1, (--)) { | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         TARGET(OP1) { | 
					
						
							|  |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP1); | 
					
						
							|  |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |         self.run_cases_test(input, output) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |     def test_array_input(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							| 
									
										
										
										
											2023-01-17 15:59:19 -08:00
										 |  |  |         inst(OP, (below, values[oparg*2], above --)) { | 
					
						
							|  |  |  |             spam(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         output = """
 | 
					
						
							| 
									
										
										
										
											2023-01-17 15:59:19 -08:00
										 |  |  |         TARGET(OP) { | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							| 
									
										
										
										
											2023-08-04 09:35:56 -07:00
										 |  |  |             PyObject *above; | 
					
						
							|  |  |  |             PyObject **values; | 
					
						
							|  |  |  |             PyObject *below; | 
					
						
							|  |  |  |             above = stack_pointer[-1]; | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |             values = &stack_pointer[-1 - oparg*2]; | 
					
						
							| 
									
										
										
										
											2023-08-04 09:35:56 -07:00
										 |  |  |             below = stack_pointer[-2 - oparg*2]; | 
					
						
							| 
									
										
										
										
											2023-01-17 15:59:19 -08:00
										 |  |  |             spam(); | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |             stack_pointer += -2 - oparg*2; | 
					
						
							| 
									
										
										
										
											2023-01-17 15:59:19 -08:00
										 |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         self.run_cases_test(input, output) | 
					
						
							| 
									
										
										
										
											2023-01-17 15:59:19 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |     def test_array_output(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							| 
									
										
										
										
											2023-02-07 15:44:37 -08:00
										 |  |  |         inst(OP, (unused, unused -- below, values[oparg*3], above)) { | 
					
						
							|  |  |  |             spam(values, oparg); | 
					
						
							| 
									
										
										
										
											2023-01-17 15:59:19 -08:00
										 |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         output = """
 | 
					
						
							| 
									
										
										
										
											2023-01-17 15:59:19 -08:00
										 |  |  |         TARGET(OP) { | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							| 
									
										
										
										
											2023-01-17 15:59:19 -08:00
										 |  |  |             PyObject *below; | 
					
						
							| 
									
										
										
										
											2023-08-04 09:35:56 -07:00
										 |  |  |             PyObject **values; | 
					
						
							| 
									
										
										
										
											2023-01-17 15:59:19 -08:00
										 |  |  |             PyObject *above; | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |             values = &stack_pointer[-1]; | 
					
						
							| 
									
										
										
										
											2023-02-07 15:44:37 -08:00
										 |  |  |             spam(values, oparg); | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |             stack_pointer[-2] = below; | 
					
						
							|  |  |  |             stack_pointer[-1 + oparg*3] = above; | 
					
						
							|  |  |  |             stack_pointer += oparg*3; | 
					
						
							| 
									
										
										
										
											2023-01-17 15:59:19 -08:00
										 |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         self.run_cases_test(input, output) | 
					
						
							| 
									
										
										
										
											2023-01-17 15:59:19 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |     def test_array_input_output(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							| 
									
										
										
										
											2023-02-07 15:44:37 -08:00
										 |  |  |         inst(OP, (values[oparg] -- values[oparg], above)) { | 
					
						
							|  |  |  |             spam(values, oparg); | 
					
						
							| 
									
										
										
										
											2023-01-17 15:59:19 -08:00
										 |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         output = """
 | 
					
						
							| 
									
										
										
										
											2023-01-17 15:59:19 -08:00
										 |  |  |         TARGET(OP) { | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							| 
									
										
										
										
											2023-08-04 09:35:56 -07:00
										 |  |  |             PyObject **values; | 
					
						
							| 
									
										
										
										
											2023-01-17 15:59:19 -08:00
										 |  |  |             PyObject *above; | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |             values = &stack_pointer[-oparg]; | 
					
						
							| 
									
										
										
										
											2023-02-07 15:44:37 -08:00
										 |  |  |             spam(values, oparg); | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |             stack_pointer[0] = above; | 
					
						
							|  |  |  |             stack_pointer += 1; | 
					
						
							| 
									
										
										
										
											2023-01-17 15:59:19 -08:00
										 |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         self.run_cases_test(input, output) | 
					
						
							| 
									
										
										
										
											2023-01-17 15:59:19 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |     def test_array_error_if(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							| 
									
										
										
										
											2023-01-17 15:59:19 -08:00
										 |  |  |         inst(OP, (extra, values[oparg] --)) { | 
					
						
							|  |  |  |             ERROR_IF(oparg == 0, somewhere); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         output = """
 | 
					
						
							| 
									
										
										
										
											2023-01-17 15:59:19 -08:00
										 |  |  |         TARGET(OP) { | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							| 
									
										
										
										
											2023-08-04 09:35:56 -07:00
										 |  |  |             PyObject **values; | 
					
						
							|  |  |  |             PyObject *extra; | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |             values = &stack_pointer[-oparg]; | 
					
						
							| 
									
										
										
										
											2023-08-04 09:35:56 -07:00
										 |  |  |             extra = stack_pointer[-1 - oparg]; | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |             if (oparg == 0) { stack_pointer += -1 - oparg; goto somewhere; } | 
					
						
							|  |  |  |             stack_pointer += -1 - oparg; | 
					
						
							| 
									
										
										
										
											2023-01-17 15:59:19 -08:00
										 |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         self.run_cases_test(input, output) | 
					
						
							| 
									
										
										
										
											2023-01-25 08:55:46 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |     def test_cond_effect(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							| 
									
										
										
										
											2023-02-07 17:35:55 -08:00
										 |  |  |         inst(OP, (aa, input if ((oparg & 1) == 1), cc -- xx, output if (oparg & 2), zz)) { | 
					
						
							| 
									
										
										
										
											2023-01-29 17:28:39 -08:00
										 |  |  |             output = spam(oparg, input); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         output = """
 | 
					
						
							| 
									
										
										
										
											2023-01-29 17:28:39 -08:00
										 |  |  |         TARGET(OP) { | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							| 
									
										
										
										
											2023-08-04 09:35:56 -07:00
										 |  |  |             PyObject *cc; | 
					
						
							|  |  |  |             PyObject *input = NULL; | 
					
						
							|  |  |  |             PyObject *aa; | 
					
						
							| 
									
										
										
										
											2023-01-29 17:28:39 -08:00
										 |  |  |             PyObject *xx; | 
					
						
							|  |  |  |             PyObject *output = NULL; | 
					
						
							|  |  |  |             PyObject *zz; | 
					
						
							| 
									
										
										
										
											2023-08-04 09:35:56 -07:00
										 |  |  |             cc = stack_pointer[-1]; | 
					
						
							| 
									
										
										
										
											2023-12-21 12:46:28 +00:00
										 |  |  |             if ((oparg & 1) == 1) { input = stack_pointer[-1 - (((oparg & 1) == 1) ? 1 : 0)]; } | 
					
						
							|  |  |  |             aa = stack_pointer[-2 - (((oparg & 1) == 1) ? 1 : 0)]; | 
					
						
							| 
									
										
										
										
											2023-01-29 17:28:39 -08:00
										 |  |  |             output = spam(oparg, input); | 
					
						
							| 
									
										
										
										
											2023-12-21 12:46:28 +00:00
										 |  |  |             stack_pointer[-2 - (((oparg & 1) == 1) ? 1 : 0)] = xx; | 
					
						
							|  |  |  |             if (oparg & 2) stack_pointer[-1 - (((oparg & 1) == 1) ? 1 : 0)] = output; | 
					
						
							|  |  |  |             stack_pointer[-1 - (((oparg & 1) == 1) ? 1 : 0) + ((oparg & 2) ? 1 : 0)] = zz; | 
					
						
							|  |  |  |             stack_pointer += -(((oparg & 1) == 1) ? 1 : 0) + ((oparg & 2) ? 1 : 0); | 
					
						
							| 
									
										
										
										
											2023-01-29 17:28:39 -08:00
										 |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         self.run_cases_test(input, output) | 
					
						
							| 
									
										
										
										
											2023-06-14 13:50:48 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |     def test_macro_cond_effect(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							| 
									
										
										
										
											2023-06-14 13:50:48 -07:00
										 |  |  |         op(A, (left, middle, right --)) { | 
					
						
							|  |  |  |             # Body of A | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         op(B, (-- deep, extra if (oparg), res)) { | 
					
						
							|  |  |  |             # Body of B | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         macro(M) = A + B; | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         output = """
 | 
					
						
							| 
									
										
										
										
											2023-06-14 13:50:48 -07:00
										 |  |  |         TARGET(M) { | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(M); | 
					
						
							| 
									
										
										
										
											2023-08-04 09:35:56 -07:00
										 |  |  |             PyObject *right; | 
					
						
							|  |  |  |             PyObject *middle; | 
					
						
							|  |  |  |             PyObject *left; | 
					
						
							|  |  |  |             PyObject *deep; | 
					
						
							|  |  |  |             PyObject *extra = NULL; | 
					
						
							|  |  |  |             PyObject *res; | 
					
						
							|  |  |  |             // A | 
					
						
							|  |  |  |             right = stack_pointer[-1]; | 
					
						
							|  |  |  |             middle = stack_pointer[-2]; | 
					
						
							|  |  |  |             left = stack_pointer[-3]; | 
					
						
							| 
									
										
										
										
											2023-06-14 13:50:48 -07:00
										 |  |  |             { | 
					
						
							|  |  |  |                 # Body of A | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2023-08-04 09:35:56 -07:00
										 |  |  |             // B | 
					
						
							| 
									
										
										
										
											2023-06-14 13:50:48 -07:00
										 |  |  |             { | 
					
						
							|  |  |  |                 # Body of B | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |             stack_pointer[-3] = deep; | 
					
						
							|  |  |  |             if (oparg) stack_pointer[-2] = extra; | 
					
						
							| 
									
										
										
										
											2023-12-21 12:46:28 +00:00
										 |  |  |             stack_pointer[-2 + ((oparg) ? 1 : 0)] = res; | 
					
						
							|  |  |  |             stack_pointer += -1 + ((oparg) ? 1 : 0); | 
					
						
							| 
									
										
										
										
											2023-06-14 13:50:48 -07:00
										 |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         self.run_cases_test(input, output) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-05 13:58:39 -07:00
										 |  |  |     def test_macro_push_push(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         op(A, (-- val1)) { | 
					
						
							|  |  |  |             val1 = spam(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         op(B, (-- val2)) { | 
					
						
							|  |  |  |             val2 = spam(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         macro(M) = A + B; | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         TARGET(M) { | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(M); | 
					
						
							| 
									
										
										
										
											2023-09-05 13:58:39 -07:00
										 |  |  |             PyObject *val1; | 
					
						
							|  |  |  |             PyObject *val2; | 
					
						
							|  |  |  |             // A | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 val1 = spam(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             // B | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 val2 = spam(); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |             stack_pointer[0] = val1; | 
					
						
							|  |  |  |             stack_pointer[1] = val2; | 
					
						
							|  |  |  |             stack_pointer += 2; | 
					
						
							| 
									
										
										
										
											2023-09-05 13:58:39 -07:00
										 |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         self.run_cases_test(input, output) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-05 15:05:29 -07:00
										 |  |  |     def test_override_inst(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         inst(OP, (--)) { | 
					
						
							|  |  |  |             spam(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         override inst(OP, (--)) { | 
					
						
							|  |  |  |             ham(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         TARGET(OP) { | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							| 
									
										
										
										
											2023-10-05 15:05:29 -07:00
										 |  |  |             ham(); | 
					
						
							|  |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         self.run_cases_test(input, output) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_override_op(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         op(OP, (--)) { | 
					
						
							|  |  |  |             spam(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         macro(M) = OP; | 
					
						
							|  |  |  |         override op(OP, (--)) { | 
					
						
							|  |  |  |             ham(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         TARGET(M) { | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(M); | 
					
						
							| 
									
										
										
										
											2023-10-05 15:05:29 -07:00
										 |  |  |             ham(); | 
					
						
							|  |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         self.run_cases_test(input, output) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-07 09:42:39 +00:00
										 |  |  |     def test_annotated_inst(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							| 
									
										
										
										
											2024-01-13 01:30:27 +08:00
										 |  |  |         pure inst(OP, (--)) { | 
					
						
							| 
									
										
										
										
											2023-11-07 09:42:39 +00:00
										 |  |  |             ham(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         TARGET(OP) { | 
					
						
							|  |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							|  |  |  |             ham(); | 
					
						
							|  |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         self.run_cases_test(input, output) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_annotated_op(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							| 
									
										
										
										
											2024-01-13 01:30:27 +08:00
										 |  |  |         pure op(OP, (--)) { | 
					
						
							| 
									
										
										
										
											2023-11-07 09:42:39 +00:00
										 |  |  |             spam(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         macro(M) = OP; | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         TARGET(M) { | 
					
						
							|  |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(M); | 
					
						
							|  |  |  |             spam(); | 
					
						
							|  |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         self.run_cases_test(input, output) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         input = """
 | 
					
						
							| 
									
										
										
										
											2024-01-13 01:30:27 +08:00
										 |  |  |         pure register specializing op(OP, (--)) { | 
					
						
							| 
									
										
										
										
											2023-11-07 09:42:39 +00:00
										 |  |  |             spam(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         macro(M) = OP; | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         self.run_cases_test(input, output) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-20 09:39:55 +00:00
										 |  |  |     def test_deopt_and_exit(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         pure op(OP, (arg1 -- out)) { | 
					
						
							|  |  |  |             DEOPT_IF(1); | 
					
						
							|  |  |  |             EXIT_IF(1); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         output = "" | 
					
						
							|  |  |  |         with self.assertRaises(Exception): | 
					
						
							|  |  |  |             self.run_cases_test(input, output) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-26 10:51:42 +01:00
										 |  |  |     def test_pop_on_error_peeks(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         op(FIRST, (x, y -- a, b)) { | 
					
						
							|  |  |  |             a = x; | 
					
						
							|  |  |  |             b = y; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         op(SECOND, (a, b -- a, b)) { | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         op(THIRD, (j, k --)) { | 
					
						
							|  |  |  |             ERROR_IF(cond, error); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         macro(TEST) = FIRST + SECOND + THIRD; | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         TARGET(TEST) { | 
					
						
							|  |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(TEST); | 
					
						
							|  |  |  |             PyObject *y; | 
					
						
							|  |  |  |             PyObject *x; | 
					
						
							|  |  |  |             PyObject *a; | 
					
						
							|  |  |  |             PyObject *b; | 
					
						
							|  |  |  |             PyObject *k; | 
					
						
							|  |  |  |             PyObject *j; | 
					
						
							|  |  |  |             // FIRST | 
					
						
							|  |  |  |             y = stack_pointer[-1]; | 
					
						
							|  |  |  |             x = stack_pointer[-2]; | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 a = x; | 
					
						
							|  |  |  |                 b = y; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             // SECOND | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             // THIRD | 
					
						
							|  |  |  |             k = b; | 
					
						
							|  |  |  |             j = a; | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 if (cond) goto pop_2_error; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             stack_pointer += -2; | 
					
						
							|  |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         self.run_cases_test(input, output) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-13 21:24:48 +08:00
										 |  |  | class TestGeneratedAbstractCases(unittest.TestCase): | 
					
						
							|  |  |  |     def setUp(self) -> None: | 
					
						
							|  |  |  |         super().setUp() | 
					
						
							|  |  |  |         self.maxDiff = None | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.temp_dir = tempfile.gettempdir() | 
					
						
							|  |  |  |         self.temp_input_filename = os.path.join(self.temp_dir, "input.txt") | 
					
						
							|  |  |  |         self.temp_input2_filename = os.path.join(self.temp_dir, "input2.txt") | 
					
						
							|  |  |  |         self.temp_output_filename = os.path.join(self.temp_dir, "output.txt") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def tearDown(self) -> None: | 
					
						
							|  |  |  |         for filename in [ | 
					
						
							|  |  |  |             self.temp_input_filename, | 
					
						
							|  |  |  |             self.temp_input2_filename, | 
					
						
							|  |  |  |             self.temp_output_filename, | 
					
						
							|  |  |  |         ]: | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 os.remove(filename) | 
					
						
							|  |  |  |             except: | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  |         super().tearDown() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def run_cases_test(self, input: str, input2: str, expected: str): | 
					
						
							|  |  |  |         with open(self.temp_input_filename, "w+") as temp_input: | 
					
						
							|  |  |  |             temp_input.write(parser.BEGIN_MARKER) | 
					
						
							|  |  |  |             temp_input.write(input) | 
					
						
							|  |  |  |             temp_input.write(parser.END_MARKER) | 
					
						
							|  |  |  |             temp_input.flush() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with open(self.temp_input2_filename, "w+") as temp_input: | 
					
						
							|  |  |  |             temp_input.write(parser.BEGIN_MARKER) | 
					
						
							|  |  |  |             temp_input.write(input2) | 
					
						
							|  |  |  |             temp_input.write(parser.END_MARKER) | 
					
						
							|  |  |  |             temp_input.flush() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with handle_stderr(): | 
					
						
							| 
									
										
										
										
											2024-02-26 08:42:53 -08:00
										 |  |  |             optimizer_generator.generate_tier2_abstract_from_files( | 
					
						
							| 
									
										
										
										
											2024-02-13 21:24:48 +08:00
										 |  |  |                 [self.temp_input_filename, self.temp_input2_filename], | 
					
						
							|  |  |  |                 self.temp_output_filename | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with open(self.temp_output_filename) as temp_output: | 
					
						
							|  |  |  |             lines = temp_output.readlines() | 
					
						
							|  |  |  |             while lines and lines[0].startswith(("// ", "#", "    #", "\n")): | 
					
						
							|  |  |  |                 lines.pop(0) | 
					
						
							|  |  |  |             while lines and lines[-1].startswith(("#", "\n")): | 
					
						
							|  |  |  |                 lines.pop(-1) | 
					
						
							|  |  |  |         actual = "".join(lines) | 
					
						
							|  |  |  |         self.assertEqual(actual.strip(), expected.strip()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_overridden_abstract(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         pure op(OP, (--)) { | 
					
						
							|  |  |  |             spam(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         input2 = """
 | 
					
						
							|  |  |  |         pure op(OP, (--)) { | 
					
						
							|  |  |  |             eggs(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         case OP: { | 
					
						
							|  |  |  |             eggs(); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         self.run_cases_test(input, input2, output) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_overridden_abstract_args(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         pure op(OP, (arg1 -- out)) { | 
					
						
							|  |  |  |             spam(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         op(OP2, (arg1 -- out)) { | 
					
						
							|  |  |  |             eggs(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         input2 = """
 | 
					
						
							|  |  |  |         op(OP, (arg1 -- out)) { | 
					
						
							|  |  |  |             eggs(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         case OP: { | 
					
						
							| 
									
										
										
										
											2024-02-27 13:25:02 +00:00
										 |  |  |             _Py_UopsSymbol *arg1; | 
					
						
							|  |  |  |             _Py_UopsSymbol *out; | 
					
						
							| 
									
										
										
										
											2024-02-13 21:24:48 +08:00
										 |  |  |             arg1 = stack_pointer[-1]; | 
					
						
							|  |  |  |             eggs(); | 
					
						
							|  |  |  |             stack_pointer[-1] = out; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         case OP2: { | 
					
						
							| 
									
										
										
										
											2024-02-27 13:25:02 +00:00
										 |  |  |             _Py_UopsSymbol *out; | 
					
						
							| 
									
										
										
										
											2024-03-13 20:57:48 +08:00
										 |  |  |             out = sym_new_not_null(ctx); | 
					
						
							| 
									
										
										
										
											2024-02-13 21:24:48 +08:00
										 |  |  |             if (out == NULL) goto out_of_space; | 
					
						
							|  |  |  |             stack_pointer[-1] = out; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |        """
 | 
					
						
							|  |  |  |         self.run_cases_test(input, input2, output) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_no_overridden_case(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         pure op(OP, (arg1 -- out)) { | 
					
						
							|  |  |  |             spam(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         pure op(OP2, (arg1 -- out)) { | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         input2 = """
 | 
					
						
							|  |  |  |         pure op(OP2, (arg1 -- out)) { | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         case OP: { | 
					
						
							| 
									
										
										
										
											2024-02-27 13:25:02 +00:00
										 |  |  |             _Py_UopsSymbol *out; | 
					
						
							| 
									
										
										
										
											2024-03-13 20:57:48 +08:00
										 |  |  |             out = sym_new_not_null(ctx); | 
					
						
							| 
									
										
										
										
											2024-02-13 21:24:48 +08:00
										 |  |  |             if (out == NULL) goto out_of_space; | 
					
						
							|  |  |  |             stack_pointer[-1] = out; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         case OP2: { | 
					
						
							| 
									
										
										
										
											2024-02-27 13:25:02 +00:00
										 |  |  |             _Py_UopsSymbol *arg1; | 
					
						
							|  |  |  |             _Py_UopsSymbol *out; | 
					
						
							| 
									
										
										
										
											2024-02-13 21:24:48 +08:00
										 |  |  |             arg1 = stack_pointer[-1]; | 
					
						
							|  |  |  |             stack_pointer[-1] = out; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         self.run_cases_test(input, input2, output) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_missing_override_failure(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         pure op(OP, (arg1 -- out)) { | 
					
						
							|  |  |  |             spam(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         input2 = """
 | 
					
						
							|  |  |  |         pure op(OTHER, (arg1 -- out)) { | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         with self.assertRaisesRegex(AssertionError, "All abstract uops"): | 
					
						
							|  |  |  |             self.run_cases_test(input, input2, output) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  | if __name__ == "__main__": | 
					
						
							|  |  |  |     unittest.main() |