diff options
Diffstat (limited to '')
-rw-r--r-- | src/lj_crecord.c | 30 |
1 files changed, 20 insertions, 10 deletions
diff --git a/src/lj_crecord.c b/src/lj_crecord.c index c0f7e3d7..d568b20a 100644 --- a/src/lj_crecord.c +++ b/src/lj_crecord.c | |||
@@ -712,6 +712,19 @@ static TRef crec_reassoc_ofs(jit_State *J, TRef tr, ptrdiff_t *ofsp, MSize sz) | |||
712 | return tr; | 712 | return tr; |
713 | } | 713 | } |
714 | 714 | ||
715 | /* Tailcall to function. */ | ||
716 | static void crec_tailcall(jit_State *J, RecordFFData *rd, cTValue *tv) | ||
717 | { | ||
718 | TRef kfunc = lj_ir_kfunc(J, funcV(tv)); | ||
719 | #if LJ_FR2 | ||
720 | J->base[-2] = kfunc; | ||
721 | J->base[-1] = TREF_FRAME; | ||
722 | #else | ||
723 | J->base[-1] = kfunc | TREF_FRAME; | ||
724 | #endif | ||
725 | rd->nres = -1; /* Pending tailcall. */ | ||
726 | } | ||
727 | |||
715 | /* Record ctype __index/__newindex metamethods. */ | 728 | /* Record ctype __index/__newindex metamethods. */ |
716 | static void crec_index_meta(jit_State *J, CTState *cts, CType *ct, | 729 | static void crec_index_meta(jit_State *J, CTState *cts, CType *ct, |
717 | RecordFFData *rd) | 730 | RecordFFData *rd) |
@@ -721,8 +734,7 @@ static void crec_index_meta(jit_State *J, CTState *cts, CType *ct, | |||
721 | if (!tv) | 734 | if (!tv) |
722 | lj_trace_err(J, LJ_TRERR_BADTYPE); | 735 | lj_trace_err(J, LJ_TRERR_BADTYPE); |
723 | if (tvisfunc(tv)) { | 736 | if (tvisfunc(tv)) { |
724 | J->base[-1] = lj_ir_kfunc(J, funcV(tv)) | TREF_FRAME; | 737 | crec_tailcall(J, rd, tv); |
725 | rd->nres = -1; /* Pending tailcall. */ | ||
726 | } else if (rd->data == 0 && tvistab(tv) && tref_isstr(J->base[1])) { | 738 | } else if (rd->data == 0 && tvistab(tv) && tref_isstr(J->base[1])) { |
727 | /* Specialize to result of __index lookup. */ | 739 | /* Specialize to result of __index lookup. */ |
728 | cTValue *o = lj_tab_get(J->L, tabV(tv), &rd->argv[1]); | 740 | cTValue *o = lj_tab_get(J->L, tabV(tv), &rd->argv[1]); |
@@ -1119,20 +1131,20 @@ static void crec_snap_caller(jit_State *J) | |||
1119 | lua_State *L = J->L; | 1131 | lua_State *L = J->L; |
1120 | TValue *base = L->base, *top = L->top; | 1132 | TValue *base = L->base, *top = L->top; |
1121 | const BCIns *pc = J->pc; | 1133 | const BCIns *pc = J->pc; |
1122 | TRef ftr = J->base[-1]; | 1134 | TRef ftr = J->base[-1-LJ_FR2]; |
1123 | ptrdiff_t delta; | 1135 | ptrdiff_t delta; |
1124 | if (!frame_islua(base-1) || J->framedepth <= 0) | 1136 | if (!frame_islua(base-1) || J->framedepth <= 0) |
1125 | lj_trace_err(J, LJ_TRERR_NYICALL); | 1137 | lj_trace_err(J, LJ_TRERR_NYICALL); |
1126 | J->pc = frame_pc(base-1); delta = 1+LJ_FR2+bc_a(J->pc[-1]); | 1138 | J->pc = frame_pc(base-1); delta = 1+LJ_FR2+bc_a(J->pc[-1]); |
1127 | L->top = base; L->base = base - delta; | 1139 | L->top = base; L->base = base - delta; |
1128 | J->base[-1] = TREF_FALSE; | 1140 | J->base[-1-LJ_FR2] = TREF_FALSE; |
1129 | J->base -= delta; J->baseslot -= (BCReg)delta; | 1141 | J->base -= delta; J->baseslot -= (BCReg)delta; |
1130 | J->maxslot = (BCReg)delta; J->framedepth--; | 1142 | J->maxslot = (BCReg)delta-LJ_FR2; J->framedepth--; |
1131 | lj_snap_add(J); | 1143 | lj_snap_add(J); |
1132 | L->base = base; L->top = top; | 1144 | L->base = base; L->top = top; |
1133 | J->framedepth++; J->maxslot = 1; | 1145 | J->framedepth++; J->maxslot = 1; |
1134 | J->base += delta; J->baseslot += (BCReg)delta; | 1146 | J->base += delta; J->baseslot += (BCReg)delta; |
1135 | J->base[-1] = ftr; J->pc = pc; | 1147 | J->base[-1-LJ_FR2] = ftr; J->pc = pc; |
1136 | } | 1148 | } |
1137 | 1149 | ||
1138 | /* Record function call. */ | 1150 | /* Record function call. */ |
@@ -1224,8 +1236,7 @@ void LJ_FASTCALL recff_cdata_call(jit_State *J, RecordFFData *rd) | |||
1224 | tv = lj_ctype_meta(cts, ctype_isptr(ct->info) ? ctype_cid(ct->info) : id, mm); | 1236 | tv = lj_ctype_meta(cts, ctype_isptr(ct->info) ? ctype_cid(ct->info) : id, mm); |
1225 | if (tv) { | 1237 | if (tv) { |
1226 | if (tvisfunc(tv)) { | 1238 | if (tvisfunc(tv)) { |
1227 | J->base[-1] = lj_ir_kfunc(J, funcV(tv)) | TREF_FRAME; | 1239 | crec_tailcall(J, rd, tv); |
1228 | rd->nres = -1; /* Pending tailcall. */ | ||
1229 | return; | 1240 | return; |
1230 | } | 1241 | } |
1231 | } else if (mm == MM_new) { | 1242 | } else if (mm == MM_new) { |
@@ -1373,8 +1384,7 @@ static TRef crec_arith_meta(jit_State *J, TRef *sp, CType **s, CTState *cts, | |||
1373 | } | 1384 | } |
1374 | if (tv) { | 1385 | if (tv) { |
1375 | if (tvisfunc(tv)) { | 1386 | if (tvisfunc(tv)) { |
1376 | J->base[-1] = lj_ir_kfunc(J, funcV(tv)) | TREF_FRAME; | 1387 | crec_tailcall(J, rd, tv); |
1377 | rd->nres = -1; /* Pending tailcall. */ | ||
1378 | return 0; | 1388 | return 0; |
1379 | } /* NYI: non-function metamethods. */ | 1389 | } /* NYI: non-function metamethods. */ |
1380 | } else if ((MMS)rd->data == MM_eq) { /* Fallback cdata pointer comparison. */ | 1390 | } else if ((MMS)rd->data == MM_eq) { /* Fallback cdata pointer comparison. */ |