@@ -2080,25 +2080,19 @@ static TRef rec_tnew(jit_State *J, uint32_t ah)
20802080
20812081typedef struct RecCatDataCP {
20822082 jit_State * J ;
2083- RecordIndex * ix ;
2083+ BCReg baseslot , topslot ;
2084+ TRef tr ;
20842085} RecCatDataCP ;
20852086
20862087static TValue * rec_mm_concat_cp (lua_State * L , lua_CFunction dummy , void * ud )
20872088{
20882089 RecCatDataCP * rcd = (RecCatDataCP * )ud ;
2089- UNUSED (L ); UNUSED (dummy );
2090- rec_mm_arith (rcd -> J , rcd -> ix , MM_concat ); /* Call __concat metamethod. */
2091- return NULL ;
2092- }
2093-
2094- static TRef rec_cat (jit_State * J , BCReg baseslot , BCReg topslot )
2095- {
2090+ jit_State * J = rcd -> J ;
2091+ BCReg baseslot = rcd -> baseslot , topslot = rcd -> topslot ;
20962092 TRef * top = & J -> base [topslot ];
2097- TValue savetv [5 + LJ_FR2 ];
20982093 BCReg s ;
20992094 RecordIndex ix ;
2100- RecCatDataCP rcd ;
2101- int errcode ;
2095+ UNUSED (L ); UNUSED (dummy );
21022096 lj_assertJ (baseslot < topslot , "bad CAT arg" );
21032097 for (s = baseslot ; s <= topslot ; s ++ )
21042098 (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)
21202114 } while (trp <= top );
21212115 tr = emitir (IRTG (IR_BUFSTR , IRT_STR ), tr , hdr );
21222116 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+ }
21242121 /* Pass partial result. */
21252122 topslot = J -> maxslot -- ;
21262123 * xbase = tr ;
@@ -2133,13 +2130,31 @@ static TRef rec_cat(jit_State *J, BCReg baseslot, BCReg topslot)
21332130 copyTV (J -> L , & ix .tabv , & J -> L -> base [topslot - 1 ]);
21342131 ix .tab = top [-1 ];
21352132 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+
2138+ static 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 ;
21372145 rcd .J = J ;
2138- rcd .ix = & ix ;
2139- errcode = lj_vm_cpcall (J -> L , NULL , & rcd , rec_mm_concat_cp );
2140- memcpy (& J -> L -> base [topslot - 1 ], savetv , sizeof (savetv )); /* Restore slots. */
2141- if (errcode ) return (TRef )(- errcode );
2142- return 0 ; /* No result yet. */
2146+ rcd .baseslot = baseslot ;
2147+ rcd .topslot = topslot ;
2148+ memcpy (savetv , & L -> base [topslot - 1 ], sizeof (savetv )); /* Save slots. */
2149+ errcode = lj_vm_cpcall (L , NULL , & rcd , rec_mm_concat_cp );
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 ;
21432158}
21442159
21452160/* -- Record bytecode ops ------------------------------------------------- */
0 commit comments