ref: cc91f8b9deafbf284609e3511ff900104499da9c
parent: e20644a3baa70dfd5baf790047ce821b396df312
author: Simon Tatham <anakin@pobox.com>
date: Fri Mar 1 07:24:05 EST 2024
Emergency fix to Puzzles WASM builds. I updated Emscripten recently, to version 3.1.54. The result was that none of the WASM puzzles run any more, because they produce a stack trace at startup with the error message "to do setValue(i64) use WASM_BIGINT". I don't fully understand this. The stack trace comes via a JS wrapper around a WASM-compiled function called __main_argc_argv, which sounds like something in the Emscripten library startup. Somewhere in there it goes via _js_get_date_64(), which tries to write an i64 into the WASM memory array, which hits this abort in setValue(). Web searching for the error message turned up https://github.com/godotengine/godot/pull/88594 which gave me the clue that '-s WASM_BIGINT' is a command-line setting for the Emscripten linker. And indeed, setting that makes the startup-time error go away and the puzzles run again. But it also causes older versions of all browsers to be unsupported, presumably on the grounds that they don't have whatever WASM bigint feature this flag causes the code to use. I don't really understand what's going on here. I assume _js_get_date_64 is being called to handle a 64-bit time_t. But the Puzzles code doesn't work with time_t at all, so this is entirely in the Emscripten standard library. And if the pre-main() startup code needs a 64-bit integer write, which won't work without this flag, then surely _nothing_ would work without this flag, and surely someone would have noticed that, and made that flag the default? This all seems confusing and I wonder if I've misunderstood something. However, if I don't fix it in _some_ way, the web puzzles will stay out of action for days and I'll get lots of email complaints. So here's something that makes them basically work again, and maybe we can figure out the rest of the story later.
--- a/cmake/platforms/emscripten.cmake
+++ b/cmake/platforms/emscripten.cmake
@@ -7,13 +7,18 @@
CACHE BOOL "Compile to WebAssembly rather than plain JavaScript")
# The minimal versions here are the ones that Puzzles' own JavaScript
-# is written for. For most browsers, that's the earliest version with
-# WebAssembly support according to https://caniuse.com/wasm. For
-# Firefox we go back to Firefox 48 because that's what KaiOS 2.5 is
-# based on.
-set(MIN_FIREFOX_VERSION 48 CACHE STRING
- "Oldest major version of Firefox to target")
-set(MIN_SAFARI_VERSION 110000 CACHE STRING
+# is written for. For most browsers, that's the earliest version whose
+# WASM Emscripten is still willing to target (as of Emscripten
+# 3.1.54). For Firefox _without_ WASM, we go back to Firefox 48
+# because that's what KaiOS 2.5 is based on.
+if(WASM)
+ set(MIN_FIREFOX_VERSION 68 CACHE STRING
+ "Oldest major version of Firefox to target")
+else()
+ set(MIN_FIREFOX_VERSION 67 CACHE STRING
+ "Oldest major version of Firefox to target")
+endif()
+set(MIN_SAFARI_VERSION 150000 CACHE STRING
"Oldest version of desktop Safari to target (XXYYZZ for version XX.YY.ZZ)")
set(MIN_CHROME_VERSION 57 CACHE STRING
"Oldest version of Chrome to target")
@@ -70,7 +75,7 @@
-s MIN_NODE_VERSION=0x7FFFFFFF \
-s STRICT_JS=1")
if(WASM)
- set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -s WASM=1")
+ set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -s WASM=1 -s WASM_BIGINT")
else()
set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -s WASM=0")
endif()