From 642ae06916ecb36fb3f8ea5902de38a612cba356 Mon Sep 17 00:00:00 2001 From: Mike Pall Date: Fri, 18 Mar 2011 23:38:05 +0100 Subject: [PATCH] x64: Use external unwinding for lua_yield(). --- src/lj_api.c | 4 ++++ 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) top[2].fr.tp.ftsz = (int)((char *)(top+3)-(char *)L->base)+FRAME_CONT; L->top = L->base = top+3; } +#if LJ_TARGET_X64 + lj_err_throw(L, LUA_YIELD); +#else L->cframe = NULL; L->status = LUA_YIELD; lj_vm_unwind_c(cf, LUA_YIELD); +#endif } lj_err_msg(L, LJ_ERR_CYIELD); 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) frame = frame_prevd(frame); break; case FRAME_PCALL: /* FF pcall() frame. */ - if (errcode) - hook_leave(G(L)); - /* fallthrough */ case FRAME_PCALLH: /* FF pcall() frame inside hook. */ if (errcode) { + if (errcode == LUA_YIELD) { + frame = frame_prevd(frame); + break; + } + if (frame_typep(frame) == FRAME_PCALL) + hook_leave(G(L)); L->cframe = cf; L->base = frame_prevd(frame) + 1; unwindstack(L, L->base); @@ -660,28 +663,28 @@ LJ_FUNCA EXCEPTION_DISPOSITION lj_err_unwind_win64(EXCEPTION_RECORD *rec, void *cf, CONTEXT *ctx, UndocumentedDispatcherContext *dispatch) { lua_State *L = cframe_L(cf); + int errcode = LJ_EXCODE_CHECK(rec->ExceptionCode) ? + LJ_EXCODE_ERRCODE(rec->ExceptionCode) : LUA_ERRRUN; if ((rec->ExceptionFlags & 6)) { /* EH_UNWINDING|EH_EXIT_UNWIND */ - err_unwind(L, cf, 1); /* Unwind internal frames. */ + /* Unwind internal frames. */ + err_unwind(L, cf, errcode); } else { void *cf2 = err_unwind(L, cf, 0); if (cf2) { /* We catch it, so start unwinding the upper frames. */ - int errcode; - if (LJ_EXCODE_CHECK(rec->ExceptionCode)) { - errcode = LJ_EXCODE_ERRCODE(rec->ExceptionCode); - } else if (rec->ExceptionCode == LJ_MSVC_EXCODE) { + if (rec->ExceptionCode == LJ_MSVC_EXCODE) { #ifdef _MSC_VER __DestructExceptionObject(rec, 1); #endif setstrV(L, L->top++, lj_err_str(L, LJ_ERR_ERRCPP)); - errcode = LUA_ERRRUN; - } else { /* Don't catch access violations etc. */ + } else if (!LJ_EXCODE_CHECK(rec->ExceptionCode)) { + /* Don't catch access violations etc. */ return ExceptionContinueSearch; } /* Unwind the stack and call all handlers for all lower C frames ** (including ourselves) again with EH_UNWINDING set. Then set ** rsp = cf, rax = errcode and jump to the specified target. */ - RtlUnwindEx(cf, (void *)(cframe_unwind_ff(cf2) ? + RtlUnwindEx(cf, (void *)((cframe_unwind_ff(cf2) && errcode != LUA_YIELD) ? lj_vm_unwind_ff_eh : lj_vm_unwind_c_eh), rec, (void *)errcode, ctx, dispatch->HistoryTable);