1 /* Re-implementation of i386 setjmp to avoid Windows-specific work,
2 which messes up Racket's (GRacket's, really) threads. */
3
4 #include "schpriv.h"
5
6 #ifdef _WIN64
7
8 # ifdef USE_MZ_SETJMP_INDIRECT
9
10 /* Implementation in "mzsj86w64.S", and these wrappers make
11 DLL exporting work: */
12
13 extern int _scheme_mz_setjmp(mz_pre_jmp_buf b);
14 extern void _scheme_mz_longjmp(mz_pre_jmp_buf b, int v);
15
scheme_get_mz_setjmp(void)16 Scheme_Setjmp_Proc scheme_get_mz_setjmp(void)
17 {
18 return _scheme_mz_setjmp;
19 }
20
scheme_mz_longjmp(mz_pre_jmp_buf b,int v)21 void scheme_mz_longjmp(mz_pre_jmp_buf b, int v)
22 {
23 _scheme_mz_longjmp(b, v);
24 }
25
scheme_mz_setjmp(mz_pre_jmp_buf b)26 int scheme_mz_setjmp(mz_pre_jmp_buf b)
27 {
28 scheme_log_abort("internal error: setjmp wasn't indirect");
29 abort();
30 return 0;
31 }
32
33 # endif
34
35 #else
36
scheme_mz_setjmp(mz_jmp_buf b)37 int __declspec(naked) scheme_mz_setjmp(mz_jmp_buf b)
38 {
39 __asm {
40 mov ECX, [ESP]
41 mov EAX, [ESP+4]
42 mov [EAX], EBP
43 mov [EAX+4], EBX
44 mov [EAX+8], EDI
45 mov [EAX+12], ESI
46 mov [EAX+16], ESP
47 mov [EAX+20], ECX
48 mov EAX, 0
49 ret
50 }
51 }
52
scheme_mz_longjmp(mz_jmp_buf b,int v)53 void __declspec(naked) scheme_mz_longjmp(mz_jmp_buf b, int v)
54 {
55 __asm {
56 mov EAX, [ESP+8]
57 mov ECX, [ESP+4]
58 mov ESP, [ECX+16]
59 mov EBP, [ECX]
60 mov EBX, [ECX+4]
61 mov EDI, [ECX+8]
62 mov ESI, [ECX+12]
63 mov ECX, [ECX+20]
64 mov [ESP], ECX
65 ret
66 }
67 }
68
69 #endif
70