@@ -211,8 +211,7 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
211
211
assert ! ( !layout. is_unsized( ) , "cannot alloc memory for unsized type" ) ;
212
212
213
213
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 ) )
216
215
}
217
216
218
217
pub fn memory ( & self ) -> & Memory < ' a , ' tcx , M > {
@@ -612,12 +611,12 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
612
611
let elem_size = self . layout_of ( elem_ty) ?. size . bytes ( ) ;
613
612
let value = self . eval_operand ( operand) ?. value ;
614
613
615
- let dest = Pointer :: from ( self . force_allocation ( dest) ?. to_ptr ( ) ? ) ;
614
+ let ( dest, dest_align ) = self . force_allocation ( dest) ?. to_ptr_align ( ) ;
616
615
617
616
// FIXME: speed up repeat filling
618
617
for i in 0 ..length {
619
618
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) ?;
621
620
}
622
621
}
623
622
@@ -955,15 +954,6 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
955
954
layout. align )
956
955
}
957
956
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
-
967
957
pub fn force_allocation ( & mut self , place : Place ) -> EvalResult < ' tcx , Place > {
968
958
let new_place = match place {
969
959
Place :: Local { frame, local } => {
@@ -984,8 +974,9 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
984
974
let ptr = self . alloc_ptr ( ty) ?;
985
975
self . stack [ frame] . locals [ local. index ( ) - 1 ] =
986
976
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
989
980
}
990
981
}
991
982
}
@@ -1002,7 +993,7 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
1002
993
) -> EvalResult < ' tcx , Value > {
1003
994
match value {
1004
995
Value :: ByRef ( ptr, align) => {
1005
- self . read_with_align ( align , |ectx| ectx . read_value ( ptr, ty ) )
996
+ self . read_value ( ptr, align , ty )
1006
997
}
1007
998
other => Ok ( other) ,
1008
999
}
@@ -1059,8 +1050,7 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
1059
1050
match dest {
1060
1051
Place :: Ptr { ptr, align, extra } => {
1061
1052
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)
1064
1054
}
1065
1055
1066
1056
Place :: Local { frame, local } => {
@@ -1091,10 +1081,7 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
1091
1081
//
1092
1082
// Thus, it would be an error to replace the `ByRef` with a `ByVal`, unless we
1093
1083
// 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) ?;
1098
1085
} else if let Value :: ByRef ( src_ptr, align) = src_val {
1099
1086
// If the value is not `ByRef`, then we know there are no pointers to it
1100
1087
// 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> {
1107
1094
// It is a valid optimization to attempt reading a primitive value out of the
1108
1095
// source and write that into the destination without making an allocation, so
1109
1096
// 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
+ }
1122
1105
} else {
1123
1106
// Finally, we have the simple case where neither source nor destination are
1124
1107
// `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> {
1131
1114
& mut self ,
1132
1115
value : Value ,
1133
1116
dest : Pointer ,
1117
+ dest_align : Align ,
1134
1118
dest_ty : Ty < ' tcx > ,
1135
1119
) -> EvalResult < ' tcx > {
1136
1120
trace ! ( "write_value_to_ptr: {:#?}" , value) ;
1121
+ let layout = self . layout_of ( dest_ty) ?;
1137
1122
match value {
1138
1123
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 )
1140
1125
}
1141
1126
Value :: ByVal ( primval) => {
1142
- let layout = self . layout_of ( dest_ty) ?;
1143
1127
match layout. abi {
1144
1128
layout:: Abi :: Scalar ( _) => { }
1145
1129
_ if primval. is_undef ( ) => { }
1146
1130
_ => bug ! ( "write_value_to_ptr: invalid ByVal layout: {:#?}" , layout)
1147
1131
}
1148
1132
// 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 )
1150
1134
}
1151
1135
Value :: ByValPair ( a_val, b_val) => {
1152
1136
let ptr = dest. to_ptr ( ) ?;
1153
- let mut layout = self . layout_of ( dest_ty) ?;
1154
1137
trace ! ( "write_value_to_ptr valpair: {:#?}" , layout) ;
1155
1138
let ( a, b) = match layout. abi {
1156
1139
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> {
1161
1144
let b_offset = a_size. abi_align ( b. align ( & self ) ) ;
1162
1145
let b_ptr = ptr. offset ( b_offset. bytes ( ) , & self ) ?. into ( ) ;
1163
1146
// 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 )
1167
1149
}
1168
1150
}
1169
1151
}
@@ -1246,8 +1228,8 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
1246
1228
}
1247
1229
}
1248
1230
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) ? {
1251
1233
Ok ( val)
1252
1234
} else {
1253
1235
bug ! ( "primitive read failed for type: {:?}" , ty) ;
@@ -1257,34 +1239,35 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
1257
1239
pub ( crate ) fn read_ptr (
1258
1240
& self ,
1259
1241
ptr : MemoryPointer ,
1242
+ ptr_align : Align ,
1260
1243
pointee_ty : Ty < ' tcx > ,
1261
1244
) -> EvalResult < ' tcx , Value > {
1262
1245
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 ( ) ;
1264
1247
if self . type_is_sized ( pointee_ty) {
1265
1248
Ok ( p. to_value ( ) )
1266
1249
} else {
1267
1250
trace ! ( "reading fat pointer extra of type {}" , pointee_ty) ;
1268
1251
let extra = ptr. offset ( ptr_size, self ) ?;
1269
1252
match self . tcx . struct_tail ( pointee_ty) . sty {
1270
1253
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 ( ) ?,
1272
1255
) ) ,
1273
1256
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 ) ,
1275
1258
) ,
1276
1259
_ => bug ! ( "unsized primval ptr read from {:?}" , pointee_ty) ,
1277
1260
}
1278
1261
}
1279
1262
}
1280
1263
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 > > {
1282
1265
use syntax:: ast:: FloatTy ;
1283
1266
1284
1267
let ptr = ptr. to_ptr ( ) ?;
1285
1268
let val = match ty. sty {
1286
1269
ty:: TyBool => {
1287
- let val = self . memory . read_primval ( ptr, 1 , false ) ?;
1270
+ let val = self . memory . read_primval ( ptr, ptr_align , 1 , false ) ?;
1288
1271
let val = match val {
1289
1272
PrimVal :: Bytes ( 0 ) => false ,
1290
1273
PrimVal :: Bytes ( 1 ) => true ,
@@ -1294,7 +1277,7 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
1294
1277
PrimVal :: from_bool ( val)
1295
1278
}
1296
1279
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 ;
1298
1281
match :: std:: char:: from_u32 ( c) {
1299
1282
Some ( ch) => PrimVal :: from_char ( ch) ,
1300
1283
None => return err ! ( InvalidChar ( c as u128 ) ) ,
@@ -1311,7 +1294,7 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
1311
1294
I128 => 16 ,
1312
1295
Is => self . memory . pointer_size ( ) ,
1313
1296
} ;
1314
- self . memory . read_primval ( ptr, size, true ) ?
1297
+ self . memory . read_primval ( ptr, ptr_align , size, true ) ?
1315
1298
}
1316
1299
1317
1300
ty:: TyUint ( uint_ty) => {
@@ -1324,19 +1307,23 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
1324
1307
U128 => 16 ,
1325
1308
Us => self . memory . pointer_size ( ) ,
1326
1309
} ;
1327
- self . memory . read_primval ( ptr, size, false ) ?
1310
+ self . memory . read_primval ( ptr, ptr_align , size, false ) ?
1328
1311
}
1329
1312
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
+ }
1332
1319
1333
- ty:: TyFnPtr ( _) => self . memory . read_ptr_sized_unsigned ( ptr) ?,
1320
+ ty:: TyFnPtr ( _) => self . memory . read_ptr_sized_unsigned ( ptr, ptr_align ) ?,
1334
1321
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 ) ,
1336
1323
1337
1324
ty:: TyAdt ( def, _) => {
1338
1325
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 ) ;
1340
1327
}
1341
1328
1342
1329
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> {
1345
1332
signed = s;
1346
1333
}
1347
1334
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) ?
1349
1336
} else {
1350
1337
return Ok ( None ) ;
1351
1338
}
0 commit comments