]> git.ipfire.org Git - thirdparty/LuaJIT.git/commitdiff
FFI: Equality comparisons never raise an error.
authorMike Pall <mike>
Wed, 23 May 2012 20:19:05 +0000 (22:19 +0200)
committerMike Pall <mike>
Wed, 23 May 2012 20:20:27 +0000 (22:20 +0200)
doc/ext_ffi_semantics.html
src/lj_carith.c
src/lj_crecord.c

index 2dbe41e9b213635560f24f160d6aea33f725cf46..304befa7746bbfe4dcd9385795a679850cddc184 100644 (file)
@@ -724,6 +724,11 @@ of them is an <tt>uint64_t</tt>, the other side is converted to an
 both sides are converted to an <tt>int64_t</tt> and a signed
 comparison is performed.</li>
 
+<li><b>Comparisons for equality/inequality</b> never raise an error.
+Even incompatible pointers can be compared for equality by address. Any
+other incompatible comparison (also with non-cdata objects) treats the
+two sides as unequal.</li>
+
 </ul>
 
 <h3 id="cdata_key">cdata objects as table keys</h3>
index 56708bf67dc68bdcc7c131f8b4908ce4819cf2c0..583a3876700f3879f3a88da141c9f1af80128b11 100644 (file)
@@ -205,6 +205,10 @@ static int lj_carith_meta(lua_State *L, CTState *cts, CDArith *ca, MMS mm)
   if (!tv) {
     const char *repr[2];
     int i;
+    if (mm == MM_eq) {  /* Equality checks never raise an error. */
+      setboolV(L->top-1, 0);
+      return 1;
+    }
     for (i = 0; i < 2; i++) {
       if (ca->ct[i])
        repr[i] = strdata(lj_ctype_repr(L, ctype_typeid(cts, ca->ct[i]), NULL));
index 81ab354091bed9a27c83a3ea1ad64017de8354a0..74d62d6cd5cbe359ac40c6e7bf52e3476f621eb2 100644 (file)
@@ -1073,13 +1073,17 @@ static void crec_arith_meta(jit_State *J, CTState *cts, RecordFFData *rd)
       tv = lj_ctype_meta(cts, argv2cdata(J, J->base[1], &rd->argv[1])->typeid,
                         (MMS)rd->data);
   }
-  if (tv && tvisfunc(tv)) {
-    J->base[-1] = lj_ir_kfunc(J, funcV(tv)) | TREF_FRAME;
-    rd->nres = -1;  /* Pending tailcall. */
-  } else {
-    /* NYI: non-function metamethods. */
-    lj_trace_err(J, LJ_TRERR_BADTYPE);
+  if (tv) {
+    if (tvisfunc(tv)) {
+      J->base[-1] = lj_ir_kfunc(J, funcV(tv)) | TREF_FRAME;
+      rd->nres = -1;  /* Pending tailcall. */
+      return;
+    }  /* NYI: non-function metamethods. */
+  } else if ((MMS)rd->data == MM_eq) {
+    J->base[0] = TREF_FALSE;
+    return;
   }
+  lj_trace_err(J, LJ_TRERR_BADTYPE);
 }
 
 void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd)