|
@@ -2080,25 +2080,19 @@ static TRef rec_tnew(jit_State *J, uint32_t ah)
|
|
|
|
|
|
typedef struct RecCatDataCP {
|
|
typedef struct RecCatDataCP {
|
|
jit_State *J;
|
|
jit_State *J;
|
|
- RecordIndex *ix;
|
|
|
|
|
|
+ BCReg baseslot, topslot;
|
|
|
|
+ TRef tr;
|
|
} RecCatDataCP;
|
|
} RecCatDataCP;
|
|
|
|
|
|
static TValue *rec_mm_concat_cp(lua_State *L, lua_CFunction dummy, void *ud)
|
|
static TValue *rec_mm_concat_cp(lua_State *L, lua_CFunction dummy, void *ud)
|
|
{
|
|
{
|
|
RecCatDataCP *rcd = (RecCatDataCP *)ud;
|
|
RecCatDataCP *rcd = (RecCatDataCP *)ud;
|
|
- UNUSED(L); UNUSED(dummy);
|
|
|
|
- rec_mm_arith(rcd->J, rcd->ix, MM_concat); /* Call __concat metamethod. */
|
|
|
|
- return NULL;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static TRef rec_cat(jit_State *J, BCReg baseslot, BCReg topslot)
|
|
|
|
-{
|
|
|
|
|
|
+ jit_State *J = rcd->J;
|
|
|
|
+ BCReg baseslot = rcd->baseslot, topslot = rcd->topslot;
|
|
TRef *top = &J->base[topslot];
|
|
TRef *top = &J->base[topslot];
|
|
- TValue savetv[5+LJ_FR2];
|
|
|
|
BCReg s;
|
|
BCReg s;
|
|
RecordIndex ix;
|
|
RecordIndex ix;
|
|
- RecCatDataCP rcd;
|
|
|
|
- int errcode;
|
|
|
|
|
|
+ UNUSED(L); UNUSED(dummy);
|
|
lj_assertJ(baseslot < topslot, "bad CAT arg");
|
|
lj_assertJ(baseslot < topslot, "bad CAT arg");
|
|
for (s = baseslot; s <= topslot; s++)
|
|
for (s = baseslot; s <= topslot; s++)
|
|
(void)getslot(J, s); /* Ensure all arguments have a reference. */
|
|
(void)getslot(J, s); /* Ensure all arguments have a reference. */
|
|
@@ -2120,7 +2114,10 @@ static TRef rec_cat(jit_State *J, BCReg baseslot, BCReg topslot)
|
|
} while (trp <= top);
|
|
} while (trp <= top);
|
|
tr = emitir(IRTG(IR_BUFSTR, IRT_STR), tr, hdr);
|
|
tr = emitir(IRTG(IR_BUFSTR, IRT_STR), tr, hdr);
|
|
J->maxslot = (BCReg)(xbase - J->base);
|
|
J->maxslot = (BCReg)(xbase - J->base);
|
|
- if (xbase == base) return tr; /* Return simple concatenation result. */
|
|
|
|
|
|
+ if (xbase == base) {
|
|
|
|
+ rcd->tr = tr; /* Return simple concatenation result. */
|
|
|
|
+ return NULL;
|
|
|
|
+ }
|
|
/* Pass partial result. */
|
|
/* Pass partial result. */
|
|
topslot = J->maxslot--;
|
|
topslot = J->maxslot--;
|
|
*xbase = tr;
|
|
*xbase = tr;
|
|
@@ -2133,13 +2130,31 @@ static TRef rec_cat(jit_State *J, BCReg baseslot, BCReg topslot)
|
|
copyTV(J->L, &ix.tabv, &J->L->base[topslot-1]);
|
|
copyTV(J->L, &ix.tabv, &J->L->base[topslot-1]);
|
|
ix.tab = top[-1];
|
|
ix.tab = top[-1];
|
|
ix.key = top[0];
|
|
ix.key = top[0];
|
|
- memcpy(savetv, &J->L->base[topslot-1], sizeof(savetv)); /* Save slots. */
|
|
|
|
|
|
+ rec_mm_arith(J, &ix, MM_concat); /* Call __concat metamethod. */
|
|
|
|
+ rcd->tr = 0; /* No result yet. */
|
|
|
|
+ return NULL;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static TRef rec_cat(jit_State *J, BCReg baseslot, BCReg topslot)
|
|
|
|
+{
|
|
|
|
+ lua_State *L = J->L;
|
|
|
|
+ ptrdiff_t delta = L->top - L->base;
|
|
|
|
+ TValue savetv[5+LJ_FR2], errobj;
|
|
|
|
+ RecCatDataCP rcd;
|
|
|
|
+ int errcode;
|
|
rcd.J = J;
|
|
rcd.J = J;
|
|
- rcd.ix = &ix;
|
|
|
|
- errcode = lj_vm_cpcall(J->L, NULL, &rcd, rec_mm_concat_cp);
|
|
|
|
- memcpy(&J->L->base[topslot-1], savetv, sizeof(savetv)); /* Restore slots. */
|
|
|
|
- if (errcode) return (TRef)(-errcode);
|
|
|
|
- return 0; /* No result yet. */
|
|
|
|
|
|
+ rcd.baseslot = baseslot;
|
|
|
|
+ rcd.topslot = topslot;
|
|
|
|
+ memcpy(savetv, &L->base[topslot-1], sizeof(savetv)); /* Save slots. */
|
|
|
|
+ errcode = lj_vm_cpcall(L, NULL, &rcd, rec_mm_concat_cp);
|
|
|
|
+ if (errcode) copyTV(L, &errobj, L->top-1);
|
|
|
|
+ memcpy(&L->base[topslot-1], savetv, sizeof(savetv)); /* Restore slots. */
|
|
|
|
+ if (errcode) {
|
|
|
|
+ L->top = L->base + delta;
|
|
|
|
+ copyTV(L, L->top++, &errobj);
|
|
|
|
+ return (TRef)(-errcode);
|
|
|
|
+ }
|
|
|
|
+ return rcd.tr;
|
|
}
|
|
}
|
|
|
|
|
|
/* -- Record bytecode ops ------------------------------------------------- */
|
|
/* -- Record bytecode ops ------------------------------------------------- */
|