aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2012-09-28 19:30:08 +0200
committerMike Pall <mike>2012-09-28 19:30:08 +0200
commitd08e7bd5183c361f9ad2ecbeb5ae4426985f485c (patch)
treecf88423e3d1a8c1b4401fa2f25a459d688119f2b /src
parent550ac44e41ad430f8a355533bf03cf04b61bb266 (diff)
downloadluajit-d08e7bd5183c361f9ad2ecbeb5ae4426985f485c.tar.gz
luajit-d08e7bd5183c361f9ad2ecbeb5ae4426985f485c.tar.bz2
luajit-d08e7bd5183c361f9ad2ecbeb5ae4426985f485c.zip
From Lua 5.2: Allow mixed metamethods for ordered comparisons.
Needs -DLUAJIT_ENABLE_LUA52COMPAT.
Diffstat (limited to 'src')
-rw-r--r--src/lj_meta.c10
-rw-r--r--src/lj_record.c15
2 files changed, 22 insertions, 3 deletions
diff --git a/src/lj_meta.c b/src/lj_meta.c
index de2b4068..ab5d1b54 100644
--- a/src/lj_meta.c
+++ b/src/lj_meta.c
@@ -386,7 +386,8 @@ TValue *lj_meta_comp(lua_State *L, cTValue *o1, cTValue *o2, int op)
386 cTValue *mo = lj_meta_lookup(L, tviscdata(o1) ? o1 : o2, mm); 386 cTValue *mo = lj_meta_lookup(L, tviscdata(o1) ? o1 : o2, mm);
387 if (LJ_UNLIKELY(tvisnil(mo))) goto err; 387 if (LJ_UNLIKELY(tvisnil(mo))) goto err;
388 return mmcall(L, cont, mo, o1, o2); 388 return mmcall(L, cont, mo, o1, o2);
389 } else if (itype(o1) == itype(o2)) { /* Never called with two numbers. */ 389 } else if (LJ_52 || itype(o1) == itype(o2)) {
390 /* Never called with two numbers. */
390 if (tvisstr(o1) && tvisstr(o2)) { 391 if (tvisstr(o1) && tvisstr(o2)) {
391 int32_t res = lj_str_cmp(strV(o1), strV(o2)); 392 int32_t res = lj_str_cmp(strV(o1), strV(o2));
392 return (TValue *)(intptr_t)(((op&2) ? res <= 0 : res < 0) ^ (op&1)); 393 return (TValue *)(intptr_t)(((op&2) ? res <= 0 : res < 0) ^ (op&1));
@@ -396,8 +397,13 @@ TValue *lj_meta_comp(lua_State *L, cTValue *o1, cTValue *o2, int op)
396 ASMFunction cont = (op & 1) ? lj_cont_condf : lj_cont_condt; 397 ASMFunction cont = (op & 1) ? lj_cont_condf : lj_cont_condt;
397 MMS mm = (op & 2) ? MM_le : MM_lt; 398 MMS mm = (op & 2) ? MM_le : MM_lt;
398 cTValue *mo = lj_meta_lookup(L, o1, mm); 399 cTValue *mo = lj_meta_lookup(L, o1, mm);
400#if LJ_52
401 if (tvisnil(mo) && tvisnil((mo = lj_meta_lookup(L, o2, mm))))
402#else
399 cTValue *mo2 = lj_meta_lookup(L, o2, mm); 403 cTValue *mo2 = lj_meta_lookup(L, o2, mm);
400 if (tvisnil(mo) || !lj_obj_equal(mo, mo2)) { 404 if (tvisnil(mo) || !lj_obj_equal(mo, mo2))
405#endif
406 {
401 if (op & 2) { /* MM_le not found: retry with MM_lt. */ 407 if (op & 2) { /* MM_le not found: retry with MM_lt. */
402 cTValue *ot = o1; o1 = o2; o2 = ot; /* Swap operands. */ 408 cTValue *ot = o1; o1 = o2; o2 = ot; /* Swap operands. */
403 op ^= 3; /* Use LT and flip condition. */ 409 op ^= 3; /* Use LT and flip condition. */
diff --git a/src/lj_record.c b/src/lj_record.c
index 5910dab4..956f3bed 100644
--- a/src/lj_record.c
+++ b/src/lj_record.c
@@ -969,6 +969,16 @@ static void rec_mm_comp(jit_State *J, RecordIndex *ix, int op)
969 copyTV(J->L, &ix->tabv, &ix->valv); 969 copyTV(J->L, &ix->tabv, &ix->valv);
970 while (1) { 970 while (1) {
971 MMS mm = (op & 2) ? MM_le : MM_lt; /* Try __le + __lt or only __lt. */ 971 MMS mm = (op & 2) ? MM_le : MM_lt; /* Try __le + __lt or only __lt. */
972#if LJ_52
973 if (!lj_record_mm_lookup(J, ix, mm)) { /* Lookup mm on 1st operand. */
974 ix->tab = ix->key;
975 copyTV(J->L, &ix->tabv, &ix->keyv);
976 if (!lj_record_mm_lookup(J, ix, mm)) /* Lookup mm on 2nd operand. */
977 goto nomatch;
978 }
979 rec_mm_callcomp(J, ix, op);
980 return;
981#else
972 if (lj_record_mm_lookup(J, ix, mm)) { /* Lookup mm on 1st operand. */ 982 if (lj_record_mm_lookup(J, ix, mm)) { /* Lookup mm on 1st operand. */
973 cTValue *bv; 983 cTValue *bv;
974 TRef mo1 = ix->mobj; 984 TRef mo1 = ix->mobj;
@@ -992,8 +1002,9 @@ static void rec_mm_comp(jit_State *J, RecordIndex *ix, int op)
992 rec_mm_callcomp(J, ix, op); 1002 rec_mm_callcomp(J, ix, op);
993 return; 1003 return;
994 } 1004 }
1005#endif
995 nomatch: 1006 nomatch:
996 /* First lookup failed. Retry with __lt and swapped operands. */ 1007 /* Lookup failed. Retry with __lt and swapped operands. */
997 if (!(op & 2)) break; /* Already at __lt. Interpreter will throw. */ 1008 if (!(op & 2)) break; /* Already at __lt. Interpreter will throw. */
998 ix->tab = ix->key; ix->key = ix->val; ix->val = ix->tab; 1009 ix->tab = ix->key; ix->key = ix->val; ix->val = ix->tab;
999 copyTV(J->L, &ix->tabv, &ix->keyv); 1010 copyTV(J->L, &ix->tabv, &ix->keyv);
@@ -1742,6 +1753,8 @@ void lj_record_ins(jit_State *J)
1742 ta = IRT_NUM; 1753 ta = IRT_NUM;
1743 } else if (ta == IRT_NUM && tc == IRT_INT) { 1754 } else if (ta == IRT_NUM && tc == IRT_INT) {
1744 rc = emitir(IRTN(IR_CONV), rc, IRCONV_NUM_INT); 1755 rc = emitir(IRTN(IR_CONV), rc, IRCONV_NUM_INT);
1756 } else if (LJ_52) {
1757 ta = IRT_NIL; /* Force metamethod for different types. */
1745 } else if (!((ta == IRT_FALSE || ta == IRT_TRUE) && 1758 } else if (!((ta == IRT_FALSE || ta == IRT_TRUE) &&
1746 (tc == IRT_FALSE || tc == IRT_TRUE))) { 1759 (tc == IRT_FALSE || tc == IRT_TRUE))) {
1747 break; /* Interpreter will throw for two different types. */ 1760 break; /* Interpreter will throw for two different types. */