Classifies Val bits; Heap routes the host to HeapPool.
(val_bits: u64)
| 225 | |
| 226 | // Classifies Val bits; Heap routes the host to HeapPool. |
| 227 | pub fn classify_decode(val_bits: u64) -> DecodeBits { |
| 228 | use nan_box::*; |
| 229 | |
| 230 | // Float: any non-QNAN-tagged pattern. |
| 231 | if (val_bits & QNAN) != QNAN { |
| 232 | return DecodeBits::Primitive { |
| 233 | tag: Tag::Float as u32, |
| 234 | bytes: PrimitiveBytes::Eight(f64::from_bits(val_bits).to_le_bytes()), |
| 235 | }; |
| 236 | } |
| 237 | // Int: QNAN|SIGN with payload. Sign-extend the 47-bit payload to i128 (wire width). |
| 238 | if (val_bits & (QNAN | SIGN)) == TAG_INT { |
| 239 | let raw = (val_bits & INT_PAYLOAD_MASK) as i64; |
| 240 | let sign_extended_i64 = (raw << 16) >> 16; |
| 241 | let as_i128 = sign_extended_i64 as i128; |
| 242 | return DecodeBits::Primitive { |
| 243 | tag: Tag::Int as u32, |
| 244 | bytes: PrimitiveBytes::Sixteen(as_i128.to_le_bytes()), |
| 245 | }; |
| 246 | } |
| 247 | // Singletons and heap handles. |
| 248 | let lower = val_bits & 0xF; |
| 249 | if (val_bits & QNAN) == QNAN && (val_bits & SIGN) == 0 { |
| 250 | if val_bits == TAG_NONE { |
| 251 | return DecodeBits::Primitive { |
| 252 | tag: Tag::None as u32, bytes: PrimitiveBytes::None, |
| 253 | }; |
| 254 | } |
| 255 | if val_bits == TAG_TRUE { |
| 256 | return DecodeBits::Primitive { |
| 257 | tag: Tag::Bool as u32, bytes: PrimitiveBytes::Bool(1), |
| 258 | }; |
| 259 | } |
| 260 | if val_bits == TAG_FALSE { |
| 261 | return DecodeBits::Primitive { |
| 262 | tag: Tag::Bool as u32, bytes: PrimitiveBytes::Bool(0), |
| 263 | }; |
| 264 | } |
| 265 | if lower >= 4 { |
| 266 | return DecodeBits::Heap; |
| 267 | } |
| 268 | } |
| 269 | DecodeBits::Invalid |
| 270 | } |