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