1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
use super::numeric_prefix::{read_u32_prefix, read_u64_prefix};
use super::value_enum::Value;
impl Value {
/// Try to interpret the value as the IR's scalar `u32` word.
#[must_use]
#[inline]
pub fn try_as_u32(&self) -> Option<u32> {
match self {
Self::U32(v) => Some(*v),
Self::I32(v) => u32::try_from(*v).ok(),
Self::U64(v) => u32::try_from(*v).ok(),
Self::Bool(v) => Some(u32::from(*v)),
Self::Bytes(bytes) => (bytes.len() <= 4).then(|| read_u32_prefix(bytes)),
Self::Float(v) => Some(*v as u32),
Self::Tensor(_) | Self::Array(_) => None,
}
}
/// Interpret the value as the IR's scalar `u32` word.
#[inline]
pub fn as_u32(&self) -> u32 {
self.try_as_u32().unwrap_or_else(|| {
panic!(
"Value cannot be represented losslessly as u32: {self:?}. \
Fix: call try_as_u32 and handle the None case."
)
})
}
/// Try to interpret the value as a full `u64`.
#[must_use]
#[inline]
pub fn try_as_u64(&self) -> Option<u64> {
match self {
Self::U32(v) => Some(u64::from(*v)),
Self::I32(v) => u64::try_from(*v).ok(),
Self::U64(v) => Some(*v),
Self::Bool(v) => Some(u64::from(*v)),
Self::Bytes(bytes) => (bytes.len() <= 8).then(|| read_u64_prefix(bytes)),
Self::Float(v) => Some(*v as u64),
Self::Tensor(_) | Self::Array(_) => None,
}
}
/// Interpret the value as a full `u64`. `U32`/`I32` widen
/// zero-extended, `Bool` widens to 0/1, and `Bytes` decodes the
/// leading 8 bytes as little-endian. Used by reference-interpreter
/// casts that must preserve the upper half of a 64-bit payload
/// (Kimi audit finding #3).
#[inline]
pub fn as_u64(&self) -> u64 {
self.try_as_u64().unwrap_or_else(|| {
panic!(
"Value cannot be represented losslessly as u64: {self:?}. \
Fix: call try_as_u64 and handle the None case."
)
})
}
/// Return the full value payload as little-endian bytes, identical
/// to [`to_bytes`] except named for callers that need the widest
/// possible byte view (cast targets, multi-word vector casts).
///
/// [`to_bytes`]: Self::to_bytes
#[inline]
pub fn wide_bytes(&self) -> Vec<u8> {
self.to_bytes()
}
}