]> git.ipfire.org Git - thirdparty/LuaJIT.git/commitdiff
x64: Use external unwinding for lua_yield().
authorMike Pall <mike>
Fri, 18 Mar 2011 22:38:05 +0000 (23:38 +0100)
committerMike Pall <mike>
Fri, 18 Mar 2011 22:38:05 +0000 (23:38 +0100)
src/lj_api.c
src/lj_err.c

index 70834f8da87f71ad57af12422ecbf23cff9d7abf..4942c1d6d71c24de2d4d5a60d0678431e104123f 100644 (file)
@@ -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 */
index f5d7b10db3faaa468f18005bfcaa8a0f852b723b..51c8fb9f5e097bb70cccc1ebc4df0525a9dd457c 100644 (file)
@@ -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);