aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lj_record.c51
1 files changed, 33 insertions, 18 deletions
diff --git a/src/lj_record.c b/src/lj_record.c
index fedd47a6..3f250008 100644
--- a/src/lj_record.c
+++ b/src/lj_record.c
@@ -2080,25 +2080,19 @@ static TRef rec_tnew(jit_State *J, uint32_t ah)
2080 2080
2081typedef struct RecCatDataCP { 2081typedef struct RecCatDataCP {
2082 jit_State *J; 2082 jit_State *J;
2083 RecordIndex *ix; 2083 BCReg baseslot, topslot;
2084 TRef tr;
2084} RecCatDataCP; 2085} RecCatDataCP;
2085 2086
2086static TValue *rec_mm_concat_cp(lua_State *L, lua_CFunction dummy, void *ud) 2087static TValue *rec_mm_concat_cp(lua_State *L, lua_CFunction dummy, void *ud)
2087{ 2088{
2088 RecCatDataCP *rcd = (RecCatDataCP *)ud; 2089 RecCatDataCP *rcd = (RecCatDataCP *)ud;
2089 UNUSED(L); UNUSED(dummy); 2090 jit_State *J = rcd->J;
2090 rec_mm_arith(rcd->J, rcd->ix, MM_concat); /* Call __concat metamethod. */ 2091 BCReg baseslot = rcd->baseslot, topslot = rcd->topslot;
2091 return NULL;
2092}
2093
2094static TRef rec_cat(jit_State *J, BCReg baseslot, BCReg topslot)
2095{
2096 TRef *top = &J->base[topslot]; 2092 TRef *top = &J->base[topslot];
2097 TValue savetv[5+LJ_FR2];
2098 BCReg s; 2093 BCReg s;
2099 RecordIndex ix; 2094 RecordIndex ix;
2100 RecCatDataCP rcd; 2095 UNUSED(L); UNUSED(dummy);
2101 int errcode;
2102 lj_assertJ(baseslot < topslot, "bad CAT arg"); 2096 lj_assertJ(baseslot < topslot, "bad CAT arg");
2103 for (s = baseslot; s <= topslot; s++) 2097 for (s = baseslot; s <= topslot; s++)
2104 (void)getslot(J, s); /* Ensure all arguments have a reference. */ 2098 (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)
2120 } while (trp <= top); 2114 } while (trp <= top);
2121 tr = emitir(IRTG(IR_BUFSTR, IRT_STR), tr, hdr); 2115 tr = emitir(IRTG(IR_BUFSTR, IRT_STR), tr, hdr);
2122 J->maxslot = (BCReg)(xbase - J->base); 2116 J->maxslot = (BCReg)(xbase - J->base);
2123 if (xbase == base) return tr; /* Return simple concatenation result. */ 2117 if (xbase == base) {
2118 rcd->tr = tr; /* Return simple concatenation result. */
2119 return NULL;
2120 }
2124 /* Pass partial result. */ 2121 /* Pass partial result. */
2125 topslot = J->maxslot--; 2122 topslot = J->maxslot--;
2126 *xbase = tr; 2123 *xbase = tr;
@@ -2133,13 +2130,31 @@ static TRef rec_cat(jit_State *J, BCReg baseslot, BCReg topslot)
2133 copyTV(J->L, &ix.tabv, &J->L->base[topslot-1]); 2130 copyTV(J->L, &ix.tabv, &J->L->base[topslot-1]);
2134 ix.tab = top[-1]; 2131 ix.tab = top[-1];
2135 ix.key = top[0]; 2132 ix.key = top[0];
2136 memcpy(savetv, &J->L->base[topslot-1], sizeof(savetv)); /* Save slots. */ 2133 rec_mm_arith(J, &ix, MM_concat); /* Call __concat metamethod. */
2134 rcd->tr = 0; /* No result yet. */
2135 return NULL;
2136}
2137
2138static TRef rec_cat(jit_State *J, BCReg baseslot, BCReg topslot)
2139{
2140 lua_State *L = J->L;
2141 ptrdiff_t delta = L->top - L->base;
2142 TValue savetv[5+LJ_FR2], errobj;
2143 RecCatDataCP rcd;
2144 int errcode;
2137 rcd.J = J; 2145 rcd.J = J;
2138 rcd.ix = &ix; 2146 rcd.baseslot = baseslot;
2139 errcode = lj_vm_cpcall(J->L, NULL, &rcd, rec_mm_concat_cp); 2147 rcd.topslot = topslot;
2140 memcpy(&J->L->base[topslot-1], savetv, sizeof(savetv)); /* Restore slots. */ 2148 memcpy(savetv, &L->base[topslot-1], sizeof(savetv)); /* Save slots. */
2141 if (errcode) return (TRef)(-errcode); 2149 errcode = lj_vm_cpcall(L, NULL, &rcd, rec_mm_concat_cp);
2142 return 0; /* No result yet. */ 2150 if (errcode) copyTV(L, &errobj, L->top-1);
2151 memcpy(&L->base[topslot-1], savetv, sizeof(savetv)); /* Restore slots. */
2152 if (errcode) {
2153 L->top = L->base + delta;
2154 copyTV(L, L->top++, &errobj);
2155 return (TRef)(-errcode);
2156 }
2157 return rcd.tr;
2143} 2158}
2144 2159
2145/* -- Record bytecode ops ------------------------------------------------- */ 2160/* -- Record bytecode ops ------------------------------------------------- */