1 use rustc::ty::layout::{Size, HasDataLayout};
3 use super::{Scalar, ScalarMaybeUndef, EvalResult};
4 use rustc_mir::interpret::sign_extend;
7 fn null(size: Size) -> Self;
8 fn from_i32(i: i32) -> Self;
9 fn from_uint(i: impl Into<u128>, ptr_size: Size) -> Self;
10 fn from_int(i: impl Into<i128>, ptr_size: Size) -> Self;
11 fn from_f32(f: f32) -> Self;
12 fn from_f64(f: f64) -> Self;
13 fn is_null(self) -> bool;
16 pub trait FalibleScalarExt {
17 fn to_usize(self, cx: impl HasDataLayout) -> EvalResult<'static, u64>;
18 fn to_isize(self, cx: impl HasDataLayout) -> EvalResult<'static, i64>;
19 fn to_i32(self) -> EvalResult<'static, i32>;
20 fn to_u8(self) -> EvalResult<'static, u8>;
22 /// HACK: this function just extracts all bits if `defined != 0`
23 /// Mainly used for args of C-functions and we should totally correctly fetch the size
24 /// of their arguments
25 fn to_bytes(self) -> EvalResult<'static, u128>;
28 impl ScalarExt for Scalar {
29 fn null(size: Size) -> Self {
30 Scalar::Bits { bits: 0, size: size.bytes() as u8 }
33 fn from_i32(i: i32) -> Self {
34 Scalar::Bits { bits: i as u32 as u128, size: 4 }
37 fn from_uint(i: impl Into<u128>, size: Size) -> Self {
38 Scalar::Bits { bits: i.into(), size: size.bytes() as u8 }
41 fn from_int(i: impl Into<i128>, size: Size) -> Self {
42 Scalar::Bits { bits: i.into() as u128, size: size.bytes() as u8 }
45 fn from_f32(f: f32) -> Self {
46 Scalar::Bits { bits: f.to_bits() as u128, size: 4 }
49 fn from_f64(f: f64) -> Self {
50 Scalar::Bits { bits: f.to_bits() as u128, size: 8 }
53 fn is_null(self) -> bool {
55 Scalar::Bits { bits, .. } => bits == 0,
56 Scalar::Ptr(_) => false
61 impl FalibleScalarExt for Scalar {
62 fn to_usize(self, cx: impl HasDataLayout) -> EvalResult<'static, u64> {
63 let b = self.to_bits(cx.data_layout().pointer_size)?;
64 assert_eq!(b as u64 as u128, b);
68 fn to_u8(self) -> EvalResult<'static, u8> {
69 let sz = Size::from_bits(8);
70 let b = self.to_bits(sz)?;
71 assert_eq!(b as u8 as u128, b);
75 fn to_isize(self, cx: impl HasDataLayout) -> EvalResult<'static, i64> {
76 let b = self.to_bits(cx.data_layout().pointer_size)?;
77 let b = sign_extend(b, cx.data_layout().pointer_size) as i128;
78 assert_eq!(b as i64 as i128, b);
82 fn to_i32(self) -> EvalResult<'static, i32> {
83 let sz = Size::from_bits(32);
84 let b = self.to_bits(sz)?;
85 let b = sign_extend(b, sz) as i128;
86 assert_eq!(b as i32 as i128, b);
90 fn to_bytes(self) -> EvalResult<'static, u128> {
92 Scalar::Bits { bits, size } => {
96 Scalar::Ptr(_) => err!(ReadPointerAsBytes),
101 impl FalibleScalarExt for ScalarMaybeUndef {
102 fn to_usize(self, cx: impl HasDataLayout) -> EvalResult<'static, u64> {
103 self.not_undef()?.to_usize(cx)
106 fn to_u8(self) -> EvalResult<'static, u8> {
107 self.not_undef()?.to_u8()
110 fn to_isize(self, cx: impl HasDataLayout) -> EvalResult<'static, i64> {
111 self.not_undef()?.to_isize(cx)
114 fn to_i32(self) -> EvalResult<'static, i32> {
115 self.not_undef()?.to_i32()
118 fn to_bytes(self) -> EvalResult<'static, u128> {
119 self.not_undef()?.to_bytes()