aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile3
-rw-r--r--src/lj_asm_x86.h3
-rw-r--r--src/lj_bc.h5
-rw-r--r--src/lj_ccall.c21
-rw-r--r--src/lj_crecord.c32
-rw-r--r--src/lj_debug.c1
-rw-r--r--src/lj_parse.c14
-rw-r--r--src/lj_record.c3
-rw-r--r--src/lj_snap.c6
-rw-r--r--src/msvcbuild.bat15
10 files changed, 60 insertions, 43 deletions
diff --git a/src/Makefile b/src/Makefile
index 4a56d1e8..c83abfa0 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -302,6 +302,9 @@ endif
302ifneq (,$(INSTALL_LJLIBD)) 302ifneq (,$(INSTALL_LJLIBD))
303 TARGET_XCFLAGS+= -DLUA_LJDIR=\"$(INSTALL_LJLIBD)\" 303 TARGET_XCFLAGS+= -DLUA_LJDIR=\"$(INSTALL_LJLIBD)\"
304endif 304endif
305ifeq (,$(shell $(TARGET_CC) -o /dev/null -c -x c /dev/null -fno-strict-float-cast-overflow 2>/dev/null || echo 1))
306 TARGET_XCFLAGS+= -fno-strict-float-cast-overflow
307endif
305 308
306############################################################################## 309##############################################################################
307# Target system detection. 310# Target system detection.
diff --git a/src/lj_asm_x86.h b/src/lj_asm_x86.h
index 936ff438..774e77b4 100644
--- a/src/lj_asm_x86.h
+++ b/src/lj_asm_x86.h
@@ -2084,7 +2084,8 @@ static void asm_intarith(ASMState *as, IRIns *ir, x86Arith xa)
2084 RegSet allow = RSET_GPR; 2084 RegSet allow = RSET_GPR;
2085 Reg dest, right; 2085 Reg dest, right;
2086 int32_t k = 0; 2086 int32_t k = 0;
2087 if (as->flagmcp == as->mcp) { /* Drop test r,r instruction. */ 2087 if (as->flagmcp == as->mcp && xa != XOg_X_IMUL) {
2088 /* Drop test r,r instruction. */
2088 MCode *p = as->mcp + ((LJ_64 && *as->mcp < XI_TESTb) ? 3 : 2); 2089 MCode *p = as->mcp + ((LJ_64 && *as->mcp < XI_TESTb) ? 3 : 2);
2089 MCode *q = p[0] == 0x0f ? p+1 : p; 2090 MCode *q = p[0] == 0x0f ? p+1 : p;
2090 if ((*q & 15) < 14) { 2091 if ((*q & 15) < 14) {
diff --git a/src/lj_bc.h b/src/lj_bc.h
index a94ea4e4..53b3e501 100644
--- a/src/lj_bc.h
+++ b/src/lj_bc.h
@@ -259,6 +259,11 @@ static LJ_AINLINE int bc_isret(BCOp op)
259 return (op == BC_RETM || op == BC_RET || op == BC_RET0 || op == BC_RET1); 259 return (op == BC_RETM || op == BC_RET || op == BC_RET0 || op == BC_RET1);
260} 260}
261 261
262static LJ_AINLINE int bc_isret_or_tail(BCOp op)
263{
264 return (op == BC_CALLMT || op == BC_CALLT || bc_isret(op));
265}
266
262LJ_DATA const uint16_t lj_bc_mode[]; 267LJ_DATA const uint16_t lj_bc_mode[];
263LJ_DATA const uint16_t lj_bc_ofs[]; 268LJ_DATA const uint16_t lj_bc_ofs[];
264 269
diff --git a/src/lj_ccall.c b/src/lj_ccall.c
index f003d756..d5f092ea 100644
--- a/src/lj_ccall.c
+++ b/src/lj_ccall.c
@@ -901,7 +901,9 @@ static void ccall_copy_struct(CCallState *cc, CType *ctr, void *dp, void *sp,
901 901
902/* -- Common C call handling ---------------------------------------------- */ 902/* -- Common C call handling ---------------------------------------------- */
903 903
904/* Infer the destination CTypeID for a vararg argument. */ 904/* Infer the destination CTypeID for a vararg argument.
905** Note: may reallocate cts->tab and invalidate CType pointers.
906*/
905CTypeID lj_ccall_ctid_vararg(CTState *cts, cTValue *o) 907CTypeID lj_ccall_ctid_vararg(CTState *cts, cTValue *o)
906{ 908{
907 if (tvisnumber(o)) { 909 if (tvisnumber(o)) {
@@ -929,13 +931,16 @@ CTypeID lj_ccall_ctid_vararg(CTState *cts, cTValue *o)
929 } 931 }
930} 932}
931 933
932/* Setup arguments for C call. */ 934/* Setup arguments for C call.
935** Note: may reallocate cts->tab and invalidate CType pointers.
936*/
933static int ccall_set_args(lua_State *L, CTState *cts, CType *ct, 937static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
934 CCallState *cc) 938 CCallState *cc)
935{ 939{
936 int gcsteps = 0; 940 int gcsteps = 0;
937 TValue *o, *top = L->top; 941 TValue *o, *top = L->top;
938 CTypeID fid; 942 CTypeID fid;
943 CTInfo info = ct->info; /* lj_ccall_ctid_vararg may invalidate ct pointer. */
939 CType *ctr; 944 CType *ctr;
940 MSize maxgpr, ngpr = 0, nsp = 0, narg; 945 MSize maxgpr, ngpr = 0, nsp = 0, narg;
941#if CCALL_NARG_FPR 946#if CCALL_NARG_FPR
@@ -954,7 +959,7 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
954#if LJ_TARGET_X86 959#if LJ_TARGET_X86
955 /* x86 has several different calling conventions. */ 960 /* x86 has several different calling conventions. */
956 cc->resx87 = 0; 961 cc->resx87 = 0;
957 switch (ctype_cconv(ct->info)) { 962 switch (ctype_cconv(info)) {
958 case CTCC_FASTCALL: maxgpr = 2; break; 963 case CTCC_FASTCALL: maxgpr = 2; break;
959 case CTCC_THISCALL: maxgpr = 1; break; 964 case CTCC_THISCALL: maxgpr = 1; break;
960 default: maxgpr = 0; break; 965 default: maxgpr = 0; break;
@@ -971,7 +976,7 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
971 } else if (ctype_iscomplex(ctr->info) || ctype_isstruct(ctr->info)) { 976 } else if (ctype_iscomplex(ctr->info) || ctype_isstruct(ctr->info)) {
972 /* Preallocate cdata object and anchor it after arguments. */ 977 /* Preallocate cdata object and anchor it after arguments. */
973 CTSize sz = ctr->size; 978 CTSize sz = ctr->size;
974 GCcdata *cd = lj_cdata_new(cts, ctype_cid(ct->info), sz); 979 GCcdata *cd = lj_cdata_new(cts, ctype_cid(info), sz);
975 void *dp = cdataptr(cd); 980 void *dp = cdataptr(cd);
976 setcdataV(L, L->top++, cd); 981 setcdataV(L, L->top++, cd);
977 if (ctype_isstruct(ctr->info)) { 982 if (ctype_isstruct(ctr->info)) {
@@ -994,7 +999,7 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
994 } 999 }
995 1000
996#if LJ_TARGET_ARM64 && LJ_ABI_WIN 1001#if LJ_TARGET_ARM64 && LJ_ABI_WIN
997 if ((ct->info & CTF_VARARG)) { 1002 if ((info & CTF_VARARG)) {
998 nsp -= maxgpr * CTSIZE_PTR; /* May end up with negative nsp. */ 1003 nsp -= maxgpr * CTSIZE_PTR; /* May end up with negative nsp. */
999 ngpr = maxgpr; 1004 ngpr = maxgpr;
1000 nfpr = CCALL_NARG_FPR; 1005 nfpr = CCALL_NARG_FPR;
@@ -1015,7 +1020,7 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
1015 lj_assertL(ctype_isfield(ctf->info), "field expected"); 1020 lj_assertL(ctype_isfield(ctf->info), "field expected");
1016 did = ctype_cid(ctf->info); 1021 did = ctype_cid(ctf->info);
1017 } else { 1022 } else {
1018 if (!(ct->info & CTF_VARARG)) 1023 if (!(info & CTF_VARARG))
1019 lj_err_caller(L, LJ_ERR_FFI_NUMARG); /* Too many arguments. */ 1024 lj_err_caller(L, LJ_ERR_FFI_NUMARG); /* Too many arguments. */
1020 did = lj_ccall_ctid_vararg(cts, o); /* Infer vararg type. */ 1025 did = lj_ccall_ctid_vararg(cts, o); /* Infer vararg type. */
1021 isva = 1; 1026 isva = 1;
@@ -1186,11 +1191,11 @@ int lj_ccall_func(lua_State *L, GCcdata *cd)
1186 ct = ctype_rawchild(cts, ct); 1191 ct = ctype_rawchild(cts, ct);
1187 } 1192 }
1188 if (ctype_isfunc(ct->info)) { 1193 if (ctype_isfunc(ct->info)) {
1194 CTypeID id = ctype_typeid(cts, ct);
1189 CCallState cc; 1195 CCallState cc;
1190 int gcsteps, ret; 1196 int gcsteps, ret;
1191 cc.func = (void (*)(void))cdata_getptr(cdataptr(cd), sz); 1197 cc.func = (void (*)(void))cdata_getptr(cdataptr(cd), sz);
1192 gcsteps = ccall_set_args(L, cts, ct, &cc); 1198 gcsteps = ccall_set_args(L, cts, ct, &cc);
1193 ct = (CType *)((intptr_t)ct-(intptr_t)cts->tab);
1194 cts->cb.slot = ~0u; 1199 cts->cb.slot = ~0u;
1195 lj_vm_ffi_call(&cc); 1200 lj_vm_ffi_call(&cc);
1196 if (cts->cb.slot != ~0u) { /* Blacklist function that called a callback. */ 1201 if (cts->cb.slot != ~0u) { /* Blacklist function that called a callback. */
@@ -1198,7 +1203,7 @@ int lj_ccall_func(lua_State *L, GCcdata *cd)
1198 tv.u64 = ((uintptr_t)(void *)cc.func >> 2) | U64x(800000000, 00000000); 1203 tv.u64 = ((uintptr_t)(void *)cc.func >> 2) | U64x(800000000, 00000000);
1199 setboolV(lj_tab_set(L, cts->miscmap, &tv), 1); 1204 setboolV(lj_tab_set(L, cts->miscmap, &tv), 1);
1200 } 1205 }
1201 ct = (CType *)((intptr_t)ct+(intptr_t)cts->tab); /* May be reallocated. */ 1206 ct = ctype_get(cts, id); /* Table may have been reallocated. */
1202 gcsteps += ccall_get_results(L, cts, ct, &cc, &ret); 1207 gcsteps += ccall_get_results(L, cts, ct, &cc, &ret);
1203#if LJ_TARGET_X86 && LJ_ABI_WIN 1208#if LJ_TARGET_X86 && LJ_ABI_WIN
1204 /* Automatically detect __stdcall and fix up C function declaration. */ 1209 /* Automatically detect __stdcall and fix up C function declaration. */
diff --git a/src/lj_crecord.c b/src/lj_crecord.c
index f88cddfd..27f2c1dd 100644
--- a/src/lj_crecord.c
+++ b/src/lj_crecord.c
@@ -1101,12 +1101,15 @@ static void crec_alloc(jit_State *J, RecordFFData *rd, CTypeID id)
1101 crec_finalizer(J, trcd, 0, fin); 1101 crec_finalizer(J, trcd, 0, fin);
1102} 1102}
1103 1103
1104/* Record argument conversions. */ 1104/* Record argument conversions.
1105** Note: may reallocate cts->tab and invalidate CType pointers.
1106*/
1105static TRef crec_call_args(jit_State *J, RecordFFData *rd, 1107static TRef crec_call_args(jit_State *J, RecordFFData *rd,
1106 CTState *cts, CType *ct) 1108 CTState *cts, CType *ct)
1107{ 1109{
1108 TRef args[CCI_NARGS_MAX]; 1110 TRef args[CCI_NARGS_MAX];
1109 CTypeID fid; 1111 CTypeID fid;
1112 CTInfo info = ct->info; /* lj_ccall_ctid_vararg may invalidate ct pointer. */
1110 MSize i, n; 1113 MSize i, n;
1111 TRef tr, *base; 1114 TRef tr, *base;
1112 cTValue *o; 1115 cTValue *o;
@@ -1115,9 +1118,9 @@ static TRef crec_call_args(jit_State *J, RecordFFData *rd,
1115 TRef *arg0 = NULL, *arg1 = NULL; 1118 TRef *arg0 = NULL, *arg1 = NULL;
1116#endif 1119#endif
1117 int ngpr = 0; 1120 int ngpr = 0;
1118 if (ctype_cconv(ct->info) == CTCC_THISCALL) 1121 if (ctype_cconv(info) == CTCC_THISCALL)
1119 ngpr = 1; 1122 ngpr = 1;
1120 else if (ctype_cconv(ct->info) == CTCC_FASTCALL) 1123 else if (ctype_cconv(info) == CTCC_FASTCALL)
1121 ngpr = 2; 1124 ngpr = 2;
1122#elif LJ_TARGET_ARM64 && LJ_TARGET_OSX 1125#elif LJ_TARGET_ARM64 && LJ_TARGET_OSX
1123 int ngpr = CCALL_NARG_GPR; 1126 int ngpr = CCALL_NARG_GPR;
@@ -1144,7 +1147,7 @@ static TRef crec_call_args(jit_State *J, RecordFFData *rd,
1144 lj_assertJ(ctype_isfield(ctf->info), "field expected"); 1147 lj_assertJ(ctype_isfield(ctf->info), "field expected");
1145 did = ctype_cid(ctf->info); 1148 did = ctype_cid(ctf->info);
1146 } else { 1149 } else {
1147 if (!(ct->info & CTF_VARARG)) 1150 if (!(info & CTF_VARARG))
1148 lj_trace_err(J, LJ_TRERR_NYICALL); /* Too many arguments. */ 1151 lj_trace_err(J, LJ_TRERR_NYICALL); /* Too many arguments. */
1149#if LJ_TARGET_ARM64 && LJ_TARGET_OSX 1152#if LJ_TARGET_ARM64 && LJ_TARGET_OSX
1150 if (ngpr >= 0) { 1153 if (ngpr >= 0) {
@@ -1248,14 +1251,17 @@ static int crec_call(jit_State *J, RecordFFData *rd, GCcdata *cd)
1248{ 1251{
1249 CTState *cts = ctype_ctsG(J2G(J)); 1252 CTState *cts = ctype_ctsG(J2G(J));
1250 CType *ct = ctype_raw(cts, cd->ctypeid); 1253 CType *ct = ctype_raw(cts, cd->ctypeid);
1254 CTInfo info;
1251 IRType tp = IRT_PTR; 1255 IRType tp = IRT_PTR;
1252 if (ctype_isptr(ct->info)) { 1256 if (ctype_isptr(ct->info)) {
1253 tp = (LJ_64 && ct->size == 8) ? IRT_P64 : IRT_P32; 1257 tp = (LJ_64 && ct->size == 8) ? IRT_P64 : IRT_P32;
1254 ct = ctype_rawchild(cts, ct); 1258 ct = ctype_rawchild(cts, ct);
1255 } 1259 }
1256 if (ctype_isfunc(ct->info)) { 1260 info = ct->info; /* crec_call_args may invalidate ct pointer. */
1261 if (ctype_isfunc(info)) {
1257 TRef func = emitir(IRT(IR_FLOAD, tp), J->base[0], IRFL_CDATA_PTR); 1262 TRef func = emitir(IRT(IR_FLOAD, tp), J->base[0], IRFL_CDATA_PTR);
1258 CType *ctr = ctype_rawchild(cts, ct); 1263 CType *ctr = ctype_rawchild(cts, ct);
1264 CTInfo ctr_info = ctr->info; /* crec_call_args may invalidate ctr. */
1259 IRType t = crec_ct2irt(cts, ctr); 1265 IRType t = crec_ct2irt(cts, ctr);
1260 TRef tr; 1266 TRef tr;
1261 TValue tv; 1267 TValue tv;
@@ -1263,22 +1269,22 @@ static int crec_call(jit_State *J, RecordFFData *rd, GCcdata *cd)
1263 tv.u64 = ((uintptr_t)cdata_getptr(cdataptr(cd), (LJ_64 && tp == IRT_P64) ? 8 : 4) >> 2) | U64x(800000000, 00000000); 1269 tv.u64 = ((uintptr_t)cdata_getptr(cdataptr(cd), (LJ_64 && tp == IRT_P64) ? 8 : 4) >> 2) | U64x(800000000, 00000000);
1264 if (tvistrue(lj_tab_get(J->L, cts->miscmap, &tv))) 1270 if (tvistrue(lj_tab_get(J->L, cts->miscmap, &tv)))
1265 lj_trace_err(J, LJ_TRERR_BLACKL); 1271 lj_trace_err(J, LJ_TRERR_BLACKL);
1266 if (ctype_isvoid(ctr->info)) { 1272 if (ctype_isvoid(ctr_info)) {
1267 t = IRT_NIL; 1273 t = IRT_NIL;
1268 rd->nres = 0; 1274 rd->nres = 0;
1269 } else if (!(ctype_isnum(ctr->info) || ctype_isptr(ctr->info) || 1275 } else if (!(ctype_isnum(ctr_info) || ctype_isptr(ctr_info) ||
1270 ctype_isenum(ctr->info)) || t == IRT_CDATA) { 1276 ctype_isenum(ctr_info)) || t == IRT_CDATA) {
1271 lj_trace_err(J, LJ_TRERR_NYICALL); 1277 lj_trace_err(J, LJ_TRERR_NYICALL);
1272 } 1278 }
1273 if ((ct->info & CTF_VARARG) 1279 if ((info & CTF_VARARG)
1274#if LJ_TARGET_X86 1280#if LJ_TARGET_X86
1275 || ctype_cconv(ct->info) != CTCC_CDECL 1281 || ctype_cconv(info) != CTCC_CDECL
1276#endif 1282#endif
1277 ) 1283 )
1278 func = emitir(IRT(IR_CARG, IRT_NIL), func, 1284 func = emitir(IRT(IR_CARG, IRT_NIL), func,
1279 lj_ir_kint(J, ctype_typeid(cts, ct))); 1285 lj_ir_kint(J, ctype_typeid(cts, ct)));
1280 tr = emitir(IRT(IR_CALLXS, t), crec_call_args(J, rd, cts, ct), func); 1286 tr = emitir(IRT(IR_CALLXS, t), crec_call_args(J, rd, cts, ct), func);
1281 if (ctype_isbool(ctr->info)) { 1287 if (ctype_isbool(ctr_info)) {
1282 if (frame_islua(J->L->base-1) && bc_b(frame_pc(J->L->base-1)[-1]) == 1) { 1288 if (frame_islua(J->L->base-1) && bc_b(frame_pc(J->L->base-1)[-1]) == 1) {
1283 /* Don't check result if ignored. */ 1289 /* Don't check result if ignored. */
1284 tr = TREF_NIL; 1290 tr = TREF_NIL;
@@ -1294,8 +1300,8 @@ static int crec_call(jit_State *J, RecordFFData *rd, GCcdata *cd)
1294 tr = TREF_TRUE; 1300 tr = TREF_TRUE;
1295 } 1301 }
1296 } else if (t == IRT_PTR || (LJ_64 && t == IRT_P32) || 1302 } else if (t == IRT_PTR || (LJ_64 && t == IRT_P32) ||
1297 t == IRT_I64 || t == IRT_U64 || ctype_isenum(ctr->info)) { 1303 t == IRT_I64 || t == IRT_U64 || ctype_isenum(ctr_info)) {
1298 TRef trid = lj_ir_kint(J, ctype_cid(ct->info)); 1304 TRef trid = lj_ir_kint(J, ctype_cid(info));
1299 tr = emitir(IRTG(IR_CNEWI, IRT_CDATA), trid, tr); 1305 tr = emitir(IRTG(IR_CNEWI, IRT_CDATA), trid, tr);
1300 if (t == IRT_I64 || t == IRT_U64) lj_needsplit(J); 1306 if (t == IRT_I64 || t == IRT_U64) lj_needsplit(J);
1301 } else if (t == IRT_FLOAT || t == IRT_U32) { 1307 } else if (t == IRT_FLOAT || t == IRT_U32) {
diff --git a/src/lj_debug.c b/src/lj_debug.c
index b3d52afc..f9392d8e 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_parse.c b/src/lj_parse.c
index f4116380..e326432a 100644
--- a/src/lj_parse.c
+++ b/src/lj_parse.c
@@ -1517,23 +1517,11 @@ static void fs_fixup_var(LexState *ls, GCproto *pt, uint8_t *p, size_t ofsvar)
1517 1517
1518#endif 1518#endif
1519 1519
1520/* Check if bytecode op returns. */
1521static int bcopisret(BCOp op)
1522{
1523 switch (op) {
1524 case BC_CALLMT: case BC_CALLT:
1525 case BC_RETM: case BC_RET: case BC_RET0: case BC_RET1:
1526 return 1;
1527 default:
1528 return 0;
1529 }
1530}
1531
1532/* Fixup return instruction for prototype. */ 1520/* Fixup return instruction for prototype. */
1533static void fs_fixup_ret(FuncState *fs) 1521static void fs_fixup_ret(FuncState *fs)
1534{ 1522{
1535 BCPos lastpc = fs->pc; 1523 BCPos lastpc = fs->pc;
1536 if (lastpc <= fs->lasttarget || !bcopisret(bc_op(fs->bcbase[lastpc-1].ins))) { 1524 if (lastpc <= fs->lasttarget || !bc_isret_or_tail(bc_op(fs->bcbase[lastpc-1].ins))) {
1537 if ((fs->bl->flags & FSCOPE_UPVAL)) 1525 if ((fs->bl->flags & FSCOPE_UPVAL))
1538 bcemit_AJ(fs, BC_UCLO, 0, 0); 1526 bcemit_AJ(fs, BC_UCLO, 0, 0);
1539 bcemit_AD(fs, BC_RET0, 0, 1); /* Need final return. */ 1527 bcemit_AD(fs, BC_RET0, 0, 1); /* Need final return. */
diff --git a/src/lj_record.c b/src/lj_record.c
index ad45bebb..6543f274 100644
--- a/src/lj_record.c
+++ b/src/lj_record.c
@@ -973,7 +973,8 @@ void lj_record_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults)
973 lj_trace_err(J, LJ_TRERR_LLEAVE); 973 lj_trace_err(J, LJ_TRERR_LLEAVE);
974 } else if (J->needsnap) { /* Tailcalled to ff with side-effects. */ 974 } else if (J->needsnap) { /* Tailcalled to ff with side-effects. */
975 lj_trace_err(J, LJ_TRERR_NYIRETL); /* No way to insert snapshot here. */ 975 lj_trace_err(J, LJ_TRERR_NYIRETL); /* No way to insert snapshot here. */
976 } else if (1 + pt->framesize >= LJ_MAX_JSLOTS) { 976 } else if (1 + pt->framesize >= LJ_MAX_JSLOTS ||
977 J->baseslot + J->maxslot >= LJ_MAX_JSLOTS) {
977 lj_trace_err(J, LJ_TRERR_STACKOV); 978 lj_trace_err(J, LJ_TRERR_STACKOV);
978 } else { /* Return to lower frame. Guard for the target we return to. */ 979 } else { /* Return to lower frame. Guard for the target we return to. */
979 TRef trpt = lj_ir_kgc(J, obj2gco(pt), IRT_PROTO); 980 TRef trpt = lj_ir_kgc(J, obj2gco(pt), IRT_PROTO);
diff --git a/src/lj_snap.c b/src/lj_snap.c
index cb104439..d0d28c81 100644
--- a/src/lj_snap.c
+++ b/src/lj_snap.c
@@ -956,8 +956,10 @@ const BCIns *lj_snap_restore(jit_State *J, void *exptr)
956 const BCIns *pc = snap_pc(&map[nent]); 956 const BCIns *pc = snap_pc(&map[nent]);
957 lua_State *L = J->L; 957 lua_State *L = J->L;
958 958
959 /* Set interpreter PC to the next PC to get correct error messages. */ 959 /* Set interpreter PC to the next PC to get correct error messages.
960 setcframe_pc(L->cframe, pc+1); 960 ** But not for returns or tail calls, since pc+1 may be out-of-range.
961 */
962 setcframe_pc(L->cframe, bc_isret_or_tail(bc_op(*pc)) ? pc : pc+1);
961 setcframe_pc(cframe_raw(cframe_prev(L->cframe)), pc); 963 setcframe_pc(cframe_raw(cframe_prev(L->cframe)), pc);
962 964
963 /* Make sure the stack is big enough for the slots from the snapshot. */ 965 /* Make sure the stack is big enough for the slots from the snapshot. */
diff --git a/src/msvcbuild.bat b/src/msvcbuild.bat
index 69c0c61a..d6aed170 100644
--- a/src/msvcbuild.bat
+++ b/src/msvcbuild.bat
@@ -5,11 +5,12 @@
5@rem Then cd to this directory and run this script. Use the following 5@rem Then cd to this directory and run this script. Use the following
6@rem options (in order), if needed. The default is a dynamic release build. 6@rem options (in order), if needed. The default is a dynamic release build.
7@rem 7@rem
8@rem nogc64 disable LJ_GC64 mode for x64 8@rem nogc64 disable LJ_GC64 mode for x64
9@rem debug emit debug symbols 9@rem debug emit debug symbols
10@rem amalg amalgamated build 10@rem lua52compat enable extra Lua 5.2 extensions
11@rem static create static lib to statically link into your project 11@rem amalg amalgamated build
12@rem mixed create static lib to build a DLL in your project 12@rem static create static lib to statically link into your project
13@rem mixed create static lib to build a DLL in your project
13 14
14@if not defined INCLUDE goto :FAIL 15@if not defined INCLUDE goto :FAIL
15 16
@@ -101,6 +102,10 @@ buildvm -m folddef -o lj_folddef.h lj_opt_fold.c
101@set LJDYNBUILD=%LJDYNBUILD_DEBUG% 102@set LJDYNBUILD=%LJDYNBUILD_DEBUG%
102@set LJLINKTYPE=%LJLINKTYPE_DEBUG% 103@set LJLINKTYPE=%LJLINKTYPE_DEBUG%
103:NODEBUG 104:NODEBUG
105@if "%1" neq "lua52compat" goto :NOLUA52COMPAT
106@shift
107@set LJCOMPILE=%LJCOMPILE% /DLUAJIT_ENABLE_LUA52COMPAT
108:NOLUA52COMPAT
104@set LJCOMPILE=%LJCOMPILE% %LJCOMPILETARGET% 109@set LJCOMPILE=%LJCOMPILE% %LJCOMPILETARGET%
105@set LJLINK=%LJLINK% %LJLINKTYPE% %LJLINKTARGET% 110@set LJLINK=%LJLINK% %LJLINKTYPE% %LJLINKTARGET%
106@if "%1"=="amalg" goto :AMALGDLL 111@if "%1"=="amalg" goto :AMALGDLL