diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lj_record.c | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/src/lj_record.c b/src/lj_record.c index 48bbbb20..6666b3c6 100644 --- a/src/lj_record.c +++ b/src/lj_record.c | |||
| @@ -1025,7 +1025,9 @@ void lj_record_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults) | |||
| 1025 | J->L->base = b + baseadj; | 1025 | J->L->base = b + baseadj; |
| 1026 | copyTV(J->L, b-(2<<LJ_FR2), &save); | 1026 | copyTV(J->L, b-(2<<LJ_FR2), &save); |
| 1027 | } | 1027 | } |
| 1028 | if (tr) { /* Store final result. */ | 1028 | if (tr >= 0xffffff00) { |
| 1029 | lj_err_throw(J->L, -(int32_t)tr); /* Propagate errors. */ | ||
| 1030 | } else if (tr) { /* Store final result. */ | ||
| 1029 | BCReg dst = bc_a(*(frame_contpc(frame)-1)); | 1031 | BCReg dst = bc_a(*(frame_contpc(frame)-1)); |
| 1030 | J->base[dst] = tr; | 1032 | J->base[dst] = tr; |
| 1031 | if (dst >= J->maxslot) { | 1033 | if (dst >= J->maxslot) { |
| @@ -2075,12 +2077,27 @@ static TRef rec_tnew(jit_State *J, uint32_t ah) | |||
| 2075 | 2077 | ||
| 2076 | /* -- Concatenation ------------------------------------------------------- */ | 2078 | /* -- Concatenation ------------------------------------------------------- */ |
| 2077 | 2079 | ||
| 2080 | typedef struct RecCatDataCP { | ||
| 2081 | jit_State *J; | ||
| 2082 | RecordIndex *ix; | ||
| 2083 | } RecCatDataCP; | ||
| 2084 | |||
| 2085 | static TValue *rec_mm_concat_cp(lua_State *L, lua_CFunction dummy, void *ud) | ||
| 2086 | { | ||
| 2087 | RecCatDataCP *rcd = (RecCatDataCP *)ud; | ||
| 2088 | UNUSED(L); UNUSED(dummy); | ||
| 2089 | rec_mm_arith(rcd->J, rcd->ix, MM_concat); /* Call __concat metamethod. */ | ||
| 2090 | return NULL; | ||
| 2091 | } | ||
| 2092 | |||
| 2078 | static TRef rec_cat(jit_State *J, BCReg baseslot, BCReg topslot) | 2093 | static TRef rec_cat(jit_State *J, BCReg baseslot, BCReg topslot) |
| 2079 | { | 2094 | { |
| 2080 | TRef *top = &J->base[topslot]; | 2095 | TRef *top = &J->base[topslot]; |
| 2081 | TValue savetv[5+LJ_FR2]; | 2096 | TValue savetv[5+LJ_FR2]; |
| 2082 | BCReg s; | 2097 | BCReg s; |
| 2083 | RecordIndex ix; | 2098 | RecordIndex ix; |
| 2099 | RecCatDataCP rcd; | ||
| 2100 | int errcode; | ||
| 2084 | lj_assertJ(baseslot < topslot, "bad CAT arg"); | 2101 | lj_assertJ(baseslot < topslot, "bad CAT arg"); |
| 2085 | for (s = baseslot; s <= topslot; s++) | 2102 | for (s = baseslot; s <= topslot; s++) |
| 2086 | (void)getslot(J, s); /* Ensure all arguments have a reference. */ | 2103 | (void)getslot(J, s); /* Ensure all arguments have a reference. */ |
| @@ -2116,8 +2133,11 @@ static TRef rec_cat(jit_State *J, BCReg baseslot, BCReg topslot) | |||
| 2116 | ix.tab = top[-1]; | 2133 | ix.tab = top[-1]; |
| 2117 | ix.key = top[0]; | 2134 | ix.key = top[0]; |
| 2118 | memcpy(savetv, &J->L->base[topslot-1], sizeof(savetv)); /* Save slots. */ | 2135 | memcpy(savetv, &J->L->base[topslot-1], sizeof(savetv)); /* Save slots. */ |
| 2119 | rec_mm_arith(J, &ix, MM_concat); /* Call __concat metamethod. */ | 2136 | rcd.J = J; |
| 2137 | rcd.ix = &ix; | ||
| 2138 | errcode = lj_vm_cpcall(J->L, NULL, &rcd, rec_mm_concat_cp); | ||
| 2120 | memcpy(&J->L->base[topslot-1], savetv, sizeof(savetv)); /* Restore slots. */ | 2139 | memcpy(&J->L->base[topslot-1], savetv, sizeof(savetv)); /* Restore slots. */ |
| 2140 | if (errcode) return (TRef)(-errcode); | ||
| 2121 | return 0; /* No result yet. */ | 2141 | return 0; /* No result yet. */ |
| 2122 | } | 2142 | } |
| 2123 | 2143 | ||
| @@ -2440,6 +2460,8 @@ void lj_record_ins(jit_State *J) | |||
| 2440 | 2460 | ||
| 2441 | case BC_CAT: | 2461 | case BC_CAT: |
| 2442 | rc = rec_cat(J, rb, rc); | 2462 | rc = rec_cat(J, rb, rc); |
| 2463 | if (rc >= 0xffffff00) | ||
| 2464 | lj_err_throw(J->L, -(int32_t)rc); /* Propagate errors. */ | ||
| 2443 | break; | 2465 | break; |
| 2444 | 2466 | ||
| 2445 | /* -- Constant and move ops --------------------------------------------- */ | 2467 | /* -- Constant and move ops --------------------------------------------- */ |
