@@ -211,8 +211,7 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
211211 assert ! ( !layout. is_unsized( ) , "cannot alloc memory for unsized type" ) ;
212212
213213 let size = layout. size . bytes ( ) ;
214- let align = layout. align . abi ( ) ;
215- self . memory . allocate ( size, align, Some ( MemoryKind :: Stack ) )
214+ self . memory . allocate ( size, layout. align , Some ( MemoryKind :: Stack ) )
216215 }
217216
218217 pub fn memory ( & self ) -> & Memory < ' a , ' tcx , M > {
@@ -612,12 +611,12 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
612611 let elem_size = self . layout_of ( elem_ty) ?. size . bytes ( ) ;
613612 let value = self . eval_operand ( operand) ?. value ;
614613
615- let dest = Pointer :: from ( self . force_allocation ( dest) ?. to_ptr ( ) ? ) ;
614+ let ( dest, dest_align ) = self . force_allocation ( dest) ?. to_ptr_align ( ) ;
616615
617616 // FIXME: speed up repeat filling
618617 for i in 0 ..length {
619618 let elem_dest = dest. offset ( i * elem_size, & self ) ?;
620- self . write_value_to_ptr ( value, elem_dest, elem_ty) ?;
619+ self . write_value_to_ptr ( value, elem_dest, dest_align , elem_ty) ?;
621620 }
622621 }
623622
@@ -955,15 +954,6 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
955954 layout. align )
956955 }
957956
958- fn copy ( & mut self , src : Pointer , dest : Pointer , ty : Ty < ' tcx > ) -> EvalResult < ' tcx > {
959- let layout = self . layout_of ( ty) ?;
960- assert ! ( !layout. is_unsized( ) , "cannot copy from an unsized type" ) ;
961- let size = layout. size . bytes ( ) ;
962- let align = layout. align . abi ( ) ;
963- self . memory . copy ( src, dest, size, align, false ) ?;
964- Ok ( ( ) )
965- }
966-
967957 pub fn force_allocation ( & mut self , place : Place ) -> EvalResult < ' tcx , Place > {
968958 let new_place = match place {
969959 Place :: Local { frame, local } => {
@@ -984,8 +974,9 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
984974 let ptr = self . alloc_ptr ( ty) ?;
985975 self . stack [ frame] . locals [ local. index ( ) - 1 ] =
986976 Some ( Value :: ByRef ( ptr. into ( ) , layout. align ) ) ; // it stays live
987- self . write_value_to_ptr ( val, ptr. into ( ) , ty) ?;
988- Place :: from_ptr ( ptr, layout. align )
977+ let place = Place :: from_ptr ( ptr, layout. align ) ;
978+ self . write_value ( ValTy { value : val, ty } , place) ?;
979+ place
989980 }
990981 }
991982 }
@@ -1002,7 +993,7 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
1002993 ) -> EvalResult < ' tcx , Value > {
1003994 match value {
1004995 Value :: ByRef ( ptr, align) => {
1005- self . read_with_align ( align , |ectx| ectx . read_value ( ptr, ty ) )
996+ self . read_value ( ptr, align , ty )
1006997 }
1007998 other => Ok ( other) ,
1008999 }
@@ -1059,8 +1050,7 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
10591050 match dest {
10601051 Place :: Ptr { ptr, align, extra } => {
10611052 assert_eq ! ( extra, PlaceExtra :: None ) ;
1062- self . write_with_align_mut ( align,
1063- |ectx| ectx. write_value_to_ptr ( src_val, ptr, dest_ty) )
1053+ self . write_value_to_ptr ( src_val, ptr, align, dest_ty)
10641054 }
10651055
10661056 Place :: Local { frame, local } => {
@@ -1091,10 +1081,7 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
10911081 //
10921082 // Thus, it would be an error to replace the `ByRef` with a `ByVal`, unless we
10931083 // knew for certain that there were no outstanding pointers to this allocation.
1094- self . write_with_align_mut ( align, |ectx| {
1095- ectx. write_value_to_ptr ( src_val, dest_ptr, dest_ty)
1096- } ) ?;
1097-
1084+ self . write_value_to_ptr ( src_val, dest_ptr, align, dest_ty) ?;
10981085 } else if let Value :: ByRef ( src_ptr, align) = src_val {
10991086 // If the value is not `ByRef`, then we know there are no pointers to it
11001087 // and we can simply overwrite the `Value` in the locals array directly.
@@ -1107,18 +1094,14 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
11071094 // It is a valid optimization to attempt reading a primitive value out of the
11081095 // source and write that into the destination without making an allocation, so
11091096 // we do so here.
1110- self . read_with_align_mut ( align, |ectx| {
1111- if let Ok ( Some ( src_val) ) = ectx. try_read_value ( src_ptr, dest_ty) {
1112- write_dest ( ectx, src_val) ?;
1113- } else {
1114- let dest_ptr = ectx. alloc_ptr ( dest_ty) ?. into ( ) ;
1115- ectx. copy ( src_ptr, dest_ptr, dest_ty) ?;
1116- let layout = ectx. layout_of ( dest_ty) ?;
1117- write_dest ( ectx, Value :: ByRef ( dest_ptr, layout. align ) ) ?;
1118- }
1119- Ok ( ( ) )
1120- } ) ?;
1121-
1097+ if let Ok ( Some ( src_val) ) = self . try_read_value ( src_ptr, align, dest_ty) {
1098+ write_dest ( self , src_val) ?;
1099+ } else {
1100+ let dest_ptr = self . alloc_ptr ( dest_ty) ?. into ( ) ;
1101+ let layout = self . layout_of ( dest_ty) ?;
1102+ self . memory . copy ( src_ptr, align. min ( layout. align ) , dest_ptr, layout. align , layout. size . bytes ( ) , false ) ?;
1103+ write_dest ( self , Value :: ByRef ( dest_ptr, layout. align ) ) ?;
1104+ }
11221105 } else {
11231106 // Finally, we have the simple case where neither source nor destination are
11241107 // `ByRef`. We may simply copy the source value over the the destintion.
@@ -1131,26 +1114,26 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
11311114 & mut self ,
11321115 value : Value ,
11331116 dest : Pointer ,
1117+ dest_align : Align ,
11341118 dest_ty : Ty < ' tcx > ,
11351119 ) -> EvalResult < ' tcx > {
11361120 trace ! ( "write_value_to_ptr: {:#?}" , value) ;
1121+ let layout = self . layout_of ( dest_ty) ?;
11371122 match value {
11381123 Value :: ByRef ( ptr, align) => {
1139- self . read_with_align_mut ( align , |ectx| ectx . copy ( ptr , dest, dest_ty ) )
1124+ self . memory . copy ( ptr , align . min ( layout . align ) , dest, dest_align . min ( layout . align ) , layout . size . bytes ( ) , false )
11401125 }
11411126 Value :: ByVal ( primval) => {
1142- let layout = self . layout_of ( dest_ty) ?;
11431127 match layout. abi {
11441128 layout:: Abi :: Scalar ( _) => { }
11451129 _ if primval. is_undef ( ) => { }
11461130 _ => bug ! ( "write_value_to_ptr: invalid ByVal layout: {:#?}" , layout)
11471131 }
11481132 // TODO: Do we need signedness?
1149- self . memory . write_primval ( dest. to_ptr ( ) ?, primval, layout. size . bytes ( ) , false )
1133+ self . memory . write_primval ( dest. to_ptr ( ) ?, dest_align , primval, layout. size . bytes ( ) , false )
11501134 }
11511135 Value :: ByValPair ( a_val, b_val) => {
11521136 let ptr = dest. to_ptr ( ) ?;
1153- let mut layout = self . layout_of ( dest_ty) ?;
11541137 trace ! ( "write_value_to_ptr valpair: {:#?}" , layout) ;
11551138 let ( a, b) = match layout. abi {
11561139 layout:: Abi :: ScalarPair ( ref a, ref b) => ( & a. value , & b. value ) ,
@@ -1161,9 +1144,8 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
11611144 let b_offset = a_size. abi_align ( b. align ( & self ) ) ;
11621145 let b_ptr = ptr. offset ( b_offset. bytes ( ) , & self ) ?. into ( ) ;
11631146 // TODO: What about signedess?
1164- self . memory . write_primval ( a_ptr, a_val, a_size. bytes ( ) , false ) ?;
1165- self . memory . write_primval ( b_ptr, b_val, b_size. bytes ( ) , false ) ?;
1166- Ok ( ( ) )
1147+ self . memory . write_primval ( a_ptr, dest_align, a_val, a_size. bytes ( ) , false ) ?;
1148+ self . memory . write_primval ( b_ptr, dest_align, b_val, b_size. bytes ( ) , false )
11671149 }
11681150 }
11691151 }
@@ -1246,8 +1228,8 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
12461228 }
12471229 }
12481230
1249- pub fn read_value ( & self , ptr : Pointer , ty : Ty < ' tcx > ) -> EvalResult < ' tcx , Value > {
1250- if let Some ( val) = self . try_read_value ( ptr, ty) ? {
1231+ pub fn read_value ( & self , ptr : Pointer , align : Align , ty : Ty < ' tcx > ) -> EvalResult < ' tcx , Value > {
1232+ if let Some ( val) = self . try_read_value ( ptr, align , ty) ? {
12511233 Ok ( val)
12521234 } else {
12531235 bug ! ( "primitive read failed for type: {:?}" , ty) ;
@@ -1257,34 +1239,35 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
12571239 pub ( crate ) fn read_ptr (
12581240 & self ,
12591241 ptr : MemoryPointer ,
1242+ ptr_align : Align ,
12601243 pointee_ty : Ty < ' tcx > ,
12611244 ) -> EvalResult < ' tcx , Value > {
12621245 let ptr_size = self . memory . pointer_size ( ) ;
1263- let p : Pointer = self . memory . read_ptr_sized_unsigned ( ptr) ?. into ( ) ;
1246+ let p: Pointer = self . memory . read_ptr_sized_unsigned ( ptr, ptr_align ) ?. into ( ) ;
12641247 if self . type_is_sized ( pointee_ty) {
12651248 Ok ( p. to_value ( ) )
12661249 } else {
12671250 trace ! ( "reading fat pointer extra of type {}" , pointee_ty) ;
12681251 let extra = ptr. offset ( ptr_size, self ) ?;
12691252 match self . tcx . struct_tail ( pointee_ty) . sty {
12701253 ty:: TyDynamic ( ..) => Ok ( p. to_value_with_vtable (
1271- self . memory . read_ptr_sized_unsigned ( extra) ?. to_ptr ( ) ?,
1254+ self . memory . read_ptr_sized_unsigned ( extra, ptr_align ) ?. to_ptr ( ) ?,
12721255 ) ) ,
12731256 ty:: TySlice ( ..) | ty:: TyStr => Ok (
1274- p. to_value_with_len ( self . memory . read_ptr_sized_unsigned ( extra) ?. to_bytes ( ) ? as u64 ) ,
1257+ p. to_value_with_len ( self . memory . read_ptr_sized_unsigned ( extra, ptr_align ) ?. to_bytes ( ) ? as u64 ) ,
12751258 ) ,
12761259 _ => bug ! ( "unsized primval ptr read from {:?}" , pointee_ty) ,
12771260 }
12781261 }
12791262 }
12801263
1281- pub fn try_read_value ( & self , ptr : Pointer , ty : Ty < ' tcx > ) -> EvalResult < ' tcx , Option < Value > > {
1264+ pub fn try_read_value ( & self , ptr : Pointer , ptr_align : Align , ty : Ty < ' tcx > ) -> EvalResult < ' tcx , Option < Value > > {
12821265 use syntax:: ast:: FloatTy ;
12831266
12841267 let ptr = ptr. to_ptr ( ) ?;
12851268 let val = match ty. sty {
12861269 ty:: TyBool => {
1287- let val = self . memory . read_primval ( ptr, 1 , false ) ?;
1270+ let val = self . memory . read_primval ( ptr, ptr_align , 1 , false ) ?;
12881271 let val = match val {
12891272 PrimVal :: Bytes ( 0 ) => false ,
12901273 PrimVal :: Bytes ( 1 ) => true ,
@@ -1294,7 +1277,7 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
12941277 PrimVal :: from_bool ( val)
12951278 }
12961279 ty:: TyChar => {
1297- let c = self . memory . read_primval ( ptr, 4 , false ) ?. to_bytes ( ) ? as u32 ;
1280+ let c = self . memory . read_primval ( ptr, ptr_align , 4 , false ) ?. to_bytes ( ) ? as u32 ;
12981281 match :: std:: char:: from_u32 ( c) {
12991282 Some ( ch) => PrimVal :: from_char ( ch) ,
13001283 None => return err ! ( InvalidChar ( c as u128 ) ) ,
@@ -1311,7 +1294,7 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
13111294 I128 => 16 ,
13121295 Is => self . memory . pointer_size ( ) ,
13131296 } ;
1314- self . memory . read_primval ( ptr, size, true ) ?
1297+ self . memory . read_primval ( ptr, ptr_align , size, true ) ?
13151298 }
13161299
13171300 ty:: TyUint ( uint_ty) => {
@@ -1324,19 +1307,23 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
13241307 U128 => 16 ,
13251308 Us => self . memory . pointer_size ( ) ,
13261309 } ;
1327- self . memory . read_primval ( ptr, size, false ) ?
1310+ self . memory . read_primval ( ptr, ptr_align , size, false ) ?
13281311 }
13291312
1330- ty:: TyFloat ( FloatTy :: F32 ) => PrimVal :: Bytes ( self . memory . read_primval ( ptr, 4 , false ) ?. to_bytes ( ) ?) ,
1331- ty:: TyFloat ( FloatTy :: F64 ) => PrimVal :: Bytes ( self . memory . read_primval ( ptr, 8 , false ) ?. to_bytes ( ) ?) ,
1313+ ty:: TyFloat ( FloatTy :: F32 ) => {
1314+ PrimVal :: Bytes ( self . memory . read_primval ( ptr, ptr_align, 4 , false ) ?. to_bytes ( ) ?)
1315+ }
1316+ ty:: TyFloat ( FloatTy :: F64 ) => {
1317+ PrimVal :: Bytes ( self . memory . read_primval ( ptr, ptr_align, 8 , false ) ?. to_bytes ( ) ?)
1318+ }
13321319
1333- ty:: TyFnPtr ( _) => self . memory . read_ptr_sized_unsigned ( ptr) ?,
1320+ ty:: TyFnPtr ( _) => self . memory . read_ptr_sized_unsigned ( ptr, ptr_align ) ?,
13341321 ty:: TyRef ( _, ref tam) |
1335- ty:: TyRawPtr ( ref tam) => return self . read_ptr ( ptr, tam. ty ) . map ( Some ) ,
1322+ ty:: TyRawPtr ( ref tam) => return self . read_ptr ( ptr, ptr_align , tam. ty ) . map ( Some ) ,
13361323
13371324 ty:: TyAdt ( def, _) => {
13381325 if def. is_box ( ) {
1339- return self . read_ptr ( ptr, ty. boxed_ty ( ) ) . map ( Some ) ;
1326+ return self . read_ptr ( ptr, ptr_align , ty. boxed_ty ( ) ) . map ( Some ) ;
13401327 }
13411328
13421329 if let layout:: Abi :: Scalar ( ref scalar) = self . layout_of ( ty) ?. abi {
@@ -1345,7 +1332,7 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
13451332 signed = s;
13461333 }
13471334 let size = scalar. value . size ( self ) . bytes ( ) ;
1348- self . memory . read_primval ( ptr, size, signed) ?
1335+ self . memory . read_primval ( ptr, ptr_align , size, signed) ?
13491336 } else {
13501337 return Ok ( None ) ;
13511338 }
0 commit comments