diff options
-rw-r--r-- | src/Makefile | 3 | ||||
-rw-r--r-- | src/lj_asm_arm.h | 2 | ||||
-rw-r--r-- | src/lj_asm_x86.h | 3 | ||||
-rw-r--r-- | src/lj_bc.h | 5 | ||||
-rw-r--r-- | src/lj_bcread.c | 10 | ||||
-rw-r--r-- | src/lj_bcwrite.c | 8 | ||||
-rw-r--r-- | src/lj_ccall.c | 39 | ||||
-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_opt_fold.c | 6 | ||||
-rw-r--r-- | src/lj_opt_mem.c | 4 | ||||
-rw-r--r-- | src/lj_parse.c | 34 | ||||
-rw-r--r-- | src/lj_record.c | 8 | ||||
-rw-r--r-- | src/lj_snap.c | 6 | ||||
-rw-r--r-- | src/lj_tab.c | 1 | ||||
-rw-r--r-- | src/msvcbuild.bat | 15 | ||||
-rw-r--r-- | src/vm_arm.dasc | 4 |
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 | |||
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_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 | ||
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_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. */ |
182 | static void bcread_ktabk(LexState *ls, TValue *o) | 182 | static 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 | */ | ||
897 | CTypeID lj_ccall_ctid_vararg(CTState *cts, cTValue *o) | 907 | CTypeID 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 | */ | ||
925 | 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, |
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 | */ | ||
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_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) | |||
2217 | LJFOLDF(fwd_href_tdup) | 2217 | LJFOLDF(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. */ | ||
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. */ |
@@ -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 | | |