SDL: Use SDL_DISABLE_ALLOCA instead of HAVE_ALLOCA in SDL_stdinc.h

From 6127ac08714f423b523c0bf6c2210a782b2f571a Mon Sep 17 00:00:00 2001
From: Anonymous Maarten <[EMAIL REDACTED]>
Date: Mon, 2 Oct 2023 11:00:06 +0200
Subject: [PATCH] Use SDL_DISABLE_ALLOCA instead of HAVE_ALLOCA in SDL_stdinc.h

---
 CMakeLists.txt                                | 27 ++++++-
 VisualC-GDK/SDL/SDL.vcxproj                   |  5 ++
 VisualC-GDK/SDL/SDL.vcxproj.filters           |  3 +
 VisualC-WinRT/SDL-UWP.vcxproj                 |  5 ++
 VisualC-WinRT/SDL-UWP.vcxproj.filters         |  3 +
 VisualC/SDL/SDL.vcxproj                       |  5 ++
 VisualC/SDL/SDL.vcxproj.filters               |  3 +
 cmake/sdlcompilers.cmake                      | 26 +++----
 include/SDL3/SDL_stdinc.h                     | 40 ++++++-----
 include/build_config/SDL_build_config.h.cmake |  3 +-
 .../build_config/SDL_build_config_android.h   |  1 -
 .../SDL_build_config_emscripten.h             |  1 -
 include/build_config/SDL_build_config_ios.h   |  1 -
 include/build_config/SDL_build_config_macos.h |  1 -
 .../build_config/SDL_build_config_windows.h   |  1 -
 .../build_config/SDL_build_config_wingdk.h    |  1 -
 include/build_config/SDL_build_config_winrt.h |  1 -
 include/build_config/SDL_build_config_xbox.h  |  1 -
 src/stdlib/SDL_mslibc.c                       | 72 +++++++++++++++++++
 src/stdlib/SDL_mslibc_x64.asm                 | 29 ++++++++
 20 files changed, 185 insertions(+), 44 deletions(-)
 create mode 100644 src/stdlib/SDL_mslibc_x64.asm

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0baea19031b7..6edba99fb69a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -486,6 +486,18 @@ sdl_glob_sources(
   "${SDL3_SOURCE_DIR}/src/video/*.c"
   "${SDL3_SOURCE_DIR}/src/video/yuv2rgb/*.c"
 )
+if(MSVC AND TARGET SDL3-shared)
+  if(SDL_CPU_X64)
+    enable_language(ASM_MASM)
+    set(asm_src "${SDL3_SOURCE_DIR}/src/stdlib/SDL_mslibc_x64.asm")
+    target_compile_options(SDL3-shared PRIVATE "$<$<COMPILE_LANGUAGE:ASM_MASM>:/nologo>")
+    set_property(SOURCE "${asm_src}" PROPERTY LANGUAGE "ASM_MASM")
+    target_sources(SDL3-shared PRIVATE "${asm_src}")
+  elseif(SDL_CPU_ARM32 OR DL_CPU_ARM64)
+    # FIXME: ARM assembler (armasm.exe/armasm64.exe) is NOT ASM_MASM, and does currently not work with CMake
+    # (https://gitlab.kitware.com/cmake/cmake/-/issues/18912)
+  endif()
+endif()
 
 if(USE_INTELCC)
   # warning #39: division by zero
@@ -985,12 +997,21 @@ if(NOT HAVE_ARMNEON)
   set(SDL_DISABLE_NEON 1)
 endif()
 
+set(SDL_DISABLE_ALLOCA 0)
+check_include_file("alloca.h" "HAVE_ALLOCA_H")
+if(MSVC)
+  check_include_file("malloc.h" "HAVE_MALLOC")
+  check_symbol_exists("_alloca" "malloc.h" _ALLOCA_IN_MALLOC_H)
+  if(NOT HAVE_ALLOCA_H AND NOT _ALLOCA_IN_MALLOC_H)
+    set(SDL_DISABLE_ALLOCA 1)
+  endif()
+endif()
+
 # TODO: Can't deactivate on FreeBSD? w/o LIBC, SDL_stdinc.h can't define anything.
 if(SDL_LIBC)
   set(available_headers)
   set(HAVE_LIBC TRUE)
   set(headers_to_check
-    alloca.h
     ctype.h
     float.h
     iconv.h
@@ -1022,7 +1043,7 @@ if(SDL_LIBC)
   endforeach()
 
   set(symbols_to_check
-    abs acos acosf alloca asin asinf atan atan2 atan2f atanf atof atoi
+    abs acos acosf asin asinf atan atan2 atan2f atanf atof atoi
     bcopy bsearch
     calloc ceil ceilf copysign copysignf cos cosf
     _Exit exp expf
@@ -1717,7 +1738,7 @@ elseif(WINDOWS)
 
   if(TARGET SDL3-shared AND MSVC AND NOT SDL_LIBC)
     # Prevent codegen that would use the VC runtime libraries.
-    target_compile_options(SDL3-shared PRIVATE "/GS-" "/Gs1048576")
+    target_compile_options(SDL3-shared PRIVATE $<$<COMPILE_LANGUAGE:C,CXX>:/GS-> $<$<COMPILE_LANGUAGE:C,CXX>:/Gs1048576>)
     if(SDL_CPU_X86)
       target_compile_options(SDL3-shared PRIVATE "/arch:SSE")
     endif()
diff --git a/VisualC-GDK/SDL/SDL.vcxproj b/VisualC-GDK/SDL/SDL.vcxproj
index bb003d0f0831..70b625b37f42 100644
--- a/VisualC-GDK/SDL/SDL.vcxproj
+++ b/VisualC-GDK/SDL/SDL.vcxproj
@@ -59,6 +59,7 @@
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
+    <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Gaming.Desktop.x64'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
@@ -729,6 +730,9 @@
     <ClCompile Include="..\..\src\stdlib\SDL_iconv.c" />
     <ClCompile Include="..\..\src\stdlib\SDL_malloc.c" />
     <ClCompile Include="..\..\src\stdlib\SDL_mslibc.c" />
+    <MASM Condition="'$(Platform)'=='x64'" Include="..\..\src\stdlib\SDL_mslibc_x64.asm" >
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+    </MASM>
     <ClCompile Include="..\..\src\stdlib\SDL_qsort.c" />
     <ClCompile Include="..\..\src\stdlib\SDL_stdlib.c" />
     <ClCompile Include="..\..\src\stdlib\SDL_string.c" />
@@ -793,5 +797,6 @@
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
+    <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
   </ImportGroup>
 </Project>
diff --git a/VisualC-GDK/SDL/SDL.vcxproj.filters b/VisualC-GDK/SDL/SDL.vcxproj.filters
index bbdc75985c4d..a530ef1bfa18 100644
--- a/VisualC-GDK/SDL/SDL.vcxproj.filters
+++ b/VisualC-GDK/SDL/SDL.vcxproj.filters
@@ -1388,6 +1388,9 @@
     <ClCompile Include="..\..\src\stdlib\SDL_mslibc.c">
       <Filter>stdlib</Filter>
     </ClCompile>
+    <MASM Include="..\..\src\stdlib\SDL_mslibc_x64.asm">
+      <Filter>stdlib</Filter>
+    </MASM>
     <ClCompile Include="..\..\src\core\gdk\SDL_gdk.cpp">
       <Filter>core\gdk</Filter>
     </ClCompile>
diff --git a/VisualC-WinRT/SDL-UWP.vcxproj b/VisualC-WinRT/SDL-UWP.vcxproj
index 372a28339683..21c5e7ebba22 100644
--- a/VisualC-WinRT/SDL-UWP.vcxproj
+++ b/VisualC-WinRT/SDL-UWP.vcxproj
@@ -413,6 +413,9 @@
     <ClCompile Include="..\src\stdlib\SDL_iconv.c" />
     <ClCompile Include="..\src\stdlib\SDL_malloc.c" />
     <ClCompile Include="..\src\stdlib\SDL_mslibc.c" />
+    <MASM Condition="'$(Platform)'=='x64'" Include="..\src\stdlib\SDL_mslibc_x64.asm" >
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+    </MASM>
     <ClCompile Include="..\src\stdlib\SDL_qsort.c" />
     <ClCompile Include="..\src\stdlib\SDL_stdlib.c" />
     <ClCompile Include="..\src\stdlib\SDL_string.c" />
@@ -668,6 +671,7 @@
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
+    <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
   </ImportGroup>
   <ImportGroup Label="Shared">
   </ImportGroup>
@@ -867,5 +871,6 @@
   </ItemDefinitionGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
+    <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
   </ImportGroup>
 </Project>
diff --git a/VisualC-WinRT/SDL-UWP.vcxproj.filters b/VisualC-WinRT/SDL-UWP.vcxproj.filters
index 92e6f4a8d4e7..430babceb123 100644
--- a/VisualC-WinRT/SDL-UWP.vcxproj.filters
+++ b/VisualC-WinRT/SDL-UWP.vcxproj.filters
@@ -875,6 +875,9 @@
     <ClCompile Include="..\src\stdlib\SDL_mslibc.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <MASM Include="..\src\stdlib\SDL_mslibc_x64.asm">
+      <Filter>stdlib</Filter>
+    </MASM>
     <ClCompile Include="..\src\core\windows\pch.c">
       <Filter>Source Files</Filter>
     </ClCompile>
diff --git a/VisualC/SDL/SDL.vcxproj b/VisualC/SDL/SDL.vcxproj
index a40d5acb5717..84e774521acc 100644
--- a/VisualC/SDL/SDL.vcxproj
+++ b/VisualC/SDL/SDL.vcxproj
@@ -43,6 +43,7 @@
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   <ImportGroup Label="ExtensionSettings">
+    <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.props" />
   </ImportGroup>
   <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
@@ -609,6 +610,9 @@
     <ClCompile Include="..\..\src\stdlib\SDL_iconv.c" />
     <ClCompile Include="..\..\src\stdlib\SDL_malloc.c" />
     <ClCompile Include="..\..\src\stdlib\SDL_mslibc.c" />
+    <MASM Condition="'$(Platform)'=='x64'" Include="..\..\src\stdlib\SDL_mslibc_x64.asm" >
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+    </MASM>
     <ClCompile Include="..\..\src\stdlib\SDL_qsort.c" />
     <ClCompile Include="..\..\src\stdlib\SDL_stdlib.c" />
     <ClCompile Include="..\..\src\stdlib\SDL_string.c" />
@@ -669,5 +673,6 @@
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
+    <Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
   </ImportGroup>
 </Project>
diff --git a/VisualC/SDL/SDL.vcxproj.filters b/VisualC/SDL/SDL.vcxproj.filters
index f72a3a0fca88..23fa7b2e3ffd 100644
--- a/VisualC/SDL/SDL.vcxproj.filters
+++ b/VisualC/SDL/SDL.vcxproj.filters
@@ -1375,6 +1375,9 @@
     <ClCompile Include="..\..\src\stdlib\SDL_mslibc.c">
       <Filter>stdlib</Filter>
     </ClCompile>
+    <MASM Include="..\..\src\stdlib\SDL_mslibc_x64.asm">
+      <Filter>stdlib</Filter>
+    </MASM>
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="..\..\src\core\windows\version.rc" />
diff --git a/cmake/sdlcompilers.cmake b/cmake/sdlcompilers.cmake
index 40bb3b6dcd57..5fd3081b4568 100644
--- a/cmake/sdlcompilers.cmake
+++ b/cmake/sdlcompilers.cmake
@@ -49,12 +49,12 @@ function(SDL_AddCommonCompilerFlags TARGET)
 
     check_c_compiler_flag(-Wundef HAVE_GCC_WUNDEF)
     if(HAVE_GCC_WUNDEF)
-      target_compile_options(${TARGET} PRIVATE "-Wundef")
+      target_compile_options(${TARGET} PRIVATE "$<$<COMPILE_LANGUAGE:C,CXX>:-Wundef>")
     endif()
 
     check_c_compiler_flag(-fno-strict-aliasing HAVE_GCC_NO_STRICT_ALIASING)
     if(HAVE_GCC_NO_STRICT_ALIASING)
-      target_compile_options(${TARGET} PRIVATE "-fno-strict-aliasing")
+      target_compile_options(${TARGET} PRIVATE "$<$<COMPILE_LANGUAGE:C,CXX>:-fno-strict-aliasing>")
     endif()
 
     check_c_compiler_flag(-Wdocumentation HAVE_GCC_WDOCUMENTATION)
@@ -62,10 +62,10 @@ function(SDL_AddCommonCompilerFlags TARGET)
       if(SDL_WERROR)
         check_c_compiler_flag(-Werror=documentation HAVE_GCC_WERROR_DOCUMENTATION)
         if(HAVE_GCC_WERROR_DOCUMENTATION)
-          target_compile_options(${TARGET} PRIVATE "-Werror=documentation")
+          target_compile_options(${TARGET} PRIVATE "$<$<COMPILE_LANGUAGE:C,CXX>:-Werror=documentation>")
         endif()
       endif()
-      target_compile_options(${TARGET} PRIVATE "-Wdocumentation")
+      target_compile_options(${TARGET} PRIVATE "$<$<COMPILE_LANGUAGE:C,CXX>:-Wdocumentation>")
     endif()
 
     check_c_compiler_flag(-Wdocumentation-unknown-command HAVE_GCC_WDOCUMENTATION_UNKNOWN_COMMAND)
@@ -73,30 +73,30 @@ function(SDL_AddCommonCompilerFlags TARGET)
       if(SDL_WERROR)
         check_c_compiler_flag(-Werror=documentation-unknown-command HAVE_GCC_WERROR_DOCUMENTATION_UNKNOWN_COMMAND)
         if(HAVE_GCC_WERROR_DOCUMENTATION_UNKNOWN_COMMAND)
-          target_compile_options(${TARGET} PRIVATE "-Werror=documentation-unknown-command")
+          target_compile_options(${TARGET} PRIVATE "$<$<COMPILE_LANGUAGE:C,CXX>:-Werror=documentation-unknown-command>")
         endif()
       endif()
-      target_compile_options(${TARGET} PRIVATE "-Wdocumentation-unknown-command")
+      target_compile_options(${TARGET} PRIVATE "$<$<COMPILE_LANGUAGE:C,CXX>:-Wdocumentation-unknown-command>")
     endif()
 
     check_c_compiler_flag(-fcomment-block-commands=threadsafety HAVE_GCC_COMMENT_BLOCK_COMMANDS)
     if(HAVE_GCC_COMMENT_BLOCK_COMMANDS)
-      target_compile_options(${TARGET} PRIVATE "-fcomment-block-commands=threadsafety")
+      target_compile_options(${TARGET} PRIVATE "$<$<COMPILE_LANGUAGE:C,CXX>:-fcomment-block-commands=threadsafety>")
     else()
       check_c_compiler_flag(/clang:-fcomment-block-commands=threadsafety HAVE_CLANG_COMMENT_BLOCK_COMMANDS)
       if(HAVE_CLANG_COMMENT_BLOCK_COMMANDS)
-        target_compile_options(${TARGET} PRIVATE "/clang:-fcomment-block-commands=threadsafety")
+        target_compile_options(${TARGET} PRIVATE "$<$<COMPILE_LANGUAGE:C,CXX>:/clang:-fcomment-block-commands=threadsafety>")
       endif()
     endif()
 
     check_c_compiler_flag(-Wshadow HAVE_GCC_WSHADOW)
     if(HAVE_GCC_WSHADOW)
-      target_compile_options(${TARGET} PRIVATE "-Wshadow")
+      target_compile_options(${TARGET} PRIVATE "$<$<COMPILE_LANGUAGE:C,CXX>:-Wshadow>")
     endif()
 
     check_c_compiler_flag(-Wunused-local-typedefs HAVE_GCC_WUNUSED_LOCAL_TYPEDEFS)
     if(HAVE_GCC_WUNUSED_LOCAL_TYPEDEFS)
-      target_compile_options(${TARGET} PRIVATE "-Wno-unused-local-typedefs")
+      target_compile_options(${TARGET} PRIVATE "$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-unused-local-typedefs>")
     endif()
   endif()
 
@@ -109,7 +109,7 @@ function(SDL_AddCommonCompilerFlags TARGET)
     elseif(USE_GCC OR USE_CLANG OR USE_INTELCC OR USE_QNX)
       check_c_compiler_flag(-Werror HAVE_WERROR)
       if(HAVE_WERROR)
-        target_compile_options(${TARGET} PRIVATE "-Werror")
+        target_compile_options(${TARGET} PRIVATE "$<$<COMPILE_LANGUAGE:C,CXX>:-Werror>")
       endif()
     endif()
   endif()
@@ -117,12 +117,12 @@ function(SDL_AddCommonCompilerFlags TARGET)
   if(USE_CLANG)
     check_c_compiler_flag("-fcolor-diagnostics" COMPILER_SUPPORTS_FCOLOR_DIAGNOSTICS)
     if(COMPILER_SUPPORTS_FCOLOR_DIAGNOSTICS)
-      target_compile_options(${TARGET} PRIVATE "-fcolor-diagnostics")
+      target_compile_options(${TARGET} PRIVATE "$<$<COMPILE_LANGUAGE:C,CXX>:-fcolor-diagnostics>")
     endif()
   else()
     check_c_compiler_flag("-fdiagnostics-color=always" COMPILER_SUPPORTS_FDIAGNOSTICS_COLOR_ALWAYS)
     if(COMPILER_SUPPORTS_FDIAGNOSTICS_COLOR_ALWAYS)
-      target_compile_options(${TARGET} PRIVATE "-fdiagnostics-color=always")
+      target_compile_options(${TARGET} PRIVATE "$<$<COMPILE_LANGUAGE:C,CXX>:-fdiagnostics-color=always>")
     endif()
   endif()
 endfunction()
diff --git a/include/SDL3/SDL_stdinc.h b/include/SDL3/SDL_stdinc.h
index 3643bb60f0c9..a3d63325c3f2 100644
--- a/include/SDL3/SDL_stdinc.h
+++ b/include/SDL3/SDL_stdinc.h
@@ -37,26 +37,28 @@
 #include <stdint.h>
 #include <wchar.h>
 
-#ifndef alloca
-# ifdef HAVE_ALLOCA_H
-#  include <alloca.h>
-# elif defined(__GNUC__)
-#  define alloca __builtin_alloca
-# elif defined(_MSC_VER)
-#  include <malloc.h>
-#  define alloca _alloca
-# elif defined(__WATCOMC__)
-#  include <malloc.h>
-# elif defined(__BORLANDC__)
-#  include <malloc.h>
-# elif defined(__DMC__)
-#  include <stdlib.h>
-# elif defined(__AIX__)
-#pragma alloca
-# elif defined(__MRC__)
+#ifndef SDL_DISABLE_ALLOCA
+# ifndef alloca
+#  ifdef HAVE_ALLOCA_H
+#   include <alloca.h>
+#  elif defined(__GNUC__)
+#   define alloca __builtin_alloca
+#  elif defined(_MSC_VER)
+#   include <malloc.h>
+#   define alloca _alloca
+#  elif defined(__WATCOMC__)
+#   include <malloc.h>
+#  elif defined(__BORLANDC__)
+#   include <malloc.h>
+#  elif defined(__DMC__)
+#   include <stdlib.h>
+#  elif defined(__AIX__)
+# pragma alloca
+#  elif defined(__MRC__)
 void *alloca(unsigned);
-# else
+#  else
 char *alloca();
+#  endif
 # endif
 #endif
 
@@ -379,7 +381,7 @@ SDL_COMPILE_TIME_ASSERT(enum, sizeof(SDL_DUMMY_ENUM) == sizeof(int));
 extern "C" {
 #endif
 
-#ifdef HAVE_ALLOCA
+#ifndef SDL_DISABLE_ALLOCA
 #define SDL_stack_alloc(type, count)    (type*)alloca(sizeof(type)*(count))
 #define SDL_stack_free(data)
 #else
diff --git a/include/build_config/SDL_build_config.h.cmake b/include/build_config/SDL_build_config.h.cmake
index 017e06b06410..35b5e58579f4 100644
--- a/include/build_config/SDL_build_config.h.cmake
+++ b/include/build_config/SDL_build_config.h.cmake
@@ -42,6 +42,8 @@
 #cmakedefine HAVE_GCC_ATOMICS @HAVE_GCC_ATOMICS@
 #cmakedefine HAVE_GCC_SYNC_LOCK_TEST_AND_SET @HAVE_GCC_SYNC_LOCK_TEST_AND_SET@
 
+#cmakedefine SDL_DISABLE_ALLOCA
+
 /* Comment this if you want to build without any C library requirements */
 #cmakedefine HAVE_LIBC 1
 #ifdef HAVE_LIBC
@@ -74,7 +76,6 @@
 #cmakedefine HAVE_CALLOC 1
 #cmakedefine HAVE_REALLOC 1
 #cmakedefine HAVE_FREE 1
-#cmakedefine HAVE_ALLOCA 1
 #ifndef __WIN32__ /* Don't use C runtime versions of these on Windows */
 #cmakedefine HAVE_GETENV 1
 #cmakedefine HAVE_SETENV 1
diff --git a/include/build_config/SDL_build_config_android.h b/include/build_config/SDL_build_config_android.h
index 1f8c3ef8f275..99a7ab7deca2 100644
--- a/include/build_config/SDL_build_config_android.h
+++ b/include/build_config/SDL_build_config_android.h
@@ -57,7 +57,6 @@
 #define HAVE_CALLOC 1
 #define HAVE_REALLOC    1
 #define HAVE_FREE   1
-#define HAVE_ALLOCA 1
 #define HAVE_GETENV 1
 #define HAVE_SETENV 1
 #define HAVE_PUTENV 1
diff --git a/include/build_config/SDL_build_config_emscripten.h b/include/build_config/SDL_build_config_emscripten.h
index 2503e98dfc7e..afa4e16e11c7 100644
--- a/include/build_config/SDL_build_config_emscripten.h
+++ b/include/build_config/SDL_build_config_emscripten.h
@@ -60,7 +60,6 @@
 #define HAVE_CALLOC 1
 #define HAVE_REALLOC 1
 #define HAVE_FREE 1
-#define HAVE_ALLOCA 1
 #define HAVE_GETENV 1
 #define HAVE_SETENV 1
 #define HAVE_PUTENV 1
diff --git a/include/build_config/SDL_build_config_ios.h b/include/build_config/SDL_build_config_ios.h
index c180ef84908d..96391f848f57 100644
--- a/include/build_config/SDL_build_config_ios.h
+++ b/include/build_config/SDL_build_config_ios.h
@@ -49,7 +49,6 @@
 #define HAVE_CALLOC 1
 #define HAVE_REALLOC    1
 #define HAVE_FREE   1
-#define HAVE_ALLOCA 1
 #define HAVE_GETENV 1
 #define HAVE_SETENV 1
 #define HAVE_PUTENV 1
diff --git a/include/build_config/SDL_build_config_macos.h b/include/build_config/SDL_build_config_macos.h
index ed3f83a64557..43400d3f6ef4 100644
--- a/include/build_config/SDL_build_config_macos.h
+++ b/include/build_config/SDL_build_config_macos.h
@@ -54,7 +54,6 @@
 #define HAVE_CALLOC 1
 #define HAVE_REALLOC    1
 #define HAVE_FREE   1
-#define HAVE_ALLOCA 1
 #define HAVE_GETENV 1
 #define HAVE_SETENV 1
 #define HAVE_PUTENV 1
diff --git a/include/build_config/SDL_build_config_windows.h b/include/build_config/SDL_build_config_windows.h
index 8a29bab171bb..4d7242e5b5d3 100644
--- a/include/build_config/SDL_build_config_windows.h
+++ b/include/build_config/SDL_build_config_windows.h
@@ -131,7 +131,6 @@ typedef unsigned int uintptr_t;
 #define HAVE_CALLOC 1
 #define HAVE_REALLOC 1
 #define HAVE_FREE 1
-#define HAVE_ALLOCA 1
 #define HAVE_QSORT 1
 #define HAVE_BSEARCH 1
 #define HAVE_ABS 1
diff --git a/include/build_config/SDL_build_config_wingdk.h b/include/build_config/SDL_build_config_wingdk.h
index 47adef5068e1..8d587e555f1e 100644
--- a/include/build_config/SDL_build_config_wingdk.h
+++ b/include/build_config/SDL_build_config_wingdk.h
@@ -77,7 +77,6 @@
 #define HAVE_CALLOC 1
 #define HAVE_REALLOC 1
 #define HAVE_FREE 1
-#define HAVE_ALLOCA 1
 #define HAVE_QSORT 1
 #define HAVE_BSEARCH 1
 #define HAVE_ABS 1
diff --git a/include/build_config/SDL_build_config_winrt.h b/include/build_config/SDL_build_config_winrt.h
index 73d467145929..bc65ffea2ffd 100644
--- a/include/build_config/SDL_build_config_winrt.h
+++ b/include/build_config/SDL_build_config_winrt.h
@@ -75,7 +75,6 @@
 #define HAVE_CALLOC 1
 #define HAVE_REALLOC 1
 #define HAVE_FREE 1
-#define HAVE_ALLOCA 1
 #define HAVE_QSORT 1
 #define HAVE_BSEARCH 1
 #define HAVE_ABS 1
diff --git a/include/build_config/SDL_build_config_xbox.h b/include/build_config/SDL_build_config_xbox.h
index 622a8bc4adfe..08def0c0146c 100644
--- a/include/build_config/SDL_build_config_xbox.h
+++ b/include/build_config/SDL_build_config_xbox.h
@@ -77,7 +77,6 @@
 #define HAVE_CALLOC 1
 #define HAVE_REALLOC 1
 #define HAVE_FREE 1
-#define HAVE_ALLOCA 1
 #define HAVE_QSORT 1
 #define HAVE_BSEARCH 1
 #define HAVE_ABS 1
diff --git a/src/stdlib/SDL_mslibc.c b/src/stdlib/SDL_mslibc.c
index 111842754994..184b7e2d1cf8 100644
--- a/src/stdlib/SDL_mslibc.c
+++ b/src/stdlib/SDL_mslibc.c
@@ -696,8 +696,80 @@ void __declspec(naked) _aullshr()
     /* *INDENT-ON* */
 }
 
+void __declspec(naked) _chkstk(void)
+{
+    __asm {
+        push        ecx
+        mov         ecx,esp     ; lea         ecx,dword ptr [esp]+4
+        add         ecx,4
+        sub         ecx,eax
+        sbb         eax,eax
+        not         eax
+        and         ecx,eax
+        mov         eax,esp
+        and         eax,0xfffff000
+L1:
+        cmp         ecx,eax
+        jb          short L2
+        mov         eax,ecx
+        pop         ecx
+        xchg        esp,eax
+        mov         eax,dword ptr [eax]
+        mov         dword ptr [esp],eax
+        ret
+L2:
+        sub         eax,0x1000
+        test        dword ptr [eax],eax
+        jmp         short L1
+    }
+}
+
+void __declspec(naked) _alloca_probe_8(void)
+{
+    /* *INDENT-OFF* */
+    __asm {
+        push        ecx
+        mov         ecx,esp     ; lea         ecx,dword ptr [esp]+8
+        add         ecx,8
+        sub         ecx,eax
+        and         ecx,0x7
+        add         eax,ecx
+        sbb         ecx,ecx
+        or          eax,ecx
+        pop         ecx
+        jmp         _chkstk
+    }
+    /* *INDENT-ON* */
+}
+
+void __declspec(naked) _alloca_probe_16(void)
+{
+    /* *INDENT-OFF* */
+    __asm {
+        push        ecx
+        mov         ecx,esp     ; lea         ecx,dword ptr [esp]+8
+        add         ecx,8
+        sub         ecx,eax
+        and         ecx,0xf
+        add         eax,ecx
+        sbb         ecx,ecx
+        or          eax,ecx
+        pop         ecx
+        jmp         _chkstk
+    }
+    /* *INDENT-ON* */
+}
+
 #endif /* _M_IX86 */
 
+#ifdef _M_ARM64
+
+void __chkstk(void);
+void __chkstk() {
+}
+
+#endif
+
 #endif /* MSC_VER */
 
 #ifdef __ICL
diff --git a/src/stdlib/SDL_mslibc_x64.asm b/src/stdlib/SDL_mslibc_x64.asm
new file mode 100644
index 000000000000..1590d88ae7ae
--- /dev/null
+++ b/src/stdlib/SDL_mslibc_x64.asm
@@ -0,0 +1,29 @@
+include ksamd64.inc
+
+text        SEGMENT EXECUTE
+
+public      __chkstk
+
+__chkstk:
+    sub         rsp,010h
+    mov         QWORD PTR [rsp],r10
+    mov         QWORD PTR [rsp+08h],r11
+    xor         r11,r11
+    lea         r10,[rsp+018h]
+    sub         r10,rax
+    cmovb       r10,r11
+    mov         r11,QWORD PTR gs:[TeStackLimit]
+    cmp         r10,r11
+    jae         chkstk_finish
+    and         r10w,0f000h
+chkstk_loop:
+    lea         r11,[r11-PAGE_SIZE]
+    mov         BYTE PTR [r11],0h
+    cmp         r10,r11
+    jne         chkstk_loop
+chkstk_finish:
+    mov         r10,QWORD PTR [rsp]
+    mov         r11,QWORD PTR [rsp+08h]
+    add         rsp,010h
+    ret
+end