@@ -11,7 +11,10 @@ use rustc::mir::interpret::{
1111 ConstValue , Pointer , Scalar ,
1212 EvalResult , EvalErrorKind ,
1313} ;
14- use super :: { EvalContext , Machine , MemPlace , MPlaceTy , MemoryKind } ;
14+ use super :: {
15+ EvalContext , Machine , AllocMap , Allocation , AllocationExtra ,
16+ MemPlace , MPlaceTy , PlaceTy , Place , MemoryKind ,
17+ } ;
1518pub use rustc:: mir:: interpret:: ScalarMaybeUndef ;
1619
1720/// A `Value` represents a single immediate self-contained Rust value.
@@ -41,6 +44,11 @@ impl Immediate {
4144}
4245
4346impl < ' tcx , Tag > Immediate < Tag > {
47+ #[ inline]
48+ pub fn from_scalar ( val : Scalar < Tag > ) -> Self {
49+ Immediate :: Scalar ( ScalarMaybeUndef :: Scalar ( val) )
50+ }
51+
4452 #[ inline]
4553 pub fn erase_tag ( self ) -> Immediate
4654 {
@@ -112,15 +120,15 @@ impl<'tcx, Tag> Immediate<Tag> {
112120// as input for binary and cast operations.
113121#[ derive( Copy , Clone , Debug ) ]
114122pub struct ImmTy < ' tcx , Tag =( ) > {
115- immediate : Immediate < Tag > ,
123+ pub imm : Immediate < Tag > ,
116124 pub layout : TyLayout < ' tcx > ,
117125}
118126
119127impl < ' tcx , Tag > :: std:: ops:: Deref for ImmTy < ' tcx , Tag > {
120128 type Target = Immediate < Tag > ;
121129 #[ inline( always) ]
122130 fn deref ( & self ) -> & Immediate < Tag > {
123- & self . immediate
131+ & self . imm
124132 }
125133}
126134
@@ -180,7 +188,7 @@ impl<Tag> Operand<Tag> {
180188
181189#[ derive( Copy , Clone , Debug , Hash , PartialEq , Eq ) ]
182190pub struct OpTy < ' tcx , Tag =( ) > {
183- crate op : Operand < Tag > , // ideally we'd make this private, but const_prop needs this
191+ op : Operand < Tag > ,
184192 pub layout : TyLayout < ' tcx > ,
185193}
186194
@@ -206,12 +214,25 @@ impl<'tcx, Tag> From<ImmTy<'tcx, Tag>> for OpTy<'tcx, Tag> {
206214 #[ inline( always) ]
207215 fn from ( val : ImmTy < ' tcx , Tag > ) -> Self {
208216 OpTy {
209- op : Operand :: Immediate ( val. immediate ) ,
217+ op : Operand :: Immediate ( val. imm ) ,
210218 layout : val. layout
211219 }
212220 }
213221}
214222
223+ impl < ' tcx , Tag : Copy > ImmTy < ' tcx , Tag >
224+ {
225+ #[ inline]
226+ pub fn from_scalar ( val : Scalar < Tag > , layout : TyLayout < ' tcx > ) -> Self {
227+ ImmTy { imm : Immediate :: from_scalar ( val) , layout }
228+ }
229+
230+ #[ inline]
231+ pub fn to_bits ( self ) -> EvalResult < ' tcx , u128 > {
232+ self . to_scalar ( ) ?. to_bits ( self . layout . size )
233+ }
234+ }
235+
215236impl < ' tcx , Tag > OpTy < ' tcx , Tag >
216237{
217238 #[ inline]
@@ -324,8 +345,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
324345 & self ,
325346 op : OpTy < ' tcx , M :: PointerTag >
326347 ) -> EvalResult < ' tcx , ImmTy < ' tcx , M :: PointerTag > > {
327- if let Ok ( immediate ) = self . try_read_immediate ( op) ? {
328- Ok ( ImmTy { immediate , layout : op. layout } )
348+ if let Ok ( imm ) = self . try_read_immediate ( op) ? {
349+ Ok ( ImmTy { imm , layout : op. layout } )
329350 } else {
330351 bug ! ( "primitive read failed for type: {:?}" , op. layout. ty) ;
331352 }
@@ -469,6 +490,22 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
469490 Ok ( OpTy { op, layout } )
470491 }
471492
493+ /// Every place can be read from, so we can turm them into an operand
494+ #[ inline( always) ]
495+ pub fn place_to_op (
496+ & self ,
497+ place : PlaceTy < ' tcx , M :: PointerTag >
498+ ) -> EvalResult < ' tcx , OpTy < ' tcx , M :: PointerTag > > {
499+ let op = match * place {
500+ Place :: Ptr ( mplace) => {
501+ Operand :: Indirect ( mplace)
502+ }
503+ Place :: Local { frame, local } =>
504+ * self . stack [ frame] . locals [ local] . access ( ) ?
505+ } ;
506+ Ok ( OpTy { op, layout : place. layout } )
507+ }
508+
472509 // Evaluate a place with the goal of reading from it. This lets us sometimes
473510 // avoid allocations.
474511 fn eval_place_to_op (
@@ -531,10 +568,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
531568 . collect ( )
532569 }
533570
534- // Used when miri runs into a constant, and by CTFE.
535- // FIXME: CTFE should use allocations, then we can make this private (embed it into
536- // `eval_operand`, ideally).
537- pub ( crate ) fn const_value_to_op (
571+ // Used when Miri runs into a constant, and (indirectly through lazy_const_to_op) by CTFE.
572+ fn const_value_to_op (
538573 & self ,
539574 val : ty:: LazyConst < ' tcx > ,
540575 ) -> EvalResult < ' tcx , Operand < M :: PointerTag > > {
@@ -666,3 +701,21 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
666701 }
667702
668703}
704+
705+ impl < ' a , ' mir , ' tcx , M > EvalContext < ' a , ' mir , ' tcx , M >
706+ where
707+ M : Machine < ' a , ' mir , ' tcx , PointerTag =( ) > ,
708+ // FIXME: Working around https://github.com/rust-lang/rust/issues/24159
709+ M :: MemoryMap : AllocMap < AllocId , ( MemoryKind < M :: MemoryKinds > , Allocation < ( ) , M :: AllocExtra > ) > ,
710+ M :: AllocExtra : AllocationExtra < ( ) , M :: MemoryExtra > ,
711+ {
712+ // FIXME: CTFE should use allocations, then we can remove this.
713+ pub ( crate ) fn lazy_const_to_op (
714+ & self ,
715+ cnst : ty:: LazyConst < ' tcx > ,
716+ ty : ty:: Ty < ' tcx > ,
717+ ) -> EvalResult < ' tcx , OpTy < ' tcx > > {
718+ let op = self . const_value_to_op ( cnst) ?;
719+ Ok ( OpTy { op, layout : self . layout_of ( ty) ? } )
720+ }
721+ }
0 commit comments