Skip to content

Commit 178b03e

Browse files
fix for tail call
1 parent 62f0b7a commit 178b03e

File tree

4 files changed

+16
-17
lines changed

4 files changed

+16
-17
lines changed

Python/ceval.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,6 +1031,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
10311031
uint8_t opcode; /* Current opcode */
10321032
int oparg; /* Current opcode argument, if any */
10331033
assert(tstate->current_frame == NULL || tstate->current_frame->stackpointer != NULL);
1034+
void **opcode_targets = opcode_targets_table;
10341035
#endif
10351036
_PyEntryFrame entry;
10361037

@@ -1040,8 +1041,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
10401041
return NULL;
10411042
}
10421043

1043-
void **opcode_targets = opcode_targets_table;
1044-
10451044
/* Local "register" variables.
10461045
* These are cached values from the frame and code object. */
10471046
_Py_CODEUNIT *next_instr;
@@ -1103,9 +1102,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
11031102
stack_pointer = _PyFrame_GetStackPointer(frame);
11041103
#if Py_TAIL_CALL_INTERP
11051104
# if Py_STATS
1106-
return _TAIL_CALL_error(frame, stack_pointer, tstate, next_instr, 0, lastopcode);
1105+
return _TAIL_CALL_error(frame, stack_pointer, tstate, next_instr, instruction_funcptr_table, 0, lastopcode);
11071106
# else
1108-
return _TAIL_CALL_error(frame, stack_pointer, tstate, next_instr, 0);
1107+
return _TAIL_CALL_error(frame, stack_pointer, tstate, next_instr, instruction_funcptr_table, 0);
11091108
# endif
11101109
#else
11111110
goto error;
@@ -1114,9 +1113,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
11141113

11151114
#if Py_TAIL_CALL_INTERP
11161115
# if Py_STATS
1117-
return _TAIL_CALL_start_frame(frame, NULL, tstate, NULL, 0, lastopcode);
1116+
return _TAIL_CALL_start_frame(frame, NULL, tstate, NULL, instruction_funcptr_table, 0, lastopcode);
11181117
# else
1119-
return _TAIL_CALL_start_frame(frame, NULL, tstate, NULL, 0);
1118+
return _TAIL_CALL_start_frame(frame, NULL, tstate, NULL, instruction_funcptr_table, 0);
11201119
# endif
11211120
#else
11221121
goto start_frame;

Python/ceval_macros.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,11 @@
7171
#endif
7272

7373
#ifdef Py_STATS
74-
# define TAIL_CALL_PARAMS _PyInterpreterFrame *frame, _PyStackRef *stack_pointer, PyThreadState *tstate, _Py_CODEUNIT *next_instr, int oparg, int lastopcode
75-
# define TAIL_CALL_ARGS frame, stack_pointer, tstate, next_instr, oparg, lastopcode
74+
# define TAIL_CALL_PARAMS _PyInterpreterFrame *frame, _PyStackRef *stack_pointer, PyThreadState *tstate, _Py_CODEUNIT *next_instr, const void *INSTRUCTION_TABLE, int oparg, int lastopcode
75+
# define TAIL_CALL_ARGS frame, stack_pointer, tstate, next_instr, INSTRUCTION_TABLE, oparg, lastopcode
7676
#else
77-
# define TAIL_CALL_PARAMS _PyInterpreterFrame *frame, _PyStackRef *stack_pointer, PyThreadState *tstate, _Py_CODEUNIT *next_instr, int oparg
78-
# define TAIL_CALL_ARGS frame, stack_pointer, tstate, next_instr, oparg
77+
# define TAIL_CALL_PARAMS _PyInterpreterFrame *frame, _PyStackRef *stack_pointer, PyThreadState *tstate, _Py_CODEUNIT *next_instr, const void *INSTRUCTION_TABLE, int oparg
78+
# define TAIL_CALL_ARGS frame, stack_pointer, tstate, next_instr, INSTRUCTION_TABLE, oparg
7979
#endif
8080

8181
#if Py_TAIL_CALL_INTERP
@@ -87,7 +87,7 @@
8787
# define TARGET(op) Py_PRESERVE_NONE_CC PyObject *_TAIL_CALL_##op(TAIL_CALL_PARAMS)
8888
# define DISPATCH_GOTO() \
8989
do { \
90-
Py_MUSTTAIL return (INSTRUCTION_TABLE[opcode])(TAIL_CALL_ARGS); \
90+
Py_MUSTTAIL return (((py_tail_call_funcptr *)INSTRUCTION_TABLE)[opcode])(TAIL_CALL_ARGS); \
9191
} while (0)
9292
# define JUMP_TO_LABEL(name) \
9393
do { \
@@ -96,12 +96,12 @@
9696
# ifdef Py_STATS
9797
# define JUMP_TO_PREDICTED(name) \
9898
do { \
99-
Py_MUSTTAIL return (_TAIL_CALL_##name)(frame, stack_pointer, tstate, this_instr, oparg, lastopcode); \
99+
Py_MUSTTAIL return (_TAIL_CALL_##name)(frame, stack_pointer, tstate, this_instr, INSTRUCTION_TABLE, oparg, lastopcode); \
100100
} while (0)
101101
# else
102102
# define JUMP_TO_PREDICTED(name) \
103103
do { \
104-
Py_MUSTTAIL return (_TAIL_CALL_##name)(frame, stack_pointer, tstate, this_instr, oparg); \
104+
Py_MUSTTAIL return (_TAIL_CALL_##name)(frame, stack_pointer, tstate, this_instr, INSTRUCTION_TABLE, oparg); \
105105
} while (0)
106106
# endif
107107
# define LABEL(name) TARGET(name)

Python/opcode_targets.h

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Tools/cases_generator/target_generator.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ def function_proto(name: str) -> str:
3838

3939

4040
def write_tailcall_dispatch_table(analysis: Analysis, out: CWriter) -> None:
41-
out.emit("static py_tail_call_funcptr INSTRUCTION_TABLE[256];\n")
41+
out.emit("static py_tail_call_funcptr instruction_funcptr_table[256];\n")
4242
out.emit("\n")
4343

4444
# Emit function prototypes for labels.
@@ -60,7 +60,7 @@ def write_tailcall_dispatch_table(analysis: Analysis, out: CWriter) -> None:
6060
out.emit("\n")
6161

6262
# Emit the dispatch table.
63-
out.emit("static py_tail_call_funcptr INSTRUCTION_TABLE[256] = {\n")
63+
out.emit("static py_tail_call_funcptr instruction_funcptr_table[256] = {\n")
6464
for name in sorted(analysis.instructions.keys()):
6565
out.emit(f"[{name}] = _TAIL_CALL_{name},\n")
6666
named_values = analysis.opmap.values()

0 commit comments

Comments
 (0)