1313#include " llvm/Support/Signals.h"
1414#include " llvm/Support/thread.h"
1515#include < cassert>
16+ #if !defined(__wasi__)
17+ #include < csignal>
18+ #endif
19+ #if LLVM_ENABLE_THREADS
1620#include < mutex>
21+ #endif
22+ #if HAVE_SETJMP
23+ // We can rely on setjmp to exist everywhere except for a subset of WebAssembly
24+ // builds.
1725#include < setjmp.h>
26+ #endif
1827
1928using namespace llvm ;
2029
@@ -31,7 +40,9 @@ struct CrashRecoveryContextImpl {
3140 const CrashRecoveryContextImpl *Next;
3241
3342 CrashRecoveryContext *CRC;
43+ #ifdef HAVE_SETJMP
3444 ::jmp_buf JumpBuffer;
45+ #endif
3546 volatile unsigned Failed : 1 ;
3647 unsigned SwitchedThread : 1 ;
3748 unsigned ValidJumpBuffer : 1 ;
@@ -50,7 +61,7 @@ struct CrashRecoveryContextImpl {
5061 // / Called when the separate crash-recovery thread was finished, to
5162 // / indicate that we don't need to clear the thread-local CurrentContext.
5263 void setSwitchedThread () {
53- #if defined( LLVM_ENABLE_THREADS) && LLVM_ENABLE_THREADS != 0
64+ #if LLVM_ENABLE_THREADS
5465 SwitchedThread = true ;
5566#endif
5667 }
@@ -72,19 +83,23 @@ struct CrashRecoveryContextImpl {
7283
7384 CRC->RetCode = RetCode;
7485
86+ #if HAVE_SETJMP
7587 // Jump back to the RunSafely we were called under.
7688 if (ValidJumpBuffer)
7789 longjmp (JumpBuffer, 1 );
90+ #endif
7891
7992 // Otherwise let the caller decide of the outcome of the crash. Currently
8093 // this occurs when using SEH on Windows with MSVC or clang-cl.
8194 }
8295};
8396
84- std::mutex &getCrashRecoveryContextMutex () {
97+ #if LLVM_ENABLE_THREADS
98+ static std::mutex &getCrashRecoveryContextMutex () {
8599 static std::mutex CrashRecoveryContextMutex;
86100 return CrashRecoveryContextMutex;
87101}
102+ #endif
88103
89104static bool gCrashRecoveryEnabled = false ;
90105
@@ -138,7 +153,9 @@ CrashRecoveryContext *CrashRecoveryContext::GetCurrent() {
138153}
139154
140155void CrashRecoveryContext::Enable () {
156+ #if LLVM_ENABLE_THREADS
141157 std::lock_guard<std::mutex> L (getCrashRecoveryContextMutex ());
158+ #endif
142159 // FIXME: Shouldn't this be a refcount or something?
143160 if (gCrashRecoveryEnabled )
144161 return ;
@@ -147,7 +164,9 @@ void CrashRecoveryContext::Enable() {
147164}
148165
149166void CrashRecoveryContext::Disable () {
167+ #if LLVM_ENABLE_THREADS
150168 std::lock_guard<std::mutex> L (getCrashRecoveryContextMutex ());
169+ #endif
151170 if (!gCrashRecoveryEnabled )
152171 return ;
153172 gCrashRecoveryEnabled = false ;
@@ -329,7 +348,16 @@ static void uninstallExceptionOrSignalHandlers() {
329348 }
330349}
331350
332- #else // !_WIN32
351+ #elif defined(__wasi__)
352+
353+ // WASI implementation.
354+ //
355+ // WASI traps are always fatal, and recovery is not possible. Do nothing.
356+
357+ static void installExceptionOrSignalHandlers () {}
358+ static void uninstallExceptionOrSignalHandlers () {}
359+
360+ #else // !_WIN32 && !__wasi__
333361
334362// Generic POSIX implementation.
335363//
@@ -417,10 +445,12 @@ bool CrashRecoveryContext::RunSafely(function_ref<void()> Fn) {
417445 CrashRecoveryContextImpl *CRCI = new CrashRecoveryContextImpl (this );
418446 Impl = CRCI;
419447
448+ #if HAVE_SETJMP
420449 CRCI->ValidJumpBuffer = true ;
421450 if (setjmp (CRCI->JumpBuffer ) != 0 ) {
422451 return false ;
423452 }
453+ #endif
424454 }
425455
426456 Fn ();
@@ -467,7 +497,9 @@ bool CrashRecoveryContext::isCrash(int RetCode) {
467497bool CrashRecoveryContext::throwIfCrash (int RetCode) {
468498 if (!isCrash (RetCode))
469499 return false ;
470- #if defined(_WIN32)
500+ #if defined(__wasi__)
501+ abort ();
502+ #elif defined(_WIN32)
471503 ::RaiseException (RetCode, 0 , 0 , NULL );
472504#else
473505 llvm::sys::unregisterHandlers ();
0 commit comments