FFI: Make FP to U64 conversions match JIT backend behavior.

This commit is contained in:
Mike Pall 2018-05-20 12:25:36 +02:00
parent cf7a0540a3
commit f5d424afe8

View File

@ -816,14 +816,22 @@ static LJ_AINLINE int32_t lj_num2bit(lua_Number n)
#define lj_num2int(n) ((int32_t)(n)) #define lj_num2int(n) ((int32_t)(n))
#endif #endif
/*
** This must match the JIT backend behavior. In particular for archs
** that don't have a common hardware instruction for this conversion.
** Note that signed FP to unsigned int conversions have an undefined
** result and should never be relied upon in portable FFI code.
** See also: C99 or C11 standard, 6.3.1.4, footnote of (1).
*/
static LJ_AINLINE uint64_t lj_num2u64(lua_Number n) static LJ_AINLINE uint64_t lj_num2u64(lua_Number n)
{ {
#ifdef _MSC_VER #if LJ_TARGET_X86ORX64 || LJ_TARGET_MIPS
if (n >= 9223372036854775808.0) /* They think it's a feature. */ int64_t i = (int64_t)n;
return (uint64_t)(int64_t)(n - 18446744073709551616.0); if (i < 0) i = (int64_t)(n - 18446744073709551616.0);
else return (uint64_t)i;
#endif #else
return (uint64_t)n; return (uint64_t)n;
#endif
} }
static LJ_AINLINE int32_t numberVint(cTValue *o) static LJ_AINLINE int32_t numberVint(cTValue *o)