aboutsummaryrefslogtreecommitdiff
path: root/src/lj_crecord.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lj_crecord.c30
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. */
716static 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. */
716static void crec_index_meta(jit_State *J, CTState *cts, CType *ct, 729static 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. */