aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lj_asm_x86.h3
-rw-r--r--src/lj_bc.h5
-rw-r--r--src/lj_ccall.c19
-rw-r--r--src/lj_crecord.c32
-rw-r--r--src/lj_debug.c1
-rw-r--r--src/lj_load.c3
-rw-r--r--src/lj_parse.c14
-rw-r--r--src/lj_record.c3
-rw-r--r--src/lj_snap.c6
9 files changed, 48 insertions, 38 deletions
diff --git a/src/lj_asm_x86.h b/src/lj_asm_x86.h
index 239066d4..8b6ce479 100644
--- a/src/lj_asm_x86.h
+++ b/src/lj_asm_x86.h
@@ -1841,7 +1841,8 @@ static void asm_intarith(ASMState *as, IRIns *ir, x86Arith xa)
1841 RegSet allow = RSET_GPR; 1841 RegSet allow = RSET_GPR;
1842 Reg dest, right; 1842 Reg dest, right;
1843 int32_t k = 0; 1843 int32_t k = 0;
1844 if (as->flagmcp == as->mcp) { /* Drop test r,r instruction. */ 1844 if (as->flagmcp == as->mcp && xa != XOg_X_IMUL) {
1845 /* Drop test r,r instruction. */
1845 MCode *p = as->mcp + ((LJ_64 && *as->mcp < XI_TESTb) ? 3 : 2); 1846 MCode *p = as->mcp + ((LJ_64 && *as->mcp < XI_TESTb) ? 3 : 2);
1846 MCode *q = p[0] == 0x0f ? p+1 : p; 1847 MCode *q = p[0] == 0x0f ? p+1 : p;
1847 if ((*q & 15) < 14) { 1848 if ((*q & 15) < 14) {
diff --git a/src/lj_bc.h b/src/lj_bc.h
index 3f0563e4..0c7249b3 100644
--- a/src/lj_bc.h
+++ b/src/lj_bc.h
@@ -255,6 +255,11 @@ static LJ_AINLINE int bc_isret(BCOp op)
255 return (op == BC_RETM || op == BC_RET || op == BC_RET0 || op == BC_RET1); 255 return (op == BC_RETM || op == BC_RET || op == BC_RET0 || op == BC_RET1);
256} 256}
257 257
258static LJ_AINLINE int bc_isret_or_tail(BCOp op)
259{
260 return (op == BC_CALLMT || op == BC_CALLT || bc_isret(op));
261}
262
258LJ_DATA const uint16_t lj_bc_mode[]; 263LJ_DATA const uint16_t lj_bc_mode[];
259LJ_DATA const uint16_t lj_bc_ofs[]; 264LJ_DATA const uint16_t lj_bc_ofs[];
260 265
diff --git a/src/lj_ccall.c b/src/lj_ccall.c
index 9c99bec7..5d6bb03d 100644
--- a/src/lj_ccall.c
+++ b/src/lj_ccall.c
@@ -623,7 +623,9 @@ noth: /* Not a homogeneous float/double aggregate. */
623 623
624/* -- Common C call handling ---------------------------------------------- */ 624/* -- Common C call handling ---------------------------------------------- */
625 625
626/* Infer the destination CTypeID for a vararg argument. */ 626/* Infer the destination CTypeID for a vararg argument.
627** Note: may reallocate cts->tab and invalidate CType pointers.
628*/
627CTypeID lj_ccall_ctid_vararg(CTState *cts, cTValue *o) 629CTypeID lj_ccall_ctid_vararg(CTState *cts, cTValue *o)
628{ 630{
629 if (tvisnumber(o)) { 631 if (tvisnumber(o)) {
@@ -651,13 +653,16 @@ CTypeID lj_ccall_ctid_vararg(CTState *cts, cTValue *o)
651 } 653 }
652} 654}
653 655
654/* Setup arguments for C call. */ 656/* Setup arguments for C call.
657** Note: may reallocate cts->tab and invalidate CType pointers.
658*/
655static int ccall_set_args(lua_State *L, CTState *cts, CType *ct, 659static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
656 CCallState *cc) 660 CCallState *cc)
657{ 661{
658 int gcsteps = 0; 662 int gcsteps = 0;
659 TValue *o, *top = L->top; 663 TValue *o, *top = L->top;
660 CTypeID fid; 664 CTypeID fid;
665 CTInfo info = ct->info; /* lj_ccall_ctid_vararg may invalidate ct pointer. */
661 CType *ctr; 666 CType *ctr;
662 MSize maxgpr, ngpr = 0, nsp = 0, narg; 667 MSize maxgpr, ngpr = 0, nsp = 0, narg;
663#if CCALL_NARG_FPR 668#if CCALL_NARG_FPR
@@ -676,7 +681,7 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
676#if LJ_TARGET_X86 681#if LJ_TARGET_X86
677 /* x86 has several different calling conventions. */ 682 /* x86 has several different calling conventions. */
678 cc->resx87 = 0; 683 cc->resx87 = 0;
679 switch (ctype_cconv(ct->info)) { 684 switch (ctype_cconv(info)) {
680 case CTCC_FASTCALL: maxgpr = 2; break; 685 case CTCC_FASTCALL: maxgpr = 2; break;
681 case CTCC_THISCALL: maxgpr = 1; break; 686 case CTCC_THISCALL: maxgpr = 1; break;
682 default: maxgpr = 0; break; 687 default: maxgpr = 0; break;
@@ -693,7 +698,7 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
693 } else if (ctype_iscomplex(ctr->info) || ctype_isstruct(ctr->info)) { 698 } else if (ctype_iscomplex(ctr->info) || ctype_isstruct(ctr->info)) {
694 /* Preallocate cdata object and anchor it after arguments. */ 699 /* Preallocate cdata object and anchor it after arguments. */
695 CTSize sz = ctr->size; 700 CTSize sz = ctr->size;
696 GCcdata *cd = lj_cdata_new(cts, ctype_cid(ct->info), sz); 701 GCcdata *cd = lj_cdata_new(cts, ctype_cid(info), sz);
697 void *dp = cdataptr(cd); 702 void *dp = cdataptr(cd);
698 setcdataV(L, L->top++, cd); 703 setcdataV(L, L->top++, cd);
699 if (ctype_isstruct(ctr->info)) { 704 if (ctype_isstruct(ctr->info)) {
@@ -729,7 +734,7 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
729 lua_assert(ctype_isfield(ctf->info)); 734 lua_assert(ctype_isfield(ctf->info));
730 did = ctype_cid(ctf->info); 735 did = ctype_cid(ctf->info);
731 } else { 736 } else {
732 if (!(ct->info & CTF_VARARG)) 737 if (!(info & CTF_VARARG))
733 lj_err_caller(L, LJ_ERR_FFI_NUMARG); /* Too many arguments. */ 738 lj_err_caller(L, LJ_ERR_FFI_NUMARG); /* Too many arguments. */
734 did = lj_ccall_ctid_vararg(cts, o); /* Infer vararg type. */ 739 did = lj_ccall_ctid_vararg(cts, o); /* Infer vararg type. */
735 isva = 1; 740 isva = 1;
@@ -869,11 +874,11 @@ int lj_ccall_func(lua_State *L, GCcdata *cd)
869 ct = ctype_rawchild(cts, ct); 874 ct = ctype_rawchild(cts, ct);
870 } 875 }
871 if (ctype_isfunc(ct->info)) { 876 if (ctype_isfunc(ct->info)) {
877 CTypeID id = ctype_typeid(cts, ct);
872 CCallState cc; 878 CCallState cc;
873 int gcsteps, ret; 879 int gcsteps, ret;
874 cc.func = (void (*)(void))cdata_getptr(cdataptr(cd), sz); 880 cc.func = (void (*)(void))cdata_getptr(cdataptr(cd), sz);
875 gcsteps = ccall_set_args(L, cts, ct, &cc); 881 gcsteps = ccall_set_args(L, cts, ct, &cc);
876 ct = (CType *)((intptr_t)ct-(intptr_t)cts->tab);
877 cts->cb.slot = ~0u; 882 cts->cb.slot = ~0u;
878 lj_vm_ffi_call(&cc); 883 lj_vm_ffi_call(&cc);
879 if (cts->cb.slot != ~0u) { /* Blacklist function that called a callback. */ 884 if (cts->cb.slot != ~0u) { /* Blacklist function that called a callback. */
@@ -881,7 +886,7 @@ int lj_ccall_func(lua_State *L, GCcdata *cd)
881 setlightudV(&tv, (void *)cc.func); 886 setlightudV(&tv, (void *)cc.func);
882 setboolV(lj_tab_set(L, cts->miscmap, &tv), 1); 887 setboolV(lj_tab_set(L, cts->miscmap, &tv), 1);
883 } 888 }
884 ct = (CType *)((intptr_t)ct+(intptr_t)cts->tab); /* May be reallocated. */ 889 ct = ctype_get(cts, id); /* Table may have been reallocated. */
885 gcsteps += ccall_get_results(L, cts, ct, &cc, &ret); 890 gcsteps += ccall_get_results(L, cts, ct, &cc, &ret);
886#if LJ_TARGET_X86 && LJ_ABI_WIN 891#if LJ_TARGET_X86 && LJ_ABI_WIN
887 /* Automatically detect __stdcall and fix up C function declaration. */ 892 /* Automatically detect __stdcall and fix up C function declaration. */
diff --git a/src/lj_crecord.c b/src/lj_crecord.c
index 216144f3..80e25ef8 100644
--- a/src/lj_crecord.c
+++ b/src/lj_crecord.c
@@ -988,12 +988,15 @@ static void crec_alloc(jit_State *J, RecordFFData *rd, CTypeID id)
988 } 988 }
989} 989}
990 990
991/* Record argument conversions. */ 991/* Record argument conversions.
992** Note: may reallocate cts->tab and invalidate CType pointers.
993*/
992static TRef crec_call_args(jit_State *J, RecordFFData *rd, 994static TRef crec_call_args(jit_State *J, RecordFFData *rd,
993 CTState *cts, CType *ct) 995 CTState *cts, CType *ct)
994{ 996{
995 TRef args[CCI_NARGS_MAX]; 997 TRef args[CCI_NARGS_MAX];
996 CTypeID fid; 998 CTypeID fid;
999 CTInfo info = ct->info; /* lj_ccall_ctid_vararg may invalidate ct pointer. */
997 MSize i, n; 1000 MSize i, n;
998 TRef tr, *base; 1001 TRef tr, *base;
999 cTValue *o; 1002 cTValue *o;
@@ -1002,9 +1005,9 @@ static TRef crec_call_args(jit_State *J, RecordFFData *rd,
1002 TRef *arg0 = NULL, *arg1 = NULL; 1005 TRef *arg0 = NULL, *arg1 = NULL;
1003#endif 1006#endif
1004 int ngpr = 0; 1007 int ngpr = 0;
1005 if (ctype_cconv(ct->info) == CTCC_THISCALL) 1008 if (ctype_cconv(info) == CTCC_THISCALL)
1006 ngpr = 1; 1009 ngpr = 1;
1007 else if (ctype_cconv(ct->info) == CTCC_FASTCALL) 1010 else if (ctype_cconv(info) == CTCC_FASTCALL)
1008 ngpr = 2; 1011 ngpr = 2;
1009#endif 1012#endif
1010 1013
@@ -1029,7 +1032,7 @@ static TRef crec_call_args(jit_State *J, RecordFFData *rd,
1029 lua_assert(ctype_isfield(ctf->info)); 1032 lua_assert(ctype_isfield(ctf->info));
1030 did = ctype_cid(ctf->info); 1033 did = ctype_cid(ctf->info);
1031 } else { 1034 } else {
1032 if (!(ct->info & CTF_VARARG)) 1035 if (!(info & CTF_VARARG))
1033 lj_trace_err(J, LJ_TRERR_NYICALL); /* Too many arguments. */ 1036 lj_trace_err(J, LJ_TRERR_NYICALL); /* Too many arguments. */
1034 did = lj_ccall_ctid_vararg(cts, o); /* Infer vararg type. */ 1037 did = lj_ccall_ctid_vararg(cts, o); /* Infer vararg type. */
1035 } 1038 }
@@ -1112,14 +1115,17 @@ static int crec_call(jit_State *J, RecordFFData *rd, GCcdata *cd)
1112{ 1115{
1113 CTState *cts = ctype_ctsG(J2G(J)); 1116 CTState *cts = ctype_ctsG(J2G(J));
1114 CType *ct = ctype_raw(cts, cd->ctypeid); 1117 CType *ct = ctype_raw(cts, cd->ctypeid);
1118 CTInfo info;
1115 IRType tp = IRT_PTR; 1119 IRType tp = IRT_PTR;
1116 if (ctype_isptr(ct->info)) { 1120 if (ctype_isptr(ct->info)) {
1117 tp = (LJ_64 && ct->size == 8) ? IRT_P64 : IRT_P32; 1121 tp = (LJ_64 && ct->size == 8) ? IRT_P64 : IRT_P32;
1118 ct = ctype_rawchild(cts, ct); 1122 ct = ctype_rawchild(cts, ct);
1119 } 1123 }
1120 if (ctype_isfunc(ct->info)) { 1124 info = ct->info; /* crec_call_args may invalidate ct pointer. */
1125 if (ctype_isfunc(info)) {
1121 TRef func = emitir(IRT(IR_FLOAD, tp), J->base[0], IRFL_CDATA_PTR); 1126 TRef func = emitir(IRT(IR_FLOAD, tp), J->base[0], IRFL_CDATA_PTR);
1122 CType *ctr = ctype_rawchild(cts, ct); 1127 CType *ctr = ctype_rawchild(cts, ct);
1128 CTInfo ctr_info = ctr->info; /* crec_call_args may invalidate ctr. */
1123 IRType t = crec_ct2irt(cts, ctr); 1129 IRType t = crec_ct2irt(cts, ctr);
1124 TRef tr; 1130 TRef tr;
1125 TValue tv; 1131 TValue tv;
@@ -1128,22 +1134,22 @@ static int crec_call(jit_State *J, RecordFFData *rd, GCcdata *cd)
1128 cdata_getptr(cdataptr(cd), (LJ_64 && tp == IRT_P64) ? 8 : 4)); 1134 cdata_getptr(cdataptr(cd), (LJ_64 && tp == IRT_P64) ? 8 : 4));
1129 if (tvistrue(lj_tab_get(J->L, cts->miscmap, &tv))) 1135 if (tvistrue(lj_tab_get(J->L, cts->miscmap, &tv)))
1130 lj_trace_err(J, LJ_TRERR_BLACKL); 1136 lj_trace_err(J, LJ_TRERR_BLACKL);
1131 if (ctype_isvoid(ctr->info)) { 1137 if (ctype_isvoid(ctr_info)) {
1132 t = IRT_NIL; 1138 t = IRT_NIL;
1133 rd->nres = 0; 1139 rd->nres = 0;
1134 } else if (!(ctype_isnum(ctr->info) || ctype_isptr(ctr->info) || 1140 } else if (!(ctype_isnum(ctr_info) || ctype_isptr(ctr_info) ||
1135 ctype_isenum(ctr->info)) || t == IRT_CDATA) { 1141 ctype_isenum(ctr_info)) || t == IRT_CDATA) {
1136 lj_trace_err(J, LJ_TRERR_NYICALL); 1142 lj_trace_err(J, LJ_TRERR_NYICALL);
1137 } 1143 }
1138 if ((ct->info & CTF_VARARG) 1144 if ((info & CTF_VARARG)
1139#if LJ_TARGET_X86 1145#if LJ_TARGET_X86
1140 || ctype_cconv(ct->info) != CTCC_CDECL 1146 || ctype_cconv(info) != CTCC_CDECL
1141#endif 1147#endif
1142 ) 1148 )
1143 func = emitir(IRT(IR_CARG, IRT_NIL), func, 1149 func = emitir(IRT(IR_CARG, IRT_NIL), func,
1144 lj_ir_kint(J, ctype_typeid(cts, ct))); 1150 lj_ir_kint(J, ctype_typeid(cts, ct)));
1145 tr = emitir(IRT(IR_CALLXS, t), crec_call_args(J, rd, cts, ct), func); 1151 tr = emitir(IRT(IR_CALLXS, t), crec_call_args(J, rd, cts, ct), func);
1146 if (ctype_isbool(ctr->info)) { 1152 if (ctype_isbool(ctr_info)) {
1147 if (frame_islua(J->L->base-1) && bc_b(frame_pc(J->L->base-1)[-1]) == 1) { 1153 if (frame_islua(J->L->base-1) && bc_b(frame_pc(J->L->base-1)[-1]) == 1) {
1148 /* Don't check result if ignored. */ 1154 /* Don't check result if ignored. */
1149 tr = TREF_NIL; 1155 tr = TREF_NIL;
@@ -1159,8 +1165,8 @@ static int crec_call(jit_State *J, RecordFFData *rd, GCcdata *cd)
1159 tr = TREF_TRUE; 1165 tr = TREF_TRUE;
1160 } 1166 }
1161 } else if (t == IRT_PTR || (LJ_64 && t == IRT_P32) || 1167 } else if (t == IRT_PTR || (LJ_64 && t == IRT_P32) ||
1162 t == IRT_I64 || t == IRT_U64 || ctype_isenum(ctr->info)) { 1168 t == IRT_I64 || t == IRT_U64 || ctype_isenum(ctr_info)) {
1163 TRef trid = lj_ir_kint(J, ctype_cid(ct->info)); 1169 TRef trid = lj_ir_kint(J, ctype_cid(info));
1164 tr = emitir(IRTG(IR_CNEWI, IRT_CDATA), trid, tr); 1170 tr = emitir(IRTG(IR_CNEWI, IRT_CDATA), trid, tr);
1165 if (t == IRT_I64 || t == IRT_U64) lj_needsplit(J); 1171 if (t == IRT_I64 || t == IRT_U64) lj_needsplit(J);
1166 } else if (t == IRT_FLOAT || t == IRT_U32) { 1172 } else if (t == IRT_FLOAT || t == IRT_U32) {
diff --git a/src/lj_debug.c b/src/lj_debug.c
index a639cddf..f3409649 100644
--- a/src/lj_debug.c
+++ b/src/lj_debug.c
@@ -101,6 +101,7 @@ static BCPos debug_framepc(lua_State *L, GCfunc *fn, cTValue *nextframe)
101 pt = funcproto(fn); 101 pt = funcproto(fn);
102 pos = proto_bcpos(pt, ins) - 1; 102 pos = proto_bcpos(pt, ins) - 1;
103#if LJ_HASJIT 103#if LJ_HASJIT
104 if (pos == NO_BCPOS) return 1; /* Pretend it's the first bytecode. */
104 if (pos > pt->sizebc) { /* Undo the effects of lj_trace_exit for JLOOP. */ 105 if (pos > pt->sizebc) { /* Undo the effects of lj_trace_exit for JLOOP. */
105 if (bc_isret(bc_op(ins[-1]))) { 106 if (bc_isret(bc_op(ins[-1]))) {
106 GCtrace *T = (GCtrace *)((char *)(ins-1) - offsetof(GCtrace, startins)); 107 GCtrace *T = (GCtrace *)((char *)(ins-1) - offsetof(GCtrace, startins));
diff --git a/src/lj_load.c b/src/lj_load.c
index 90a61027..6c8ae9f1 100644
--- a/src/lj_load.c
+++ b/src/lj_load.c
@@ -108,8 +108,9 @@ LUALIB_API int luaL_loadfilex(lua_State *L, const char *filename,
108 copyTV(L, L->top-1, L->top); 108 copyTV(L, L->top-1, L->top);
109 } 109 }
110 if (err) { 110 if (err) {
111 const char *fname = filename ? filename : "stdin";
111 L->top--; 112 L->top--;
112 lua_pushfstring(L, "cannot read %s: %s", chunkname+1, strerror(err)); 113 lua_pushfstring(L, "cannot read %s: %s", fname, strerror(err));
113 return LUA_ERRFILE; 114 return LUA_ERRFILE;
114 } 115 }
115 return status; 116 return status;
diff --git a/src/lj_parse.c b/src/lj_parse.c
index ffd11b3b..3370296f 100644
--- a/src/lj_parse.c
+++ b/src/lj_parse.c
@@ -1529,23 +1529,11 @@ static void fs_fixup_var(LexState *ls, GCproto *pt, uint8_t *p, size_t ofsvar)
1529 1529
1530#endif 1530#endif
1531 1531
1532/* Check if bytecode op returns. */
1533static int bcopisret(BCOp op)
1534{
1535 switch (op) {
1536 case BC_CALLMT: case BC_CALLT:
1537 case BC_RETM: case BC_RET: case BC_RET0: case BC_RET1:
1538 return 1;
1539 default:
1540 return 0;
1541 }
1542}
1543
1544/* Fixup return instruction for prototype. */ 1532/* Fixup return instruction for prototype. */
1545static void fs_fixup_ret(FuncState *fs) 1533static void fs_fixup_ret(FuncState *fs)
1546{ 1534{
1547 BCPos lastpc = fs->pc; 1535 BCPos lastpc = fs->pc;
1548 if (lastpc <= fs->lasttarget || !bcopisret(bc_op(fs->bcbase[lastpc-1].ins))) { 1536 if (lastpc <= fs->lasttarget || !bc_isret_or_tail(bc_op(fs->bcbase[lastpc-1].ins))) {
1549 if ((fs->bl->flags & FSCOPE_UPVAL)) 1537 if ((fs->bl->flags & FSCOPE_UPVAL))
1550 bcemit_AJ(fs, BC_UCLO, 0, 0); 1538 bcemit_AJ(fs, BC_UCLO, 0, 0);
1551 bcemit_AD(fs, BC_RET0, 0, 1); /* Need final return. */ 1539 bcemit_AD(fs, BC_RET0, 0, 1); /* Need final return. */
diff --git a/src/lj_record.c b/src/lj_record.c
index d336f642..1d535a22 100644
--- a/src/lj_record.c
+++ b/src/lj_record.c
@@ -749,7 +749,8 @@ void lj_record_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults)
749 lj_trace_err(J, LJ_TRERR_LLEAVE); 749 lj_trace_err(J, LJ_TRERR_LLEAVE);
750 } else if (J->needsnap) { /* Tailcalled to ff with side-effects. */ 750 } else if (J->needsnap) { /* Tailcalled to ff with side-effects. */
751 lj_trace_err(J, LJ_TRERR_NYIRETL); /* No way to insert snapshot here. */ 751 lj_trace_err(J, LJ_TRERR_NYIRETL); /* No way to insert snapshot here. */
752 } else if (1 + pt->framesize >= LJ_MAX_JSLOTS) { 752 } else if (1 + pt->framesize >= LJ_MAX_JSLOTS ||
753 J->baseslot + J->maxslot >= LJ_MAX_JSLOTS) {
753 lj_trace_err(J, LJ_TRERR_STACKOV); 754 lj_trace_err(J, LJ_TRERR_STACKOV);
754 } else { /* Return to lower frame. Guard for the target we return to. */ 755 } else { /* Return to lower frame. Guard for the target we return to. */
755 TRef trpt = lj_ir_kgc(J, obj2gco(pt), IRT_PROTO); 756 TRef trpt = lj_ir_kgc(J, obj2gco(pt), IRT_PROTO);
diff --git a/src/lj_snap.c b/src/lj_snap.c
index 82ab6983..54260021 100644
--- a/src/lj_snap.c
+++ b/src/lj_snap.c
@@ -872,8 +872,10 @@ const BCIns *lj_snap_restore(jit_State *J, void *exptr)
872 const BCIns *pc = snap_pc(map[nent]); 872 const BCIns *pc = snap_pc(map[nent]);
873 lua_State *L = J->L; 873 lua_State *L = J->L;
874 874
875 /* Set interpreter PC to the next PC to get correct error messages. */ 875 /* Set interpreter PC to the next PC to get correct error messages.
876 setcframe_pc(L->cframe, pc+1); 876 ** But not for returns or tail calls, since pc+1 may be out-of-range.
877 */
878 setcframe_pc(L->cframe, bc_isret_or_tail(bc_op(*pc)) ? pc : pc+1);
877 setcframe_pc(cframe_raw(cframe_prev(L->cframe)), pc); 879 setcframe_pc(cframe_raw(cframe_prev(L->cframe)), pc);
878 880
879 /* Make sure the stack is big enough for the slots from the snapshot. */ 881 /* Make sure the stack is big enough for the slots from the snapshot. */