diff --git a/src/lj_crecord.c b/src/lj_crecord.c index 8612f005..69b21f88 100644 --- a/src/lj_crecord.c +++ b/src/lj_crecord.c @@ -1317,7 +1317,7 @@ static TRef crec_arith_ptr(jit_State *J, TRef *sp, CType **s, MMS mm) } /* Record ctype arithmetic metamethods. */ -static TRef crec_arith_meta(jit_State *J, TRef *sp, CTState *cts, +static TRef crec_arith_meta(jit_State *J, TRef *sp, CType **s, CTState *cts, RecordFFData *rd) { cTValue *tv = NULL; @@ -1342,7 +1342,7 @@ static TRef crec_arith_meta(jit_State *J, TRef *sp, CTState *cts, return 0; } /* NYI: non-function metamethods. */ } else if ((MMS)rd->data == MM_eq) { /* Fallback cdata pointer comparison. */ - if (sp[0] && sp[1]) { + if (sp[0] && sp[1] && ctype_isnum(s[0]->info) == ctype_isnum(s[1]->info)) { /* Assume true comparison. Fixup and emit pending guard later. */ lj_ir_set(J, IRTG(IR_EQ, IRT_PTR), sp[0], sp[1]); J->postproc = LJ_POST_FIXGUARD; @@ -1420,9 +1420,13 @@ void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd) emitir(IRTG(IR_EQ, IRT_STR), tr, lj_ir_kstr(J, str)); ct = ctype_child(cts, cct); tr = lj_ir_kint(J, (int32_t)ofs); - } /* else: interpreter will throw. */ - } else { + } else { /* Interpreter will throw or return false. */ + ct = ctype_get(cts, CTID_P_VOID); + } + } else if (ctype_isptr(ct->info)) { tr = emitir(IRT(IR_ADD, IRT_PTR), tr, lj_ir_kintp(J, sizeof(GCstr))); + } else { + ct = ctype_get(cts, CTID_P_VOID); } } else if (!tref_isnum(tr)) { tr = 0; @@ -1435,7 +1439,7 @@ void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd) TRef tr; if (!(tr = crec_arith_int64(J, sp, s, (MMS)rd->data)) && !(tr = crec_arith_ptr(J, sp, s, (MMS)rd->data)) && - !(tr = crec_arith_meta(J, sp, cts, rd))) + !(tr = crec_arith_meta(J, sp, s, cts, rd))) return; J->base[0] = tr; /* Fixup cdata comparisons, too. Avoids some cdata escapes. */