diff options
author | Mike Pall <mike> | 2011-03-18 23:38:05 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2011-03-18 23:38:05 +0100 |
commit | 642ae06916ecb36fb3f8ea5902de38a612cba356 (patch) | |
tree | 32ca483604ee926a820eb99b777fdc1d791b26d9 /src | |
parent | 063182d79c4152b1b1e74b1226b5a7139969b8cf (diff) | |
download | luajit-642ae06916ecb36fb3f8ea5902de38a612cba356.tar.gz luajit-642ae06916ecb36fb3f8ea5902de38a612cba356.tar.bz2 luajit-642ae06916ecb36fb3f8ea5902de38a612cba356.zip |
x64: Use external unwinding for lua_yield().
Diffstat (limited to 'src')
-rw-r--r-- | src/lj_api.c | 4 | ||||
-rw-r--r-- | src/lj_err.c | 25 |
2 files changed, 18 insertions, 11 deletions
diff --git a/src/lj_api.c b/src/lj_api.c index 70834f8d..4942c1d6 100644 --- a/src/lj_api.c +++ b/src/lj_api.c | |||
@@ -1107,9 +1107,13 @@ LUA_API int lua_yield(lua_State *L, int nresults) | |||
1107 | top[2].fr.tp.ftsz = (int)((char *)(top+3)-(char *)L->base)+FRAME_CONT; | 1107 | top[2].fr.tp.ftsz = (int)((char *)(top+3)-(char *)L->base)+FRAME_CONT; |
1108 | L->top = L->base = top+3; | 1108 | L->top = L->base = top+3; |
1109 | } | 1109 | } |
1110 | #if LJ_TARGET_X64 | ||
1111 | lj_err_throw(L, LUA_YIELD); | ||
1112 | #else | ||
1110 | L->cframe = NULL; | 1113 | L->cframe = NULL; |
1111 | L->status = LUA_YIELD; | 1114 | L->status = LUA_YIELD; |
1112 | lj_vm_unwind_c(cf, LUA_YIELD); | 1115 | lj_vm_unwind_c(cf, LUA_YIELD); |
1116 | #endif | ||
1113 | } | 1117 | } |
1114 | lj_err_msg(L, LJ_ERR_CYIELD); | 1118 | lj_err_msg(L, LJ_ERR_CYIELD); |
1115 | return 0; /* unreachable */ | 1119 | return 0; /* unreachable */ |
diff --git a/src/lj_err.c b/src/lj_err.c index f5d7b10d..51c8fb9f 100644 --- a/src/lj_err.c +++ b/src/lj_err.c | |||
@@ -502,11 +502,14 @@ static void *err_unwind(lua_State *L, void *stopcf, int errcode) | |||
502 | frame = frame_prevd(frame); | 502 | frame = frame_prevd(frame); |
503 | break; | 503 | break; |
504 | case FRAME_PCALL: /* FF pcall() frame. */ | 504 | case FRAME_PCALL: /* FF pcall() frame. */ |
505 | if (errcode) | ||
506 | hook_leave(G(L)); | ||
507 | /* fallthrough */ | ||
508 | case FRAME_PCALLH: /* FF pcall() frame inside hook. */ | 505 | case FRAME_PCALLH: /* FF pcall() frame inside hook. */ |
509 | if (errcode) { | 506 | if (errcode) { |
507 | if (errcode == LUA_YIELD) { | ||
508 | frame = frame_prevd(frame); | ||
509 | break; | ||
510 | } | ||
511 | if (frame_typep(frame) == FRAME_PCALL) | ||
512 | hook_leave(G(L)); | ||
510 | L->cframe = cf; | 513 | L->cframe = cf; |
511 | L->base = frame_prevd(frame) + 1; | 514 | L->base = frame_prevd(frame) + 1; |
512 | unwindstack(L, L->base); | 515 | unwindstack(L, L->base); |
@@ -660,28 +663,28 @@ LJ_FUNCA EXCEPTION_DISPOSITION lj_err_unwind_win64(EXCEPTION_RECORD *rec, | |||
660 | void *cf, CONTEXT *ctx, UndocumentedDispatcherContext *dispatch) | 663 | void *cf, CONTEXT *ctx, UndocumentedDispatcherContext *dispatch) |
661 | { | 664 | { |
662 | lua_State *L = cframe_L(cf); | 665 | lua_State *L = cframe_L(cf); |
666 | int errcode = LJ_EXCODE_CHECK(rec->ExceptionCode) ? | ||
667 | LJ_EXCODE_ERRCODE(rec->ExceptionCode) : LUA_ERRRUN; | ||
663 | if ((rec->ExceptionFlags & 6)) { /* EH_UNWINDING|EH_EXIT_UNWIND */ | 668 | if ((rec->ExceptionFlags & 6)) { /* EH_UNWINDING|EH_EXIT_UNWIND */ |
664 | err_unwind(L, cf, 1); /* Unwind internal frames. */ | 669 | /* Unwind internal frames. */ |
670 | err_unwind(L, cf, errcode); | ||
665 | } else { | 671 | } else { |
666 | void *cf2 = err_unwind(L, cf, 0); | 672 | void *cf2 = err_unwind(L, cf, 0); |
667 | if (cf2) { /* We catch it, so start unwinding the upper frames. */ | 673 | if (cf2) { /* We catch it, so start unwinding the upper frames. */ |
668 | int errcode; | 674 | if (rec->ExceptionCode == LJ_MSVC_EXCODE) { |
669 | if (LJ_EXCODE_CHECK(rec->ExceptionCode)) { | ||
670 | errcode = LJ_EXCODE_ERRCODE(rec->ExceptionCode); | ||
671 | } else if (rec->ExceptionCode == LJ_MSVC_EXCODE) { | ||
672 | #ifdef _MSC_VER | 675 | #ifdef _MSC_VER |
673 | __DestructExceptionObject(rec, 1); | 676 | __DestructExceptionObject(rec, 1); |
674 | #endif | 677 | #endif |
675 | setstrV(L, L->top++, lj_err_str(L, LJ_ERR_ERRCPP)); | 678 | setstrV(L, L->top++, lj_err_str(L, LJ_ERR_ERRCPP)); |
676 | errcode = LUA_ERRRUN; | 679 | } else if (!LJ_EXCODE_CHECK(rec->ExceptionCode)) { |
677 | } else { /* Don't catch access violations etc. */ | 680 | /* Don't catch access violations etc. */ |
678 | return ExceptionContinueSearch; | 681 | return ExceptionContinueSearch; |
679 | } | 682 | } |
680 | /* Unwind the stack and call all handlers for all lower C frames | 683 | /* Unwind the stack and call all handlers for all lower C frames |
681 | ** (including ourselves) again with EH_UNWINDING set. Then set | 684 | ** (including ourselves) again with EH_UNWINDING set. Then set |
682 | ** rsp = cf, rax = errcode and jump to the specified target. | 685 | ** rsp = cf, rax = errcode and jump to the specified target. |
683 | */ | 686 | */ |
684 | RtlUnwindEx(cf, (void *)(cframe_unwind_ff(cf2) ? | 687 | RtlUnwindEx(cf, (void *)((cframe_unwind_ff(cf2) && errcode != LUA_YIELD) ? |
685 | lj_vm_unwind_ff_eh : | 688 | lj_vm_unwind_ff_eh : |
686 | lj_vm_unwind_c_eh), | 689 | lj_vm_unwind_c_eh), |
687 | rec, (void *)errcode, ctx, dispatch->HistoryTable); | 690 | rec, (void *)errcode, ctx, dispatch->HistoryTable); |