Skip to content

Commit ae1ec5c

Browse files
committed
Build the tail-calling interpreter using MSVC
1 parent f963239 commit ae1ec5c

6 files changed

Lines changed: 252 additions & 240 deletions

File tree

Include/pyport.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,10 @@
3838

3939
// Static inline functions should use _Py_NULL rather than using directly NULL
4040
// to prevent C++ compiler warnings. On C23 and newer and on C++11 and newer,
41-
// _Py_NULL is defined as nullptr.
42-
#if (defined (__STDC_VERSION__) && __STDC_VERSION__ > 201710L) \
43-
|| (defined(__cplusplus) && __cplusplus >= 201103)
41+
// _Py_NULL is defined as nullptr (but not all compilers support it).
42+
#if (defined(__GNUC__) || defined(__clang__)) \
43+
&& ((defined (__STDC_VERSION__) && __STDC_VERSION__ > 201710L) \
44+
|| (defined(__cplusplus) && __cplusplus >= 201103))
4445
# define _Py_NULL nullptr
4546
#else
4647
# define _Py_NULL NULL

PCbuild/build.bat

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ echo. overrides -c and -d
3636
echo. --disable-gil Enable experimental support for running without the GIL.
3737
echo. --test-marker Enable the test marker within the build.
3838
echo. --regen Regenerate all opcodes, grammar and tokens.
39+
echo. --tail-call-interp Enable the tail-calling interpreter.
3940
echo. --experimental-jit Enable the experimental just-in-time compiler.
4041
echo. --experimental-jit-off Ditto but off by default (PYTHON_JIT=1 enables).
4142
echo. --experimental-jit-interpreter Enable the experimental Tier 2 interpreter.
@@ -90,6 +91,7 @@ if "%~1"=="--disable-gil" (set UseDisableGil=true) & shift & goto CheckOpts
9091
if "%~1"=="--test-marker" (set UseTestMarker=true) & shift & goto CheckOpts
9192
if "%~1"=="-V" shift & goto Version
9293
if "%~1"=="--regen" (set Regen=true) & shift & goto CheckOpts
94+
if "%~1"=="--tail-call-interp" (set UseTailCalls=true) & shift & goto CheckOpts
9395
if "%~1"=="--experimental-jit" (set UseJIT=true) & (set UseTIER2=1) & shift & goto CheckOpts
9496
if "%~1"=="--experimental-jit-off" (set UseJIT=true) & (set UseTIER2=3) & shift & goto CheckOpts
9597
if "%~1"=="--experimental-jit-interpreter" (set UseTIER2=4) & shift & goto CheckOpts
@@ -186,6 +188,7 @@ echo on
186188
/p:IncludeSSL=%IncludeSSL% /p:IncludeTkinter=%IncludeTkinter%^
187189
/p:DisableGil=%UseDisableGil%^
188190
/p:UseTestMarker=%UseTestMarker% %GITProperty%^
191+
/p:UseTailCalls=%UseTailCalls%^
189192
/p:UseJIT=%UseJIT%^
190193
/p:UseTIER2=%UseTIER2%^
191194
/p:PyStats=%PyStats%^

PCbuild/pythoncore.vcxproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@
104104
<AdditionalIncludeDirectories Condition="$(IncludeExternals)">$(zlibDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
105105
<PreprocessorDefinitions>_USRDLL;Py_BUILD_CORE;Py_BUILD_CORE_BUILTIN;Py_ENABLE_SHARED;MS_DLL_ID="$(SysWinVer)";%(PreprocessorDefinitions)</PreprocessorDefinitions>
106106
<PreprocessorDefinitions Condition="$(IncludeExternals)">_Py_HAVE_ZLIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
107+
<AdditionalOptions Condition="'$(UseTailCalls)' == 'true'">/std:clatest %(AdditionalOptions)</AdditionalOptions>
108+
<PreprocessorDefinitions Condition="'$(UseTailCalls)' == 'true'">Py_TAIL_CALL_INTERP=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
107109
<PreprocessorDefinitions Condition="'$(UseJIT)' == 'true'">_Py_JIT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
108110
<PreprocessorDefinitions Condition="'$(UseTIER2)' != '' and '$(UseTIER2)' != '0'">_Py_TIER2=$(UseTIER2);%(PreprocessorDefinitions)</PreprocessorDefinitions>
109111
</ClCompile>

Python/ceval_macros.h

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,18 @@
7474
#define TAIL_CALL_ARGS frame, stack_pointer, tstate, next_instr, oparg
7575

7676
#if Py_TAIL_CALL_INTERP
77-
// Note: [[clang::musttail]] works for GCC 15, but not __attribute__((musttail)) at the moment.
78-
# define Py_MUSTTAIL [[clang::musttail]]
79-
# define Py_PRESERVE_NONE_CC __attribute__((preserve_none))
80-
Py_PRESERVE_NONE_CC typedef PyObject* (*py_tail_call_funcptr)(TAIL_CALL_PARAMS);
81-
82-
# define TARGET(op) Py_PRESERVE_NONE_CC PyObject *_TAIL_CALL_##op(TAIL_CALL_PARAMS)
77+
# ifdef _MSC_VER
78+
# define Py_MUSTTAIL [[msvc::musttail]]
79+
# define Py_PRESERVE_NONE_CC __volatilecall
80+
# else
81+
// Note: [[clang::musttail]] works for GCC 15, but not __attribute__((musttail)) at the moment.
82+
# define Py_MUSTTAIL [[clang::musttail]]
83+
# define Py_PRESERVE_NONE_CC __attribute__((preserve_none))
84+
# endif
85+
86+
typedef PyObject* (Py_PRESERVE_NONE_CC *py_tail_call_funcptr)(TAIL_CALL_PARAMS);
87+
88+
# define TARGET(op) PyObject *Py_PRESERVE_NONE_CC _TAIL_CALL_##op(TAIL_CALL_PARAMS)
8389
# define DISPATCH_GOTO() \
8490
do { \
8591
Py_MUSTTAIL return (INSTRUCTION_TABLE[opcode])(TAIL_CALL_ARGS); \

0 commit comments

Comments
 (0)