46
46
** the wrapper function feature. Lua errors thrown through C++ frames
47
47
** cannot be caught by C++ code and C++ destructors are not run.
48
48
**
49
- ** EXT is the default on x64 systems, INT is the default on all other systems.
49
+ ** EXT is the default on x64 systems and on Windows, INT is the default on all
50
+ ** other systems.
50
51
**
51
52
** EXT can be manually enabled on POSIX systems using GCC and DWARF2 stack
52
53
** unwinding with -DLUAJIT_UNWIND_EXTERNAL. *All* C code must be compiled
55
56
** and all C libraries that have callbacks which may be used to call back
56
57
** into Lua. C++ code must *not* be compiled with -fno-exceptions.
57
58
**
58
- ** EXT cannot be enabled on WIN32 since system exceptions use code-driven SEH.
59
59
** EXT is mandatory on WIN64 since the calling convention has an abundance
60
60
** of callee-saved registers (rbx, rbp, rsi, rdi, r12-r15, xmm6-xmm15).
61
61
** The POSIX/x64 interpreter only saves r12/r13 for INT (e.g. PS4).
62
62
*/
63
63
64
64
#if defined(__GNUC__ ) && (LJ_TARGET_X64 || defined(LUAJIT_UNWIND_EXTERNAL )) && !LJ_NO_UNWIND
65
65
#define LJ_UNWIND_EXT 1
66
- #elif LJ_TARGET_X64 && LJ_TARGET_WINDOWS
66
+ #elif LJ_TARGET_WINDOWS
67
67
#define LJ_UNWIND_EXT 1
68
68
#endif
69
69
@@ -384,7 +384,7 @@ static void err_raise_ext(int errcode)
384
384
385
385
#endif /* LJ_TARGET_ARM */
386
386
387
- #elif LJ_TARGET_X64 && LJ_ABI_WIN
387
+ #elif LJ_ABI_WIN
388
388
389
389
/*
390
390
** Someone in Redmond owes me several days of my life. A lot of this is
@@ -402,6 +402,7 @@ static void err_raise_ext(int errcode)
402
402
#define WIN32_LEAN_AND_MEAN
403
403
#include <windows.h>
404
404
405
+ #if LJ_TARGET_X64
405
406
/* Taken from: http://www.nynaeve.net/?p=99 */
406
407
typedef struct UndocumentedDispatcherContext {
407
408
ULONG64 ControlPc ;
@@ -416,11 +417,14 @@ typedef struct UndocumentedDispatcherContext {
416
417
ULONG ScopeIndex ;
417
418
ULONG Fill0 ;
418
419
} UndocumentedDispatcherContext ;
420
+ #else
421
+ typedef void * UndocumentedDispatcherContext ;
422
+ #endif
419
423
420
424
/* Another wild guess. */
421
425
extern void __DestructExceptionObject (EXCEPTION_RECORD * rec , int nothrow );
422
426
423
- #ifdef MINGW_SDK_INIT
427
+ #if LJ_TARGET_X64 && defined( MINGW_SDK_INIT )
424
428
/* Workaround for broken MinGW64 declaration. */
425
429
VOID RtlUnwindEx_FIXED (PVOID ,PVOID ,PVOID ,PVOID ,PVOID ,PVOID ) asm("RtlUnwindEx" );
426
430
#define RtlUnwindEx RtlUnwindEx_FIXED
@@ -434,10 +438,15 @@ VOID RtlUnwindEx_FIXED(PVOID,PVOID,PVOID,PVOID,PVOID,PVOID) asm("RtlUnwindEx");
434
438
#define LJ_EXCODE_CHECK (cl ) (((cl) ^ LJ_EXCODE) <= 0xff)
435
439
#define LJ_EXCODE_ERRCODE (cl ) ((int)((cl) & 0xff))
436
440
437
- /* Win64 exception handler for interpreter frame. */
438
- LJ_FUNCA EXCEPTION_DISPOSITION lj_err_unwind_win64 (EXCEPTION_RECORD * rec ,
439
- void * cf , CONTEXT * ctx , UndocumentedDispatcherContext * dispatch )
441
+ /* Windows exception handler for interpreter frame. */
442
+ LJ_FUNCA EXCEPTION_DISPOSITION lj_err_unwind_win (EXCEPTION_RECORD * rec ,
443
+ void * f , CONTEXT * ctx , UndocumentedDispatcherContext * dispatch )
440
444
{
445
+ #if LJ_TARGET_X64
446
+ void * cf = f ;
447
+ #else
448
+ void * cf = (char * )f - CFRAME_OFS_SEH ;
449
+ #endif
441
450
lua_State * L = cframe_L (cf );
442
451
int errcode = LJ_EXCODE_CHECK (rec -> ExceptionCode ) ?
443
452
LJ_EXCODE_ERRCODE (rec -> ExceptionCode ) : LUA_ERRRUN ;
@@ -457,6 +466,7 @@ LJ_FUNCA EXCEPTION_DISPOSITION lj_err_unwind_win64(EXCEPTION_RECORD *rec,
457
466
/* Don't catch access violations etc. */
458
467
return ExceptionContinueSearch ;
459
468
}
469
+ #if LJ_TARGET_X64
460
470
/* Unwind the stack and call all handlers for all lower C frames
461
471
** (including ourselves) again with EH_UNWINDING set. Then set
462
472
** rsp = cf, rax = errcode and jump to the specified target.
@@ -466,6 +476,18 @@ LJ_FUNCA EXCEPTION_DISPOSITION lj_err_unwind_win64(EXCEPTION_RECORD *rec,
466
476
lj_vm_unwind_c_eh ),
467
477
rec , (void * )(uintptr_t )errcode , ctx , dispatch -> HistoryTable );
468
478
/* RtlUnwindEx should never return. */
479
+ #else
480
+ UNUSED (ctx );
481
+ UNUSED (dispatch );
482
+ /* Call all handlers for all lower C frames (including ourselves) again
483
+ ** with EH_UNWINDING set. Then call the specified function, passing cf
484
+ ** and errcode.
485
+ */
486
+ lj_vm_rtlunwind (cf , (void * )rec ,
487
+ (cframe_unwind_ff (cf2 ) && errcode != LUA_YIELD ) ?
488
+ (void * )lj_vm_unwind_ff : (void * )lj_vm_unwind_c , errcode );
489
+ /* lj_vm_rtlunwind does not return. */
490
+ #endif
469
491
}
470
492
}
471
493
return ExceptionContinueSearch ;
0 commit comments