diff --git a/src/lib_ffi.c b/src/lib_ffi.c index 45065c12..361c3ba1 100644 --- a/src/lib_ffi.c +++ b/src/lib_ffi.c @@ -482,7 +482,7 @@ LJLIB_CF(ffi_fill) LJLIB_REC(.) #define H_(le, be) LJ_ENDIAN_SELECT(0x##le, 0x##be) /* Test ABI string. */ -LJLIB_CF(ffi_abi) +LJLIB_CF(ffi_abi) LJLIB_REC(.) { GCstr *s = lj_lib_checkstr(L, 1); int b = 0; @@ -511,6 +511,7 @@ LJLIB_CF(ffi_abi) break; } setboolV(L->top-1, b); + setboolV(&G(L)->tmptv2, b); /* Remember for trace recorder. */ return 1; } diff --git a/src/lj_crecord.c b/src/lj_crecord.c index 8e68a5d6..73575fe2 100644 --- a/src/lj_crecord.c +++ b/src/lj_crecord.c @@ -1008,6 +1008,16 @@ void LJ_FASTCALL recff_ffi_fill(jit_State *J, RecordFFData *rd) } /* else: interpreter will throw. */ } +void LJ_FASTCALL recff_ffi_abi(jit_State *J, RecordFFData *rd) +{ + if (tref_isstr(J->base[0])) { + /* Specialize to the ABI string to make the boolean result a constant. */ + emitir(IRTG(IR_EQ, IRT_STR), J->base[0], lj_ir_kstr(J, strV(&rd->argv[0]))); + J->postproc = LJ_POST_FIXBOOL; + J->base[0] = TREF_TRUE; + } /* else: interpreter will throw. */ +} + /* -- Miscellaneous library functions ------------------------------------- */ void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd) diff --git a/src/lj_crecord.h b/src/lj_crecord.h index 1714f1c4..0199e0eb 100644 --- a/src/lj_crecord.h +++ b/src/lj_crecord.h @@ -19,6 +19,7 @@ LJ_FUNC void LJ_FASTCALL recff_ffi_new(jit_State *J, RecordFFData *rd); LJ_FUNC void LJ_FASTCALL recff_ffi_string(jit_State *J, RecordFFData *rd); LJ_FUNC void LJ_FASTCALL recff_ffi_copy(jit_State *J, RecordFFData *rd); LJ_FUNC void LJ_FASTCALL recff_ffi_fill(jit_State *J, RecordFFData *rd); +LJ_FUNC void LJ_FASTCALL recff_ffi_abi(jit_State *J, RecordFFData *rd); LJ_FUNC void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd); #else #define recff_cdata_index recff_nyi @@ -29,6 +30,7 @@ LJ_FUNC void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd); #define recff_ffi_string recff_nyi #define recff_ffi_copy recff_nyi #define recff_ffi_fill recff_nyi +#define recff_ffi_abi recff_nyi #endif #endif diff --git a/src/lj_jit.h b/src/lj_jit.h index 2f3df2a0..e2dd5fb8 100644 --- a/src/lj_jit.h +++ b/src/lj_jit.h @@ -112,7 +112,8 @@ typedef enum { typedef enum { LJ_POST_NONE, /* No action. */ LJ_POST_FIXCOMP, /* Fixup comparison and emit pending guard. */ - LJ_POST_FIXGUARD /* Fixup and emit pending guard. */ + LJ_POST_FIXGUARD, /* Fixup and emit pending guard. */ + LJ_POST_FIXBOOL /* Fixup boolean result. */ } PostProc; /* Machine code type. */ diff --git a/src/lj_record.c b/src/lj_record.c index d8c67499..26e87ab3 100644 --- a/src/lj_record.c +++ b/src/lj_record.c @@ -1388,16 +1388,19 @@ void lj_record_ins(jit_State *J) rec_comp_fixup(J, pc, (!tvistruecond(&J2G(J)->tmptv2) ^ (bc_op(*pc)&1))); /* fallthrough */ case LJ_POST_FIXGUARD: /* Fixup and emit pending guard. */ + if (!tvistruecond(&J2G(J)->tmptv2)) + J->fold.ins.o ^= 1; /* Flip guard to opposite. */ + lj_opt_fold(J); /* Emit pending guard. */ + /* fallthrough */ + case LJ_POST_FIXBOOL: if (!tvistruecond(&J2G(J)->tmptv2)) { BCReg s; - J->fold.ins.o ^= 1; /* Flip guard to opposite. */ for (s = 0; s < J->maxslot; s++) /* Fixup stack slot (if any). */ if (J->base[s] == TREF_TRUE && tvisfalse(&J->L->base[s])) { J->base[s] = TREF_FALSE; break; } } - lj_opt_fold(J); /* Emit pending guard. */ break; default: lua_assert(0); break; }