瀏覽代碼

FFI: Equality comparisons never raise an error.

Mike Pall 13 年之前
父節點
當前提交
3a43ea5084
共有 3 個文件被更改,包括 19 次插入6 次删除
  1. 5 0
      doc/ext_ffi_semantics.html
  2. 4 0
      src/lj_carith.c
  3. 10 6
      src/lj_crecord.c

+ 5 - 0
doc/ext_ffi_semantics.html

@@ -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>

+ 4 - 0
src/lj_carith.c

@@ -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));

+ 10 - 6
src/lj_crecord.c

@@ -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)