J->L->base = b + baseadj;
copyTV(J->L, b-(2<<LJ_FR2), &save);
}
- if (tr) { /* Store final result. */
+ if (tr >= 0xffffff00) {
+ lj_err_throw(J->L, -(int32_t)tr); /* Propagate errors. */
+ } else if (tr) { /* Store final result. */
BCReg dst = bc_a(*(frame_contpc(frame)-1));
J->base[dst] = tr;
if (dst >= J->maxslot) {
/* -- Concatenation ------------------------------------------------------- */
+typedef struct RecCatDataCP {
+ jit_State *J;
+ RecordIndex *ix;
+} RecCatDataCP;
+
+static TValue *rec_mm_concat_cp(lua_State *L, lua_CFunction dummy, void *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)
{
TRef *top = &J->base[topslot];
TValue savetv[5+LJ_FR2];
BCReg s;
RecordIndex ix;
+ RecCatDataCP rcd;
+ int errcode;
lj_assertJ(baseslot < topslot, "bad CAT arg");
for (s = baseslot; s <= topslot; s++)
(void)getslot(J, s); /* Ensure all arguments have a reference. */
ix.tab = top[-1];
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.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. */
}
case BC_CAT:
rc = rec_cat(J, rb, rc);
+ if (rc >= 0xffffff00)
+ lj_err_throw(J->L, -(int32_t)rc); /* Propagate errors. */
break;
/* -- Constant and move ops --------------------------------------------- */