]> git.ipfire.org Git - thirdparty/LuaJIT.git/commitdiff
From Lua 5.2: Allow mixed metamethods for ordered comparisons.
authorMike Pall <mike>
Fri, 28 Sep 2012 17:30:08 +0000 (19:30 +0200)
committerMike Pall <mike>
Fri, 28 Sep 2012 17:30:08 +0000 (19:30 +0200)
Needs -DLUAJIT_ENABLE_LUA52COMPAT.

src/lj_meta.c
src/lj_record.c

index de2b4068f52760ab5b00c4f91f983de4f6860e0d..ab5d1b54be5be787267ff2f5941832c1be6cfb27 100644 (file)
@@ -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);
     if (LJ_UNLIKELY(tvisnil(mo))) goto err;
     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)) {
       int32_t res = lj_str_cmp(strV(o1), strV(o2));
       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;
        MMS mm = (op & 2) ? MM_le : MM_lt;
        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);
-       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. */
            cTValue *ot = o1; o1 = o2; o2 = ot;  /* Swap operands. */
            op ^= 3;  /* Use LT and flip condition. */
index 5910dab4384bf6961d20023d68efcb1b5ced2b3c..956f3bed480086760e4e095489ad61c85e7a22c4 100644 (file)
@@ -969,6 +969,16 @@ static void rec_mm_comp(jit_State *J, RecordIndex *ix, int op)
   copyTV(J->L, &ix->tabv, &ix->valv);
   while (1) {
     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. */
       cTValue *bv;
       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);
       return;
     }
+#endif
   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. */
     ix->tab = ix->key; ix->key = ix->val; ix->val = ix->tab;
     copyTV(J->L, &ix->tabv, &ix->keyv);
@@ -1742,6 +1753,8 @@ void lj_record_ins(jit_State *J)
          ta = IRT_NUM;
        } else if (ta == IRT_NUM && tc == IRT_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) &&
                     (tc == IRT_FALSE || tc == IRT_TRUE))) {
          break;  /* Interpreter will throw for two different types. */