2
0
Эх сурвалжийг харах

Don't use stack unwinding for lua_yield().

Mike Pall 13 жил өмнө
parent
commit
eabfdfe1aa

+ 8 - 5
src/lj_api.c

@@ -1103,6 +1103,9 @@ LUA_API int lua_yield(lua_State *L, int nresults)
 	while (--nresults >= 0) copyTV(L, t++, f++);
 	L->top = t;
       }
+      L->cframe = NULL;
+      L->status = LUA_YIELD;
+      return -1;
     } else {  /* Yield from hook: add a pseudo-frame. */
       TValue *top = L->top;
       hook_leave(g);
@@ -1112,14 +1115,14 @@ LUA_API int lua_yield(lua_State *L, int nresults)
       setframe_gc(top+2, obj2gco(L));
       setframe_ftsz(top+2, (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);
+      lj_err_throw(L, LUA_YIELD);
 #else
-    L->cframe = NULL;
-    L->status = LUA_YIELD;
-    lj_vm_unwind_c(cf, LUA_YIELD);
+      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 */

+ 5 - 3
src/vm_arm.dasc

@@ -269,10 +269,12 @@ static void build_subroutines(BuildCtx *ctx)
   |  sub RA, RA, #8
   |
   |->vm_returnc:
-  |  add RC, RC, #8			// RC = (nresults+1)*8.
-  |   ands CARG1, PC, #FRAME_TYPE
+  |  adds RC, RC, #8			// RC = (nresults+1)*8.
+  |  mov CRET1, #LUA_YIELD
+  |  beq ->vm_unwind_c_eh
   |  str RC, SAVE_MULTRES
-  |   beq ->BC_RET_Z			// Handle regular return to Lua.
+  |  ands CARG1, PC, #FRAME_TYPE
+  |  beq ->BC_RET_Z			// Handle regular return to Lua.
   |
   |->vm_return:
   |  // BASE = base, RA = resultptr, RC/MULTRES = (nresults+1)*8, PC = return

+ 3 - 1
src/vm_mips.dasc

@@ -327,8 +327,10 @@ static void build_subroutines(BuildCtx *ctx)
   |   addiu RA, RA, -8
   |
   |->vm_returnc:
-  |  andi TMP0, PC, FRAME_TYPE
   |   addiu RD, RD, 8			// RD = (nresults+1)*8.
+  |  andi TMP0, PC, FRAME_TYPE
+  |   beqz RD, ->vm_unwind_c_eh
+  |.   li CRET1, LUA_YIELD
   |  beqz TMP0, ->BC_RET_Z		// Handle regular return to Lua.
   |.  move MULTRES, RD
   |

+ 7 - 4
src/vm_ppc.dasc

@@ -452,10 +452,13 @@ static void build_subroutines(BuildCtx *ctx)
   |   stwu TMP1, FRAME_PC(RA)		// Prepend true to results.
   |
   |->vm_returnc:
-  |  andix. TMP0, PC, FRAME_TYPE
-  |   addi RD, RD, 8			// RD = (nresults+1)*8.
-  |   mr MULTRES, RD
-  |  beq ->BC_RET_Z			// Handle regular return to Lua.
+  |  addi RD, RD, 8			// RD = (nresults+1)*8.
+  |   andix. TMP0, PC, FRAME_TYPE
+  |  cmpwi cr1, RD, 0
+  |  li CRET1, LUA_YIELD
+  |  beq cr1, ->vm_unwind_c_eh
+  |  mr MULTRES, RD
+  |   beq ->BC_RET_Z			// Handle regular return to Lua.
   |
   |->vm_return:
   |  // BASE = base, RA = resultptr, RD/MULTRES = (nresults+1)*8, PC = return

+ 7 - 4
src/vm_ppcspe.dasc

@@ -294,10 +294,13 @@ static void build_subroutines(BuildCtx *ctx)
   |   stwu TMP1, FRAME_PC(RA)		// Prepend true to results.
   |
   |->vm_returnc:
-  |  andi. TMP0, PC, FRAME_TYPE
-  |   addi RD, RD, 8			// RD = (nresults+1)*8.
-  |   mr MULTRES, RD
-  |  beq ->BC_RET_Z			// Handle regular return to Lua.
+  |  addi RD, RD, 8			// RD = (nresults+1)*8.
+  |   andi. TMP0, PC, FRAME_TYPE
+  |  cmpwi cr1, RD, 0
+  |  li CRET1, LUA_YIELD
+  |  beq cr1, ->vm_unwind_c_eh
+  |  mr MULTRES, RD
+  |   beq ->BC_RET_Z			// Handle regular return to Lua.
   |
   |->vm_return:
   |  // BASE = base, RA = resultptr, RD/MULTRES = (nresults+1)*8, PC = return

+ 5 - 0
src/vm_x86.dasc

@@ -443,6 +443,7 @@ static void build_subroutines(BuildCtx *ctx)
   |
   |->vm_returnc:
   |  add RD, 1				// RD = nresults+1
+  |  jz ->vm_unwind_yield
   |  mov MULTRES, RD
   |  test PC, FRAME_TYPE
   |  jz ->BC_RET_Z			// Handle regular return to Lua.
@@ -526,6 +527,10 @@ static void build_subroutines(BuildCtx *ctx)
   |  mov BASE, L:RB->top		// Need the (realloced) L->top in BASE.
   |  jmp <3
   |
+  |->vm_unwind_yield:
+  |  mov al, LUA_YIELD
+  |  jmp ->vm_unwind_c_eh
+  |
   |->vm_unwind_c@8:			// Unwind C stack, return from vm_pcall.
   |  // (void *cframe, int errcode)
   |.if X64