diff options
author | Mike Pall <mike> | 2016-05-07 12:32:15 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2016-05-07 12:32:15 +0200 |
commit | 35b09e692ead67181755795352f1df12547fd4fa (patch) | |
tree | d120dd561f649f955ddbbe844fe00a97f7b9e625 /src/vm_x86.dasc | |
parent | 6a9973203c55daa4c1fcd611718bc5df09e4e5b5 (diff) | |
download | luajit-35b09e692ead67181755795352f1df12547fd4fa.tar.gz luajit-35b09e692ead67181755795352f1df12547fd4fa.tar.bz2 luajit-35b09e692ead67181755795352f1df12547fd4fa.zip |
Windows/x86: Add full exception interoperability.
Contributed by Peter Cawley.
Diffstat (limited to 'src/vm_x86.dasc')
-rw-r--r-- | src/vm_x86.dasc | 77 |
1 files changed, 74 insertions, 3 deletions
diff --git a/src/vm_x86.dasc b/src/vm_x86.dasc index f108c0b5..39ccaa2e 100644 --- a/src/vm_x86.dasc +++ b/src/vm_x86.dasc | |||
@@ -121,19 +121,68 @@ | |||
121 | |//----------------------------------------------------------------------- | 121 | |//----------------------------------------------------------------------- |
122 | |.if not X64 // x86 stack layout. | 122 | |.if not X64 // x86 stack layout. |
123 | | | 123 | | |
124 | |.define CFRAME_SPACE, aword*7 // Delta for esp (see <--). | 124 | |.if WIN |
125 | | | ||
126 | |.define CFRAME_SPACE, aword*9 // Delta for esp (see <--). | ||
125 | |.macro saveregs_ | 127 | |.macro saveregs_ |
126 | | push edi; push esi; push ebx | 128 | | push edi; push esi; push ebx |
129 | | push extern lj_err_unwind_win | ||
130 | | fs; push dword [0] | ||
131 | | fs; mov [0], esp | ||
127 | | sub esp, CFRAME_SPACE | 132 | | sub esp, CFRAME_SPACE |
128 | |.endmacro | 133 | |.endmacro |
129 | |.macro saveregs | 134 | |.macro restoreregs |
130 | | push ebp; saveregs_ | 135 | | add esp, CFRAME_SPACE |
136 | | fs; pop dword [0] | ||
137 | | pop edi // Short for esp += 4. | ||
138 | | pop ebx; pop esi; pop edi; pop ebp | ||
139 | |.endmacro | ||
140 | | | ||
141 | |.else | ||
142 | | | ||
143 | |.define CFRAME_SPACE, aword*7 // Delta for esp (see <--). | ||
144 | |.macro saveregs_ | ||
145 | | push edi; push esi; push ebx | ||
146 | | sub esp, CFRAME_SPACE | ||
131 | |.endmacro | 147 | |.endmacro |
132 | |.macro restoreregs | 148 | |.macro restoreregs |
133 | | add esp, CFRAME_SPACE | 149 | | add esp, CFRAME_SPACE |
134 | | pop ebx; pop esi; pop edi; pop ebp | 150 | | pop ebx; pop esi; pop edi; pop ebp |
135 | |.endmacro | 151 | |.endmacro |
136 | | | 152 | | |
153 | |.endif | ||
154 | | | ||
155 | |.macro saveregs | ||
156 | | push ebp; saveregs_ | ||
157 | |.endmacro | ||
158 | | | ||
159 | |.if WIN | ||
160 | |.define SAVE_ERRF, aword [esp+aword*19] // vm_pcall/vm_cpcall only. | ||
161 | |.define SAVE_NRES, aword [esp+aword*18] | ||
162 | |.define SAVE_CFRAME, aword [esp+aword*17] | ||
163 | |.define SAVE_L, aword [esp+aword*16] | ||
164 | |//----- 16 byte aligned, ^^^ arguments from C caller | ||
165 | |.define SAVE_RET, aword [esp+aword*15] //<-- esp entering interpreter. | ||
166 | |.define SAVE_R4, aword [esp+aword*14] | ||
167 | |.define SAVE_R3, aword [esp+aword*13] | ||
168 | |.define SAVE_R2, aword [esp+aword*12] | ||
169 | |//----- 16 byte aligned | ||
170 | |.define SAVE_R1, aword [esp+aword*11] | ||
171 | |.define SEH_FUNC, aword [esp+aword*10] | ||
172 | |.define SEH_NEXT, aword [esp+aword*9] //<-- esp after register saves. | ||
173 | |.define UNUSED2, aword [esp+aword*8] | ||
174 | |//----- 16 byte aligned | ||
175 | |.define UNUSED1, aword [esp+aword*7] | ||
176 | |.define SAVE_PC, aword [esp+aword*6] | ||
177 | |.define TMP2, aword [esp+aword*5] | ||
178 | |.define TMP1, aword [esp+aword*4] | ||
179 | |//----- 16 byte aligned | ||
180 | |.define ARG4, aword [esp+aword*3] | ||
181 | |.define ARG3, aword [esp+aword*2] | ||
182 | |.define ARG2, aword [esp+aword*1] | ||
183 | |.define ARG1, aword [esp] //<-- esp while in interpreter. | ||
184 | |//----- 16 byte aligned, ^^^ arguments for C callee | ||
185 | |.else | ||
137 | |.define SAVE_ERRF, aword [esp+aword*15] // vm_pcall/vm_cpcall only. | 186 | |.define SAVE_ERRF, aword [esp+aword*15] // vm_pcall/vm_cpcall only. |
138 | |.define SAVE_NRES, aword [esp+aword*14] | 187 | |.define SAVE_NRES, aword [esp+aword*14] |
139 | |.define SAVE_CFRAME, aword [esp+aword*13] | 188 | |.define SAVE_CFRAME, aword [esp+aword*13] |
@@ -154,6 +203,7 @@ | |||
154 | |.define ARG2, aword [esp+aword*1] | 203 | |.define ARG2, aword [esp+aword*1] |
155 | |.define ARG1, aword [esp] //<-- esp while in interpreter. | 204 | |.define ARG1, aword [esp] //<-- esp while in interpreter. |
156 | |//----- 16 byte aligned, ^^^ arguments for C callee | 205 | |//----- 16 byte aligned, ^^^ arguments for C callee |
206 | |.endif | ||
157 | | | 207 | | |
158 | |// FPARGx overlaps ARGx and ARG(x+1) on x86. | 208 | |// FPARGx overlaps ARGx and ARG(x+1) on x86. |
159 | |.define FPARG3, qword [esp+qword*1] | 209 | |.define FPARG3, qword [esp+qword*1] |
@@ -554,6 +604,10 @@ static void build_subroutines(BuildCtx *ctx) | |||
554 | |.else | 604 | |.else |
555 | | mov eax, FCARG2 // Error return status for vm_pcall. | 605 | | mov eax, FCARG2 // Error return status for vm_pcall. |
556 | | mov esp, FCARG1 | 606 | | mov esp, FCARG1 |
607 | |.if WIN | ||
608 | | lea FCARG1, SEH_NEXT | ||
609 | | fs; mov [0], FCARG1 | ||
610 | |.endif | ||
557 | |.endif | 611 | |.endif |
558 | |->vm_unwind_c_eh: // Landing pad for external unwinder. | 612 | |->vm_unwind_c_eh: // Landing pad for external unwinder. |
559 | | mov L:RB, SAVE_L | 613 | | mov L:RB, SAVE_L |
@@ -577,6 +631,10 @@ static void build_subroutines(BuildCtx *ctx) | |||
577 | |.else | 631 | |.else |
578 | | and FCARG1, CFRAME_RAWMASK | 632 | | and FCARG1, CFRAME_RAWMASK |
579 | | mov esp, FCARG1 | 633 | | mov esp, FCARG1 |
634 | |.if WIN | ||
635 | | lea FCARG1, SEH_NEXT | ||
636 | | fs; mov [0], FCARG1 | ||
637 | |.endif | ||
580 | |.endif | 638 | |.endif |
581 | |->vm_unwind_ff_eh: // Landing pad for external unwinder. | 639 | |->vm_unwind_ff_eh: // Landing pad for external unwinder. |
582 | | mov L:RB, SAVE_L | 640 | | mov L:RB, SAVE_L |
@@ -590,6 +648,19 @@ static void build_subroutines(BuildCtx *ctx) | |||
590 | | set_vmstate INTERP | 648 | | set_vmstate INTERP |
591 | | jmp ->vm_returnc // Increments RD/MULTRES and returns. | 649 | | jmp ->vm_returnc // Increments RD/MULTRES and returns. |
592 | | | 650 | | |
651 | |.if WIN and not X64 | ||
652 | |->vm_rtlunwind@16: // Thin layer around RtlUnwind. | ||
653 | | // (void *cframe, void *excptrec, void *unwinder, int errcode) | ||
654 | | mov [esp], FCARG1 // Return value for RtlUnwind. | ||
655 | | push FCARG2 // Exception record for RtlUnwind. | ||
656 | | push 0 // Ignored by RtlUnwind. | ||
657 | | push dword [FCARG1+CFRAME_OFS_SEH] | ||
658 | | call extern RtlUnwind@16 // Violates ABI (clobbers too much). | ||
659 | | mov FCARG1, eax | ||
660 | | mov FCARG2, [esp+4] // errcode (for vm_unwind_c). | ||
661 | | ret // Jump to unwinder. | ||
662 | |.endif | ||
663 | | | ||
593 | |//----------------------------------------------------------------------- | 664 | |//----------------------------------------------------------------------- |
594 | |//-- Grow stack for calls ----------------------------------------------- | 665 | |//-- Grow stack for calls ----------------------------------------------- |
595 | |//----------------------------------------------------------------------- | 666 | |//----------------------------------------------------------------------- |