IEEE 754 NaN payloads (51 bits in double precision) are actively exploited by JS and Lua runtimes to store all non-float values and type tags in a single 64-bit word.
Key Takeaways
NaN-boxing lets JavaScriptCore, SpiderMonkey, and LuaJIT encode every runtime value – pointers, integers, booleans – in 64 bits by repurposing quiet NaN payload bits.
JSC’s encoding uses the top 16 bits as a type tag: 0x0000 = pointer, 0xFFFF = 32-bit integer, with doubles shifted by 2^48 to avoid those ranges.
The IEEE 754-2008 spec explicitly encourages preserving NaN payload bits for “diagnostic information”, making this a standards-blessed hack, not an abuse.
Signaling NaNs (payload top bit = 0) can trigger exceptions and are used to detect reads of uninitialized variables; quiet NaNs (top bit = 1) propagate silently.
48-bit x86-64 pointers and 32-bit integers both fit inside the 51-bit payload, which is why the trick works on current hardware.