From 3a43ea50843e4f6db73b8edf637dfd209ffbe2ab Mon Sep 17 00:00:00 2001 From: Mike Pall Date: Wed, 23 May 2012 22:19:05 +0200 Subject: [PATCH] FFI: Equality comparisons never raise an error. --- doc/ext_ffi_semantics.html | 5 +++++ src/lj_carith.c | 4 ++++ src/lj_crecord.c | 16 ++++++++++------ 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/doc/ext_ffi_semantics.html b/doc/ext_ffi_semantics.html index 2dbe41e9..304befa7 100644 --- a/doc/ext_ffi_semantics.html +++ b/doc/ext_ffi_semantics.html @@ -724,6 +724,11 @@ of them is an uint64_t, the other side is converted to an both sides are converted to an int64_t and a signed comparison is performed. +
  • Comparisons for equality/inequality 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.
  • +

    cdata objects as table keys

    diff --git a/src/lj_carith.c b/src/lj_carith.c index 56708bf6..583a3876 100644 --- a/src/lj_carith.c +++ b/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)); diff --git a/src/lj_crecord.c b/src/lj_crecord.c index 81ab3540..74d62d6c 100644 --- a/src/lj_crecord.c +++ b/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)