13
13
#include " llvm/Support/Signals.h"
14
14
#include " llvm/Support/thread.h"
15
15
#include < cassert>
16
+ #if !defined(__wasi__)
17
+ #include < csignal>
18
+ #endif
19
+ #if LLVM_ENABLE_THREADS
16
20
#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.
17
25
#include < setjmp.h>
26
+ #endif
18
27
19
28
using namespace llvm ;
20
29
@@ -31,7 +40,9 @@ struct CrashRecoveryContextImpl {
31
40
const CrashRecoveryContextImpl *Next;
32
41
33
42
CrashRecoveryContext *CRC;
43
+ #ifdef HAVE_SETJMP
34
44
::jmp_buf JumpBuffer;
45
+ #endif
35
46
volatile unsigned Failed : 1 ;
36
47
unsigned SwitchedThread : 1 ;
37
48
unsigned ValidJumpBuffer : 1 ;
@@ -50,7 +61,7 @@ struct CrashRecoveryContextImpl {
50
61
// / Called when the separate crash-recovery thread was finished, to
51
62
// / indicate that we don't need to clear the thread-local CurrentContext.
52
63
void setSwitchedThread () {
53
- #if defined( LLVM_ENABLE_THREADS) && LLVM_ENABLE_THREADS != 0
64
+ #if LLVM_ENABLE_THREADS
54
65
SwitchedThread = true ;
55
66
#endif
56
67
}
@@ -72,19 +83,23 @@ struct CrashRecoveryContextImpl {
72
83
73
84
CRC->RetCode = RetCode;
74
85
86
+ #if HAVE_SETJMP
75
87
// Jump back to the RunSafely we were called under.
76
88
if (ValidJumpBuffer)
77
89
longjmp (JumpBuffer, 1 );
90
+ #endif
78
91
79
92
// Otherwise let the caller decide of the outcome of the crash. Currently
80
93
// this occurs when using SEH on Windows with MSVC or clang-cl.
81
94
}
82
95
};
83
96
84
- std::mutex &getCrashRecoveryContextMutex () {
97
+ #if LLVM_ENABLE_THREADS
98
+ static std::mutex &getCrashRecoveryContextMutex () {
85
99
static std::mutex CrashRecoveryContextMutex;
86
100
return CrashRecoveryContextMutex;
87
101
}
102
+ #endif
88
103
89
104
static bool gCrashRecoveryEnabled = false ;
90
105
@@ -138,7 +153,9 @@ CrashRecoveryContext *CrashRecoveryContext::GetCurrent() {
138
153
}
139
154
140
155
void CrashRecoveryContext::Enable () {
156
+ #if LLVM_ENABLE_THREADS
141
157
std::lock_guard<std::mutex> L (getCrashRecoveryContextMutex ());
158
+ #endif
142
159
// FIXME: Shouldn't this be a refcount or something?
143
160
if (gCrashRecoveryEnabled )
144
161
return ;
@@ -147,7 +164,9 @@ void CrashRecoveryContext::Enable() {
147
164
}
148
165
149
166
void CrashRecoveryContext::Disable () {
167
+ #if LLVM_ENABLE_THREADS
150
168
std::lock_guard<std::mutex> L (getCrashRecoveryContextMutex ());
169
+ #endif
151
170
if (!gCrashRecoveryEnabled )
152
171
return ;
153
172
gCrashRecoveryEnabled = false ;
@@ -329,7 +348,16 @@ static void uninstallExceptionOrSignalHandlers() {
329
348
}
330
349
}
331
350
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__
333
361
334
362
// Generic POSIX implementation.
335
363
//
@@ -417,10 +445,12 @@ bool CrashRecoveryContext::RunSafely(function_ref<void()> Fn) {
417
445
CrashRecoveryContextImpl *CRCI = new CrashRecoveryContextImpl (this );
418
446
Impl = CRCI;
419
447
448
+ #if HAVE_SETJMP
420
449
CRCI->ValidJumpBuffer = true ;
421
450
if (setjmp (CRCI->JumpBuffer ) != 0 ) {
422
451
return false ;
423
452
}
453
+ #endif
424
454
}
425
455
426
456
Fn ();
@@ -467,7 +497,9 @@ bool CrashRecoveryContext::isCrash(int RetCode) {
467
497
bool CrashRecoveryContext::throwIfCrash (int RetCode) {
468
498
if (!isCrash (RetCode))
469
499
return false ;
470
- #if defined(_WIN32)
500
+ #if defined(__wasi__)
501
+ abort ();
502
+ #elif defined(_WIN32)
471
503
::RaiseException (RetCode, 0 , 0 , NULL );
472
504
#else
473
505
llvm::sys::unregisterHandlers ();
0 commit comments