| 
									
										
										
										
											2023-09-07 20:53:38 +03:00
										 |  |  | import contextlib | 
					
						
							| 
									
										
										
										
											2023-09-12 04:30:07 +02:00
										 |  |  | import os | 
					
						
							| 
									
										
										
										
											2024-11-25 16:53:49 -08:00
										 |  |  | import re | 
					
						
							| 
									
										
										
										
											2023-09-12 04:30:07 +02:00
										 |  |  | import sys | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  | import tempfile | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  | import unittest | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-25 16:53:49 -08:00
										 |  |  | from io import StringIO | 
					
						
							| 
									
										
										
										
											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"): | 
					
						
							| 
									
										
										
										
											2024-11-25 16:53:49 -08:00
										 |  |  |     from analyzer import analyze_forest, StackItem | 
					
						
							|  |  |  |     from cwriter import CWriter | 
					
						
							| 
									
										
										
										
											2023-12-21 12:46:28 +00:00
										 |  |  |     import parser | 
					
						
							| 
									
										
										
										
											2024-08-01 09:27:26 +01:00
										 |  |  |     from stack import Local, Stack | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |     import tier1_generator | 
					
						
							| 
									
										
										
										
											2024-11-25 16:53:49 -08:00
										 |  |  |     import opcode_metadata_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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-25 16:53:49 -08:00
										 |  |  | def parse_src(src): | 
					
						
							|  |  |  |     p = parser.Parser(src, "test.c") | 
					
						
							|  |  |  |     nodes = [] | 
					
						
							|  |  |  |     while node := p.definition(): | 
					
						
							|  |  |  |         nodes.append(node) | 
					
						
							|  |  |  |     return nodes | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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 = [ | 
					
						
							| 
									
										
										
										
											2025-03-20 15:39:38 +00: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 = [ | 
					
						
							| 
									
										
										
										
											2025-03-20 15:39:38 +00:00
										 |  |  |             StackItem("x", None, "1"), | 
					
						
							|  |  |  |             StackItem("b", None, "oparg*4"), | 
					
						
							|  |  |  |             StackItem("c", None, "1"), | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         ] | 
					
						
							| 
									
										
										
										
											2025-03-31 13:52:48 +01:00
										 |  |  |         null = CWriter.null() | 
					
						
							|  |  |  |         stack.pop(z, null) | 
					
						
							|  |  |  |         stack.pop(y, null) | 
					
						
							|  |  |  |         stack.pop(x, null) | 
					
						
							| 
									
										
										
										
											2023-12-21 12:46:28 +00:00
										 |  |  |         for out in outputs: | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             stack.push(Local.undefined(out)) | 
					
						
							| 
									
										
										
										
											2024-08-01 09:27:26 +01:00
										 |  |  |         self.assertEqual(stack.base_offset.to_c(), "-1 - oparg - oparg*2") | 
					
						
							| 
									
										
										
										
											2025-03-31 13:52:48 +01:00
										 |  |  |         self.assertEqual(stack.physical_sp.to_c(), "0") | 
					
						
							|  |  |  |         self.assertEqual(stack.logical_sp.to_c(), "1 - oparg - oparg*2 + 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: | 
					
						
							| 
									
										
										
										
											2025-01-27 18:30:20 +08:00
										 |  |  |             lines = temp_output.read() | 
					
						
							|  |  |  |             _, rest = lines.split(tier1_generator.INSTRUCTION_START_MARKER) | 
					
						
							|  |  |  |             instructions, labels_with_prelude_and_postlude = rest.split(tier1_generator.INSTRUCTION_END_MARKER) | 
					
						
							|  |  |  |             _, labels_with_postlude = labels_with_prelude_and_postlude.split(tier1_generator.LABEL_START_MARKER) | 
					
						
							|  |  |  |             labels, _ = labels_with_postlude.split(tier1_generator.LABEL_END_MARKER) | 
					
						
							| 
									
										
										
										
											2025-02-04 12:18:31 +00:00
										 |  |  |             actual = instructions.strip() + "\n\n        " + labels.strip() | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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, (--)) { | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             SPAM(); | 
					
						
							| 
									
										
										
										
											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) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = OP; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             SPAM(); | 
					
						
							| 
									
										
										
										
											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_pop(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |         inst(OP, (value --)) { | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             SPAM(value); | 
					
						
							|  |  |  |             DEAD(value); | 
					
						
							| 
									
										
										
										
											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) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = OP; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							| 
									
										
										
										
											2024-06-27 03:10:43 +08:00
										 |  |  |             _PyStackRef value; | 
					
						
							| 
									
										
										
										
											2023-08-04 09:35:56 -07:00
										 |  |  |             value = stack_pointer[-1]; | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             SPAM(value); | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |             stack_pointer += -1; | 
					
						
							| 
									
										
										
										
											2024-06-25 16:42:29 +01:00
										 |  |  |             assert(WITHIN_STACK_BOUNDS()); | 
					
						
							| 
									
										
										
										
											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)) { | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             res = SPAM(); | 
					
						
							| 
									
										
										
										
											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) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = OP; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							| 
									
										
										
										
											2024-06-27 03:10:43 +08:00
										 |  |  |             _PyStackRef res; | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             res = SPAM(); | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |             stack_pointer[0] = res; | 
					
						
							|  |  |  |             stack_pointer += 1; | 
					
						
							| 
									
										
										
										
											2024-06-25 16:42:29 +01:00
										 |  |  |             assert(WITHIN_STACK_BOUNDS()); | 
					
						
							| 
									
										
										
										
											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)) { | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             res = SPAM(value); | 
					
						
							|  |  |  |             DEAD(value); | 
					
						
							| 
									
										
										
										
											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) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = OP; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							| 
									
										
										
										
											2024-06-27 03:10:43 +08:00
										 |  |  |             _PyStackRef value; | 
					
						
							|  |  |  |             _PyStackRef res; | 
					
						
							| 
									
										
										
										
											2023-08-04 09:35:56 -07:00
										 |  |  |             value = stack_pointer[-1]; | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             res = SPAM(value); | 
					
						
							| 
									
										
										
										
											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)) { | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             res = SPAM(left, right); | 
					
						
							|  |  |  |             INPUTS_DEAD(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = OP; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							| 
									
										
										
										
											2024-06-27 03:10:43 +08:00
										 |  |  |             _PyStackRef left; | 
					
						
							| 
									
										
										
										
											2024-07-18 12:49:24 +01:00
										 |  |  |             _PyStackRef right; | 
					
						
							| 
									
										
										
										
											2024-06-27 03:10:43 +08:00
										 |  |  |             _PyStackRef res; | 
					
						
							| 
									
										
										
										
											2023-08-04 09:35:56 -07:00
										 |  |  |             right = stack_pointer[-1]; | 
					
						
							|  |  |  |             left = stack_pointer[-2]; | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             res = SPAM(left, right); | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |             stack_pointer[-2] = res; | 
					
						
							|  |  |  |             stack_pointer += -1; | 
					
						
							| 
									
										
										
										
											2024-06-25 16:42:29 +01:00
										 |  |  |             assert(WITHIN_STACK_BOUNDS()); | 
					
						
							| 
									
										
										
										
											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)) { | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             result = SPAM(left, right); | 
					
						
							|  |  |  |             INPUTS_DEAD(); | 
					
						
							| 
									
										
										
										
											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) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = OP; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							| 
									
										
										
										
											2024-06-27 03:10:43 +08:00
										 |  |  |             _PyStackRef left; | 
					
						
							| 
									
										
										
										
											2024-07-18 12:49:24 +01:00
										 |  |  |             _PyStackRef right; | 
					
						
							| 
									
										
										
										
											2024-06-27 03:10:43 +08:00
										 |  |  |             _PyStackRef result; | 
					
						
							| 
									
										
										
										
											2023-08-04 09:35:56 -07:00
										 |  |  |             right = stack_pointer[-1]; | 
					
						
							|  |  |  |             left = stack_pointer[-2]; | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             result = SPAM(left, right); | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-14 12:04:05 +01:00
										 |  |  |     def test_predictions(self): | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         input = """
 | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |         inst(OP1, (arg -- res)) { | 
					
						
							| 
									
										
										
										
											2025-03-26 15:21:35 +00:00
										 |  |  |             DEAD(arg); | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             res = Py_None; | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-02-07 20:03:22 -08:00
										 |  |  |         inst(OP3, (arg -- res)) { | 
					
						
							| 
									
										
										
										
											2025-03-26 15:21:35 +00:00
										 |  |  |             DEAD(arg); | 
					
						
							| 
									
										
										
										
											2023-10-03 10:13:50 -07:00
										 |  |  |             DEOPT_IF(xxx); | 
					
						
							| 
									
										
										
										
											2024-07-18 12:49:24 +01:00
										 |  |  |             res = Py_None; | 
					
						
							| 
									
										
										
										
											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) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = OP1; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP1); | 
					
						
							| 
									
										
										
										
											2025-01-22 09:22:25 +08:00
										 |  |  |             PREDICTED_OP1:; | 
					
						
							| 
									
										
										
										
											2025-03-26 15:21:35 +00:00
										 |  |  |             _PyStackRef arg; | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             _PyStackRef res; | 
					
						
							| 
									
										
										
										
											2025-03-26 15:21:35 +00:00
										 |  |  |             arg = stack_pointer[-1]; | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             res = Py_None; | 
					
						
							|  |  |  |             stack_pointer[-1] = res; | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         TARGET(OP3) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = OP3; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             _Py_CODEUNIT* const this_instr = next_instr; | 
					
						
							|  |  |  |             (void)this_instr; | 
					
						
							| 
									
										
										
										
											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"); | 
					
						
							| 
									
										
										
										
											2025-03-26 15:21:35 +00:00
										 |  |  |             _PyStackRef arg; | 
					
						
							| 
									
										
										
										
											2024-06-27 03:10:43 +08:00
										 |  |  |             _PyStackRef res; | 
					
						
							| 
									
										
										
										
											2025-03-26 15:21:35 +00:00
										 |  |  |             arg = stack_pointer[-1]; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             if (xxx) { | 
					
						
							|  |  |  |                 UPDATE_MISS_STATS(OP1); | 
					
						
							|  |  |  |                 assert(_PyOpcode_Deopt[opcode] == (OP1)); | 
					
						
							|  |  |  |                 JUMP_TO_PREDICTED(OP1); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2024-07-18 12:49:24 +01:00
										 |  |  |             res = Py_None; | 
					
						
							| 
									
										
										
										
											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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |     def test_sync_sp(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         inst(A, (arg -- res)) { | 
					
						
							| 
									
										
										
										
											2025-03-26 15:21:35 +00:00
										 |  |  |             DEAD(arg); | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             SYNC_SP(); | 
					
						
							|  |  |  |             escaping_call(); | 
					
						
							|  |  |  |             res = Py_None; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         inst(B, (arg -- res)) { | 
					
						
							| 
									
										
										
										
											2025-03-26 15:21:35 +00:00
										 |  |  |             DEAD(arg); | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             res = Py_None; | 
					
						
							|  |  |  |             SYNC_SP(); | 
					
						
							|  |  |  |             escaping_call(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         TARGET(A) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = A; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(A); | 
					
						
							| 
									
										
										
										
											2025-03-26 15:21:35 +00:00
										 |  |  |             _PyStackRef arg; | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             _PyStackRef res; | 
					
						
							| 
									
										
										
										
											2025-03-26 15:21:35 +00:00
										 |  |  |             arg = stack_pointer[-1]; | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             stack_pointer += -1; | 
					
						
							|  |  |  |             assert(WITHIN_STACK_BOUNDS()); | 
					
						
							|  |  |  |             _PyFrame_SetStackPointer(frame, stack_pointer); | 
					
						
							|  |  |  |             escaping_call(); | 
					
						
							|  |  |  |             stack_pointer = _PyFrame_GetStackPointer(frame); | 
					
						
							|  |  |  |             res = Py_None; | 
					
						
							|  |  |  |             stack_pointer[0] = res; | 
					
						
							|  |  |  |             stack_pointer += 1; | 
					
						
							|  |  |  |             assert(WITHIN_STACK_BOUNDS()); | 
					
						
							|  |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         TARGET(B) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = B; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(B); | 
					
						
							| 
									
										
										
										
											2025-03-26 15:21:35 +00:00
										 |  |  |             _PyStackRef arg; | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             _PyStackRef res; | 
					
						
							| 
									
										
										
										
											2025-03-26 15:21:35 +00:00
										 |  |  |             arg = stack_pointer[-1]; | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             res = Py_None; | 
					
						
							|  |  |  |             stack_pointer[-1] = res; | 
					
						
							|  |  |  |             _PyFrame_SetStackPointer(frame, stack_pointer); | 
					
						
							|  |  |  |             escaping_call(); | 
					
						
							|  |  |  |             stack_pointer = _PyFrame_GetStackPointer(frame); | 
					
						
							|  |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |         self.run_cases_test(input, output) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_pep7_condition(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         inst(OP, (arg1 -- out)) { | 
					
						
							|  |  |  |             if (arg1) | 
					
						
							|  |  |  |                 out = 0; | 
					
						
							|  |  |  |             else { | 
					
						
							|  |  |  |                 out = 1; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         output = "" | 
					
						
							|  |  |  |         with self.assertRaises(SyntaxError): | 
					
						
							|  |  |  |             self.run_cases_test(input, output) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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, (--)) { | 
					
						
							| 
									
										
										
										
											2025-04-29 17:21:53 -07:00
										 |  |  |             ERROR_IF(cond); | 
					
						
							| 
									
										
										
										
											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) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = OP; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							| 
									
										
										
										
											2025-02-03 12:41:32 +00:00
										 |  |  |             if (cond) { | 
					
						
							| 
									
										
										
										
											2025-04-29 17:21:53 -07:00
										 |  |  |                 JUMP_TO_LABEL(error); | 
					
						
							| 
									
										
										
										
											2025-02-03 12:41:32 +00:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											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_with_comment(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							| 
									
										
										
										
											2023-01-24 22:39:13 +00:00
										 |  |  |         inst(OP, (--)) { | 
					
						
							| 
									
										
										
										
											2025-04-29 17:21:53 -07:00
										 |  |  |             ERROR_IF(cond);  // Comment is ok | 
					
						
							| 
									
										
										
										
											2023-01-24 22:39:13 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2023-07-17 02:05:24 +03:00
										 |  |  |         output = """
 | 
					
						
							| 
									
										
										
										
											2023-01-24 22:39:13 +00:00
										 |  |  |         TARGET(OP) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = OP; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							| 
									
										
										
										
											2025-02-03 12:41:32 +00:00
										 |  |  |             if (cond) { | 
					
						
							| 
									
										
										
										
											2025-04-29 17:21:53 -07:00
										 |  |  |                 JUMP_TO_LABEL(error); | 
					
						
							| 
									
										
										
										
											2025-02-03 12:41:32 +00:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											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)) { | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             SPAM(left, right); | 
					
						
							|  |  |  |             INPUTS_DEAD(); | 
					
						
							| 
									
										
										
										
											2025-04-29 17:21:53 -07:00
										 |  |  |             ERROR_IF(cond); | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             res = 0; | 
					
						
							| 
									
										
										
										
											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) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = OP; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							| 
									
										
										
										
											2024-06-27 03:10:43 +08:00
										 |  |  |             _PyStackRef left; | 
					
						
							| 
									
										
										
										
											2024-07-18 12:49:24 +01:00
										 |  |  |             _PyStackRef right; | 
					
						
							| 
									
										
										
										
											2024-06-27 03:10:43 +08:00
										 |  |  |             _PyStackRef res; | 
					
						
							| 
									
										
										
										
											2023-08-04 09:35:56 -07:00
										 |  |  |             right = stack_pointer[-1]; | 
					
						
							|  |  |  |             left = stack_pointer[-2]; | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             SPAM(left, right); | 
					
						
							| 
									
										
										
										
											2025-02-03 12:41:32 +00:00
										 |  |  |             if (cond) { | 
					
						
							| 
									
										
										
										
											2025-04-29 17:21:53 -07:00
										 |  |  |                 JUMP_TO_LABEL(pop_2_error); | 
					
						
							| 
									
										
										
										
											2025-02-03 12:41:32 +00:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             res = 0; | 
					
						
							|  |  |  |             stack_pointer[-2] = res; | 
					
						
							|  |  |  |             stack_pointer += -1; | 
					
						
							|  |  |  |             assert(WITHIN_STACK_BOUNDS()); | 
					
						
							|  |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |         self.run_cases_test(input, output) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_error_if_pop_with_result(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         inst(OP, (left, right -- res)) { | 
					
						
							|  |  |  |             res = SPAM(left, right); | 
					
						
							|  |  |  |             INPUTS_DEAD(); | 
					
						
							| 
									
										
										
										
											2025-04-29 17:21:53 -07:00
										 |  |  |             ERROR_IF(cond); | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         TARGET(OP) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = OP; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							|  |  |  |             _PyStackRef left; | 
					
						
							|  |  |  |             _PyStackRef right; | 
					
						
							|  |  |  |             _PyStackRef res; | 
					
						
							|  |  |  |             right = stack_pointer[-1]; | 
					
						
							|  |  |  |             left = stack_pointer[-2]; | 
					
						
							|  |  |  |             res = SPAM(left, right); | 
					
						
							| 
									
										
										
										
											2025-02-03 12:41:32 +00:00
										 |  |  |             if (cond) { | 
					
						
							| 
									
										
										
										
											2025-04-29 17:21:53 -07:00
										 |  |  |                 JUMP_TO_LABEL(pop_2_error); | 
					
						
							| 
									
										
										
										
											2025-02-03 12:41:32 +00:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |             stack_pointer[-2] = res; | 
					
						
							|  |  |  |             stack_pointer += -1; | 
					
						
							| 
									
										
										
										
											2024-06-25 16:42:29 +01:00
										 |  |  |             assert(WITHIN_STACK_BOUNDS()); | 
					
						
							| 
									
										
										
										
											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 --)) { | 
					
						
							| 
									
										
										
										
											2025-03-26 15:21:35 +00:00
										 |  |  |             DEAD(value); | 
					
						
							| 
									
										
										
										
											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) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = OP; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             _Py_CODEUNIT* const this_instr = next_instr; | 
					
						
							| 
									
										
										
										
											2024-02-29 18:53:32 -08:00
										 |  |  |             (void)this_instr; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             next_instr += 4; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							| 
									
										
										
										
											2025-03-26 15:21:35 +00:00
										 |  |  |             _PyStackRef 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; | 
					
						
							| 
									
										
										
										
											2024-06-25 16:42:29 +01:00
										 |  |  |             assert(WITHIN_STACK_BOUNDS()); | 
					
						
							| 
									
										
										
										
											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 = """
 | 
					
						
							| 
									
										
										
										
											2025-02-04 12:18:31 +00:00
										 |  |  |         label(somewhere) { | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = OP; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             JUMP_TO_LABEL(somewhere); | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-02-04 12:18:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |         LABEL(somewhere) | 
					
						
							| 
									
										
										
										
											2025-02-04 12:18:31 +00:00
										 |  |  |         { | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |     """
 | 
					
						
							| 
									
										
										
										
											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); | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             INPUTS_DEAD(); | 
					
						
							| 
									
										
										
										
											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); | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             INPUTS_DEAD(); | 
					
						
							| 
									
										
										
										
											2023-01-30 11:23:57 -08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											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) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = OP; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 6; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							| 
									
										
										
										
											2025-01-22 09:22:25 +08:00
										 |  |  |             PREDICTED_OP:; | 
					
						
							| 
									
										
										
										
											2024-10-09 14:54:39 +02:00
										 |  |  |             _Py_CODEUNIT* const this_instr = next_instr - 6; | 
					
						
							| 
									
										
										
										
											2024-02-29 18:53:32 -08:00
										 |  |  |             (void)this_instr; | 
					
						
							| 
									
										
										
										
											2024-06-27 03:10:43 +08:00
										 |  |  |             _PyStackRef left; | 
					
						
							| 
									
										
										
										
											2024-07-18 12:49:24 +01:00
										 |  |  |             _PyStackRef right; | 
					
						
							| 
									
										
										
										
											2024-06-27 03:10:43 +08:00
										 |  |  |             _PyStackRef arg2; | 
					
						
							|  |  |  |             _PyStackRef res; | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |             // _OP1 | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |             { | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |                 right = stack_pointer[-1]; | 
					
						
							|  |  |  |                 left = stack_pointer[-2]; | 
					
						
							| 
									
										
										
										
											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; | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |                 _PyFrame_SetStackPointer(frame, stack_pointer); | 
					
						
							| 
									
										
										
										
											2023-01-30 11:23:57 -08:00
										 |  |  |                 op1(left, right); | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |                 stack_pointer = _PyFrame_GetStackPointer(frame); | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |             { | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |                 arg2 = stack_pointer[-3]; | 
					
						
							| 
									
										
										
										
											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; | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |                 _PyFrame_SetStackPointer(frame, stack_pointer); | 
					
						
							| 
									
										
										
										
											2023-01-30 11:23:57 -08:00
										 |  |  |                 res = op2(arg2, left, right); | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |                 stack_pointer = _PyFrame_GetStackPointer(frame); | 
					
						
							| 
									
										
										
										
											2023-01-06 08:04:20 -08:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |             stack_pointer[-3] = res; | 
					
						
							|  |  |  |             stack_pointer += -2; | 
					
						
							| 
									
										
										
										
											2024-06-25 16:42:29 +01:00
										 |  |  |             assert(WITHIN_STACK_BOUNDS()); | 
					
						
							| 
									
										
										
										
											2023-01-30 11:23:57 -08:00
										 |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-22 15:19:50 +00:00
										 |  |  |         TARGET(OP1) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = OP1; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             _Py_CODEUNIT* const this_instr = next_instr; | 
					
						
							| 
									
										
										
										
											2024-02-29 18:53:32 -08:00
										 |  |  |             (void)this_instr; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							| 
									
										
										
										
											2023-11-22 15:19:50 +00:00
										 |  |  |             next_instr += 2; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP1); | 
					
						
							| 
									
										
										
										
											2024-06-27 03:10:43 +08:00
										 |  |  |             _PyStackRef left; | 
					
						
							| 
									
										
										
										
											2024-07-18 12:49:24 +01:00
										 |  |  |             _PyStackRef right; | 
					
						
							| 
									
										
										
										
											2023-11-22 15:19:50 +00:00
										 |  |  |             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; | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             _PyFrame_SetStackPointer(frame, stack_pointer); | 
					
						
							| 
									
										
										
										
											2023-11-22 15:19:50 +00:00
										 |  |  |             op1(left, right); | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             stack_pointer = _PyFrame_GetStackPointer(frame); | 
					
						
							| 
									
										
										
										
											2023-11-22 15:19:50 +00:00
										 |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-30 11:23:57 -08:00
										 |  |  |         TARGET(OP3) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = OP3; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											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"); | 
					
						
							| 
									
										
										
										
											2024-06-27 03:10:43 +08:00
										 |  |  |             _PyStackRef arg2; | 
					
						
							| 
									
										
										
										
											2024-07-18 12:49:24 +01:00
										 |  |  |             _PyStackRef left; | 
					
						
							|  |  |  |             _PyStackRef right; | 
					
						
							| 
									
										
										
										
											2024-06-27 03:10:43 +08:00
										 |  |  |             _PyStackRef 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]; | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             _PyFrame_SetStackPointer(frame, stack_pointer); | 
					
						
							| 
									
										
										
										
											2023-01-30 11:23:57 -08:00
										 |  |  |             res = op3(arg2, left, right); | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             stack_pointer = _PyFrame_GetStackPointer(frame); | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |             stack_pointer[-3] = res; | 
					
						
							|  |  |  |             stack_pointer += -2; | 
					
						
							| 
									
										
										
										
											2024-06-25 16:42:29 +01:00
										 |  |  |             assert(WITHIN_STACK_BOUNDS()); | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |             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 --)) { | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             body; | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         TARGET(OP) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = OP; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |             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 */ | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01: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 = """
 | 
					
						
							| 
									
										
										
										
											2024-05-29 10:47:56 +01:00
										 |  |  |         pseudo(OP, (in -- out1, out2)) = { | 
					
						
							| 
									
										
										
										
											2023-11-30 11:03:30 +00:00
										 |  |  |             OP1, | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         inst(OP1, (--)) { | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         TARGET(OP1) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = OP1; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2023-11-30 11:03:30 +00:00
										 |  |  |             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 = """
 | 
					
						
							| 
									
										
										
										
											2024-05-29 10:47:56 +01:00
										 |  |  |         pseudo(OP, (in1, in2 --), (HAS_ARG, HAS_JUMP)) = { | 
					
						
							| 
									
										
										
										
											2023-11-30 11:03:30 +00:00
										 |  |  |             OP1, | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         inst(OP1, (--)) { | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         TARGET(OP1) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = OP1; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2023-11-30 11:03:30 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP1); | 
					
						
							|  |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |         self.run_cases_test(input, output) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-25 15:51:25 +01:00
										 |  |  |     def test_pseudo_instruction_as_sequence(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         pseudo(OP, (in -- out1, out2)) = [ | 
					
						
							|  |  |  |             OP1, OP2 | 
					
						
							|  |  |  |         ]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         inst(OP1, (--)) { | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         inst(OP2, (--)) { | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         TARGET(OP1) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = OP1; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2024-09-25 15:51:25 +01:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP1); | 
					
						
							|  |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         TARGET(OP2) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = OP2; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2024-09-25 15:51:25 +01:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP2); | 
					
						
							|  |  |  |             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 --)) { | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             SPAM(values, oparg); | 
					
						
							| 
									
										
										
										
											2025-03-26 15:21:35 +00:00
										 |  |  |             DEAD(below); | 
					
						
							|  |  |  |             DEAD(values); | 
					
						
							|  |  |  |             DEAD(above); | 
					
						
							| 
									
										
										
										
											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) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = OP; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							| 
									
										
										
										
											2025-03-26 15:21:35 +00:00
										 |  |  |             _PyStackRef below; | 
					
						
							| 
									
										
										
										
											2024-06-27 03:10:43 +08:00
										 |  |  |             _PyStackRef *values; | 
					
						
							| 
									
										
										
										
											2025-03-26 15:21:35 +00:00
										 |  |  |             _PyStackRef above; | 
					
						
							|  |  |  |             above = stack_pointer[-1]; | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |             values = &stack_pointer[-1 - oparg*2]; | 
					
						
							| 
									
										
										
										
											2025-03-26 15:21:35 +00:00
										 |  |  |             below = stack_pointer[-2 - oparg*2]; | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             SPAM(values, oparg); | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |             stack_pointer += -2 - oparg*2; | 
					
						
							| 
									
										
										
										
											2024-06-25 16:42:29 +01:00
										 |  |  |             assert(WITHIN_STACK_BOUNDS()); | 
					
						
							| 
									
										
										
										
											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)) { | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             SPAM(values, oparg); | 
					
						
							|  |  |  |             below = 0; | 
					
						
							|  |  |  |             above = 0; | 
					
						
							| 
									
										
										
										
											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) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = OP; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             _PyStackRef below; | 
					
						
							| 
									
										
										
										
											2024-06-27 03:10:43 +08:00
										 |  |  |             _PyStackRef *values; | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             _PyStackRef above; | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |             values = &stack_pointer[-1]; | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             SPAM(values, oparg); | 
					
						
							|  |  |  |             below = 0; | 
					
						
							|  |  |  |             above = 0; | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |             stack_pointer[-2] = below; | 
					
						
							|  |  |  |             stack_pointer[-1 + oparg*3] = above; | 
					
						
							|  |  |  |             stack_pointer += oparg*3; | 
					
						
							| 
									
										
										
										
											2024-06-25 16:42:29 +01:00
										 |  |  |             assert(WITHIN_STACK_BOUNDS()); | 
					
						
							| 
									
										
										
										
											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)) { | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             SPAM(values, oparg); | 
					
						
							|  |  |  |             above = 0; | 
					
						
							| 
									
										
										
										
											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) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = OP; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							| 
									
										
										
										
											2024-06-27 03:10:43 +08:00
										 |  |  |             _PyStackRef *values; | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             _PyStackRef above; | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |             values = &stack_pointer[-oparg]; | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             SPAM(values, oparg); | 
					
						
							|  |  |  |             above = 0; | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |             stack_pointer[0] = above; | 
					
						
							|  |  |  |             stack_pointer += 1; | 
					
						
							| 
									
										
										
										
											2024-06-25 16:42:29 +01:00
										 |  |  |             assert(WITHIN_STACK_BOUNDS()); | 
					
						
							| 
									
										
										
										
											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] --)) { | 
					
						
							| 
									
										
										
										
											2025-03-26 15:21:35 +00:00
										 |  |  |             DEAD(extra); | 
					
						
							|  |  |  |             DEAD(values); | 
					
						
							| 
									
										
										
										
											2025-04-29 17:21:53 -07:00
										 |  |  |             ERROR_IF(oparg == 0); | 
					
						
							| 
									
										
										
										
											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) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = OP; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							| 
									
										
										
										
											2025-03-26 15:21:35 +00:00
										 |  |  |             _PyStackRef extra; | 
					
						
							|  |  |  |             _PyStackRef *values; | 
					
						
							|  |  |  |             values = &stack_pointer[-oparg]; | 
					
						
							|  |  |  |             extra = stack_pointer[-1 - oparg]; | 
					
						
							| 
									
										
										
										
											2024-08-01 09:27:26 +01:00
										 |  |  |             if (oparg == 0) { | 
					
						
							|  |  |  |                 stack_pointer += -1 - oparg; | 
					
						
							|  |  |  |                 assert(WITHIN_STACK_BOUNDS()); | 
					
						
							| 
									
										
										
										
											2025-04-29 17:21:53 -07:00
										 |  |  |                 JUMP_TO_LABEL(error); | 
					
						
							| 
									
										
										
										
											2024-08-01 09:27:26 +01:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |             stack_pointer += -1 - oparg; | 
					
						
							| 
									
										
										
										
											2024-06-25 16:42:29 +01:00
										 |  |  |             assert(WITHIN_STACK_BOUNDS()); | 
					
						
							| 
									
										
										
										
											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-09-05 13:58:39 -07:00
										 |  |  |     def test_macro_push_push(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         op(A, (-- val1)) { | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             val1 = SPAM(); | 
					
						
							| 
									
										
										
										
											2023-09-05 13:58:39 -07:00
										 |  |  |         } | 
					
						
							|  |  |  |         op(B, (-- val2)) { | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             val2 = SPAM(); | 
					
						
							| 
									
										
										
										
											2023-09-05 13:58:39 -07:00
										 |  |  |         } | 
					
						
							|  |  |  |         macro(M) = A + B; | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         TARGET(M) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = M; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(M); | 
					
						
							| 
									
										
										
										
											2024-06-27 03:10:43 +08:00
										 |  |  |             _PyStackRef val1; | 
					
						
							|  |  |  |             _PyStackRef val2; | 
					
						
							| 
									
										
										
										
											2023-09-05 13:58:39 -07:00
										 |  |  |             // A | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |                 val1 = SPAM(); | 
					
						
							| 
									
										
										
										
											2023-09-05 13:58:39 -07:00
										 |  |  |             } | 
					
						
							|  |  |  |             // B | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |                 val2 = SPAM(); | 
					
						
							| 
									
										
										
										
											2023-09-05 13:58:39 -07:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2023-12-18 11:14:40 +00:00
										 |  |  |             stack_pointer[0] = val1; | 
					
						
							|  |  |  |             stack_pointer[1] = val2; | 
					
						
							|  |  |  |             stack_pointer += 2; | 
					
						
							| 
									
										
										
										
											2024-06-25 16:42:29 +01:00
										 |  |  |             assert(WITHIN_STACK_BOUNDS()); | 
					
						
							| 
									
										
										
										
											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, (--)) { | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             spam; | 
					
						
							| 
									
										
										
										
											2023-10-05 15:05:29 -07:00
										 |  |  |         } | 
					
						
							|  |  |  |         override inst(OP, (--)) { | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             ham; | 
					
						
							| 
									
										
										
										
											2023-10-05 15:05:29 -07:00
										 |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         TARGET(OP) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = OP; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             ham; | 
					
						
							| 
									
										
										
										
											2023-10-05 15:05:29 -07:00
										 |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         self.run_cases_test(input, output) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_override_op(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         op(OP, (--)) { | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             spam; | 
					
						
							| 
									
										
										
										
											2023-10-05 15:05:29 -07:00
										 |  |  |         } | 
					
						
							|  |  |  |         macro(M) = OP; | 
					
						
							|  |  |  |         override op(OP, (--)) { | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             ham; | 
					
						
							| 
									
										
										
										
											2023-10-05 15:05:29 -07:00
										 |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         TARGET(M) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = M; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2023-10-31 10:09:54 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(M); | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             ham; | 
					
						
							| 
									
										
										
										
											2023-10-05 15:05:29 -07:00
										 |  |  |             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, (--)) { | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             ham; | 
					
						
							| 
									
										
										
										
											2023-11-07 09:42:39 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         TARGET(OP) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = OP; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2023-11-07 09:42:39 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             ham; | 
					
						
							| 
									
										
										
										
											2023-11-07 09:42:39 +00:00
										 |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         self.run_cases_test(input, output) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_annotated_op(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							| 
									
										
										
										
											2024-01-13 01:30:27 +08:00
										 |  |  |         pure op(OP, (--)) { | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             SPAM(); | 
					
						
							| 
									
										
										
										
											2023-11-07 09:42:39 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |         macro(M) = OP; | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         TARGET(M) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = M; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2023-11-07 09:42:39 +00:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(M); | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             SPAM(); | 
					
						
							| 
									
										
										
										
											2023-11-07 09:42:39 +00:00
										 |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         self.run_cases_test(input, output) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         input = """
 | 
					
						
							| 
									
										
										
										
											2024-01-13 01:30:27 +08:00
										 |  |  |         pure register specializing op(OP, (--)) { | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             SPAM(); | 
					
						
							| 
									
										
										
										
											2023-11-07 09:42:39 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |         macro(M) = OP; | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         self.run_cases_test(input, output) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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 = "" | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |         with self.assertRaises(SyntaxError): | 
					
						
							| 
									
										
										
										
											2024-02-20 09:39:55 +00:00
										 |  |  |             self.run_cases_test(input, output) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-09 11:33:56 +01:00
										 |  |  |     def test_array_of_one(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         inst(OP, (arg[1] -- out[1])) { | 
					
						
							|  |  |  |             out[0] = arg[0]; | 
					
						
							| 
									
										
										
										
											2025-03-26 15:21:35 +00:00
										 |  |  |             DEAD(arg); | 
					
						
							| 
									
										
										
										
											2024-07-09 11:33:56 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         TARGET(OP) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = OP; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2024-07-09 11:33:56 +01:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							|  |  |  |             _PyStackRef *arg; | 
					
						
							|  |  |  |             _PyStackRef *out; | 
					
						
							|  |  |  |             arg = &stack_pointer[-1]; | 
					
						
							|  |  |  |             out = &stack_pointer[-1]; | 
					
						
							|  |  |  |             out[0] = arg[0]; | 
					
						
							|  |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         self.run_cases_test(input, output) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_pointer_to_stackref(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         inst(OP, (arg: _PyStackRef * -- out)) { | 
					
						
							|  |  |  |             out = *arg; | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             DEAD(arg); | 
					
						
							| 
									
										
										
										
											2024-07-09 11:33:56 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         TARGET(OP) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = OP; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2024-07-09 11:33:56 +01:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							|  |  |  |             _PyStackRef *arg; | 
					
						
							|  |  |  |             _PyStackRef out; | 
					
						
							|  |  |  |             arg = (_PyStackRef *)stack_pointer[-1].bits; | 
					
						
							|  |  |  |             out = *arg; | 
					
						
							|  |  |  |             stack_pointer[-1] = out; | 
					
						
							|  |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         self.run_cases_test(input, output) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-18 12:49:24 +01:00
										 |  |  |     def test_unused_cached_value(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         op(FIRST, (arg1 -- out)) { | 
					
						
							|  |  |  |             out = arg1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         op(SECOND, (unused -- unused)) { | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         macro(BOTH) = FIRST + SECOND; | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         with self.assertRaises(SyntaxError): | 
					
						
							|  |  |  |             self.run_cases_test(input, output) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_unused_named_values(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         op(OP, (named -- named)) { | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         macro(INST) = OP; | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         TARGET(INST) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = INST; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2024-07-18 12:49:24 +01:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(INST); | 
					
						
							|  |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         self.run_cases_test(input, output) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_used_unused_used(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         op(FIRST, (w -- w)) { | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             USE(w); | 
					
						
							| 
									
										
										
										
											2024-07-18 12:49:24 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         op(SECOND, (x -- x)) { | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         op(THIRD, (y -- y)) { | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             USE(y); | 
					
						
							| 
									
										
										
										
											2024-07-18 12:49:24 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         macro(TEST) = FIRST + SECOND + THIRD; | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         TARGET(TEST) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = TEST; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2024-07-18 12:49:24 +01:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(TEST); | 
					
						
							|  |  |  |             _PyStackRef w; | 
					
						
							|  |  |  |             _PyStackRef y; | 
					
						
							|  |  |  |             // FIRST | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |                 w = stack_pointer[-1]; | 
					
						
							|  |  |  |                 USE(w); | 
					
						
							| 
									
										
										
										
											2024-07-18 12:49:24 +01:00
										 |  |  |             } | 
					
						
							|  |  |  |             // SECOND | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             // THIRD | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |                 y = w; | 
					
						
							|  |  |  |                 USE(y); | 
					
						
							| 
									
										
										
										
											2024-07-18 12:49:24 +01:00
										 |  |  |             } | 
					
						
							|  |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         self.run_cases_test(input, output) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_unused_used_used(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         op(FIRST, (w -- w)) { | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         op(SECOND, (x -- x)) { | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             USE(x); | 
					
						
							| 
									
										
										
										
											2024-07-18 12:49:24 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         op(THIRD, (y -- y)) { | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             USE(y); | 
					
						
							| 
									
										
										
										
											2024-07-18 12:49:24 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         macro(TEST) = FIRST + SECOND + THIRD; | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         TARGET(TEST) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = TEST; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2024-07-18 12:49:24 +01:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(TEST); | 
					
						
							|  |  |  |             _PyStackRef x; | 
					
						
							|  |  |  |             _PyStackRef y; | 
					
						
							|  |  |  |             // FIRST | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             // SECOND | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |                 x = stack_pointer[-1]; | 
					
						
							|  |  |  |                 USE(x); | 
					
						
							| 
									
										
										
										
											2024-07-18 12:49:24 +01:00
										 |  |  |             } | 
					
						
							|  |  |  |             // THIRD | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |                 y = x; | 
					
						
							|  |  |  |                 USE(y); | 
					
						
							| 
									
										
										
										
											2024-07-18 12:49:24 +01:00
										 |  |  |             } | 
					
						
							|  |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         self.run_cases_test(input, output) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_flush(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         op(FIRST, ( -- a, b)) { | 
					
						
							|  |  |  |             a = 0; | 
					
						
							|  |  |  |             b = 1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         op(SECOND, (a, b -- )) { | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             USE(a, b); | 
					
						
							|  |  |  |             INPUTS_DEAD(); | 
					
						
							| 
									
										
										
										
											2024-07-18 12:49:24 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         macro(TEST) = FIRST + flush + SECOND; | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         TARGET(TEST) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = TEST; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2024-07-18 12:49:24 +01:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(TEST); | 
					
						
							|  |  |  |             _PyStackRef a; | 
					
						
							|  |  |  |             _PyStackRef b; | 
					
						
							|  |  |  |             // FIRST | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 a = 0; | 
					
						
							|  |  |  |                 b = 1; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             // flush | 
					
						
							|  |  |  |             stack_pointer[0] = a; | 
					
						
							|  |  |  |             stack_pointer[1] = b; | 
					
						
							|  |  |  |             stack_pointer += 2; | 
					
						
							|  |  |  |             assert(WITHIN_STACK_BOUNDS()); | 
					
						
							|  |  |  |             // SECOND | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |                 USE(a, b); | 
					
						
							| 
									
										
										
										
											2024-07-18 12:49:24 +01:00
										 |  |  |             } | 
					
						
							|  |  |  |             stack_pointer += -2; | 
					
						
							|  |  |  |             assert(WITHIN_STACK_BOUNDS()); | 
					
						
							|  |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         self.run_cases_test(input, output) | 
					
						
							| 
									
										
										
										
											2024-07-23 14:12:06 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_pop_on_error_peeks(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         op(FIRST, (x, y -- a, b)) { | 
					
						
							|  |  |  |             a = x; | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             DEAD(x); | 
					
						
							| 
									
										
										
										
											2024-07-23 14:12:06 +01:00
										 |  |  |             b = y; | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             DEAD(y); | 
					
						
							| 
									
										
										
										
											2024-07-23 14:12:06 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         op(SECOND, (a, b -- a, b)) { | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         op(THIRD, (j, k --)) { | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             INPUTS_DEAD(); // Mark j and k as used | 
					
						
							| 
									
										
										
										
											2025-04-29 17:21:53 -07:00
										 |  |  |             ERROR_IF(cond); | 
					
						
							| 
									
										
										
										
											2024-07-23 14:12:06 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         macro(TEST) = FIRST + SECOND + THIRD; | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         TARGET(TEST) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = TEST; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2024-07-23 14:12:06 +01:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(TEST); | 
					
						
							|  |  |  |             _PyStackRef x; | 
					
						
							|  |  |  |             _PyStackRef y; | 
					
						
							|  |  |  |             _PyStackRef a; | 
					
						
							|  |  |  |             _PyStackRef b; | 
					
						
							|  |  |  |             // FIRST | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |                 y = stack_pointer[-1]; | 
					
						
							|  |  |  |                 x = stack_pointer[-2]; | 
					
						
							| 
									
										
										
										
											2024-07-23 14:12:06 +01:00
										 |  |  |                 a = x; | 
					
						
							|  |  |  |                 b = y; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             // SECOND | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             // THIRD | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2025-02-03 12:41:32 +00:00
										 |  |  |                 if (cond) { | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |                     JUMP_TO_LABEL(pop_2_error); | 
					
						
							| 
									
										
										
										
											2025-02-03 12:41:32 +00:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2024-07-23 14:12:06 +01:00
										 |  |  |             } | 
					
						
							|  |  |  |             stack_pointer += -2; | 
					
						
							|  |  |  |             assert(WITHIN_STACK_BOUNDS()); | 
					
						
							|  |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         self.run_cases_test(input, output) | 
					
						
							| 
									
										
										
										
											2024-08-01 09:27:26 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_push_then_error(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         op(FIRST, ( -- a)) { | 
					
						
							|  |  |  |             a = 1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         op(SECOND, (a -- a, b)) { | 
					
						
							|  |  |  |             b = 1; | 
					
						
							| 
									
										
										
										
											2025-04-29 17:21:53 -07:00
										 |  |  |             ERROR_IF(cond); | 
					
						
							| 
									
										
										
										
											2024-08-01 09:27:26 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         macro(TEST) = FIRST + SECOND; | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         TARGET(TEST) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = TEST; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2024-08-01 09:27:26 +01:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(TEST); | 
					
						
							|  |  |  |             _PyStackRef a; | 
					
						
							|  |  |  |             _PyStackRef b; | 
					
						
							|  |  |  |             // FIRST | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 a = 1; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             // SECOND | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 b = 1; | 
					
						
							|  |  |  |                 if (cond) { | 
					
						
							|  |  |  |                     stack_pointer[0] = a; | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |                     stack_pointer[1] = b; | 
					
						
							|  |  |  |                     stack_pointer += 2; | 
					
						
							| 
									
										
										
										
											2024-08-01 09:27:26 +01:00
										 |  |  |                     assert(WITHIN_STACK_BOUNDS()); | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |                     JUMP_TO_LABEL(error); | 
					
						
							| 
									
										
										
										
											2024-08-01 09:27:26 +01:00
										 |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             stack_pointer[0] = a; | 
					
						
							|  |  |  |             stack_pointer[1] = b; | 
					
						
							|  |  |  |             stack_pointer += 2; | 
					
						
							|  |  |  |             assert(WITHIN_STACK_BOUNDS()); | 
					
						
							|  |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         self.run_cases_test(input, output) | 
					
						
							| 
									
										
										
										
											2024-09-12 15:32:45 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-22 10:11:29 +01:00
										 |  |  |     def test_error_if_true(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         inst(OP1, ( --)) { | 
					
						
							| 
									
										
										
										
											2025-04-29 17:21:53 -07:00
										 |  |  |             ERROR_IF(true); | 
					
						
							| 
									
										
										
										
											2024-10-22 10:11:29 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |         inst(OP2, ( --)) { | 
					
						
							| 
									
										
										
										
											2025-04-29 17:21:53 -07:00
										 |  |  |             ERROR_IF(1); | 
					
						
							| 
									
										
										
										
											2024-10-22 10:11:29 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         TARGET(OP1) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = OP1; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2024-10-22 10:11:29 +01:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP1); | 
					
						
							| 
									
										
										
										
											2025-04-29 17:21:53 -07:00
										 |  |  |             JUMP_TO_LABEL(error); | 
					
						
							| 
									
										
										
										
											2024-10-22 10:11:29 +01:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         TARGET(OP2) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = OP2; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2024-10-22 10:11:29 +01:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP2); | 
					
						
							| 
									
										
										
										
											2025-04-29 17:21:53 -07:00
										 |  |  |             JUMP_TO_LABEL(error); | 
					
						
							| 
									
										
										
										
											2024-10-22 10:11:29 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         self.run_cases_test(input, output) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-12 15:32:45 +01:00
										 |  |  |     def test_scalar_array_inconsistency(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         op(FIRST, ( -- a)) { | 
					
						
							|  |  |  |             a = 1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         op(SECOND, (a[1] -- b)) { | 
					
						
							|  |  |  |             b = 1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         macro(TEST) = FIRST + SECOND; | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         with self.assertRaises(SyntaxError): | 
					
						
							|  |  |  |             self.run_cases_test(input, output) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_array_size_inconsistency(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         op(FIRST, ( -- a[2])) { | 
					
						
							|  |  |  |             a[0] = 1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         op(SECOND, (a[1] -- b)) { | 
					
						
							|  |  |  |             b = 1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         macro(TEST) = FIRST + SECOND; | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         with self.assertRaises(SyntaxError): | 
					
						
							|  |  |  |             self.run_cases_test(input, output) | 
					
						
							| 
									
										
										
										
											2024-07-18 12:49:24 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |     def test_stack_save_reload(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         inst(BALANCED, ( -- )) { | 
					
						
							|  |  |  |             SAVE_STACK(); | 
					
						
							| 
									
										
										
										
											2025-02-12 17:44:59 +00:00
										 |  |  |             code(); | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             RELOAD_STACK(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         TARGET(BALANCED) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = BALANCED; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(BALANCED); | 
					
						
							|  |  |  |             _PyFrame_SetStackPointer(frame, stack_pointer); | 
					
						
							| 
									
										
										
										
											2025-02-12 17:44:59 +00:00
										 |  |  |             code(); | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             stack_pointer = _PyFrame_GetStackPointer(frame); | 
					
						
							|  |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         self.run_cases_test(input, output) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-12 17:44:59 +00:00
										 |  |  |     def test_stack_save_reload_paired(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         inst(BALANCED, ( -- )) { | 
					
						
							|  |  |  |             SAVE_STACK(); | 
					
						
							|  |  |  |             RELOAD_STACK(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         TARGET(BALANCED) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-12 17:44:59 +00:00
										 |  |  |             int opcode = BALANCED; | 
					
						
							|  |  |  |             (void)(opcode); | 
					
						
							|  |  |  |             #endif | 
					
						
							|  |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(BALANCED); | 
					
						
							|  |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         self.run_cases_test(input, output) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |     def test_stack_reload_only(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         inst(BALANCED, ( -- )) { | 
					
						
							|  |  |  |             RELOAD_STACK(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         TARGET(BALANCED) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = BALANCED; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(BALANCED); | 
					
						
							|  |  |  |             _PyFrame_SetStackPointer(frame, stack_pointer); | 
					
						
							|  |  |  |             stack_pointer = _PyFrame_GetStackPointer(frame); | 
					
						
							|  |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         with self.assertRaises(SyntaxError): | 
					
						
							|  |  |  |             self.run_cases_test(input, output) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_stack_save_only(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         inst(BALANCED, ( -- )) { | 
					
						
							|  |  |  |             SAVE_STACK(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         TARGET(BALANCED) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = BALANCED; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             _Py_CODEUNIT* const this_instr = next_instr; | 
					
						
							|  |  |  |             (void)this_instr; | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(BALANCED); | 
					
						
							|  |  |  |             _PyFrame_SetStackPointer(frame, stack_pointer); | 
					
						
							|  |  |  |             stack_pointer = _PyFrame_GetStackPointer(frame); | 
					
						
							|  |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         with self.assertRaises(SyntaxError): | 
					
						
							|  |  |  |             self.run_cases_test(input, output) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-29 18:25:05 +01:00
										 |  |  |     def test_instruction_size_macro(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         inst(OP, (--)) { | 
					
						
							|  |  |  |             frame->return_offset = INSTRUCTION_SIZE; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         TARGET(OP) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = OP; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2024-10-29 18:25:05 +01:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							|  |  |  |             frame->return_offset = 1 ; | 
					
						
							|  |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         self.run_cases_test(input, output) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Two instructions of different sizes referencing the same | 
					
						
							|  |  |  |         # uop containing the `INSTRUCTION_SIZE` macro is not allowed. | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         inst(OP, (--)) { | 
					
						
							|  |  |  |             frame->return_offset = INSTRUCTION_SIZE; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         macro(OP2) = unused/1 + OP; | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         output = ""  # No output needed as this should raise an error. | 
					
						
							|  |  |  |         with self.assertRaisesRegex(SyntaxError, "All instructions containing a uop"): | 
					
						
							|  |  |  |             self.run_cases_test(input, output) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-01 08:53:03 -07:00
										 |  |  |     def test_escaping_call_next_to_cmacro(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         inst(OP, (--)) { | 
					
						
							|  |  |  |             #ifdef Py_GIL_DISABLED | 
					
						
							|  |  |  |             escaping_call(); | 
					
						
							|  |  |  |             #else | 
					
						
							|  |  |  |             another_escaping_call(); | 
					
						
							|  |  |  |             #endif | 
					
						
							|  |  |  |             yet_another_escaping_call(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         TARGET(OP) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = OP; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2024-11-01 08:53:03 -07:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							|  |  |  |             #ifdef Py_GIL_DISABLED | 
					
						
							|  |  |  |             _PyFrame_SetStackPointer(frame, stack_pointer); | 
					
						
							|  |  |  |             escaping_call(); | 
					
						
							|  |  |  |             stack_pointer = _PyFrame_GetStackPointer(frame); | 
					
						
							|  |  |  |             #else | 
					
						
							|  |  |  |             _PyFrame_SetStackPointer(frame, stack_pointer); | 
					
						
							|  |  |  |             another_escaping_call(); | 
					
						
							|  |  |  |             stack_pointer = _PyFrame_GetStackPointer(frame); | 
					
						
							|  |  |  |             #endif | 
					
						
							|  |  |  |             _PyFrame_SetStackPointer(frame, stack_pointer); | 
					
						
							|  |  |  |             yet_another_escaping_call(); | 
					
						
							|  |  |  |             stack_pointer = _PyFrame_GetStackPointer(frame); | 
					
						
							|  |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         self.run_cases_test(input, output) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-14 11:56:11 -08:00
										 |  |  |     def test_pystackref_frompyobject_new_next_to_cmacro(self): | 
					
						
							| 
									
										
										
										
											2024-12-13 10:17:16 -08:00
										 |  |  |         input = """
 | 
					
						
							| 
									
										
										
										
											2025-01-14 11:56:11 -08:00
										 |  |  |         inst(OP, (-- out1, out2)) { | 
					
						
							|  |  |  |             PyObject *obj = SPAM(); | 
					
						
							|  |  |  |             #ifdef Py_GIL_DISABLED | 
					
						
							|  |  |  |             out1 = PyStackRef_FromPyObjectNew(obj); | 
					
						
							|  |  |  |             #else | 
					
						
							|  |  |  |             out1 = PyStackRef_FromPyObjectNew(obj); | 
					
						
							|  |  |  |             #endif | 
					
						
							|  |  |  |             out2 = PyStackRef_FromPyObjectNew(obj); | 
					
						
							| 
									
										
										
										
											2024-12-13 10:17:16 -08:00
										 |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         TARGET(OP) { | 
					
						
							| 
									
										
										
										
											2025-02-16 03:01:24 +08:00
										 |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             int opcode = OP; | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             (void)(opcode); | 
					
						
							| 
									
										
										
										
											2025-02-07 21:11:57 +08:00
										 |  |  |             #endif | 
					
						
							| 
									
										
										
										
											2024-12-13 10:17:16 -08:00
										 |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							| 
									
										
										
										
											2025-01-14 11:56:11 -08:00
										 |  |  |             _PyStackRef out1; | 
					
						
							|  |  |  |             _PyStackRef out2; | 
					
						
							|  |  |  |             PyObject *obj = SPAM(); | 
					
						
							|  |  |  |             #ifdef Py_GIL_DISABLED | 
					
						
							|  |  |  |             out1 = PyStackRef_FromPyObjectNew(obj); | 
					
						
							|  |  |  |             #else | 
					
						
							|  |  |  |             out1 = PyStackRef_FromPyObjectNew(obj); | 
					
						
							|  |  |  |             #endif | 
					
						
							|  |  |  |             out2 = PyStackRef_FromPyObjectNew(obj); | 
					
						
							|  |  |  |             stack_pointer[0] = out1; | 
					
						
							|  |  |  |             stack_pointer[1] = out2; | 
					
						
							|  |  |  |             stack_pointer += 2; | 
					
						
							| 
									
										
										
										
											2024-12-13 10:17:16 -08:00
										 |  |  |             assert(WITHIN_STACK_BOUNDS()); | 
					
						
							|  |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         self.run_cases_test(input, output) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-06 14:16:22 +00:00
										 |  |  |     def test_no_escaping_calls_in_branching_macros(self): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         inst(OP, ( -- )) { | 
					
						
							|  |  |  |             DEOPT_IF(escaping_call()); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         with self.assertRaises(SyntaxError): | 
					
						
							|  |  |  |             self.run_cases_test(input, "") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         inst(OP, ( -- )) { | 
					
						
							|  |  |  |             EXIT_IF(escaping_call()); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         with self.assertRaises(SyntaxError): | 
					
						
							|  |  |  |             self.run_cases_test(input, "") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         inst(OP, ( -- )) { | 
					
						
							| 
									
										
										
										
											2025-04-29 17:21:53 -07:00
										 |  |  |             ERROR_IF(escaping_call()); | 
					
						
							| 
									
										
										
										
											2025-01-06 14:16:22 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         with self.assertRaises(SyntaxError): | 
					
						
							|  |  |  |             self.run_cases_test(input, "") | 
					
						
							| 
									
										
										
										
											2024-07-09 11:33:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-13 12:37:48 +00:00
										 |  |  |     def test_kill_in_wrong_order(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         inst(OP, (a, b -- c)) { | 
					
						
							|  |  |  |             c = b; | 
					
						
							|  |  |  |             PyStackRef_CLOSE(a); | 
					
						
							|  |  |  |             PyStackRef_CLOSE(b); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         with self.assertRaises(SyntaxError): | 
					
						
							|  |  |  |             self.run_cases_test(input, "") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-27 18:30:20 +08:00
										 |  |  |     def test_complex_label(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							| 
									
										
										
										
											2025-02-04 12:18:31 +00:00
										 |  |  |         label(other_label) { | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         label(other_label2) { | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-27 18:30:20 +08:00
										 |  |  |         label(my_label) { | 
					
						
							|  |  |  |             // Comment | 
					
						
							| 
									
										
										
										
											2025-02-04 12:18:31 +00:00
										 |  |  |             do_thing(); | 
					
						
							| 
									
										
										
										
											2025-01-27 18:30:20 +08:00
										 |  |  |             if (complex) { | 
					
						
							|  |  |  |                 goto other_label; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             goto other_label2; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |         LABEL(other_label) | 
					
						
							| 
									
										
										
										
											2025-02-04 12:18:31 +00:00
										 |  |  |         { | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |         LABEL(other_label2) | 
					
						
							| 
									
										
										
										
											2025-02-04 12:18:31 +00:00
										 |  |  |         { | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |         LABEL(my_label) | 
					
						
							| 
									
										
										
										
											2025-01-27 18:30:20 +08:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-02-04 12:18:31 +00:00
										 |  |  |             _PyFrame_SetStackPointer(frame, stack_pointer); | 
					
						
							|  |  |  |             do_thing(); | 
					
						
							|  |  |  |             stack_pointer = _PyFrame_GetStackPointer(frame); | 
					
						
							| 
									
										
										
										
											2025-01-27 18:30:20 +08:00
										 |  |  |             if (complex) { | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |                 JUMP_TO_LABEL(other_label); | 
					
						
							| 
									
										
										
										
											2025-01-27 18:30:20 +08:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             JUMP_TO_LABEL(other_label2); | 
					
						
							| 
									
										
										
										
											2025-01-27 18:30:20 +08:00
										 |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         self.run_cases_test(input, output) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-04 12:18:31 +00:00
										 |  |  |     def test_spilled_label(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         spilled label(one) { | 
					
						
							|  |  |  |             RELOAD_STACK(); | 
					
						
							|  |  |  |             goto two; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         label(two) { | 
					
						
							|  |  |  |             SAVE_STACK(); | 
					
						
							|  |  |  |             goto one; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |         LABEL(one) | 
					
						
							| 
									
										
										
										
											2025-02-04 12:18:31 +00:00
										 |  |  |         { | 
					
						
							|  |  |  |             stack_pointer = _PyFrame_GetStackPointer(frame); | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             JUMP_TO_LABEL(two); | 
					
						
							| 
									
										
										
										
											2025-02-04 12:18:31 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |         LABEL(two) | 
					
						
							| 
									
										
										
										
											2025-02-04 12:18:31 +00:00
										 |  |  |         { | 
					
						
							|  |  |  |             _PyFrame_SetStackPointer(frame, stack_pointer); | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             JUMP_TO_LABEL(one); | 
					
						
							| 
									
										
										
										
											2025-02-04 12:18:31 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         self.run_cases_test(input, output) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_incorrect_spills(self): | 
					
						
							|  |  |  |         input1 = """
 | 
					
						
							|  |  |  |         spilled label(one) { | 
					
						
							|  |  |  |             goto two; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         label(two) { | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         input2 = """
 | 
					
						
							|  |  |  |         spilled label(one) { | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         label(two) { | 
					
						
							|  |  |  |             goto one; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         with self.assertRaisesRegex(SyntaxError, ".*reload.*"): | 
					
						
							|  |  |  |             self.run_cases_test(input1, "") | 
					
						
							|  |  |  |         with self.assertRaisesRegex(SyntaxError, ".*spill.*"): | 
					
						
							|  |  |  |             self.run_cases_test(input2, "") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-27 18:30:20 +08:00
										 |  |  |     def test_multiple_labels(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         label(my_label_1) { | 
					
						
							|  |  |  |             // Comment | 
					
						
							|  |  |  |             do_thing1(); | 
					
						
							|  |  |  |             goto my_label_2; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         label(my_label_2) { | 
					
						
							|  |  |  |             // Comment | 
					
						
							|  |  |  |             do_thing2(); | 
					
						
							| 
									
										
										
										
											2025-02-04 12:18:31 +00:00
										 |  |  |             goto my_label_1; | 
					
						
							| 
									
										
										
										
											2025-01-27 18:30:20 +08:00
										 |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |         LABEL(my_label_1) | 
					
						
							| 
									
										
										
										
											2025-01-27 18:30:20 +08:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             _PyFrame_SetStackPointer(frame, stack_pointer); | 
					
						
							| 
									
										
										
										
											2025-01-27 18:30:20 +08:00
										 |  |  |             do_thing1(); | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             stack_pointer = _PyFrame_GetStackPointer(frame); | 
					
						
							|  |  |  |             JUMP_TO_LABEL(my_label_2); | 
					
						
							| 
									
										
										
										
											2025-01-27 18:30:20 +08:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |         LABEL(my_label_2) | 
					
						
							| 
									
										
										
										
											2025-01-27 18:30:20 +08:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             _PyFrame_SetStackPointer(frame, stack_pointer); | 
					
						
							| 
									
										
										
										
											2025-01-27 18:30:20 +08:00
										 |  |  |             do_thing2(); | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |             stack_pointer = _PyFrame_GetStackPointer(frame); | 
					
						
							|  |  |  |             JUMP_TO_LABEL(my_label_1); | 
					
						
							| 
									
										
										
										
											2025-01-27 18:30:20 +08:00
										 |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2025-02-06 23:21:57 +08:00
										 |  |  |         self.run_cases_test(input, output) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-21 11:38:17 +00:00
										 |  |  |     def test_reassigning_live_inputs(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							| 
									
										
										
										
											2025-04-14 12:19:53 +01:00
										 |  |  |         inst(OP, (in -- in)) { | 
					
						
							| 
									
										
										
										
											2025-03-21 11:38:17 +00:00
										 |  |  |             in = 0; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2025-04-14 12:19:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         TARGET(OP) { | 
					
						
							|  |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							|  |  |  |             int opcode = OP; | 
					
						
							|  |  |  |             (void)(opcode); | 
					
						
							|  |  |  |             #endif | 
					
						
							|  |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							|  |  |  |             _PyStackRef in; | 
					
						
							|  |  |  |             in = stack_pointer[-1]; | 
					
						
							|  |  |  |             in = 0; | 
					
						
							|  |  |  |             stack_pointer[-1] = in; | 
					
						
							|  |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         self.run_cases_test(input, output) | 
					
						
							| 
									
										
										
										
											2025-03-21 11:38:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def test_reassigning_dead_inputs(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         inst(OP, (in -- )) { | 
					
						
							|  |  |  |             temp = use(in); | 
					
						
							|  |  |  |             DEAD(in); | 
					
						
							|  |  |  |             in = temp; | 
					
						
							|  |  |  |             PyStackRef_CLOSE(in); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         TARGET(OP) { | 
					
						
							|  |  |  |             #if Py_TAIL_CALL_INTERP | 
					
						
							|  |  |  |             int opcode = OP; | 
					
						
							|  |  |  |             (void)(opcode); | 
					
						
							|  |  |  |             #endif | 
					
						
							|  |  |  |             frame->instr_ptr = next_instr; | 
					
						
							|  |  |  |             next_instr += 1; | 
					
						
							|  |  |  |             INSTRUCTION_STATS(OP); | 
					
						
							|  |  |  |             _PyStackRef in; | 
					
						
							|  |  |  |             in = stack_pointer[-1]; | 
					
						
							|  |  |  |             _PyFrame_SetStackPointer(frame, stack_pointer); | 
					
						
							|  |  |  |             temp = use(in); | 
					
						
							|  |  |  |             stack_pointer = _PyFrame_GetStackPointer(frame); | 
					
						
							|  |  |  |             in = temp; | 
					
						
							|  |  |  |             stack_pointer += -1; | 
					
						
							|  |  |  |             assert(WITHIN_STACK_BOUNDS()); | 
					
						
							|  |  |  |             _PyFrame_SetStackPointer(frame, stack_pointer); | 
					
						
							|  |  |  |             PyStackRef_CLOSE(in); | 
					
						
							|  |  |  |             stack_pointer = _PyFrame_GetStackPointer(frame); | 
					
						
							|  |  |  |             DISPATCH(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         self.run_cases_test(input, output) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-13 12:37:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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, (--)) { | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             SPAM(); | 
					
						
							| 
									
										
										
										
											2024-02-13 21:24:48 +08:00
										 |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         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)) { | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             out = SPAM(arg1); | 
					
						
							| 
									
										
										
										
											2024-02-13 21:24:48 +08:00
										 |  |  |         } | 
					
						
							|  |  |  |         op(OP2, (arg1 -- out)) { | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             out = EGGS(arg1); | 
					
						
							| 
									
										
										
										
											2024-02-13 21:24:48 +08:00
										 |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         input2 = """
 | 
					
						
							|  |  |  |         op(OP, (arg1 -- out)) { | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             out = EGGS(arg1); | 
					
						
							| 
									
										
										
										
											2024-02-13 21:24:48 +08:00
										 |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         case OP: { | 
					
						
							| 
									
										
										
										
											2025-01-20 15:49:15 +00:00
										 |  |  |             JitOptSymbol *arg1; | 
					
						
							|  |  |  |             JitOptSymbol *out; | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             arg1 = stack_pointer[-1]; | 
					
						
							|  |  |  |             out = EGGS(arg1); | 
					
						
							| 
									
										
										
										
											2024-02-13 21:24:48 +08:00
										 |  |  |             stack_pointer[-1] = out; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         case OP2: { | 
					
						
							| 
									
										
										
										
											2025-01-20 15:49:15 +00:00
										 |  |  |             JitOptSymbol *out; | 
					
						
							| 
									
										
										
										
											2024-03-13 20:57:48 +08:00
										 |  |  |             out = sym_new_not_null(ctx); | 
					
						
							| 
									
										
										
										
											2024-02-13 21:24:48 +08:00
										 |  |  |             stack_pointer[-1] = out; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |        """
 | 
					
						
							|  |  |  |         self.run_cases_test(input, input2, output) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_no_overridden_case(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         pure op(OP, (arg1 -- out)) { | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             out = SPAM(arg1); | 
					
						
							| 
									
										
										
										
											2024-02-13 21:24:48 +08:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         pure op(OP2, (arg1 -- out)) { | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         input2 = """
 | 
					
						
							|  |  |  |         pure op(OP2, (arg1 -- out)) { | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             out = NULL; | 
					
						
							| 
									
										
										
										
											2024-02-13 21:24:48 +08:00
										 |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         output = """
 | 
					
						
							|  |  |  |         case OP: { | 
					
						
							| 
									
										
										
										
											2025-01-20 15:49:15 +00:00
										 |  |  |             JitOptSymbol *out; | 
					
						
							| 
									
										
										
										
											2024-03-13 20:57:48 +08:00
										 |  |  |             out = sym_new_not_null(ctx); | 
					
						
							| 
									
										
										
										
											2024-02-13 21:24:48 +08:00
										 |  |  |             stack_pointer[-1] = out; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         case OP2: { | 
					
						
							| 
									
										
										
										
											2025-01-20 15:49:15 +00:00
										 |  |  |             JitOptSymbol *out; | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             out = NULL; | 
					
						
							| 
									
										
										
										
											2024-02-13 21:24:48 +08:00
										 |  |  |             stack_pointer[-1] = out; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         self.run_cases_test(input, input2, output) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def test_missing_override_failure(self): | 
					
						
							|  |  |  |         input = """
 | 
					
						
							|  |  |  |         pure op(OP, (arg1 -- out)) { | 
					
						
							| 
									
										
										
										
											2024-10-07 14:56:39 +01:00
										 |  |  |             SPAM(); | 
					
						
							| 
									
										
										
										
											2024-02-13 21:24:48 +08:00
										 |  |  |         } | 
					
						
							|  |  |  |         """
 | 
					
						
							|  |  |  |         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() |