diff options
-rw-r--r-- | src/lib_ffi.c | 17 | ||||
-rw-r--r-- | src/lj_asm.c | 2 | ||||
-rw-r--r-- | src/lj_crecord.c | 57 | ||||
-rw-r--r-- | src/lj_record.c | 1 |
4 files changed, 49 insertions, 28 deletions
diff --git a/src/lib_ffi.c b/src/lib_ffi.c index 89baa356..42d71153 100644 --- a/src/lib_ffi.c +++ b/src/lib_ffi.c | |||
@@ -157,14 +157,13 @@ static int ffi_arith_ptr(lua_State *L, CTState *cts, FFIArith *fa, MMS mm) | |||
157 | return 1; | 157 | return 1; |
158 | } | 158 | } |
159 | } | 159 | } |
160 | if (!((mm == MM_add || mm == MM_sub) && | 160 | if (!((mm == MM_add || mm == MM_sub) && ctype_isnum(fa->ct[1]->info))) |
161 | ctype_isnum(fa->ct[1]->info))) return 0; | 161 | return 0; |
162 | lj_cconv_ct_ct(cts, ctype_get(cts, CTID_INT_PSZ), fa->ct[1], | 162 | lj_cconv_ct_ct(cts, ctype_get(cts, CTID_INT_PSZ), fa->ct[1], |
163 | (uint8_t *)&idx, fa->p[1], 0); | 163 | (uint8_t *)&idx, fa->p[1], 0); |
164 | if (mm == MM_sub) idx = -idx; | 164 | if (mm == MM_sub) idx = -idx; |
165 | } else if (mm == MM_add && | 165 | } else if (mm == MM_add && ctype_isnum(ctp->info) && |
166 | (ctype_isptr(fa->ct[1]->info) || ctype_isrefarray(fa->ct[1]->info))) { | 166 | (ctype_isptr(fa->ct[1]->info) || ctype_isrefarray(fa->ct[1]->info))) { |
167 | if (!ctype_isnum(ctp->info)) return 0; | ||
168 | /* Swap pointer and index. */ | 167 | /* Swap pointer and index. */ |
169 | ctp = fa->ct[1]; pp = fa->p[1]; | 168 | ctp = fa->ct[1]; pp = fa->p[1]; |
170 | lj_cconv_ct_ct(cts, ctype_get(cts, CTID_INT_PSZ), fa->ct[0], | 169 | lj_cconv_ct_ct(cts, ctype_get(cts, CTID_INT_PSZ), fa->ct[0], |
@@ -264,8 +263,10 @@ static int ffi_arith(lua_State *L) | |||
264 | FFIArith fa; | 263 | FFIArith fa; |
265 | MMS mm = (MMS)(curr_func(L)->c.ffid - (int)FF_ffi_meta___eq + (int)MM_eq); | 264 | MMS mm = (MMS)(curr_func(L)->c.ffid - (int)FF_ffi_meta___eq + (int)MM_eq); |
266 | if (ffi_checkarith(L, cts, &fa)) { | 265 | if (ffi_checkarith(L, cts, &fa)) { |
267 | if (ffi_arith_int64(L, cts, &fa, mm) || ffi_arith_ptr(L, cts, &fa, mm)) | 266 | if (ffi_arith_int64(L, cts, &fa, mm) || ffi_arith_ptr(L, cts, &fa, mm)) { |
267 | copyTV(L, &G(L)->tmptv2, L->top-1); /* Remember for trace recorder. */ | ||
268 | return 1; | 268 | return 1; |
269 | } | ||
269 | } | 270 | } |
270 | /* NYI: per-cdata metamethods. */ | 271 | /* NYI: per-cdata metamethods. */ |
271 | { | 272 | { |
@@ -319,7 +320,7 @@ LJLIB_CF(ffi_meta___newindex) LJLIB_REC(cdata_index 1) | |||
319 | } | 320 | } |
320 | 321 | ||
321 | /* The following functions must be in contiguous ORDER MM. */ | 322 | /* The following functions must be in contiguous ORDER MM. */ |
322 | LJLIB_CF(ffi_meta___eq) | 323 | LJLIB_CF(ffi_meta___eq) LJLIB_REC(cdata_arith MM_eq) |
323 | { | 324 | { |
324 | return ffi_arith(L); | 325 | return ffi_arith(L); |
325 | } | 326 | } |
@@ -329,12 +330,12 @@ LJLIB_CF(ffi_meta___len) | |||
329 | return ffi_arith(L); | 330 | return ffi_arith(L); |
330 | } | 331 | } |
331 | 332 | ||
332 | LJLIB_CF(ffi_meta___lt) | 333 | LJLIB_CF(ffi_meta___lt) LJLIB_REC(cdata_arith MM_lt) |
333 | { | 334 | { |
334 | return ffi_arith(L); | 335 | return ffi_arith(L); |
335 | } | 336 | } |
336 | 337 | ||
337 | LJLIB_CF(ffi_meta___le) | 338 | LJLIB_CF(ffi_meta___le) LJLIB_REC(cdata_arith MM_le) |
338 | { | 339 | { |
339 | return ffi_arith(L); | 340 | return ffi_arith(L); |
340 | } | 341 | } |
diff --git a/src/lj_asm.c b/src/lj_asm.c index af8ac51b..db126d74 100644 --- a/src/lj_asm.c +++ b/src/lj_asm.c | |||
@@ -2927,7 +2927,7 @@ static void asm_comp_(ASMState *as, IRIns *ir, int cc) | |||
2927 | IROp leftop = (IROp)(IR(lref)->o); | 2927 | IROp leftop = (IROp)(IR(lref)->o); |
2928 | Reg r64 = REX_64IR(ir, 0); | 2928 | Reg r64 = REX_64IR(ir, 0); |
2929 | int32_t imm = 0; | 2929 | int32_t imm = 0; |
2930 | lua_assert(irt_isint(ir->t) || irt_isaddr(ir->t)); | 2930 | lua_assert(irt_is64(ir->t) || irt_isint(ir->t) || irt_isaddr(ir->t)); |
2931 | /* Swap constants (only for ABC) and fusable loads to the right. */ | 2931 | /* Swap constants (only for ABC) and fusable loads to the right. */ |
2932 | if (irref_isk(lref) || (!irref_isk(rref) && opisfusableload(leftop))) { | 2932 | if (irref_isk(lref) || (!irref_isk(rref) && opisfusableload(leftop))) { |
2933 | if ((cc & 0xc) == 0xc) cc ^= 3; /* L <-> G, LE <-> GE */ | 2933 | if ((cc & 0xc) == 0xc) cc ^= 3; /* L <-> G, LE <-> GE */ |
diff --git a/src/lj_crecord.c b/src/lj_crecord.c index e2b3e8af..c6577975 100644 --- a/src/lj_crecord.c +++ b/src/lj_crecord.c | |||
@@ -663,7 +663,20 @@ static TRef crec_arith_int64(jit_State *J, TRef *sp, CType **s, MMS mm) | |||
663 | sp[i] = emitconv(sp[i], dt, IRT_INT, | 663 | sp[i] = emitconv(sp[i], dt, IRT_INT, |
664 | ((st - IRT_I8) & 1) ? 0 : IRCONV_SEXT); | 664 | ((st - IRT_I8) & 1) ? 0 : IRCONV_SEXT); |
665 | } | 665 | } |
666 | if (mm == MM_pow) { | 666 | if (mm < MM_add) { |
667 | /* Assume true comparison. Fixup and emit pending guard later. */ | ||
668 | IROp op; | ||
669 | if (mm == MM_eq) { | ||
670 | op = IR_EQ; | ||
671 | } else { | ||
672 | op = mm == MM_lt ? IR_LT : IR_LE; | ||
673 | if (dt == IRT_U64) | ||
674 | op += (IR_ULT-IR_LT); | ||
675 | } | ||
676 | lj_ir_set(J, IRTG(op, dt), sp[0], sp[1]); | ||
677 | J->postproc = LJ_POST_FIXGUARD; | ||
678 | return TREF_TRUE; | ||
679 | } else if (mm == MM_pow) { | ||
667 | tr = lj_ir_call(J, IRCALL_lj_cdata_powi64, sp[0], sp[1], | 680 | tr = lj_ir_call(J, IRCALL_lj_cdata_powi64, sp[0], sp[1], |
668 | lj_ir_kint(J, (int)dt-(int)IRT_I64)); | 681 | lj_ir_kint(J, (int)dt-(int)IRT_I64)); |
669 | } else { | 682 | } else { |
@@ -683,35 +696,41 @@ static TRef crec_arith_ptr(jit_State *J, TRef *sp, CType **s, MMS mm) | |||
683 | { | 696 | { |
684 | CTState *cts = ctype_ctsG(J2G(J)); | 697 | CTState *cts = ctype_ctsG(J2G(J)); |
685 | CType *ctp = s[0]; | 698 | CType *ctp = s[0]; |
686 | CTSize sz; | 699 | if (ctype_isptr(ctp->info) || ctype_isrefarray(ctp->info)) { |
687 | if (!(mm == MM_add || mm == MM_sub)) | 700 | if ((mm == MM_sub || mm == MM_eq || mm == MM_lt || mm == MM_le) && |
688 | return 0; | 701 | (ctype_isptr(s[1]->info) || ctype_isrefarray(s[1]->info))) { |
689 | if (ctype_ispointer(ctp->info)) { | 702 | if (mm == MM_sub) { /* Pointer difference. */ |
690 | sz = lj_ctype_size(cts, ctype_cid(ctp->info)); | 703 | TRef tr; |
691 | if (mm == MM_sub && ctype_ispointer(s[1]->info)) { | 704 | CTSize sz = lj_ctype_size(cts, ctype_cid(ctp->info)); |
692 | /* Pointer difference. */ | 705 | if (sz == 0 || (sz & (sz-1)) != 0) |
693 | TRef tr; | 706 | return 0; /* NYI: integer division. */ |
694 | if (sz == 0 || (sz & (sz-1)) != 0) | 707 | tr = emitir(IRT(IR_SUB, IRT_PTR), sp[0], sp[1]); |
695 | return 0; /* NYI: integer division. */ | 708 | tr = emitir(IRT(IR_BSAR, IRT_INTP), tr, lj_ir_kint(J, lj_fls(sz))); |
696 | tr = emitir(IRT(IR_SUB, IRT_PTR), sp[0], sp[1]); | ||
697 | tr = emitir(IRT(IR_BSAR, IRT_INTP), tr, lj_ir_kint(J, lj_fls(sz))); | ||
698 | #if LJ_64 | 709 | #if LJ_64 |
699 | tr = emitconv(tr, IRT_NUM, IRT_INTP, 0); | 710 | tr = emitconv(tr, IRT_NUM, IRT_INTP, 0); |
700 | #endif | 711 | #endif |
701 | return tr; | 712 | return tr; |
713 | } else { /* Pointer comparison (unsigned). */ | ||
714 | /* Assume true comparison. Fixup and emit pending guard later. */ | ||
715 | IROp op = mm == MM_eq ? IR_EQ : mm == MM_lt ? IR_ULT : IR_ULE; | ||
716 | lj_ir_set(J, IRTG(op, IRT_PTR), sp[0], sp[1]); | ||
717 | J->postproc = LJ_POST_FIXGUARD; | ||
718 | return TREF_TRUE; | ||
719 | } | ||
702 | } | 720 | } |
703 | if (!ctype_isnum(s[1]->info)) return 0; | 721 | if (!((mm == MM_add || mm == MM_sub) && ctype_isnum(s[1]->info))) |
704 | } else if (mm == MM_add && | 722 | return 0; |
705 | ctype_isnum(ctp->info) && ctype_ispointer(s[1]->info)) { | 723 | } else if (mm == MM_add && ctype_isnum(ctp->info) && |
724 | (ctype_isptr(s[1]->info) || ctype_isrefarray(s[1]->info))) { | ||
706 | TRef tr = sp[0]; sp[0] = sp[1]; sp[1] = tr; /* Swap pointer and index. */ | 725 | TRef tr = sp[0]; sp[0] = sp[1]; sp[1] = tr; /* Swap pointer and index. */ |
707 | ctp = s[1]; | 726 | ctp = s[1]; |
708 | sz = lj_ctype_size(cts, ctype_cid(ctp->info)); | ||
709 | } else { | 727 | } else { |
710 | return 0; | 728 | return 0; |
711 | } | 729 | } |
712 | { | 730 | { |
713 | TRef tr = sp[1]; | 731 | TRef tr = sp[1]; |
714 | IRType t = tref_type(tr); | 732 | IRType t = tref_type(tr); |
733 | CTSize sz = lj_ctype_size(cts, ctype_cid(ctp->info)); | ||
715 | CTypeID id; | 734 | CTypeID id; |
716 | #if LJ_64 | 735 | #if LJ_64 |
717 | if (t == IRT_NUM || t == IRT_FLOAT) | 736 | if (t == IRT_NUM || t == IRT_FLOAT) |
diff --git a/src/lj_record.c b/src/lj_record.c index 1669fde1..c150e2e4 100644 --- a/src/lj_record.c +++ b/src/lj_record.c | |||
@@ -819,6 +819,7 @@ static void rec_mm_comp(jit_State *J, RecordIndex *ix, int op) | |||
819 | /* Setup call to cdata comparison metamethod. */ | 819 | /* Setup call to cdata comparison metamethod. */ |
820 | static void rec_mm_comp_cdata(jit_State *J, RecordIndex *ix, int op, MMS mm) | 820 | static void rec_mm_comp_cdata(jit_State *J, RecordIndex *ix, int op, MMS mm) |
821 | { | 821 | { |
822 | lj_snap_add(J); | ||
822 | if (tref_iscdata(ix->val)) { | 823 | if (tref_iscdata(ix->val)) { |
823 | ix->tab = ix->val; | 824 | ix->tab = ix->val; |
824 | copyTV(J->L, &ix->tabv, &ix->valv); | 825 | copyTV(J->L, &ix->tabv, &ix->valv); |