diff options
author | Mike Pall <mike> | 2025-03-09 21:28:17 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2025-03-09 21:28:17 +0100 |
commit | eee16efa77b542e99c8e546a3d52fc023925c7bc (patch) | |
tree | 06634363ac6436c943d26c1a4ee461beb8af650e | |
parent | 4219efae43f9fc600554c3f7d07f47374e03a391 (diff) | |
download | luajit-eee16efa77b542e99c8e546a3d52fc023925c7bc.tar.gz luajit-eee16efa77b542e99c8e546a3d52fc023925c7bc.tar.bz2 luajit-eee16efa77b542e99c8e546a3d52fc023925c7bc.zip |
Fix state restore when recording __concat metamethod.
Reported by Sergey Kaplun. #1338 #1298
-rw-r--r-- | src/lj_record.c | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/src/lj_record.c b/src/lj_record.c index 38c180e8..c6a082d4 100644 --- a/src/lj_record.c +++ b/src/lj_record.c | |||
@@ -2079,6 +2079,7 @@ static TRef rec_tnew(jit_State *J, uint32_t ah) | |||
2079 | /* -- Concatenation ------------------------------------------------------- */ | 2079 | /* -- Concatenation ------------------------------------------------------- */ |
2080 | 2080 | ||
2081 | typedef struct RecCatDataCP { | 2081 | typedef struct RecCatDataCP { |
2082 | TValue savetv[5+LJ_FR2]; | ||
2082 | jit_State *J; | 2083 | jit_State *J; |
2083 | BCReg baseslot, topslot; | 2084 | BCReg baseslot, topslot; |
2084 | TRef tr; | 2085 | TRef tr; |
@@ -2119,7 +2120,9 @@ static TValue *rec_mm_concat_cp(lua_State *L, lua_CFunction dummy, void *ud) | |||
2119 | return NULL; | 2120 | return NULL; |
2120 | } | 2121 | } |
2121 | /* Pass partial result. */ | 2122 | /* Pass partial result. */ |
2122 | topslot = J->maxslot--; | 2123 | rcd->topslot = topslot = J->maxslot--; |
2124 | /* Save updated range of slots. */ | ||
2125 | memcpy(rcd->savetv, &L->base[topslot-1], sizeof(rcd->savetv)); | ||
2123 | *xbase = tr; | 2126 | *xbase = tr; |
2124 | top = xbase; | 2127 | top = xbase; |
2125 | setstrV(J->L, &ix.keyv, &J2G(J)->strempty); /* Simulate string result. */ | 2128 | 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) | |||
2139 | { | 2142 | { |
2140 | lua_State *L = J->L; | 2143 | lua_State *L = J->L; |
2141 | ptrdiff_t delta = L->top - L->base; | 2144 | ptrdiff_t delta = L->top - L->base; |
2142 | TValue savetv[5+LJ_FR2], errobj; | 2145 | TValue errobj; |
2143 | RecCatDataCP rcd; | 2146 | RecCatDataCP rcd; |
2144 | int errcode; | 2147 | int errcode; |
2145 | rcd.J = J; | 2148 | rcd.J = J; |
2146 | rcd.baseslot = baseslot; | 2149 | rcd.baseslot = baseslot; |
2147 | rcd.topslot = topslot; | 2150 | rcd.topslot = topslot; |
2148 | memcpy(savetv, &L->base[topslot-1], sizeof(savetv)); /* Save slots. */ | 2151 | /* Save slots. */ |
2152 | memcpy(rcd.savetv, &L->base[topslot-1], sizeof(rcd.savetv)); | ||
2149 | errcode = lj_vm_cpcall(L, NULL, &rcd, rec_mm_concat_cp); | 2153 | errcode = lj_vm_cpcall(L, NULL, &rcd, rec_mm_concat_cp); |
2150 | if (errcode) copyTV(L, &errobj, L->top-1); | 2154 | if (errcode) copyTV(L, &errobj, L->top-1); |
2151 | memcpy(&L->base[topslot-1], savetv, sizeof(savetv)); /* Restore slots. */ | 2155 | /* Restore slots. */ |
2156 | memcpy(&L->base[rcd.topslot-1], rcd.savetv, sizeof(rcd.savetv)); | ||
2152 | if (errcode) { | 2157 | if (errcode) { |
2153 | L->top = L->base + delta; | 2158 | L->top = L->base + delta; |
2154 | copyTV(L, L->top++, &errobj); | 2159 | copyTV(L, L->top++, &errobj); |