Don't use stack unwinding for lua_yield().

This commit is contained in:
Mike Pall 2012-10-09 13:19:57 +02:00
parent da682b0e91
commit eabfdfe1aa
6 changed files with 35 additions and 17 deletions

View File

@ -1103,6 +1103,9 @@ LUA_API int lua_yield(lua_State *L, int nresults)
while (--nresults >= 0) copyTV(L, t++, f++); while (--nresults >= 0) copyTV(L, t++, f++);
L->top = t; L->top = t;
} }
L->cframe = NULL;
L->status = LUA_YIELD;
return -1;
} else { /* Yield from hook: add a pseudo-frame. */ } else { /* Yield from hook: add a pseudo-frame. */
TValue *top = L->top; TValue *top = L->top;
hook_leave(g); hook_leave(g);
@ -1112,7 +1115,6 @@ LUA_API int lua_yield(lua_State *L, int nresults)
setframe_gc(top+2, obj2gco(L)); setframe_gc(top+2, obj2gco(L));
setframe_ftsz(top+2, (int)((char *)(top+3)-(char *)L->base)+FRAME_CONT); setframe_ftsz(top+2, (int)((char *)(top+3)-(char *)L->base)+FRAME_CONT);
L->top = L->base = top+3; L->top = L->base = top+3;
}
#if LJ_TARGET_X64 #if LJ_TARGET_X64
lj_err_throw(L, LUA_YIELD); lj_err_throw(L, LUA_YIELD);
#else #else
@ -1121,6 +1123,7 @@ LUA_API int lua_yield(lua_State *L, int nresults)
lj_vm_unwind_c(cf, LUA_YIELD); lj_vm_unwind_c(cf, LUA_YIELD);
#endif #endif
} }
}
lj_err_msg(L, LJ_ERR_CYIELD); lj_err_msg(L, LJ_ERR_CYIELD);
return 0; /* unreachable */ return 0; /* unreachable */
} }

View File

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

View File

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

View File

@ -452,8 +452,11 @@ static void build_subroutines(BuildCtx *ctx)
| stwu TMP1, FRAME_PC(RA) // Prepend true to results. | stwu TMP1, FRAME_PC(RA) // Prepend true to results.
| |
|->vm_returnc: |->vm_returnc:
| andix. TMP0, PC, FRAME_TYPE
| addi RD, RD, 8 // RD = (nresults+1)*8. | 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 | mr MULTRES, RD
| beq ->BC_RET_Z // Handle regular return to Lua. | beq ->BC_RET_Z // Handle regular return to Lua.
| |

View File

@ -294,8 +294,11 @@ static void build_subroutines(BuildCtx *ctx)
| stwu TMP1, FRAME_PC(RA) // Prepend true to results. | stwu TMP1, FRAME_PC(RA) // Prepend true to results.
| |
|->vm_returnc: |->vm_returnc:
| andi. TMP0, PC, FRAME_TYPE
| addi RD, RD, 8 // RD = (nresults+1)*8. | 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 | mr MULTRES, RD
| beq ->BC_RET_Z // Handle regular return to Lua. | beq ->BC_RET_Z // Handle regular return to Lua.
| |

View File

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