1 //! An interpreter for MIR used in CTFE and by miri
14 pub use self::eval_context::{EvalContext, Frame, StackPopCleanup,
17 pub use self::place::{Place, PlaceExtra};
19 pub use self::memory::{Memory, MemoryKind, HasMemory};
21 pub use self::const_eval::{
26 const_value_to_allocation_provider,
33 pub use self::machine::Machine;
35 pub use self::memory::{write_target_uint, write_target_int, read_target_uint};
37 use rustc::mir::interpret::{EvalResult, EvalErrorKind};
38 use rustc::ty::{Ty, TyCtxt, ParamEnv};
40 pub fn sign_extend<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, value: u128, ty: Ty<'tcx>) -> EvalResult<'tcx, u128> {
41 let param_env = ParamEnv::empty();
42 let layout = tcx.layout_of(param_env.and(ty)).map_err(|layout| EvalErrorKind::Layout(layout))?;
43 let size = layout.size.bits();
44 assert!(layout.abi.is_signed());
46 let shift = 128 - size;
47 // shift the unsigned value to the left
48 // and back to the right as signed (essentially fills with FF on the left)
49 Ok((((value << shift) as i128) >> shift) as u128)
52 pub fn truncate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, value: u128, ty: Ty<'tcx>) -> EvalResult<'tcx, u128> {
53 let param_env = ParamEnv::empty();
54 let layout = tcx.layout_of(param_env.and(ty)).map_err(|layout| EvalErrorKind::Layout(layout))?;
55 let size = layout.size.bits();
56 let shift = 128 - size;
57 // truncate (shift left to drop out leftover values, shift right to fill with zeroes)
58 Ok((value << shift) >> shift)