mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 23:24:09 +00:00
From Lua 5.2: Allow mixed metamethods for ordered comparisons.
Needs -DLUAJIT_ENABLE_LUA52COMPAT.
This commit is contained in:
parent
550ac44e41
commit
d08e7bd518
@ -386,7 +386,8 @@ TValue *lj_meta_comp(lua_State *L, cTValue *o1, cTValue *o2, int op)
|
|||||||
cTValue *mo = lj_meta_lookup(L, tviscdata(o1) ? o1 : o2, mm);
|
cTValue *mo = lj_meta_lookup(L, tviscdata(o1) ? o1 : o2, mm);
|
||||||
if (LJ_UNLIKELY(tvisnil(mo))) goto err;
|
if (LJ_UNLIKELY(tvisnil(mo))) goto err;
|
||||||
return mmcall(L, cont, mo, o1, o2);
|
return mmcall(L, cont, mo, o1, o2);
|
||||||
} else if (itype(o1) == itype(o2)) { /* Never called with two numbers. */
|
} else if (LJ_52 || itype(o1) == itype(o2)) {
|
||||||
|
/* Never called with two numbers. */
|
||||||
if (tvisstr(o1) && tvisstr(o2)) {
|
if (tvisstr(o1) && tvisstr(o2)) {
|
||||||
int32_t res = lj_str_cmp(strV(o1), strV(o2));
|
int32_t res = lj_str_cmp(strV(o1), strV(o2));
|
||||||
return (TValue *)(intptr_t)(((op&2) ? res <= 0 : res < 0) ^ (op&1));
|
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)
|
|||||||
ASMFunction cont = (op & 1) ? lj_cont_condf : lj_cont_condt;
|
ASMFunction cont = (op & 1) ? lj_cont_condf : lj_cont_condt;
|
||||||
MMS mm = (op & 2) ? MM_le : MM_lt;
|
MMS mm = (op & 2) ? MM_le : MM_lt;
|
||||||
cTValue *mo = lj_meta_lookup(L, o1, mm);
|
cTValue *mo = lj_meta_lookup(L, o1, mm);
|
||||||
|
#if LJ_52
|
||||||
|
if (tvisnil(mo) && tvisnil((mo = lj_meta_lookup(L, o2, mm))))
|
||||||
|
#else
|
||||||
cTValue *mo2 = lj_meta_lookup(L, o2, mm);
|
cTValue *mo2 = lj_meta_lookup(L, o2, mm);
|
||||||
if (tvisnil(mo) || !lj_obj_equal(mo, mo2)) {
|
if (tvisnil(mo) || !lj_obj_equal(mo, mo2))
|
||||||
|
#endif
|
||||||
|
{
|
||||||
if (op & 2) { /* MM_le not found: retry with MM_lt. */
|
if (op & 2) { /* MM_le not found: retry with MM_lt. */
|
||||||
cTValue *ot = o1; o1 = o2; o2 = ot; /* Swap operands. */
|
cTValue *ot = o1; o1 = o2; o2 = ot; /* Swap operands. */
|
||||||
op ^= 3; /* Use LT and flip condition. */
|
op ^= 3; /* Use LT and flip condition. */
|
||||||
|
@ -969,6 +969,16 @@ static void rec_mm_comp(jit_State *J, RecordIndex *ix, int op)
|
|||||||
copyTV(J->L, &ix->tabv, &ix->valv);
|
copyTV(J->L, &ix->tabv, &ix->valv);
|
||||||
while (1) {
|
while (1) {
|
||||||
MMS mm = (op & 2) ? MM_le : MM_lt; /* Try __le + __lt or only __lt. */
|
MMS mm = (op & 2) ? MM_le : MM_lt; /* Try __le + __lt or only __lt. */
|
||||||
|
#if LJ_52
|
||||||
|
if (!lj_record_mm_lookup(J, ix, mm)) { /* Lookup mm on 1st operand. */
|
||||||
|
ix->tab = ix->key;
|
||||||
|
copyTV(J->L, &ix->tabv, &ix->keyv);
|
||||||
|
if (!lj_record_mm_lookup(J, ix, mm)) /* Lookup mm on 2nd operand. */
|
||||||
|
goto nomatch;
|
||||||
|
}
|
||||||
|
rec_mm_callcomp(J, ix, op);
|
||||||
|
return;
|
||||||
|
#else
|
||||||
if (lj_record_mm_lookup(J, ix, mm)) { /* Lookup mm on 1st operand. */
|
if (lj_record_mm_lookup(J, ix, mm)) { /* Lookup mm on 1st operand. */
|
||||||
cTValue *bv;
|
cTValue *bv;
|
||||||
TRef mo1 = ix->mobj;
|
TRef mo1 = ix->mobj;
|
||||||
@ -992,8 +1002,9 @@ static void rec_mm_comp(jit_State *J, RecordIndex *ix, int op)
|
|||||||
rec_mm_callcomp(J, ix, op);
|
rec_mm_callcomp(J, ix, op);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
nomatch:
|
nomatch:
|
||||||
/* First lookup failed. Retry with __lt and swapped operands. */
|
/* Lookup failed. Retry with __lt and swapped operands. */
|
||||||
if (!(op & 2)) break; /* Already at __lt. Interpreter will throw. */
|
if (!(op & 2)) break; /* Already at __lt. Interpreter will throw. */
|
||||||
ix->tab = ix->key; ix->key = ix->val; ix->val = ix->tab;
|
ix->tab = ix->key; ix->key = ix->val; ix->val = ix->tab;
|
||||||
copyTV(J->L, &ix->tabv, &ix->keyv);
|
copyTV(J->L, &ix->tabv, &ix->keyv);
|
||||||
@ -1742,6 +1753,8 @@ void lj_record_ins(jit_State *J)
|
|||||||
ta = IRT_NUM;
|
ta = IRT_NUM;
|
||||||
} else if (ta == IRT_NUM && tc == IRT_INT) {
|
} else if (ta == IRT_NUM && tc == IRT_INT) {
|
||||||
rc = emitir(IRTN(IR_CONV), rc, IRCONV_NUM_INT);
|
rc = emitir(IRTN(IR_CONV), rc, IRCONV_NUM_INT);
|
||||||
|
} else if (LJ_52) {
|
||||||
|
ta = IRT_NIL; /* Force metamethod for different types. */
|
||||||
} else if (!((ta == IRT_FALSE || ta == IRT_TRUE) &&
|
} else if (!((ta == IRT_FALSE || ta == IRT_TRUE) &&
|
||||||
(tc == IRT_FALSE || tc == IRT_TRUE))) {
|
(tc == IRT_FALSE || tc == IRT_TRUE))) {
|
||||||
break; /* Interpreter will throw for two different types. */
|
break; /* Interpreter will throw for two different types. */
|
||||||
|
Loading…
Reference in New Issue
Block a user