aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile3
-rw-r--r--src/lj_asm_arm.h2
-rw-r--r--src/lj_asm_x86.h3
-rw-r--r--src/lj_bc.h5
-rw-r--r--src/lj_bcread.c10
-rw-r--r--src/lj_bcwrite.c8
-rw-r--r--src/lj_ccall.c39
-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_opt_fold.c6
-rw-r--r--src/lj_opt_mem.c4
-rw-r--r--src/lj_parse.c34
-rw-r--r--src/lj_record.c8
-rw-r--r--src/lj_snap.c6
-rw-r--r--src/lj_tab.c1
-rw-r--r--src/msvcbuild.bat15
-rw-r--r--src/vm_arm.dasc4
18 files changed, 106 insertions, 78 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_arm.h b/src/lj_asm_arm.h
index de435057..24deaeae 100644
--- a/src/lj_asm_arm.h
+++ b/src/lj_asm_arm.h
@@ -1927,7 +1927,7 @@ static void asm_hiop(ASMState *as, IRIns *ir)
1927 } else if ((ir-1)->o == IR_MIN || (ir-1)->o == IR_MAX) { 1927 } else if ((ir-1)->o == IR_MIN || (ir-1)->o == IR_MAX) {
1928 as->curins--; /* Always skip the loword min/max. */ 1928 as->curins--; /* Always skip the loword min/max. */
1929 if (uselo || usehi) 1929 if (uselo || usehi)
1930 asm_sfpmin_max(as, ir-1, (ir-1)->o == IR_MIN ? CC_PL : CC_LE); 1930 asm_sfpmin_max(as, ir-1, (ir-1)->o == IR_MIN ? CC_HS : CC_LS);
1931 return; 1931 return;
1932#elif LJ_HASFFI 1932#elif LJ_HASFFI
1933 } else if ((ir-1)->o == IR_CONV) { 1933 } else if ((ir-1)->o == IR_CONV) {
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_bcread.c b/src/lj_bcread.c
index ee7d7c18..55709522 100644
--- a/src/lj_bcread.c
+++ b/src/lj_bcread.c
@@ -179,7 +179,7 @@ static const void *bcread_varinfo(GCproto *pt)
179} 179}
180 180
181/* Read a single constant key/value of a template table. */ 181/* Read a single constant key/value of a template table. */
182static void bcread_ktabk(LexState *ls, TValue *o) 182static void bcread_ktabk(LexState *ls, TValue *o, GCtab *t)
183{ 183{
184 MSize tp = bcread_uleb128(ls); 184 MSize tp = bcread_uleb128(ls);
185 if (tp >= BCDUMP_KTAB_STR) { 185 if (tp >= BCDUMP_KTAB_STR) {
@@ -191,6 +191,8 @@ static void bcread_ktabk(LexState *ls, TValue *o)
191 } else if (tp == BCDUMP_KTAB_NUM) { 191 } else if (tp == BCDUMP_KTAB_NUM) {
192 o->u32.lo = bcread_uleb128(ls); 192 o->u32.lo = bcread_uleb128(ls);
193 o->u32.hi = bcread_uleb128(ls); 193 o->u32.hi = bcread_uleb128(ls);
194 } else if (t && tp == BCDUMP_KTAB_NIL) { /* Restore nil value marker. */
195 settabV(ls->L, o, t);
194 } else { 196 } else {
195 lj_assertLS(tp <= BCDUMP_KTAB_TRUE, "bad constant type %d", tp); 197 lj_assertLS(tp <= BCDUMP_KTAB_TRUE, "bad constant type %d", tp);
196 setpriV(o, ~tp); 198 setpriV(o, ~tp);
@@ -207,15 +209,15 @@ static GCtab *bcread_ktab(LexState *ls)
207 MSize i; 209 MSize i;
208 TValue *o = tvref(t->array); 210 TValue *o = tvref(t->array);
209 for (i = 0; i < narray; i++, o++) 211 for (i = 0; i < narray; i++, o++)
210 bcread_ktabk(ls, o); 212 bcread_ktabk(ls, o, NULL);
211 } 213 }
212 if (nhash) { /* Read hash entries. */ 214 if (nhash) { /* Read hash entries. */
213 MSize i; 215 MSize i;
214 for (i = 0; i < nhash; i++) { 216 for (i = 0; i < nhash; i++) {
215 TValue key; 217 TValue key;
216 bcread_ktabk(ls, &key); 218 bcread_ktabk(ls, &key, NULL);
217 lj_assertLS(!tvisnil(&key), "nil key"); 219 lj_assertLS(!tvisnil(&key), "nil key");
218 bcread_ktabk(ls, lj_tab_set(ls->L, t, &key)); 220 bcread_ktabk(ls, lj_tab_set(ls->L, t, &key), t);
219 } 221 }
220 } 222 }
221 return t; 223 return t;
diff --git a/src/lj_bcwrite.c b/src/lj_bcwrite.c
index de200ef4..ec6f13c8 100644
--- a/src/lj_bcwrite.c
+++ b/src/lj_bcwrite.c
@@ -71,6 +71,8 @@ static void bcwrite_ktabk(BCWriteCtx *ctx, cTValue *o, int narrow)
71 *p++ = BCDUMP_KTAB_NUM; 71 *p++ = BCDUMP_KTAB_NUM;
72 p = lj_strfmt_wuleb128(p, o->u32.lo); 72 p = lj_strfmt_wuleb128(p, o->u32.lo);
73 p = lj_strfmt_wuleb128(p, o->u32.hi); 73 p = lj_strfmt_wuleb128(p, o->u32.hi);
74 } else if (tvistab(o)) { /* Write the nil value marker as a nil. */
75 *p++ = BCDUMP_KTAB_NIL;
74 } else { 76 } else {
75 lj_assertBCW(tvispri(o), "unhandled type %d", itype(o)); 77 lj_assertBCW(tvispri(o), "unhandled type %d", itype(o));
76 *p++ = BCDUMP_KTAB_NIL+~itype(o); 78 *p++ = BCDUMP_KTAB_NIL+~itype(o);
@@ -133,7 +135,7 @@ static void bcwrite_ktab_sorted_hash(BCWriteCtx *ctx, Node *node, MSize nhash)
133 TValue **heap = ctx->heap; 135 TValue **heap = ctx->heap;
134 MSize i = nhash; 136 MSize i = nhash;
135 for (;; node--) { /* Build heap. */ 137 for (;; node--) { /* Build heap. */
136 if (!tvisnil(&node->key)) { 138 if (!tvisnil(&node->val)) {
137 bcwrite_ktabk_heap_insert(heap, --i, nhash, &node->key); 139 bcwrite_ktabk_heap_insert(heap, --i, nhash, &node->key);
138 if (i == 0) break; 140 if (i == 0) break;
139 } 141 }
@@ -163,7 +165,7 @@ static void bcwrite_ktab(BCWriteCtx *ctx, char *p, const GCtab *t)
163 MSize i, hmask = t->hmask; 165 MSize i, hmask = t->hmask;
164 Node *node = noderef(t->node); 166 Node *node = noderef(t->node);
165 for (i = 0; i <= hmask; i++) 167 for (i = 0; i <= hmask; i++)
166 nhash += !tvisnil(&node[i].key); 168 nhash += !tvisnil(&node[i].val);
167 } 169 }
168 /* Write number of array slots and hash slots. */ 170 /* Write number of array slots and hash slots. */
169 p = lj_strfmt_wuleb128(p, narray); 171 p = lj_strfmt_wuleb128(p, narray);
@@ -184,7 +186,7 @@ static void bcwrite_ktab(BCWriteCtx *ctx, char *p, const GCtab *t)
184 } else { 186 } else {
185 MSize i = nhash; 187 MSize i = nhash;
186 for (;; node--) 188 for (;; node--)
187 if (!tvisnil(&node->key)) { 189 if (!tvisnil(&node->val)) {
188 bcwrite_ktabk(ctx, &node->key, 0); 190 bcwrite_ktabk(ctx, &node->key, 0);
189 bcwrite_ktabk(ctx, &node->val, 1); 191 bcwrite_ktabk(ctx, &node->val, 1);
190 if (--i == 0) break; 192 if (--i == 0) break;
diff --git a/src/lj_ccall.c b/src/lj_ccall.c
index ae69cd28..d5f092ea 100644
--- a/src/lj_ccall.c
+++ b/src/lj_ccall.c
@@ -781,17 +781,24 @@ static unsigned int ccall_classify_struct(CTState *cts, CType *ct)
781{ 781{
782 CTSize sz = ct->size; 782 CTSize sz = ct->size;
783 unsigned int r = 0, n = 0, isu = (ct->info & CTF_UNION); 783 unsigned int r = 0, n = 0, isu = (ct->info & CTF_UNION);
784 while (ct->sib) { 784 while (ct->sib && n <= 4) {
785 unsigned int m = 1;
785 CType *sct; 786 CType *sct;
786 ct = ctype_get(cts, ct->sib); 787 ct = ctype_get(cts, ct->sib);
787 if (ctype_isfield(ct->info)) { 788 if (ctype_isfield(ct->info)) {
788 sct = ctype_rawchild(cts, ct); 789 sct = ctype_rawchild(cts, ct);
790 if (ctype_isarray(sct->info)) {
791 CType *cct = ctype_rawchild(cts, sct);
792 if (!cct->size) continue;
793 m = sct->size / cct->size;
794 sct = cct;
795 }
789 if (ctype_isfp(sct->info)) { 796 if (ctype_isfp(sct->info)) {
790 r |= sct->size; 797 r |= sct->size;
791 if (!isu) n++; else if (n == 0) n = 1; 798 if (!isu) n += m; else if (n < m) n = m;
792 } else if (ctype_iscomplex(sct->info)) { 799 } else if (ctype_iscomplex(sct->info)) {
793 r |= (sct->size >> 1); 800 r |= (sct->size >> 1);
794 if (!isu) n += 2; else if (n < 2) n = 2; 801 if (!isu) n += 2*m; else if (n < 2*m) n = 2*m;
795 } else if (ctype_isstruct(sct->info)) { 802 } else if (ctype_isstruct(sct->info)) {
796 goto substruct; 803 goto substruct;
797 } else { 804 } else {
@@ -803,10 +810,11 @@ static unsigned int ccall_classify_struct(CTState *cts, CType *ct)
803 sct = ctype_rawchild(cts, ct); 810 sct = ctype_rawchild(cts, ct);
804 substruct: 811 substruct:
805 if (sct->size > 0) { 812 if (sct->size > 0) {
806 unsigned int s = ccall_classify_struct(cts, sct); 813 unsigned int s = ccall_classify_struct(cts, sct), sn;
807 if (s <= 1) goto noth; 814 if (s <= 1) goto noth;
808 r |= (s & 255); 815 r |= (s & 255);
809 if (!isu) n += (s >> 8); else if (n < (s >>8)) n = (s >> 8); 816 sn = (s >> 8) * m;
817 if (!isu) n += sn; else if (n < sn) n = sn;
810 } 818 }
811 } 819 }
812 } 820 }
@@ -893,7 +901,9 @@ static void ccall_copy_struct(CCallState *cc, CType *ctr, void *dp, void *sp,
893 901
894/* -- Common C call handling ---------------------------------------------- */ 902/* -- Common C call handling ---------------------------------------------- */
895 903
896/* 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*/
897CTypeID lj_ccall_ctid_vararg(CTState *cts, cTValue *o) 907CTypeID lj_ccall_ctid_vararg(CTState *cts, cTValue *o)
898{ 908{
899 if (tvisnumber(o)) { 909 if (tvisnumber(o)) {
@@ -921,13 +931,16 @@ CTypeID lj_ccall_ctid_vararg(CTState *cts, cTValue *o)
921 } 931 }
922} 932}
923 933
924/* Setup arguments for C call. */ 934/* Setup arguments for C call.
935** Note: may reallocate cts->tab and invalidate CType pointers.
936*/
925static int ccall_set_args(lua_State *L, CTState *cts, CType *ct, 937static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
926 CCallState *cc) 938 CCallState *cc)
927{ 939{
928 int gcsteps = 0; 940 int gcsteps = 0;
929 TValue *o, *top = L->top; 941 TValue *o, *top = L->top;
930 CTypeID fid; 942 CTypeID fid;
943 CTInfo info = ct->info; /* lj_ccall_ctid_vararg may invalidate ct pointer. */
931 CType *ctr; 944 CType *ctr;
932 MSize maxgpr, ngpr = 0, nsp = 0, narg; 945 MSize maxgpr, ngpr = 0, nsp = 0, narg;
933#if CCALL_NARG_FPR 946#if CCALL_NARG_FPR
@@ -946,7 +959,7 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
946#if LJ_TARGET_X86 959#if LJ_TARGET_X86
947 /* x86 has several different calling conventions. */ 960 /* x86 has several different calling conventions. */
948 cc->resx87 = 0; 961 cc->resx87 = 0;
949 switch (ctype_cconv(ct->info)) { 962 switch (ctype_cconv(info)) {
950 case CTCC_FASTCALL: maxgpr = 2; break; 963 case CTCC_FASTCALL: maxgpr = 2; break;
951 case CTCC_THISCALL: maxgpr = 1; break; 964 case CTCC_THISCALL: maxgpr = 1; break;
952 default: maxgpr = 0; break; 965 default: maxgpr = 0; break;
@@ -963,7 +976,7 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
963 } else if (ctype_iscomplex(ctr->info) || ctype_isstruct(ctr->info)) { 976 } else if (ctype_iscomplex(ctr->info) || ctype_isstruct(ctr->info)) {
964 /* Preallocate cdata object and anchor it after arguments. */ 977 /* Preallocate cdata object and anchor it after arguments. */
965 CTSize sz = ctr->size; 978 CTSize sz = ctr->size;
966 GCcdata *cd = lj_cdata_new(cts, ctype_cid(ct->info), sz); 979 GCcdata *cd = lj_cdata_new(cts, ctype_cid(info), sz);
967 void *dp = cdataptr(cd); 980 void *dp = cdataptr(cd);
968 setcdataV(L, L->top++, cd); 981 setcdataV(L, L->top++, cd);
969 if (ctype_isstruct(ctr->info)) { 982 if (ctype_isstruct(ctr->info)) {
@@ -986,7 +999,7 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
986 } 999 }
987 1000
988#if LJ_TARGET_ARM64 && LJ_ABI_WIN 1001#if LJ_TARGET_ARM64 && LJ_ABI_WIN
989 if ((ct->info & CTF_VARARG)) { 1002 if ((info & CTF_VARARG)) {
990 nsp -= maxgpr * CTSIZE_PTR; /* May end up with negative nsp. */ 1003 nsp -= maxgpr * CTSIZE_PTR; /* May end up with negative nsp. */
991 ngpr = maxgpr; 1004 ngpr = maxgpr;
992 nfpr = CCALL_NARG_FPR; 1005 nfpr = CCALL_NARG_FPR;
@@ -1007,7 +1020,7 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
1007 lj_assertL(ctype_isfield(ctf->info), "field expected"); 1020 lj_assertL(ctype_isfield(ctf->info), "field expected");
1008 did = ctype_cid(ctf->info); 1021 did = ctype_cid(ctf->info);
1009 } else { 1022 } else {
1010 if (!(ct->info & CTF_VARARG)) 1023 if (!(info & CTF_VARARG))
1011 lj_err_caller(L, LJ_ERR_FFI_NUMARG); /* Too many arguments. */ 1024 lj_err_caller(L, LJ_ERR_FFI_NUMARG); /* Too many arguments. */
1012 did = lj_ccall_ctid_vararg(cts, o); /* Infer vararg type. */ 1025 did = lj_ccall_ctid_vararg(cts, o); /* Infer vararg type. */
1013 isva = 1; 1026 isva = 1;
@@ -1178,11 +1191,11 @@ int lj_ccall_func(lua_State *L, GCcdata *cd)
1178 ct = ctype_rawchild(cts, ct); 1191 ct = ctype_rawchild(cts, ct);
1179 } 1192 }
1180 if (ctype_isfunc(ct->info)) { 1193 if (ctype_isfunc(ct->info)) {
1194 CTypeID id = ctype_typeid(cts, ct);
1181 CCallState cc; 1195 CCallState cc;
1182 int gcsteps, ret; 1196 int gcsteps, ret;
1183 cc.func = (void (*)(void))cdata_getptr(cdataptr(cd), sz); 1197 cc.func = (void (*)(void))cdata_getptr(cdataptr(cd), sz);
1184 gcsteps = ccall_set_args(L, cts, ct, &cc); 1198 gcsteps = ccall_set_args(L, cts, ct, &cc);
1185 ct = (CType *)((intptr_t)ct-(intptr_t)cts->tab);
1186 cts->cb.slot = ~0u; 1199 cts->cb.slot = ~0u;
1187 lj_vm_ffi_call(&cc); 1200 lj_vm_ffi_call(&cc);
1188 if (cts->cb.slot != ~0u) { /* Blacklist function that called a callback. */ 1201 if (cts->cb.slot != ~0u) { /* Blacklist function that called a callback. */
@@ -1190,7 +1203,7 @@ int lj_ccall_func(lua_State *L, GCcdata *cd)
1190 tv.u64 = ((uintptr_t)(void *)cc.func >> 2) | U64x(800000000, 00000000); 1203 tv.u64 = ((uintptr_t)(void *)cc.func >> 2) | U64x(800000000, 00000000);
1191 setboolV(lj_tab_set(L, cts->miscmap, &tv), 1); 1204 setboolV(lj_tab_set(L, cts->miscmap, &tv), 1);
1192 } 1205 }
1193 ct = (CType *)((intptr_t)ct+(intptr_t)cts->tab); /* May be reallocated. */ 1206 ct = ctype_get(cts, id); /* Table may have been reallocated. */
1194 gcsteps += ccall_get_results(L, cts, ct, &cc, &ret); 1207 gcsteps += ccall_get_results(L, cts, ct, &cc, &ret);
1195#if LJ_TARGET_X86 && LJ_ABI_WIN 1208#if LJ_TARGET_X86 && LJ_ABI_WIN
1196 /* 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_load.c b/src/lj_load.c
index 828bf8ae..24b660a8 100644
--- a/src/lj_load.c
+++ b/src/lj_load.c
@@ -122,8 +122,9 @@ LUALIB_API int luaL_loadfilex(lua_State *L, const char *filename,
122 copyTV(L, L->top-1, L->top); 122 copyTV(L, L->top-1, L->top);
123 } 123 }
124 if (err) { 124 if (err) {
125 const char *fname = filename ? filename : "stdin";
125 L->top--; 126 L->top--;
126 lua_pushfstring(L, "cannot read %s: %s", chunkname+1, strerror(err)); 127 lua_pushfstring(L, "cannot read %s: %s", fname, strerror(err));
127 return LUA_ERRFILE; 128 return LUA_ERRFILE;
128 } 129 }
129 return status; 130 return status;
diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c
index 36aacebb..6fdf4566 100644
--- a/src/lj_opt_fold.c
+++ b/src/lj_opt_fold.c
@@ -2217,9 +2217,11 @@ LJFOLD(HREF TDUP KNUM)
2217LJFOLDF(fwd_href_tdup) 2217LJFOLDF(fwd_href_tdup)
2218{ 2218{
2219 TValue keyv; 2219 TValue keyv;
2220 cTValue *val;
2220 lj_ir_kvalue(J->L, &keyv, fright); 2221 lj_ir_kvalue(J->L, &keyv, fright);
2221 if (lj_tab_get(J->L, ir_ktab(IR(fleft->op1)), &keyv) == niltvg(J2G(J)) && 2222 val = lj_tab_get(J->L, ir_ktab(IR(fleft->op1)), &keyv);
2222 lj_opt_fwd_href_nokey(J)) 2223 /* Check for either nil or the nil value marker in the template table. */
2224 if ((tvisnil(val) || tvistab(val)) && lj_opt_fwd_href_nokey(J))
2223 return lj_ir_kkptr(J, niltvg(J2G(J))); 2225 return lj_ir_kkptr(J, niltvg(J2G(J)));
2224 return NEXTFOLD; 2226 return NEXTFOLD;
2225} 2227}
diff --git a/src/lj_opt_mem.c b/src/lj_opt_mem.c
index 8cacfcfe..6f956b37 100644
--- a/src/lj_opt_mem.c
+++ b/src/lj_opt_mem.c
@@ -233,7 +233,9 @@ static TRef fwd_ahload(jit_State *J, IRRef xref)
233 return lj_ir_knum_u64(J, tv->u64); 233 return lj_ir_knum_u64(J, tv->u64);
234 else if (tvisint(tv)) 234 else if (tvisint(tv))
235 return lj_ir_kint(J, intV(tv)); 235 return lj_ir_kint(J, intV(tv));
236 else if (tvisgcv(tv)) 236 else if (tvistab(tv)) /* Template table nil value marker. */
237 return TREF_NIL;
238 else if (tvisstr(tv))
237 return lj_ir_kstr(J, strV(tv)); 239 return lj_ir_kstr(J, strV(tv));
238 } 240 }
239 /* Othwerwise: don't intern as a constant. */ 241 /* Othwerwise: don't intern as a constant. */
diff --git a/src/lj_parse.c b/src/lj_parse.c
index 70097598..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. */
@@ -1725,7 +1713,7 @@ static void expr_table(LexState *ls, ExpDesc *e)
1725 FuncState *fs = ls->fs; 1713 FuncState *fs = ls->fs;
1726 BCLine line = ls->linenumber; 1714 BCLine line = ls->linenumber;
1727 GCtab *t = NULL; 1715 GCtab *t = NULL;
1728 int vcall = 0, needarr = 0, fixt = 0; 1716 int vcall = 0, needarr = 0;
1729 uint32_t narr = 1; /* First array index. */ 1717 uint32_t narr = 1; /* First array index. */
1730 uint32_t nhash = 0; /* Number of hash entries. */ 1718 uint32_t nhash = 0; /* Number of hash entries. */
1731 BCReg freg = fs->freereg; 1719 BCReg freg = fs->freereg;
@@ -1769,9 +1757,10 @@ static void expr_table(LexState *ls, ExpDesc *e)
1769 lj_gc_anybarriert(fs->L, t); 1757 lj_gc_anybarriert(fs->L, t);
1770 if (expr_isk_nojump(&val)) { /* Add const key/value to template table. */ 1758 if (expr_isk_nojump(&val)) { /* Add const key/value to template table. */
1771 expr_kvalue(fs, v, &val); 1759 expr_kvalue(fs, v, &val);
1772 } else { /* Otherwise create dummy string key (avoids lj_tab_newkey). */ 1760 /* Mark nil value with table value itself to preserve the key. */
1773 settabV(fs->L, v, t); /* Preserve key with table itself as value. */ 1761 if (key.k == VKSTR && tvisnil(v)) settabV(fs->L, v, t);
1774 fixt = 1; /* Fix this later, after all resizes. */ 1762 } else { /* Preserve the key for the following non-const store. */
1763 settabV(fs->L, v, t);
1775 goto nonconst; 1764 goto nonconst;
1776 } 1765 }
1777 } else { 1766 } else {
@@ -1813,17 +1802,6 @@ static void expr_table(LexState *ls, ExpDesc *e)
1813 } else { 1802 } else {
1814 if (needarr && t->asize < narr) 1803 if (needarr && t->asize < narr)
1815 lj_tab_reasize(fs->L, t, narr-1); 1804 lj_tab_reasize(fs->L, t, narr-1);
1816 if (fixt) { /* Fix value for dummy keys in template table. */
1817 Node *node = noderef(t->node);
1818 uint32_t i, hmask = t->hmask;
1819 for (i = 0; i <= hmask; i++) {
1820 Node *n = &node[i];
1821 if (tvistab(&n->val)) {
1822 lj_assertFS(tabV(&n->val) == t, "bad dummy key in template table");
1823 setnilV(&n->val); /* Turn value into nil. */
1824 }
1825 }
1826 }
1827 lj_gc_check(fs->L); 1805 lj_gc_check(fs->L);
1828 } 1806 }
1829} 1807}
diff --git a/src/lj_record.c b/src/lj_record.c
index c6a082d4..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);
@@ -1107,7 +1108,10 @@ int lj_record_mm_lookup(jit_State *J, RecordIndex *ix, MMS mm)
1107 return 0; /* No metamethod. */ 1108 return 0; /* No metamethod. */
1108 } 1109 }
1109 /* The cdata metatable is treated as immutable. */ 1110 /* The cdata metatable is treated as immutable. */
1110 if (LJ_HASFFI && tref_iscdata(ix->tab)) goto immutable_mt; 1111 if (LJ_HASFFI && tref_iscdata(ix->tab)) {
1112 mix.tab = TREF_NIL;
1113 goto immutable_mt;
1114 }
1111 ix->mt = mix.tab = lj_ir_ggfload(J, IRT_TAB, 1115 ix->mt = mix.tab = lj_ir_ggfload(J, IRT_TAB,
1112 GG_OFS(g.gcroot[GCROOT_BASEMT+itypemap(&ix->tabv)])); 1116 GG_OFS(g.gcroot[GCROOT_BASEMT+itypemap(&ix->tabv)]));
1113 goto nocheck; 1117 goto nocheck;
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/lj_tab.c b/src/lj_tab.c
index 2d080552..62e33611 100644
--- a/src/lj_tab.c
+++ b/src/lj_tab.c
@@ -194,6 +194,7 @@ GCtab * LJ_FASTCALL lj_tab_dup(lua_State *L, const GCtab *kt)
194 Node *next = nextnode(kn); 194 Node *next = nextnode(kn);
195 /* Don't use copyTV here, since it asserts on a copy of a dead key. */ 195 /* Don't use copyTV here, since it asserts on a copy of a dead key. */
196 n->val = kn->val; n->key = kn->key; 196 n->val = kn->val; n->key = kn->key;
197 if (tvistab(&n->val)) setnilV(&n->val); /* Replace nil value marker. */
197 setmref(n->next, next == NULL? next : (Node *)((char *)next + d)); 198 setmref(n->next, next == NULL? next : (Node *)((char *)next + d));
198 } 199 }
199 } 200 }
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
diff --git a/src/vm_arm.dasc b/src/vm_arm.dasc
index ca08fc11..86bef0cf 100644
--- a/src/vm_arm.dasc
+++ b/src/vm_arm.dasc
@@ -1717,8 +1717,8 @@ static void build_subroutines(BuildCtx *ctx)
1717 |.endif 1717 |.endif
1718 |.endmacro 1718 |.endmacro
1719 | 1719 |
1720 | math_minmax math_min, gt, pl 1720 | math_minmax math_min, gt, hs
1721 | math_minmax math_max, lt, le 1721 | math_minmax math_max, lt, ls
1722 | 1722 |
1723 |//-- String library ----------------------------------------------------- 1723 |//-- String library -----------------------------------------------------
1724 | 1724 |