16f6f79efSAndrew Brown //! This module gives users to instantiate values that Cranelift understands. These values are used,
26f6f79efSAndrew Brown //! for example, during interpretation and for wrapping immediates.
390ac295eSAlex Crichton use crate::ir::immediates::{Ieee16, Ieee32, Ieee64, Ieee128, Offset32};
490ac295eSAlex Crichton use crate::ir::{ConstantData, Type, types};
57ac3fda7Sbeetrees use core::cmp::Ordering;
66f6f79efSAndrew Brown use core::fmt::{self, Display, Formatter};
76f6f79efSAndrew Brown
86f6f79efSAndrew Brown /// Represent a data value. Where [Value] is an SSA reference, [DataValue] is the type + value
96f6f79efSAndrew Brown /// that would be referred to by a [Value].
106f6f79efSAndrew Brown ///
116f6f79efSAndrew Brown /// [Value]: crate::ir::Value
12099102d9SAlex Crichton #[expect(missing_docs, reason = "self-describing variants")]
139856664fSJamey Sharp #[derive(Clone, Debug, PartialOrd)]
146f6f79efSAndrew Brown pub enum DataValue {
156f6f79efSAndrew Brown I8(i8),
166f6f79efSAndrew Brown I16(i16),
176f6f79efSAndrew Brown I32(i32),
186f6f79efSAndrew Brown I64(i64),
19084383f6SAfonso Bordado I128(i128),
207ac3fda7Sbeetrees F16(Ieee16),
213778fa02SAndrew Brown F32(Ieee32),
223778fa02SAndrew Brown F64(Ieee64),
237ac3fda7Sbeetrees F128(Ieee128),
246f6f79efSAndrew Brown V128([u8; 16]),
253ef89b77SDamian Heaton V64([u8; 8]),
26d48b3856Sbeetrees V32([u8; 4]),
27d48b3856Sbeetrees V16([u8; 2]),
286f6f79efSAndrew Brown }
296f6f79efSAndrew Brown
309856664fSJamey Sharp impl PartialEq for DataValue {
eq(&self, other: &Self) -> bool319856664fSJamey Sharp fn eq(&self, other: &Self) -> bool {
329856664fSJamey Sharp use DataValue::*;
339856664fSJamey Sharp match (self, other) {
349856664fSJamey Sharp (I8(l), I8(r)) => l == r,
359856664fSJamey Sharp (I8(_), _) => false,
369856664fSJamey Sharp (I16(l), I16(r)) => l == r,
379856664fSJamey Sharp (I16(_), _) => false,
389856664fSJamey Sharp (I32(l), I32(r)) => l == r,
399856664fSJamey Sharp (I32(_), _) => false,
409856664fSJamey Sharp (I64(l), I64(r)) => l == r,
419856664fSJamey Sharp (I64(_), _) => false,
429856664fSJamey Sharp (I128(l), I128(r)) => l == r,
439856664fSJamey Sharp (I128(_), _) => false,
447ac3fda7Sbeetrees (F16(l), F16(r)) => l.partial_cmp(&r) == Some(Ordering::Equal),
457ac3fda7Sbeetrees (F16(_), _) => false,
469856664fSJamey Sharp (F32(l), F32(r)) => l.as_f32() == r.as_f32(),
479856664fSJamey Sharp (F32(_), _) => false,
489856664fSJamey Sharp (F64(l), F64(r)) => l.as_f64() == r.as_f64(),
499856664fSJamey Sharp (F64(_), _) => false,
507ac3fda7Sbeetrees (F128(l), F128(r)) => l.partial_cmp(&r) == Some(Ordering::Equal),
517ac3fda7Sbeetrees (F128(_), _) => false,
529856664fSJamey Sharp (V128(l), V128(r)) => l == r,
539856664fSJamey Sharp (V128(_), _) => false,
549856664fSJamey Sharp (V64(l), V64(r)) => l == r,
559856664fSJamey Sharp (V64(_), _) => false,
56d48b3856Sbeetrees (V32(l), V32(r)) => l == r,
57d48b3856Sbeetrees (V32(_), _) => false,
58d48b3856Sbeetrees (V16(l), V16(r)) => l == r,
59d48b3856Sbeetrees (V16(_), _) => false,
609856664fSJamey Sharp }
619856664fSJamey Sharp }
629856664fSJamey Sharp }
639856664fSJamey Sharp
646f6f79efSAndrew Brown impl DataValue {
65a2fb019bSAfonso Bordado /// Try to cast an immediate integer (a wrapped `i64` on most Cranelift instructions) to the
666d500998SAndrew Brown /// given Cranelift [Type].
from_integer(imm: i128, ty: Type) -> Result<DataValue, DataValueCastFailure>67084383f6SAfonso Bordado pub fn from_integer(imm: i128, ty: Type) -> Result<DataValue, DataValueCastFailure> {
686f6f79efSAndrew Brown match ty {
696d500998SAndrew Brown types::I8 => Ok(DataValue::I8(imm as i8)),
706d500998SAndrew Brown types::I16 => Ok(DataValue::I16(imm as i16)),
716d500998SAndrew Brown types::I32 => Ok(DataValue::I32(imm as i32)),
72084383f6SAfonso Bordado types::I64 => Ok(DataValue::I64(imm as i64)),
73084383f6SAfonso Bordado types::I128 => Ok(DataValue::I128(imm)),
746d500998SAndrew Brown _ => Err(DataValueCastFailure::FromInteger(imm, ty)),
756f6f79efSAndrew Brown }
766f6f79efSAndrew Brown }
776f6f79efSAndrew Brown
786f6f79efSAndrew Brown /// Return the Cranelift IR [Type] for this [DataValue].
ty(&self) -> Type796f6f79efSAndrew Brown pub fn ty(&self) -> Type {
806f6f79efSAndrew Brown match self {
81387db16dST0b1-iOS DataValue::I8(_) => types::I8,
82387db16dST0b1-iOS DataValue::I16(_) => types::I16,
83387db16dST0b1-iOS DataValue::I32(_) => types::I32,
84387db16dST0b1-iOS DataValue::I64(_) => types::I64,
85387db16dST0b1-iOS DataValue::I128(_) => types::I128,
867ac3fda7Sbeetrees DataValue::F16(_) => types::F16,
876f6f79efSAndrew Brown DataValue::F32(_) => types::F32,
886f6f79efSAndrew Brown DataValue::F64(_) => types::F64,
897ac3fda7Sbeetrees DataValue::F128(_) => types::F128,
906f6f79efSAndrew Brown DataValue::V128(_) => types::I8X16, // A default type.
913ef89b77SDamian Heaton DataValue::V64(_) => types::I8X8, // A default type.
92d48b3856Sbeetrees DataValue::V32(_) => types::I8X4, // A default type.
93d48b3856Sbeetrees DataValue::V16(_) => types::I8X2, // A default type.
946f6f79efSAndrew Brown }
956f6f79efSAndrew Brown }
966f6f79efSAndrew Brown
976f6f79efSAndrew Brown /// Return true if the value is a vector (i.e. `DataValue::V128`).
is_vector(&self) -> bool986f6f79efSAndrew Brown pub fn is_vector(&self) -> bool {
996f6f79efSAndrew Brown match self {
100d48b3856Sbeetrees DataValue::V128(_) | DataValue::V64(_) | DataValue::V32(_) | DataValue::V16(_) => true,
1016f6f79efSAndrew Brown _ => false,
1026f6f79efSAndrew Brown }
1036f6f79efSAndrew Brown }
1046d500998SAndrew Brown
swap_bytes(self) -> Self105db8fe010SJan-Justin van Tonder fn swap_bytes(self) -> Self {
106db8fe010SJan-Justin van Tonder match self {
107db8fe010SJan-Justin van Tonder DataValue::I8(i) => DataValue::I8(i.swap_bytes()),
108db8fe010SJan-Justin van Tonder DataValue::I16(i) => DataValue::I16(i.swap_bytes()),
109db8fe010SJan-Justin van Tonder DataValue::I32(i) => DataValue::I32(i.swap_bytes()),
110db8fe010SJan-Justin van Tonder DataValue::I64(i) => DataValue::I64(i.swap_bytes()),
111db8fe010SJan-Justin van Tonder DataValue::I128(i) => DataValue::I128(i.swap_bytes()),
1127ac3fda7Sbeetrees DataValue::F16(f) => DataValue::F16(Ieee16::with_bits(f.bits().swap_bytes())),
113db8fe010SJan-Justin van Tonder DataValue::F32(f) => DataValue::F32(Ieee32::with_bits(f.bits().swap_bytes())),
114db8fe010SJan-Justin van Tonder DataValue::F64(f) => DataValue::F64(Ieee64::with_bits(f.bits().swap_bytes())),
1157ac3fda7Sbeetrees DataValue::F128(f) => DataValue::F128(Ieee128::with_bits(f.bits().swap_bytes())),
116db8fe010SJan-Justin van Tonder DataValue::V128(mut v) => {
117db8fe010SJan-Justin van Tonder v.reverse();
118db8fe010SJan-Justin van Tonder DataValue::V128(v)
119db8fe010SJan-Justin van Tonder }
120db8fe010SJan-Justin van Tonder DataValue::V64(mut v) => {
121db8fe010SJan-Justin van Tonder v.reverse();
122db8fe010SJan-Justin van Tonder DataValue::V64(v)
123db8fe010SJan-Justin van Tonder }
124d48b3856Sbeetrees DataValue::V32(mut v) => {
125d48b3856Sbeetrees v.reverse();
126d48b3856Sbeetrees DataValue::V32(v)
127d48b3856Sbeetrees }
128d48b3856Sbeetrees DataValue::V16(mut v) => {
129d48b3856Sbeetrees v.reverse();
130d48b3856Sbeetrees DataValue::V16(v)
131d48b3856Sbeetrees }
132db8fe010SJan-Justin van Tonder }
133db8fe010SJan-Justin van Tonder }
134db8fe010SJan-Justin van Tonder
135db8fe010SJan-Justin van Tonder /// Converts `self` to big endian from target's endianness.
to_be(self) -> Self136db8fe010SJan-Justin van Tonder pub fn to_be(self) -> Self {
137db8fe010SJan-Justin van Tonder if cfg!(target_endian = "big") {
138db8fe010SJan-Justin van Tonder self
139db8fe010SJan-Justin van Tonder } else {
140db8fe010SJan-Justin van Tonder self.swap_bytes()
141db8fe010SJan-Justin van Tonder }
142db8fe010SJan-Justin van Tonder }
143db8fe010SJan-Justin van Tonder
144db8fe010SJan-Justin van Tonder /// Converts `self` to little endian from target's endianness.
to_le(self) -> Self145db8fe010SJan-Justin van Tonder pub fn to_le(self) -> Self {
146db8fe010SJan-Justin van Tonder if cfg!(target_endian = "little") {
147db8fe010SJan-Justin van Tonder self
148db8fe010SJan-Justin van Tonder } else {
149db8fe010SJan-Justin van Tonder self.swap_bytes()
150db8fe010SJan-Justin van Tonder }
151db8fe010SJan-Justin van Tonder }
152db8fe010SJan-Justin van Tonder
153db8fe010SJan-Justin van Tonder /// Write a [DataValue] to a slice in native-endian byte order.
1542776074dSAfonso Bordado ///
1552776074dSAfonso Bordado /// # Panics:
1562776074dSAfonso Bordado ///
1572776074dSAfonso Bordado /// Panics if the slice does not have enough space to accommodate the [DataValue]
write_to_slice_ne(&self, dst: &mut [u8])158db8fe010SJan-Justin van Tonder pub fn write_to_slice_ne(&self, dst: &mut [u8]) {
1596d500998SAndrew Brown match self {
1601b8154e0SUlrich Weigand DataValue::I8(i) => dst[..1].copy_from_slice(&i.to_ne_bytes()[..]),
1611b8154e0SUlrich Weigand DataValue::I16(i) => dst[..2].copy_from_slice(&i.to_ne_bytes()[..]),
1621b8154e0SUlrich Weigand DataValue::I32(i) => dst[..4].copy_from_slice(&i.to_ne_bytes()[..]),
1631b8154e0SUlrich Weigand DataValue::I64(i) => dst[..8].copy_from_slice(&i.to_ne_bytes()[..]),
1648115e725SAfonso Bordado DataValue::I128(i) => dst[..16].copy_from_slice(&i.to_ne_bytes()[..]),
1657ac3fda7Sbeetrees DataValue::F16(f) => dst[..2].copy_from_slice(&f.bits().to_ne_bytes()[..]),
1661b8154e0SUlrich Weigand DataValue::F32(f) => dst[..4].copy_from_slice(&f.bits().to_ne_bytes()[..]),
1671b8154e0SUlrich Weigand DataValue::F64(f) => dst[..8].copy_from_slice(&f.bits().to_ne_bytes()[..]),
1687ac3fda7Sbeetrees DataValue::F128(f) => dst[..16].copy_from_slice(&f.bits().to_ne_bytes()[..]),
16967870d15SUlrich Weigand DataValue::V128(v) => dst[..16].copy_from_slice(&v[..]),
17067870d15SUlrich Weigand DataValue::V64(v) => dst[..8].copy_from_slice(&v[..]),
171d48b3856Sbeetrees DataValue::V32(v) => dst[..4].copy_from_slice(&v[..]),
172d48b3856Sbeetrees DataValue::V16(v) => dst[..2].copy_from_slice(&v[..]),
1732776074dSAfonso Bordado };
1742776074dSAfonso Bordado }
1752776074dSAfonso Bordado
176db8fe010SJan-Justin van Tonder /// Write a [DataValue] to a slice in big-endian byte order.
1772776074dSAfonso Bordado ///
1782776074dSAfonso Bordado /// # Panics:
1792776074dSAfonso Bordado ///
1802776074dSAfonso Bordado /// Panics if the slice does not have enough space to accommodate the [DataValue]
write_to_slice_be(&self, dst: &mut [u8])181db8fe010SJan-Justin van Tonder pub fn write_to_slice_be(&self, dst: &mut [u8]) {
182db8fe010SJan-Justin van Tonder self.clone().to_be().write_to_slice_ne(dst);
183db8fe010SJan-Justin van Tonder }
184db8fe010SJan-Justin van Tonder
185db8fe010SJan-Justin van Tonder /// Write a [DataValue] to a slice in little-endian byte order.
186db8fe010SJan-Justin van Tonder ///
187db8fe010SJan-Justin van Tonder /// # Panics:
188db8fe010SJan-Justin van Tonder ///
189db8fe010SJan-Justin van Tonder /// Panics if the slice does not have enough space to accommodate the [DataValue]
write_to_slice_le(&self, dst: &mut [u8])190db8fe010SJan-Justin van Tonder pub fn write_to_slice_le(&self, dst: &mut [u8]) {
191db8fe010SJan-Justin van Tonder self.clone().to_le().write_to_slice_ne(dst);
192db8fe010SJan-Justin van Tonder }
193db8fe010SJan-Justin van Tonder
194db8fe010SJan-Justin van Tonder /// Read a [DataValue] from a slice using a given [Type] with native-endian byte order.
195db8fe010SJan-Justin van Tonder ///
196db8fe010SJan-Justin van Tonder /// # Panics:
197db8fe010SJan-Justin van Tonder ///
198db8fe010SJan-Justin van Tonder /// Panics if the slice does not have enough space to accommodate the [DataValue]
read_from_slice_ne(src: &[u8], ty: Type) -> Self199db8fe010SJan-Justin van Tonder pub fn read_from_slice_ne(src: &[u8], ty: Type) -> Self {
2002776074dSAfonso Bordado match ty {
2011b8154e0SUlrich Weigand types::I8 => DataValue::I8(i8::from_ne_bytes(src[..1].try_into().unwrap())),
2021b8154e0SUlrich Weigand types::I16 => DataValue::I16(i16::from_ne_bytes(src[..2].try_into().unwrap())),
2031b8154e0SUlrich Weigand types::I32 => DataValue::I32(i32::from_ne_bytes(src[..4].try_into().unwrap())),
2041b8154e0SUlrich Weigand types::I64 => DataValue::I64(i64::from_ne_bytes(src[..8].try_into().unwrap())),
2058115e725SAfonso Bordado types::I128 => DataValue::I128(i128::from_ne_bytes(src[..16].try_into().unwrap())),
2067ac3fda7Sbeetrees types::F16 => DataValue::F16(Ieee16::with_bits(u16::from_ne_bytes(
2077ac3fda7Sbeetrees src[..2].try_into().unwrap(),
2087ac3fda7Sbeetrees ))),
2091b8154e0SUlrich Weigand types::F32 => DataValue::F32(Ieee32::with_bits(u32::from_ne_bytes(
2102776074dSAfonso Bordado src[..4].try_into().unwrap(),
2112776074dSAfonso Bordado ))),
2121b8154e0SUlrich Weigand types::F64 => DataValue::F64(Ieee64::with_bits(u64::from_ne_bytes(
2132776074dSAfonso Bordado src[..8].try_into().unwrap(),
2142776074dSAfonso Bordado ))),
2157ac3fda7Sbeetrees types::F128 => DataValue::F128(Ieee128::with_bits(u128::from_ne_bytes(
2167ac3fda7Sbeetrees src[..16].try_into().unwrap(),
2177ac3fda7Sbeetrees ))),
218d48b3856Sbeetrees _ if ty.is_vector() => match ty.bytes() {
219d48b3856Sbeetrees 16 => DataValue::V128(src[..16].try_into().unwrap()),
220d48b3856Sbeetrees 8 => DataValue::V64(src[..8].try_into().unwrap()),
221d48b3856Sbeetrees 4 => DataValue::V32(src[..4].try_into().unwrap()),
222d48b3856Sbeetrees 2 => DataValue::V16(src[..2].try_into().unwrap()),
223d48b3856Sbeetrees _ => unimplemented!(),
224d48b3856Sbeetrees },
2256d500998SAndrew Brown _ => unimplemented!(),
2266d500998SAndrew Brown }
2276d500998SAndrew Brown }
2286d500998SAndrew Brown
229db8fe010SJan-Justin van Tonder /// Read a [DataValue] from a slice using a given [Type] in big-endian byte order.
230db8fe010SJan-Justin van Tonder ///
231db8fe010SJan-Justin van Tonder /// # Panics:
232db8fe010SJan-Justin van Tonder ///
233db8fe010SJan-Justin van Tonder /// Panics if the slice does not have enough space to accommodate the [DataValue]
read_from_slice_be(src: &[u8], ty: Type) -> Self234db8fe010SJan-Justin van Tonder pub fn read_from_slice_be(src: &[u8], ty: Type) -> Self {
235db8fe010SJan-Justin van Tonder DataValue::read_from_slice_ne(src, ty).to_be()
2362776074dSAfonso Bordado }
2372776074dSAfonso Bordado
238db8fe010SJan-Justin van Tonder /// Read a [DataValue] from a slice using a given [Type] in little-endian byte order.
239db8fe010SJan-Justin van Tonder ///
240db8fe010SJan-Justin van Tonder /// # Panics:
241db8fe010SJan-Justin van Tonder ///
242db8fe010SJan-Justin van Tonder /// Panics if the slice does not have enough space to accommodate the [DataValue]
read_from_slice_le(src: &[u8], ty: Type) -> Self243db8fe010SJan-Justin van Tonder pub fn read_from_slice_le(src: &[u8], ty: Type) -> Self {
244db8fe010SJan-Justin van Tonder DataValue::read_from_slice_ne(src, ty).to_le()
245db8fe010SJan-Justin van Tonder }
246db8fe010SJan-Justin van Tonder
247db8fe010SJan-Justin van Tonder /// Write a [DataValue] to a memory location in native-endian byte order.
write_value_to(&self, p: *mut u128)248db8fe010SJan-Justin van Tonder pub unsafe fn write_value_to(&self, p: *mut u128) {
249db8fe010SJan-Justin van Tonder let size = self.ty().bytes() as usize;
250*0889323aSSSD self.write_to_slice_ne(unsafe { core::slice::from_raw_parts_mut(p as *mut u8, size) });
251db8fe010SJan-Justin van Tonder }
252db8fe010SJan-Justin van Tonder
253db8fe010SJan-Justin van Tonder /// Read a [DataValue] from a memory location using a given [Type] in native-endian byte order.
read_value_from(p: *const u128, ty: Type) -> Self2546d500998SAndrew Brown pub unsafe fn read_value_from(p: *const u128, ty: Type) -> Self {
255db8fe010SJan-Justin van Tonder DataValue::read_from_slice_ne(
256*0889323aSSSD unsafe { core::slice::from_raw_parts(p as *const u8, ty.bytes() as usize) },
2572776074dSAfonso Bordado ty,
2582776074dSAfonso Bordado )
2596d500998SAndrew Brown }
2607e45cff4SAfonso Bordado
2617e45cff4SAfonso Bordado /// Performs a bitwise comparison over the contents of [DataValue].
2627e45cff4SAfonso Bordado ///
2637e45cff4SAfonso Bordado /// Returns true if all bits are equal.
2647e45cff4SAfonso Bordado ///
2657e45cff4SAfonso Bordado /// This behaviour is different from PartialEq for NaN floats.
bitwise_eq(&self, other: &DataValue) -> bool2667e45cff4SAfonso Bordado pub fn bitwise_eq(&self, other: &DataValue) -> bool {
2677e45cff4SAfonso Bordado match (self, other) {
2687e45cff4SAfonso Bordado // We need to bit compare the floats to ensure that we produce the correct values
2697e45cff4SAfonso Bordado // on NaN's. The test suite expects to assert the precise bit pattern on NaN's or
2707e45cff4SAfonso Bordado // works around it in the tests themselves.
2717ac3fda7Sbeetrees (DataValue::F16(a), DataValue::F16(b)) => a.bits() == b.bits(),
2727e45cff4SAfonso Bordado (DataValue::F32(a), DataValue::F32(b)) => a.bits() == b.bits(),
2737e45cff4SAfonso Bordado (DataValue::F64(a), DataValue::F64(b)) => a.bits() == b.bits(),
2747ac3fda7Sbeetrees (DataValue::F128(a), DataValue::F128(b)) => a.bits() == b.bits(),
2757e45cff4SAfonso Bordado
2767e45cff4SAfonso Bordado // We don't need to worry about F32x4 / F64x2 Since we compare V128 which is already the
2777e45cff4SAfonso Bordado // raw bytes anyway
2787e45cff4SAfonso Bordado (a, b) => a == b,
2797e45cff4SAfonso Bordado }
2807e45cff4SAfonso Bordado }
2816f6f79efSAndrew Brown }
2826f6f79efSAndrew Brown
2836f6f79efSAndrew Brown /// Record failures to cast [DataValue].
28403fdbadfSbjorn3 #[derive(Debug, PartialEq)]
285099102d9SAlex Crichton #[expect(missing_docs, reason = "self-describing variants")]
2866f6f79efSAndrew Brown pub enum DataValueCastFailure {
2876f6f79efSAndrew Brown TryInto(Type, Type),
288084383f6SAfonso Bordado FromInteger(i128, Type),
2896f6f79efSAndrew Brown }
2906f6f79efSAndrew Brown
29182f3ad4fSbjorn3 // This is manually implementing Error and Display instead of using thiserror to reduce the amount
29282f3ad4fSbjorn3 // of dependencies used by Cranelift.
293*0889323aSSSD impl core::error::Error for DataValueCastFailure {}
29403fdbadfSbjorn3
29503fdbadfSbjorn3 impl Display for DataValueCastFailure {
fmt(&self, f: &mut Formatter) -> fmt::Result29603fdbadfSbjorn3 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
29703fdbadfSbjorn3 match self {
29803fdbadfSbjorn3 DataValueCastFailure::TryInto(from, to) => {
299a0442ea0SHamir Mahal write!(f, "unable to cast data value of type {from} to type {to}")
30003fdbadfSbjorn3 }
30103fdbadfSbjorn3 DataValueCastFailure::FromInteger(val, to) => {
302a0442ea0SHamir Mahal write!(f, "unable to cast i64({val}) to a data value of type {to}")
30303fdbadfSbjorn3 }
30403fdbadfSbjorn3 }
30503fdbadfSbjorn3 }
30603fdbadfSbjorn3 }
30703fdbadfSbjorn3
3086f6f79efSAndrew Brown /// Helper for creating conversion implementations for [DataValue].
3096f6f79efSAndrew Brown macro_rules! build_conversion_impl {
3106f6f79efSAndrew Brown ( $rust_ty:ty, $data_value_ty:ident, $cranelift_ty:ident ) => {
3116f6f79efSAndrew Brown impl From<$rust_ty> for DataValue {
3126f6f79efSAndrew Brown fn from(data: $rust_ty) -> Self {
3136f6f79efSAndrew Brown DataValue::$data_value_ty(data)
3146f6f79efSAndrew Brown }
3156f6f79efSAndrew Brown }
3166f6f79efSAndrew Brown
3176f6f79efSAndrew Brown impl TryInto<$rust_ty> for DataValue {
3186f6f79efSAndrew Brown type Error = DataValueCastFailure;
3196f6f79efSAndrew Brown fn try_into(self) -> Result<$rust_ty, Self::Error> {
3206f6f79efSAndrew Brown if let DataValue::$data_value_ty(v) = self {
3216f6f79efSAndrew Brown Ok(v)
3226f6f79efSAndrew Brown } else {
3236f6f79efSAndrew Brown Err(DataValueCastFailure::TryInto(
3246f6f79efSAndrew Brown self.ty(),
3256f6f79efSAndrew Brown types::$cranelift_ty,
3266f6f79efSAndrew Brown ))
3276f6f79efSAndrew Brown }
3286f6f79efSAndrew Brown }
3296f6f79efSAndrew Brown }
3306f6f79efSAndrew Brown };
3316f6f79efSAndrew Brown }
3326f6f79efSAndrew Brown build_conversion_impl!(i8, I8, I8);
3336f6f79efSAndrew Brown build_conversion_impl!(i16, I16, I16);
3346f6f79efSAndrew Brown build_conversion_impl!(i32, I32, I32);
3356f6f79efSAndrew Brown build_conversion_impl!(i64, I64, I64);
336084383f6SAfonso Bordado build_conversion_impl!(i128, I128, I128);
3377ac3fda7Sbeetrees build_conversion_impl!(Ieee16, F16, F16);
3383778fa02SAndrew Brown build_conversion_impl!(Ieee32, F32, F32);
3393778fa02SAndrew Brown build_conversion_impl!(Ieee64, F64, F64);
3407ac3fda7Sbeetrees build_conversion_impl!(Ieee128, F128, F128);
3416f6f79efSAndrew Brown build_conversion_impl!([u8; 16], V128, I8X16);
3423ef89b77SDamian Heaton build_conversion_impl!([u8; 8], V64, I8X8);
343d48b3856Sbeetrees build_conversion_impl!([u8; 4], V32, I8X4);
344d48b3856Sbeetrees build_conversion_impl!([u8; 2], V16, I8X2);
3453a2025fdSAndrew Brown impl From<Offset32> for DataValue {
from(o: Offset32) -> Self3463a2025fdSAndrew Brown fn from(o: Offset32) -> Self {
3473a2025fdSAndrew Brown DataValue::from(Into::<i32>::into(o))
3483a2025fdSAndrew Brown }
3493a2025fdSAndrew Brown }
3506f6f79efSAndrew Brown
3516f6f79efSAndrew Brown impl Display for DataValue {
fmt(&self, f: &mut Formatter<'_>) -> fmt::Result3526f6f79efSAndrew Brown fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
3536f6f79efSAndrew Brown match self {
354a0442ea0SHamir Mahal DataValue::I8(dv) => write!(f, "{dv}"),
355a0442ea0SHamir Mahal DataValue::I16(dv) => write!(f, "{dv}"),
356a0442ea0SHamir Mahal DataValue::I32(dv) => write!(f, "{dv}"),
357a0442ea0SHamir Mahal DataValue::I64(dv) => write!(f, "{dv}"),
358a0442ea0SHamir Mahal DataValue::I128(dv) => write!(f, "{dv}"),
3593778fa02SAndrew Brown // The Ieee* wrappers here print the expected syntax.
360a0442ea0SHamir Mahal DataValue::F16(dv) => write!(f, "{dv}"),
361a0442ea0SHamir Mahal DataValue::F32(dv) => write!(f, "{dv}"),
362a0442ea0SHamir Mahal DataValue::F64(dv) => write!(f, "{dv}"),
363a0442ea0SHamir Mahal DataValue::F128(dv) => write!(f, "{dv}"),
3646f6f79efSAndrew Brown // Again, for syntax consistency, use ConstantData, which in this case displays as hex.
3656f6f79efSAndrew Brown DataValue::V128(dv) => write!(f, "{}", ConstantData::from(&dv[..])),
3663ef89b77SDamian Heaton DataValue::V64(dv) => write!(f, "{}", ConstantData::from(&dv[..])),
367d48b3856Sbeetrees DataValue::V32(dv) => write!(f, "{}", ConstantData::from(&dv[..])),
368d48b3856Sbeetrees DataValue::V16(dv) => write!(f, "{}", ConstantData::from(&dv[..])),
3696f6f79efSAndrew Brown }
3706f6f79efSAndrew Brown }
3716f6f79efSAndrew Brown }
3726f6f79efSAndrew Brown
3736f6f79efSAndrew Brown /// Helper structure for printing bracket-enclosed vectors of [DataValue]s.
3746f6f79efSAndrew Brown /// - for empty vectors, display `[]`
3756f6f79efSAndrew Brown /// - for single item vectors, display `42`, e.g.
3766f6f79efSAndrew Brown /// - for multiple item vectors, display `[42, 43, 44]`, e.g.
3776f6f79efSAndrew Brown pub struct DisplayDataValues<'a>(pub &'a [DataValue]);
3786f6f79efSAndrew Brown
3796f6f79efSAndrew Brown impl<'a> Display for DisplayDataValues<'a> {
fmt(&self, f: &mut Formatter<'_>) -> fmt::Result3806f6f79efSAndrew Brown fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
3816f6f79efSAndrew Brown if self.0.len() == 1 {
3826f6f79efSAndrew Brown write!(f, "{}", self.0[0])
3836f6f79efSAndrew Brown } else {
3846f6f79efSAndrew Brown write!(f, "[")?;
3856f6f79efSAndrew Brown write_data_value_list(f, &self.0)?;
3866f6f79efSAndrew Brown write!(f, "]")
3876f6f79efSAndrew Brown }
3886f6f79efSAndrew Brown }
3896f6f79efSAndrew Brown }
3906f6f79efSAndrew Brown
3916f6f79efSAndrew Brown /// Helper function for displaying `Vec<DataValue>`.
write_data_value_list(f: &mut Formatter<'_>, list: &[DataValue]) -> fmt::Result3926f6f79efSAndrew Brown pub fn write_data_value_list(f: &mut Formatter<'_>, list: &[DataValue]) -> fmt::Result {
3936f6f79efSAndrew Brown match list.len() {
3946f6f79efSAndrew Brown 0 => Ok(()),
3956f6f79efSAndrew Brown 1 => write!(f, "{}", list[0]),
3966f6f79efSAndrew Brown _ => {
3976f6f79efSAndrew Brown write!(f, "{}", list[0])?;
3986f6f79efSAndrew Brown for dv in list.iter().skip(1) {
399a0442ea0SHamir Mahal write!(f, ", {dv}")?;
4006f6f79efSAndrew Brown }
4016f6f79efSAndrew Brown Ok(())
4026f6f79efSAndrew Brown }
4036f6f79efSAndrew Brown }
4046f6f79efSAndrew Brown }
4056f6f79efSAndrew Brown
4066f6f79efSAndrew Brown #[cfg(test)]
4076f6f79efSAndrew Brown mod test {
4086f6f79efSAndrew Brown use super::*;
4096f6f79efSAndrew Brown
4106f6f79efSAndrew Brown #[test]
type_conversions()4116f6f79efSAndrew Brown fn type_conversions() {
4126f6f79efSAndrew Brown assert_eq!(DataValue::V128([0; 16]).ty(), types::I8X16);
4136f6f79efSAndrew Brown assert_eq!(
4146f6f79efSAndrew Brown TryInto::<[u8; 16]>::try_into(DataValue::V128([0; 16])).unwrap(),
4156f6f79efSAndrew Brown [0; 16]
4166f6f79efSAndrew Brown );
4176f6f79efSAndrew Brown assert_eq!(
4186f6f79efSAndrew Brown TryInto::<i32>::try_into(DataValue::V128([0; 16])).unwrap_err(),
4196f6f79efSAndrew Brown DataValueCastFailure::TryInto(types::I8X16, types::I32)
4206f6f79efSAndrew Brown );
4216f6f79efSAndrew Brown }
4226f6f79efSAndrew Brown }
423