diff options
author | Mike Pall <mike> | 2011-06-02 01:21:32 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2011-06-02 01:21:32 +0200 |
commit | 9e153003b4edd0272fbf0355f7bd128b17fb3dfe (patch) | |
tree | bf33ff244950ccdd3cb4ac7049837595226aaede /src | |
parent | 8dd09d5041545f95cd946ebc1e94b397fd2f4811 (diff) | |
download | luajit-9e153003b4edd0272fbf0355f7bd128b17fb3dfe.tar.gz luajit-9e153003b4edd0272fbf0355f7bd128b17fb3dfe.tar.bz2 luajit-9e153003b4edd0272fbf0355f7bd128b17fb3dfe.zip |
ARM: Catch C++ exceptions in interpreter frames.
Diffstat (limited to 'src')
-rw-r--r-- | src/buildvm_asm.c | 15 | ||||
-rw-r--r-- | src/lj_err.c | 31 |
2 files changed, 45 insertions, 1 deletions
diff --git a/src/buildvm_asm.c b/src/buildvm_asm.c index 6468912c..35f413b9 100644 --- a/src/buildvm_asm.c +++ b/src/buildvm_asm.c | |||
@@ -191,6 +191,14 @@ void emit_asm(BuildCtx *ctx) | |||
191 | if (ctx->mode != BUILD_machasm) | 191 | if (ctx->mode != BUILD_machasm) |
192 | fprintf(ctx->fp, ".Lbegin:\n"); | 192 | fprintf(ctx->fp, ".Lbegin:\n"); |
193 | 193 | ||
194 | #if LJ_TARGET_ARM && defined(__GNUC__) | ||
195 | /* This should really be moved into buildvm_arm.dasc. */ | ||
196 | fprintf(ctx->fp, | ||
197 | ".fnstart\n" | ||
198 | ".save {r4, r5, r6, r7, r8, r9, r10, r11, lr}\n" | ||
199 | ".pad #28\n"); | ||
200 | #endif | ||
201 | |||
194 | for (i = rel = 0; i < ctx->nsym; i++) { | 202 | for (i = rel = 0; i < ctx->nsym; i++) { |
195 | int32_t ofs = ctx->sym[i].ofs; | 203 | int32_t ofs = ctx->sym[i].ofs; |
196 | int32_t next = ctx->sym[i+1].ofs; | 204 | int32_t next = ctx->sym[i+1].ofs; |
@@ -219,6 +227,13 @@ void emit_asm(BuildCtx *ctx) | |||
219 | #endif | 227 | #endif |
220 | } | 228 | } |
221 | 229 | ||
230 | #if LJ_TARGET_ARM && defined(__GNUC__) | ||
231 | fprintf(ctx->fp, | ||
232 | ".globl lj_err_unwind_arm\n" | ||
233 | ".personality lj_err_unwind_arm\n" | ||
234 | ".fnend\n"); | ||
235 | #endif | ||
236 | |||
222 | fprintf(ctx->fp, "\n"); | 237 | fprintf(ctx->fp, "\n"); |
223 | switch (ctx->mode) { | 238 | switch (ctx->mode) { |
224 | case BUILD_elfasm: | 239 | case BUILD_elfasm: |
diff --git a/src/lj_err.c b/src/lj_err.c index d1d326e9..11f0922f 100644 --- a/src/lj_err.c +++ b/src/lj_err.c | |||
@@ -531,7 +531,7 @@ static void *err_unwind(lua_State *L, void *stopcf, int errcode) | |||
531 | 531 | ||
532 | /* -- External frame unwinding -------------------------------------------- */ | 532 | /* -- External frame unwinding -------------------------------------------- */ |
533 | 533 | ||
534 | #if defined(__GNUC__) && !LJ_TARGET_ARM | 534 | #if defined(__GNUC__) |
535 | 535 | ||
536 | #ifdef __clang__ | 536 | #ifdef __clang__ |
537 | /* http://llvm.org/bugs/show_bug.cgi?id=8703 */ | 537 | /* http://llvm.org/bugs/show_bug.cgi?id=8703 */ |
@@ -545,6 +545,8 @@ static void *err_unwind(lua_State *L, void *stopcf, int errcode) | |||
545 | #define LJ_UEXCLASS_CHECK(cl) (((cl) ^ LJ_UEXCLASS) <= 0xff) | 545 | #define LJ_UEXCLASS_CHECK(cl) (((cl) ^ LJ_UEXCLASS) <= 0xff) |
546 | #define LJ_UEXCLASS_ERRCODE(cl) ((int)((cl) & 0xff)) | 546 | #define LJ_UEXCLASS_ERRCODE(cl) ((int)((cl) & 0xff)) |
547 | 547 | ||
548 | #if !LJ_TARGET_ARM | ||
549 | |||
548 | /* DWARF2 personality handler referenced from interpreter .eh_frame. */ | 550 | /* DWARF2 personality handler referenced from interpreter .eh_frame. */ |
549 | LJ_FUNCA int lj_err_unwind_dwarf(int version, _Unwind_Action actions, | 551 | LJ_FUNCA int lj_err_unwind_dwarf(int version, _Unwind_Action actions, |
550 | _Unwind_Exception_Class uexclass, struct _Unwind_Exception *uex, | 552 | _Unwind_Exception_Class uexclass, struct _Unwind_Exception *uex, |
@@ -618,6 +620,33 @@ static void err_raise_ext(int errcode) | |||
618 | } | 620 | } |
619 | #endif | 621 | #endif |
620 | 622 | ||
623 | #else | ||
624 | |||
625 | /* ARM unwinder personality handler referenced from interpreter .ARM.extab. */ | ||
626 | LJ_FUNCA _Unwind_Reason_Code lj_err_unwind_arm(_Unwind_State state, | ||
627 | _Unwind_Control_Block *ucb, | ||
628 | _Unwind_Context *ctx) | ||
629 | { | ||
630 | void *cf = (void *)_Unwind_GetGR(ctx, 13); | ||
631 | lua_State *L = cframe_L(cf); | ||
632 | if ((state & _US_ACTION_MASK) == _US_VIRTUAL_UNWIND_FRAME) { | ||
633 | setstrV(L, L->top++, lj_err_str(L, LJ_ERR_ERRCPP)); | ||
634 | return _URC_HANDLER_FOUND; | ||
635 | } | ||
636 | if ((state & _US_ACTION_MASK) == _US_UNWIND_FRAME_STARTING) { | ||
637 | _Unwind_DeleteException(ucb); | ||
638 | _Unwind_SetGR(ctx, 15, (_Unwind_Word)(void *)lj_err_throw); | ||
639 | _Unwind_SetGR(ctx, 0, (_Unwind_Word)L); | ||
640 | _Unwind_SetGR(ctx, 1, (_Unwind_Word)LUA_ERRRUN); | ||
641 | return _URC_INSTALL_CONTEXT; | ||
642 | } | ||
643 | if (__gnu_unwind_frame(ucb, ctx) != _URC_OK) | ||
644 | return _URC_FAILURE; | ||
645 | return _URC_CONTINUE_UNWIND; | ||
646 | } | ||
647 | |||
648 | #endif | ||
649 | |||
621 | #elif LJ_TARGET_X64 && LJ_TARGET_WINDOWS | 650 | #elif LJ_TARGET_X64 && LJ_TARGET_WINDOWS |
622 | 651 | ||
623 | /* | 652 | /* |