diff options
author | Mike Pall <mike> | 2012-09-28 19:30:08 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2012-09-28 19:30:08 +0200 |
commit | d08e7bd5183c361f9ad2ecbeb5ae4426985f485c (patch) | |
tree | cf88423e3d1a8c1b4401fa2f25a459d688119f2b /src | |
parent | 550ac44e41ad430f8a355533bf03cf04b61bb266 (diff) | |
download | luajit-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.c | 10 | ||||
-rw-r--r-- | src/lj_record.c | 15 |
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. */ |