diff options
-rw-r--r-- | src/lj_asm_x86.h | 3 | ||||
-rw-r--r-- | src/lj_bc.h | 5 | ||||
-rw-r--r-- | src/lj_ccall.c | 19 | ||||
-rw-r--r-- | src/lj_crecord.c | 32 | ||||
-rw-r--r-- | src/lj_debug.c | 1 | ||||
-rw-r--r-- | src/lj_load.c | 3 | ||||
-rw-r--r-- | src/lj_parse.c | 14 | ||||
-rw-r--r-- | src/lj_record.c | 3 | ||||
-rw-r--r-- | src/lj_snap.c | 6 |
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 | ||
258 | static LJ_AINLINE int bc_isret_or_tail(BCOp op) | ||
259 | { | ||
260 | return (op == BC_CALLMT || op == BC_CALLT || bc_isret(op)); | ||
261 | } | ||
262 | |||
258 | LJ_DATA const uint16_t lj_bc_mode[]; | 263 | LJ_DATA const uint16_t lj_bc_mode[]; |
259 | LJ_DATA const uint16_t lj_bc_ofs[]; | 264 | LJ_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 | */ | ||
627 | CTypeID lj_ccall_ctid_vararg(CTState *cts, cTValue *o) | 629 | CTypeID 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 | */ | ||
655 | static int ccall_set_args(lua_State *L, CTState *cts, CType *ct, | 659 | static 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 | */ | ||
992 | static TRef crec_call_args(jit_State *J, RecordFFData *rd, | 994 | static 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. */ | ||
1533 | static 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. */ |
1545 | static void fs_fixup_ret(FuncState *fs) | 1533 | static 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. */ |