diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile | 3 | ||||
-rw-r--r-- | src/lj_asm_x86.h | 3 | ||||
-rw-r--r-- | src/lj_bc.h | 5 | ||||
-rw-r--r-- | src/lj_ccall.c | 21 | ||||
-rw-r--r-- | src/lj_crecord.c | 32 | ||||
-rw-r--r-- | src/lj_debug.c | 1 | ||||
-rw-r--r-- | src/lj_parse.c | 14 | ||||
-rw-r--r-- | src/lj_record.c | 3 | ||||
-rw-r--r-- | src/lj_snap.c | 6 | ||||
-rw-r--r-- | src/msvcbuild.bat | 15 |
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 | |||
302 | ifneq (,$(INSTALL_LJLIBD)) | 302 | ifneq (,$(INSTALL_LJLIBD)) |
303 | TARGET_XCFLAGS+= -DLUA_LJDIR=\"$(INSTALL_LJLIBD)\" | 303 | TARGET_XCFLAGS+= -DLUA_LJDIR=\"$(INSTALL_LJLIBD)\" |
304 | endif | 304 | endif |
305 | ifeq (,$(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 | ||
307 | endif | ||
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 | ||
262 | static LJ_AINLINE int bc_isret_or_tail(BCOp op) | ||
263 | { | ||
264 | return (op == BC_CALLMT || op == BC_CALLT || bc_isret(op)); | ||
265 | } | ||
266 | |||
262 | LJ_DATA const uint16_t lj_bc_mode[]; | 267 | LJ_DATA const uint16_t lj_bc_mode[]; |
263 | LJ_DATA const uint16_t lj_bc_ofs[]; | 268 | LJ_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 | */ | ||
905 | CTypeID lj_ccall_ctid_vararg(CTState *cts, cTValue *o) | 907 | CTypeID 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 | */ | ||
933 | static int ccall_set_args(lua_State *L, CTState *cts, CType *ct, | 937 | static 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 | */ | ||
1105 | static TRef crec_call_args(jit_State *J, RecordFFData *rd, | 1107 | static 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. */ | ||
1521 | static 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. */ |
1533 | static void fs_fixup_ret(FuncState *fs) | 1521 | static 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 |