|
@@ -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);
|