SDL: emscripten: Make sure SDL_malloc and friends are marked KEEPALIVE.

From 423d6ec15a9efa613b0e611e4708d7df95214289 Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Mon, 19 Aug 2024 23:49:07 -0400
Subject: [PATCH] emscripten: Make sure SDL_malloc and friends are marked
 KEEPALIVE.

Reference PR #9937.
---
 src/stdlib/SDL_malloc.c                     | 11 +++++++++++
 src/video/emscripten/SDL_emscriptenevents.c |  8 ++++----
 src/video/emscripten/SDL_emscriptenmouse.c  |  2 +-
 3 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/src/stdlib/SDL_malloc.c b/src/stdlib/SDL_malloc.c
index dee973cecf5d9..356050ab0fcd3 100644
--- a/src/stdlib/SDL_malloc.c
+++ b/src/stdlib/SDL_malloc.c
@@ -5196,6 +5196,17 @@ static void  SDLCALL real_free(void *p) { free(p); }
 #define real_free dlfree
 #endif
 
+// mark the allocator entry points as KEEPALIVE so we can call these from JavaScript.
+// otherwise they could could get so aggressively inlined that their symbols
+// don't exist at all in the final binary!
+#ifdef SDL_PLATFORM_EMSCRIPTEN
+#include <emscripten/emscripten.h>
+extern SDL_DECLSPEC SDL_MALLOC EMSCRIPTEN_KEEPALIVE void * SDLCALL SDL_malloc(size_t size);
+extern SDL_DECLSPEC SDL_MALLOC SDL_ALLOC_SIZE2(1, 2) EMSCRIPTEN_KEEPALIVE void * SDLCALL SDL_calloc(size_t nmemb, size_t size);
+extern SDL_DECLSPEC SDL_ALLOC_SIZE(2) EMSCRIPTEN_KEEPALIVE void * SDLCALL SDL_realloc(void *mem, size_t size);
+extern SDL_DECLSPEC EMSCRIPTEN_KEEPALIVE void SDLCALL SDL_free(void *mem);
+#endif
+
 /* Memory functions used by SDL that can be replaced by the application */
 static struct
 {
diff --git a/src/video/emscripten/SDL_emscriptenevents.c b/src/video/emscripten/SDL_emscriptenevents.c
index 102a56ff0be43..803d9f9ce1a83 100644
--- a/src/video/emscripten/SDL_emscriptenevents.c
+++ b/src/video/emscripten/SDL_emscriptenevents.c
@@ -740,7 +740,7 @@ static void Emscripten_set_pointer_event_callbacks(SDL_WindowData *data)
             var makePointerEventCStruct = function(event) {
                 var ptr = 0;
                 if (event.pointerType == "pen") {
-                    ptr = _malloc($2);
+                    ptr = _SDL_malloc($2);
                     if (ptr != 0) {
                         var rect = target.getBoundingClientRect();
                         var idx = ptr >> 2;
@@ -762,18 +762,18 @@ static void Emscripten_set_pointer_event_callbacks(SDL_WindowData *data)
             };
 
             SDL3.eventHandlerPointerEnter = function(event) {
-                var d = makePointerEventCStruct(event); if (d != 0) { _Emscripten_HandlePointerEnter(data, d); _free(d); }
+                var d = makePointerEventCStruct(event); if (d != 0) { _Emscripten_HandlePointerEnter(data, d); _SDL_free(d); }
             };
             target.addEventListener("pointerenter", SDL3.eventHandlerPointerEnter);
 
             SDL3.eventHandlerPointerLeave = function(event) {
-                var d = makePointerEventCStruct(event); if (d != 0) { _Emscripten_HandlePointerLeave(data, d); _free(d); }
+                var d = makePointerEventCStruct(event); if (d != 0) { _Emscripten_HandlePointerLeave(data, d); _SDL_free(d); }
             };
             target.addEventListener("pointerleave", SDL3.eventHandlerPointerLeave);
             target.addEventListener("pointercancel", SDL3.eventHandlerPointerLeave);  /* catch this, just in case. */
 
             SDL3.eventHandlerPointerGeneric = function(event) {
-                var d = makePointerEventCStruct(event); if (d != 0) { _Emscripten_HandlePointerGeneric(data, d); _free(d); }
+                var d = makePointerEventCStruct(event); if (d != 0) { _Emscripten_HandlePointerGeneric(data, d); _SDL_free(d); }
             };
             target.addEventListener("pointerdown", SDL3.eventHandlerPointerGeneric);
             target.addEventListener("pointerup", SDL3.eventHandlerPointerGeneric);
diff --git a/src/video/emscripten/SDL_emscriptenmouse.c b/src/video/emscripten/SDL_emscriptenmouse.c
index 75e3852980c25..886c4a529b902 100644
--- a/src/video/emscripten/SDL_emscriptenmouse.c
+++ b/src/video/emscripten/SDL_emscriptenmouse.c
@@ -104,7 +104,7 @@ static SDL_Cursor *Emscripten_CreateCursor(SDL_Surface *surface, int hot_x, int
             ? "url(" + canvas.toDataURL() + "), auto"
             : "url(" + canvas.toDataURL() + ") " + hot_x + " " + hot_y + ", auto";
 
-        var urlBuf = _malloc(url.length + 1);
+        var urlBuf = _SDL_malloc(url.length + 1);
         stringToUTF8(url, urlBuf, url.length + 1);
 
         return urlBuf;