Fix state restore when recording __concat metamethod.
Reported by Sergey Kaplun. #1338 #1298
This commit is contained in:
@@ -2079,6 +2079,7 @@ static TRef rec_tnew(jit_State *J, uint32_t ah)
|
|||||||
/* -- Concatenation ------------------------------------------------------- */
|
/* -- Concatenation ------------------------------------------------------- */
|
||||||
|
|
||||||
typedef struct RecCatDataCP {
|
typedef struct RecCatDataCP {
|
||||||
|
TValue savetv[5+LJ_FR2];
|
||||||
jit_State *J;
|
jit_State *J;
|
||||||
BCReg baseslot, topslot;
|
BCReg baseslot, topslot;
|
||||||
TRef tr;
|
TRef tr;
|
||||||
@@ -2119,7 +2120,9 @@ static TValue *rec_mm_concat_cp(lua_State *L, lua_CFunction dummy, void *ud)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/* Pass partial result. */
|
/* Pass partial result. */
|
||||||
topslot = J->maxslot--;
|
rcd->topslot = topslot = J->maxslot--;
|
||||||
|
/* Save updated range of slots. */
|
||||||
|
memcpy(rcd->savetv, &L->base[topslot-1], sizeof(rcd->savetv));
|
||||||
*xbase = tr;
|
*xbase = tr;
|
||||||
top = xbase;
|
top = xbase;
|
||||||
setstrV(J->L, &ix.keyv, &J2G(J)->strempty); /* Simulate string result. */
|
setstrV(J->L, &ix.keyv, &J2G(J)->strempty); /* Simulate string result. */
|
||||||
@@ -2139,16 +2142,18 @@ static TRef rec_cat(jit_State *J, BCReg baseslot, BCReg topslot)
|
|||||||
{
|
{
|
||||||
lua_State *L = J->L;
|
lua_State *L = J->L;
|
||||||
ptrdiff_t delta = L->top - L->base;
|
ptrdiff_t delta = L->top - L->base;
|
||||||
TValue savetv[5+LJ_FR2], errobj;
|
TValue errobj;
|
||||||
RecCatDataCP rcd;
|
RecCatDataCP rcd;
|
||||||
int errcode;
|
int errcode;
|
||||||
rcd.J = J;
|
rcd.J = J;
|
||||||
rcd.baseslot = baseslot;
|
rcd.baseslot = baseslot;
|
||||||
rcd.topslot = topslot;
|
rcd.topslot = topslot;
|
||||||
memcpy(savetv, &L->base[topslot-1], sizeof(savetv)); /* Save slots. */
|
/* Save slots. */
|
||||||
|
memcpy(rcd.savetv, &L->base[topslot-1], sizeof(rcd.savetv));
|
||||||
errcode = lj_vm_cpcall(L, NULL, &rcd, rec_mm_concat_cp);
|
errcode = lj_vm_cpcall(L, NULL, &rcd, rec_mm_concat_cp);
|
||||||
if (errcode) copyTV(L, &errobj, L->top-1);
|
if (errcode) copyTV(L, &errobj, L->top-1);
|
||||||
memcpy(&L->base[topslot-1], savetv, sizeof(savetv)); /* Restore slots. */
|
/* Restore slots. */
|
||||||
|
memcpy(&L->base[rcd.topslot-1], rcd.savetv, sizeof(rcd.savetv));
|
||||||
if (errcode) {
|
if (errcode) {
|
||||||
L->top = L->base + delta;
|
L->top = L->base + delta;
|
||||||
copyTV(L, L->top++, &errobj);
|
copyTV(L, L->top++, &errobj);
|
||||||
|
|||||||
Reference in New Issue
Block a user