safari 26.0 can not handle wasm-exceptions anymore
in case anyone wonders and looks into here for help because their emsdk built web apps are not working anymore with apples latest macOS, iPadOS and iPhoneOS...
my two web projects were since years compiled and linked to use the faster and more efficient native wasm-exceptions
My findings:
- compiled and linked with
-fwasm-exceptionswill crash the web app on startup on apples latest safari 26 while the previous safari versions and all other web browsers still work fine.
I had to rebuild with -fexceptions to make them run also under apples latest safari 26.0
for reference the issue on my project: https://github.com/vc64web/virtualc64web/issues/285
to test a build with the faster native wasm exceptions run https://vamigaweb.github.io/uat/
the build with the about 13% slower javascript-based exceptions you can start with https://vamigaweb.github.io
because vAmigaWeb uses intensively local browser cache to make the app offline capable the best is to open it in a private browser tab to get the current version.
Can you paste the error message? I don't have Safari 26 available on my Mac yet.
I installed the latest JavaScriptCore (v300391) using jsvu and ran it with a simple program compiled with -fwasm-exceptions, and it ran successfully. I don't think jsvu supports installing older versions (https://webkitgtk.org/jsc-built-products/x86_64/release/ contains only recent versions). So either the problem was fixed at some point or the problem only manifests in the browser setting or is specific to application characteristics.
@aheejin
it is here at the green line where an exception is thrown
I will try to step a bit into the entryFunction which is set to in the aboves code _main
UPDATE:
Safari Technology Preview Release 228 (WebKit 21623.1.7.19.1)
also crashes... hope that safari 26.1 fixes it again
I opened a bug report at the webkit bug tracker
https://bugs.webkit.org/show_bug.cgi?id=299629
Ok I tracked the problem down to this
only when using LinkerFlag -O3 and -fwasm-exceptions and Safari26
then it does not catch exceptions with the following statement catch(...)
for example
try { emu->isReady(); } catch(...) {
EM_ASM({
setTimeout(function() {message_handler( 'MSG_ROM_MISSING' );}, 0);
});
}
will produce an unhandled exception stopping the web app
if I change the code to catch(std::exception& e)
try { emu->isReady(); } catch(std::exception& e) {
EM_ASM({
setTimeout(function() {message_handler( 'MSG_ROM_MISSING' );}, 0);
});
}
then it can be handled by Safari26.
if we lower down the LF from -O3 to -O2 then Safari26 also works with catch(...) statements
We still don't have a reproducer, right? (I'm not sure how I can run that emu->isReady() you mentioned.)
I tried to make a very simple program and compiled with em++ -fwasm-exceptions -O3
#include <stdexcept>
int main() {
try {
throw std::runtime_error("what");
} catch (...) {
}
return 0;
}
And it looks jsc that's installed with jsvu doesn't have any problems with this. But as I said, jsc's current version may be much more recent than Safari 26 and I don't have a way of installing older versions. And I don't have Safari26 on my mac either (this is my work mac, and the update schedule is set by my employer).
We still don't have a reproducer, right?
@aheejin
I tried to make a reproducer like you did. When I create a small very simple program then everything works fine. Error does not happen on a small program it seems.
So I got back to one of my bigger projects in terms of code size i.e. vAmiga.wasm which has the size of 8652818 Bytes
I played a bit around and I got some new insights
-
that it generally works with LF=-O2 is not quite correct. What I accidentally did is setting LF=-O2 but CF was still -O3 which albeit fixed the issue but possibly prevented also some optimisations at all ? Because when I set CF and LF to -O2 then the issue also occurs and the code is much smaller and more performant in chrome than the mixed build.
-
back to Safari26, I throwed the same Error in main function in my main file
try{
printf("%s\n", "throw ROM_MISSING error in main() ");
throw AppError(Fault::ROM_MISSING);
} catch(...) {
printf("%s\n", "catched ROM_MISSING error");
}
and it catched the AppError.
but when the Error is thrown in a different class file e.g. Memory.cpp like here
void
Memory::_isReady() const
{
if (!hasRom || FORCE_ROM_MISSING) {
printf("%s\n", "throw ROM_MISSING error in Memory::_isReady() ");
throw AppError(Fault::ROM_MISSING);
}
}
then it is not catched in the main file (see here)
printf("*****check if vAmiga is ready to run ...\n");
try {
emu->isReady();
} catch(AppError &exception) {
printf("catched missing rom message\n");
EM_ASM({
setTimeout(function() {message_handler( 'MSG_ROM_MISSING' );}, 0);
});
}
printf("wrapper calls run on vAmiga->run() method\n");
for reference see here the printf output in the safari26 browser console
this is how it looks in all other browsers like chrome FF and also safari18
throw ROM_MISSING error in main()
catched ROM_MISSING error
launch completed
*****check if vAmiga is ready to run ...
throw ROM_MISSING error in Memory::_isReady()
catched missing rom message
- tested some more build configs on safari26
not working (not all exceptions are catched):
- mixed build e.g. CF=-O3 -flto, LF=O2 -flto
- build e.g. CF=-O2, LF=O2
- CF=-O1 -flto, LF=-O1 -flto
working (all exceptions are catched):
- CF=-O3, LF=-O2 does work in safari26 (which is probably something that we should not do ,right ?)
- using -fexceptions instead of -fwasm-exceptions
- CF=-O1, LF=-O1
for us only not using -fwasm-exceptions worked
webkit team just did a PR which hopefully solves this issue
https://github.com/WebKit/WebKit/pull/51888
webkit team just did a PR which hopefully solves this issue
nah, bug webkit/299629 was reopened and commit was reverted https://github.com/WebKit/WebKit/commit/f3aac4ef8b3dc95c96c47f2354bb770ce35c8903
seems it was reopened because the PR reviewer pointed to a better place in the code to fix it. 🤓
@danlliu now fixed it in the IPIntGenerator. ❤️
Is there any way to download the webkit build so that we can test it before it gets into a new safari26.x ?
I believe we'll be able to verify the fix in Safari Technology Preview 230 when it's available https://developer.apple.com/documentation/safari-technology-preview-release-notes
bug WebKit/299629 was fixed in commit https://commits.webkit.org/301170@main (https://github.com/WebKit/WebKit/commit/09be1474d0e68e869cf7047db875ca5a6eba4a16) Fix IPInt catch handler bounds generation
I discovered https://webkit.org/downloads/
and did go to "webkit build archives" for downloading latest webkit builds
wow 🤩 here are plenty of recent builds...
ok lets test first a build from yesterday before @danlliu pushed the fix to the new IPInt
3031165@main OCTOBER 7, 2025 AT 11:36 PM which failed to catch all exceptions
we expect it to break the -fwasm-exceptions build of vAmigaWeb
Oh yes it breaks ... which is expected result
now lets test the latest build from just some minutes ago with the bugfix in the IPInt
3031194 OCTOBER 8, 2025 AT 10:16 AM
yes! @danlliu you did it 🤓, it works again ...🥳
lets hope that it lands soon in Safari26.1 so that we can code optimize our apps again. In my case until then I had to downgrade on compile and link time optimisations in https://vc64web.github.io and https://vAmigaWeb.github.io (my two Commodore emulator projects)
I believe we'll be able to verify the fix in Safari Technology Preview 230 when it's available
apple just released safari preview 230 which I just tried ... it still has the bug.
This release includes WebKit changes between: 300291@main…300986@main.
the fix is in https://commits.webkit.org/301170@main so it is an expected thing that it does not work yet correctly
Apple just released Safari Preview 231 which contains the bugfix.
Tested it and everything works fine with that release again.
Should we close this issue or should we let it stay open until the bug fix has landed into the official safari ?
Perhaps we should keep it open til the official release, as people might search for it until then. Sounds like it'll be fixed in Safari 27?
@kripken ok I will take care of closing it. Hope that it will make it into safari 26.2. For the 26.1 it is maybe a bit too late ... we will see
Thanks!
the fix finally made it into safari 26.2 which was released yesterday and it resolved the problem.
Does this mean that wasm legacy exceptions in general requires safari 26.2 in order to run? Should we update out feature matrix accordingly: https://github.com/emscripten-core/emscripten/blob/64a850d2866fc99cc5ace1a2f3783f6aab8024e6/tools/feature_matrix.py#L138-L157
How about https://webassembly.org/features/ ?
Should we update out feature matrix accordingly...
from Safari 26.0 - 26.1 due to the addition of a new in-place interpreter for Wasm, exception catching was not working in some cases concerning native exceptions i.e. using -wasm-exceptions
-wasm-exceptions is not generally broken but buggy... depending on the project code and optimisation level it could fail in Safari 26.0-26.1 to work correctly...
Safari 26.2 fixes the buggy implementation.
it is not an intentional removal of wasm exceptions ... only sort of buggy ... so I think you should not necessarily change feature matrix...
Does this mean that wasm legacy exceptions in general requires safari 26.2 in order to run?
is legacy exceptions the -fexceptions ? Then this option was not affected ... it worked also safe in 26.0 -26.1.
is legacy exceptions the
-fexceptions? Then this option was not affected ... it worked also safe in 26.0 -26.1.
No, legacy wasm excptions are what you get by default with -fwasm-exceptions unless you opt out with -sWASM_LEGACY_EXCEPTIONS=0