Skip to content

Commit 1be3e2a

Browse files
Merge the two interpreters into one
1 parent cf18981 commit 1be3e2a

15 files changed

+2397
-16332
lines changed

.gitattributes

-2
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,6 @@ Programs/test_frozenmain.h generated
9595
Python/Python-ast.c generated
9696
Python/executor_cases.c.h generated
9797
Python/generated_cases.c.h generated
98-
Python/generated_tail_call_handlers.c.h generated
99-
Python/generated_tail_call_labels.c.h generated
10098
Python/optimizer_cases.c.h generated
10199
Python/opcode_targets.h generated
102100
Python/stdlib_module_names.h generated

.github/workflows/tail-call.yml

-4
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,11 @@ on:
55
- 'Python/bytecodes.c'
66
- 'Python/ceval.c'
77
- 'Python/ceval_macros.h'
8-
- 'Python/generated_tail_call_handlers.c.h'
9-
- 'Python/generated_tail_call_labels.c.h'
108
push:
119
paths:
1210
- 'Python/bytecodes.c'
1311
- 'Python/ceval.c'
1412
- 'Python/ceval_macros.h'
15-
- 'Python/generated_tail_call_handlers.c.h'
16-
- 'Python/generated_tail_call_labels.c.h'
1713
workflow_dispatch:
1814

1915
permissions:

Lib/test/test_generated_cases.py

+18-142
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ def skip_if_different_mount_drives():
3636
import parser
3737
from stack import Local, Stack
3838
import tier1_generator
39-
import tier1_tail_call_generator
4039
import opcode_metadata_generator
4140
import optimizer_generator
4241

@@ -462,7 +461,7 @@ def test_predictions(self):
462461
if (xxx) {
463462
UPDATE_MISS_STATS(OP1);
464463
assert(_PyOpcode_Deopt[opcode] == (OP1));
465-
goto PREDICTED_OP1;
464+
JUMP_TO_PREDICTED(OP1);
466465
}
467466
res = Py_None;
468467
stack_pointer[-1] = res;
@@ -544,7 +543,7 @@ def test_error_if_plain(self):
544543
next_instr += 1;
545544
INSTRUCTION_STATS(OP);
546545
if (cond) {
547-
goto label;
546+
JUMP_TO_LABEL(label);
548547
}
549548
DISPATCH();
550549
}
@@ -563,7 +562,7 @@ def test_error_if_plain_with_comment(self):
563562
next_instr += 1;
564563
INSTRUCTION_STATS(OP);
565564
if (cond) {
566-
goto label;
565+
JUMP_TO_LABEL(label);
567566
}
568567
// Comment is ok
569568
DISPATCH();
@@ -592,7 +591,7 @@ def test_error_if_pop(self):
592591
left = stack_pointer[-2];
593592
SPAM(left, right);
594593
if (cond) {
595-
goto pop_2_label;
594+
JUMP_TO_LABEL(pop_2_label);
596595
}
597596
res = 0;
598597
stack_pointer[-2] = res;
@@ -623,7 +622,7 @@ def test_error_if_pop_with_result(self):
623622
left = stack_pointer[-2];
624623
res = SPAM(left, right);
625624
if (cond) {
626-
goto pop_2_label;
625+
JUMP_TO_LABEL(pop_2_label);
627626
}
628627
stack_pointer[-2] = res;
629628
stack_pointer += -1;
@@ -640,8 +639,9 @@ def test_cache_effect(self):
640639
"""
641640
output = """
642641
TARGET(OP) {
643-
_Py_CODEUNIT* const this_instr = frame->instr_ptr = next_instr;
642+
_Py_CODEUNIT* const this_instr = next_instr;
644643
(void)this_instr;
644+
frame->instr_ptr = next_instr;
645645
next_instr += 4;
646646
INSTRUCTION_STATS(OP);
647647
uint16_t counter = read_u16(&this_instr[1].cache);
@@ -726,8 +726,9 @@ def test_macro_instruction(self):
726726
}
727727
728728
TARGET(OP1) {
729-
_Py_CODEUNIT* const this_instr = frame->instr_ptr = next_instr;
729+
_Py_CODEUNIT* const this_instr = next_instr;
730730
(void)this_instr;
731+
frame->instr_ptr = next_instr;
731732
next_instr += 2;
732733
INSTRUCTION_STATS(OP1);
733734
_PyStackRef left;
@@ -942,7 +943,7 @@ def test_array_error_if(self):
942943
if (oparg == 0) {
943944
stack_pointer += -1 - oparg;
944945
assert(WITHIN_STACK_BOUNDS());
945-
goto somewhere;
946+
JUMP_TO_LABEL(somewhere);
946947
}
947948
stack_pointer += -1 - oparg;
948949
assert(WITHIN_STACK_BOUNDS());
@@ -1406,7 +1407,7 @@ def test_pop_on_error_peeks(self):
14061407
{
14071408
// Mark j and k as used
14081409
if (cond) {
1409-
goto pop_2_error;
1410+
JUMP_TO_LABEL(pop_2_error);
14101411
}
14111412
}
14121413
stack_pointer += -2;
@@ -1450,7 +1451,7 @@ def test_push_then_error(self):
14501451
stack_pointer[1] = b;
14511452
stack_pointer += 2;
14521453
assert(WITHIN_STACK_BOUNDS());
1453-
goto error;
1454+
JUMP_TO_LABEL(error);
14541455
}
14551456
}
14561457
stack_pointer[0] = a;
@@ -1477,14 +1478,14 @@ def test_error_if_true(self):
14771478
frame->instr_ptr = next_instr;
14781479
next_instr += 1;
14791480
INSTRUCTION_STATS(OP1);
1480-
goto here;
1481+
JUMP_TO_LABEL(here);
14811482
}
14821483
14831484
TARGET(OP2) {
14841485
frame->instr_ptr = next_instr;
14851486
next_instr += 1;
14861487
INSTRUCTION_STATS(OP2);
1487-
goto there;
1488+
JUMP_TO_LABEL(there);
14881489
}
14891490
"""
14901491
self.run_cases_test(input, output)
@@ -1784,7 +1785,7 @@ def test_complex_label(self):
17841785
"""
17851786

17861787
output = """
1787-
my_label:
1788+
LABEL(my_label)
17881789
{
17891790
// Comment
17901791
do_thing()
@@ -1812,146 +1813,21 @@ def test_multiple_labels(self):
18121813
"""
18131814

18141815
output = """
1815-
my_label_1:
1816+
LABEL(my_label_1)
18161817
{
18171818
// Comment
18181819
do_thing1();
18191820
goto my_label_2;
18201821
}
18211822
1822-
my_label_2:
1823+
LABEL(my_label_2)
18231824
{
18241825
// Comment
18251826
do_thing2();
18261827
goto my_label_3;
18271828
}
18281829
"""
1829-
1830-
class TestGeneratedTailCallHandlers(unittest.TestCase):
1831-
def setUp(self) -> None:
1832-
super().setUp()
1833-
self.maxDiff = None
1834-
1835-
self.temp_dir = tempfile.gettempdir()
1836-
self.temp_input_filename = os.path.join(self.temp_dir, "input.txt")
1837-
self.temp_output_filename = os.path.join(self.temp_dir, "output.txt")
1838-
self.temp_labels_output_filename = os.path.join(self.temp_dir, "labels_output.txt")
1839-
1840-
def tearDown(self) -> None:
1841-
for filename in [
1842-
self.temp_input_filename,
1843-
self.temp_output_filename,
1844-
self.temp_labels_output_filename,
1845-
]:
1846-
try:
1847-
os.remove(filename)
1848-
except Exception:
1849-
pass
1850-
super().tearDown()
1851-
1852-
def run_cases_test(self, input: str, expected: str, expected_labels: str):
1853-
with open(self.temp_input_filename, "w+") as temp_input:
1854-
temp_input.write(parser.BEGIN_MARKER)
1855-
temp_input.write(input)
1856-
temp_input.write(parser.END_MARKER)
1857-
temp_input.flush()
1858-
1859-
with handle_stderr():
1860-
tier1_tail_call_generator.generate_tier1_from_files(
1861-
[self.temp_input_filename], self.temp_output_filename, self.temp_labels_output_filename, False
1862-
)
1863-
1864-
with open(self.temp_output_filename) as temp_output:
1865-
lines = temp_output.read()
1866-
_, rest = lines.split(tier1_generator.INSTRUCTION_START_MARKER)
1867-
instructions, _ = rest.split(tier1_generator.INSTRUCTION_END_MARKER)
1868-
1869-
with open(self.temp_labels_output_filename) as temp_output:
1870-
lines = temp_output.readlines()
1871-
while lines and lines[0].startswith(("// ", "#", " #", "\n")):
1872-
lines.pop(0)
1873-
while lines and lines[-1].startswith(("#", "\n")):
1874-
lines.pop(-1)
1875-
actual_labels = "".join(lines)
1876-
1877-
self.assertEqual(instructions.strip(), expected.strip())
1878-
self.assertEqual(actual_labels.strip(), expected_labels.strip())
1879-
1880-
def test_basic(self):
1881-
input = """
1882-
inst(OP, (--)) {
1883-
SPAM();
1884-
}
1885-
"""
1886-
output = """
1887-
Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_OP(TAIL_CALL_PARAMS) {
1888-
{
1889-
int opcode = next_instr->op.code;
1890-
(void)(opcode);
1891-
frame->instr_ptr = next_instr;
1892-
next_instr += 1;
1893-
INSTRUCTION_STATS(OP);
1894-
SPAM();
1895-
}
1896-
DISPATCH();
1897-
}
1898-
"""
1899-
output_labels = ""
1900-
self.run_cases_test(input, output, output_labels)
1901-
1902-
def test_label_transformed(self):
1903-
"""This tests that the labels and their gotos/DISPATCH get transformed to tail calls in the
1904-
tail-calling interpreter, while staying the same/becoming an entry call in the normal interpreter.
1905-
"""
1906-
input = """
1907-
inst(OP, (--)) {
1908-
SPAM();
1909-
}
1910-
1911-
label(hello) {
1912-
EGGS();
1913-
if (x) {
1914-
goto baz;
1915-
}
1916-
DISPATCH();
1917-
}
1918-
"""
1919-
output = """
1920-
Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_hello(TAIL_CALL_PARAMS)
1921-
{
1922-
EGGS();
1923-
if (x) {
1924-
TAIL_CALL(baz);
1925-
}
1926-
DISPATCH();
1927-
}
1928-
1929-
1930-
Py_PRESERVE_NONE_CC static PyObject *_TAIL_CALL_OP(TAIL_CALL_PARAMS) {
1931-
{
1932-
int opcode = next_instr->op.code;
1933-
(void)(opcode);
1934-
frame->instr_ptr = next_instr;
1935-
next_instr += 1;
1936-
INSTRUCTION_STATS(OP);
1937-
SPAM();
1938-
}
1939-
DISPATCH();
1940-
hello:
1941-
TAIL_CALL(hello);
1942-
}
1943-
"""
1944-
output_labels = """
1945-
hello:
1946-
{
1947-
EGGS();
1948-
if (x) {
1949-
goto baz;
1950-
}
1951-
return _TAIL_CALL_entry(frame, stack_pointer, tstate, next_instr, 0);
1952-
}
1953-
"""
1954-
self.run_cases_test(input, output, output_labels)
1830+
self.run_cases_test(input, output)
19551831

19561832

19571833
class TestGeneratedAbstractCases(unittest.TestCase):

Makefile.pre.in

+1-8
Original file line numberDiff line numberDiff line change
@@ -1985,7 +1985,7 @@ Objects/mimalloc/page.o: $(srcdir)/Objects/mimalloc/page-queue.c
19851985
.PHONY: regen-cases
19861986
regen-cases: \
19871987
regen-opcode-ids regen-opcode-targets regen-uop-ids regen-opcode-metadata-py \
1988-
regen-generated-cases regen-generated-tail-call-handlers regen-executor-cases regen-optimizer-cases \
1988+
regen-generated-cases regen-executor-cases regen-optimizer-cases \
19891989
regen-opcode-metadata regen-uop-metadata
19901990

19911991
.PHONY: regen-opcode-ids
@@ -2018,12 +2018,6 @@ regen-generated-cases:
20182018
-o $(srcdir)/Python/generated_cases.c.h.new $(srcdir)/Python/bytecodes.c
20192019
$(UPDATE_FILE) $(srcdir)/Python/generated_cases.c.h $(srcdir)/Python/generated_cases.c.h.new
20202020

2021-
.PHONY: regen-generated-tail-call-handlers
2022-
regen-generated-tail-call-handlers:
2023-
$(PYTHON_FOR_REGEN) $(srcdir)/Tools/cases_generator/tier1_tail_call_generator.py \
2024-
-o $(srcdir)/Python/generated_tail_call_handlers.c.h.new $(srcdir)/Python/bytecodes.c
2025-
$(UPDATE_FILE) $(srcdir)/Python/generated_tail_call_handlers.c.h $(srcdir)/Python/generated_tail_call_handlers.c.h.new
2026-
20272021
.PHONY: regen-executor-cases
20282022
regen-executor-cases:
20292023
$(PYTHON_FOR_REGEN) $(srcdir)/Tools/cases_generator/tier2_generator.py \
@@ -2061,7 +2055,6 @@ Python/ceval.o: \
20612055
$(srcdir)/Python/ceval_macros.h \
20622056
$(srcdir)/Python/condvar.h \
20632057
$(srcdir)/Python/generated_cases.c.h \
2064-
$(srcdir)/Python/generated_tail_call_handlers.c.h \
20652058
$(srcdir)/Python/executor_cases.c.h \
20662059
$(srcdir)/Python/opcode_targets.h
20672060

0 commit comments

Comments
 (0)