@@ -14,7 +14,7 @@ use ty::layout::{HasDataLayout, Size};
1414use ty:: subst:: Substs ;
1515use hir:: def_id:: DefId ;
1616
17- use super :: { EvalResult , Pointer , PointerArithmetic , Allocation , AllocId , sign_extend} ;
17+ use super :: { EvalResult , Pointer , PointerArithmetic , Allocation , AllocId , sign_extend, truncate } ;
1818
1919/// Represents a constant value in Rust. Scalar and ScalarPair are optimizations which
2020/// matches the LocalValue optimizations for easy conversions between Value and ConstValue.
@@ -58,6 +58,7 @@ impl<'tcx> ConstValue<'tcx> {
5858 self . try_to_scalar ( ) ?. to_ptr ( ) . ok ( )
5959 }
6060
61+ #[ inline]
6162 pub fn new_slice (
6263 val : Scalar ,
6364 len : u64 ,
@@ -69,23 +70,27 @@ impl<'tcx> ConstValue<'tcx> {
6970 } . into ( ) )
7071 }
7172
73+ #[ inline]
7274 pub fn new_dyn_trait ( val : Scalar , vtable : Pointer ) -> Self {
7375 ConstValue :: ScalarPair ( val, Scalar :: Ptr ( vtable) . into ( ) )
7476 }
7577}
7678
7779impl < ' tcx > Scalar {
80+ #[ inline]
7881 pub fn ptr_null ( cx : impl HasDataLayout ) -> Self {
7982 Scalar :: Bits {
8083 bits : 0 ,
8184 size : cx. data_layout ( ) . pointer_size . bytes ( ) as u8 ,
8285 }
8386 }
8487
88+ #[ inline]
8589 pub fn zst ( ) -> Self {
8690 Scalar :: Bits { bits : 0 , size : 0 }
8791 }
8892
93+ #[ inline]
8994 pub fn ptr_signed_offset ( self , i : i64 , cx : impl HasDataLayout ) -> EvalResult < ' tcx , Self > {
9095 let layout = cx. data_layout ( ) ;
9196 match self {
@@ -100,6 +105,7 @@ impl<'tcx> Scalar {
100105 }
101106 }
102107
108+ #[ inline]
103109 pub fn ptr_offset ( self , i : Size , cx : impl HasDataLayout ) -> EvalResult < ' tcx , Self > {
104110 let layout = cx. data_layout ( ) ;
105111 match self {
@@ -114,6 +120,7 @@ impl<'tcx> Scalar {
114120 }
115121 }
116122
123+ #[ inline]
117124 pub fn ptr_wrapping_signed_offset ( self , i : i64 , cx : impl HasDataLayout ) -> Self {
118125 let layout = cx. data_layout ( ) ;
119126 match self {
@@ -128,6 +135,7 @@ impl<'tcx> Scalar {
128135 }
129136 }
130137
138+ #[ inline]
131139 pub fn is_null_ptr ( self , cx : impl HasDataLayout ) -> bool {
132140 match self {
133141 Scalar :: Bits { bits, size } => {
@@ -138,14 +146,53 @@ impl<'tcx> Scalar {
138146 }
139147 }
140148
149+ #[ inline]
150+ pub fn is_null ( self ) -> bool {
151+ match self {
152+ Scalar :: Bits { bits, .. } => bits == 0 ,
153+ Scalar :: Ptr ( _) => false
154+ }
155+ }
156+
157+ #[ inline]
141158 pub fn from_bool ( b : bool ) -> Self {
142159 Scalar :: Bits { bits : b as u128 , size : 1 }
143160 }
144161
162+ #[ inline]
145163 pub fn from_char ( c : char ) -> Self {
146164 Scalar :: Bits { bits : c as u128 , size : 4 }
147165 }
148166
167+ #[ inline]
168+ pub fn from_uint ( i : impl Into < u128 > , size : Size ) -> Self {
169+ let i = i. into ( ) ;
170+ debug_assert_eq ! ( truncate( i, size) , i,
171+ "Unsigned value {} does not fit in {} bits" , i, size. bits( ) ) ;
172+ Scalar :: Bits { bits : i, size : size. bytes ( ) as u8 }
173+ }
174+
175+ #[ inline]
176+ pub fn from_int ( i : impl Into < i128 > , size : Size ) -> Self {
177+ let i = i. into ( ) ;
178+ // `into` performed sign extension, we have to truncate
179+ let truncated = truncate ( i as u128 , size) ;
180+ debug_assert_eq ! ( sign_extend( truncated, size) as i128 , i,
181+ "Signed value {} does not fit in {} bits" , i, size. bits( ) ) ;
182+ Scalar :: Bits { bits : truncated, size : size. bytes ( ) as u8 }
183+ }
184+
185+ #[ inline]
186+ pub fn from_f32 ( f : f32 ) -> Self {
187+ Scalar :: Bits { bits : f. to_bits ( ) as u128 , size : 4 }
188+ }
189+
190+ #[ inline]
191+ pub fn from_f64 ( f : f64 ) -> Self {
192+ Scalar :: Bits { bits : f. to_bits ( ) as u128 , size : 8 }
193+ }
194+
195+ #[ inline]
149196 pub fn to_bits ( self , target_size : Size ) -> EvalResult < ' tcx , u128 > {
150197 match self {
151198 Scalar :: Bits { bits, size } => {
@@ -157,6 +204,7 @@ impl<'tcx> Scalar {
157204 }
158205 }
159206
207+ #[ inline]
160208 pub fn to_ptr ( self ) -> EvalResult < ' tcx , Pointer > {
161209 match self {
162210 Scalar :: Bits { bits : 0 , .. } => err ! ( InvalidNullPointerUsage ) ,
@@ -165,13 +213,15 @@ impl<'tcx> Scalar {
165213 }
166214 }
167215
216+ #[ inline]
168217 pub fn is_bits ( self ) -> bool {
169218 match self {
170219 Scalar :: Bits { .. } => true ,
171220 _ => false ,
172221 }
173222 }
174223
224+ #[ inline]
175225 pub fn is_ptr ( self ) -> bool {
176226 match self {
177227 Scalar :: Ptr ( _) => true ,
@@ -209,6 +259,13 @@ impl<'tcx> Scalar {
209259 Ok ( b as u32 )
210260 }
211261
262+ pub fn to_u64 ( self ) -> EvalResult < ' static , u64 > {
263+ let sz = Size :: from_bits ( 64 ) ;
264+ let b = self . to_bits ( sz) ?;
265+ assert_eq ! ( b as u64 as u128 , b) ;
266+ Ok ( b as u64 )
267+ }
268+
212269 pub fn to_usize ( self , cx : impl HasDataLayout ) -> EvalResult < ' static , u64 > {
213270 let b = self . to_bits ( cx. data_layout ( ) . pointer_size ) ?;
214271 assert_eq ! ( b as u64 as u128 , b) ;
@@ -231,12 +288,30 @@ impl<'tcx> Scalar {
231288 Ok ( b as i32 )
232289 }
233290
291+ pub fn to_i64 ( self ) -> EvalResult < ' static , i64 > {
292+ let sz = Size :: from_bits ( 64 ) ;
293+ let b = self . to_bits ( sz) ?;
294+ let b = sign_extend ( b, sz) as i128 ;
295+ assert_eq ! ( b as i64 as i128 , b) ;
296+ Ok ( b as i64 )
297+ }
298+
234299 pub fn to_isize ( self , cx : impl HasDataLayout ) -> EvalResult < ' static , i64 > {
235300 let b = self . to_bits ( cx. data_layout ( ) . pointer_size ) ?;
236301 let b = sign_extend ( b, cx. data_layout ( ) . pointer_size ) as i128 ;
237302 assert_eq ! ( b as i64 as i128 , b) ;
238303 Ok ( b as i64 )
239304 }
305+
306+ #[ inline]
307+ pub fn to_f32 ( self ) -> EvalResult < ' static , f32 > {
308+ Ok ( f32:: from_bits ( self . to_u32 ( ) ?) )
309+ }
310+
311+ #[ inline]
312+ pub fn to_f64 ( self ) -> EvalResult < ' static , f64 > {
313+ Ok ( f64:: from_bits ( self . to_u64 ( ) ?) )
314+ }
240315}
241316
242317impl From < Pointer > for Scalar {
@@ -308,6 +383,16 @@ impl<'tcx> ScalarMaybeUndef {
308383 self . not_undef ( ) ?. to_char ( )
309384 }
310385
386+ #[ inline( always) ]
387+ pub fn to_f32 ( self ) -> EvalResult < ' tcx , f32 > {
388+ self . not_undef ( ) ?. to_f32 ( )
389+ }
390+
391+ #[ inline( always) ]
392+ pub fn to_f64 ( self ) -> EvalResult < ' tcx , f64 > {
393+ self . not_undef ( ) ?. to_f64 ( )
394+ }
395+
311396 #[ inline( always) ]
312397 pub fn to_u8 ( self ) -> EvalResult < ' tcx , u8 > {
313398 self . not_undef ( ) ?. to_u8 ( )
@@ -318,6 +403,11 @@ impl<'tcx> ScalarMaybeUndef {
318403 self . not_undef ( ) ?. to_u32 ( )
319404 }
320405
406+ #[ inline( always) ]
407+ pub fn to_u64 ( self ) -> EvalResult < ' tcx , u64 > {
408+ self . not_undef ( ) ?. to_u64 ( )
409+ }
410+
321411 #[ inline( always) ]
322412 pub fn to_usize ( self , cx : impl HasDataLayout ) -> EvalResult < ' tcx , u64 > {
323413 self . not_undef ( ) ?. to_usize ( cx)
@@ -333,6 +423,11 @@ impl<'tcx> ScalarMaybeUndef {
333423 self . not_undef ( ) ?. to_i32 ( )
334424 }
335425
426+ #[ inline( always) ]
427+ pub fn to_i64 ( self ) -> EvalResult < ' tcx , i64 > {
428+ self . not_undef ( ) ?. to_i64 ( )
429+ }
430+
336431 #[ inline( always) ]
337432 pub fn to_isize ( self , cx : impl HasDataLayout ) -> EvalResult < ' tcx , i64 > {
338433 self . not_undef ( ) ?. to_isize ( cx)
0 commit comments