Skip to content

Commit 08646c6

Browse files
committed
miri: use separate Pointer and Align instead of PtrAndAlign.
1 parent ff080d3 commit 08646c6

File tree

8 files changed

+113
-177
lines changed

8 files changed

+113
-177
lines changed

src/librustc/mir/interpret/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ mod value;
1010

1111
pub use self::error::{EvalError, EvalResult, EvalErrorKind};
1212

13-
pub use self::value::{PrimVal, PrimValKind, Value, Pointer, PtrAndAlign, bytes_to_f32, bytes_to_f64};
13+
pub use self::value::{PrimVal, PrimValKind, Value, Pointer, bytes_to_f32, bytes_to_f64};
1414

1515
use std::collections::BTreeMap;
1616
use ty::layout::HasDataLayout;

src/librustc/mir/interpret/value.rs

+1-19
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,6 @@ use super::{EvalResult, MemoryPointer, PointerArithmetic};
66
use syntax::ast::FloatTy;
77
use rustc_const_math::ConstFloat;
88

9-
#[derive(Copy, Clone, Debug)]
10-
pub struct PtrAndAlign {
11-
pub ptr: Pointer,
12-
pub align: Align,
13-
}
14-
15-
impl PtrAndAlign {
16-
pub fn to_ptr<'tcx>(self) -> EvalResult<'tcx, MemoryPointer> {
17-
self.ptr.to_ptr()
18-
}
19-
pub fn offset<'tcx, C: HasDataLayout>(self, i: u64, cx: C) -> EvalResult<'tcx, Self> {
20-
Ok(PtrAndAlign {
21-
ptr: self.ptr.offset(i, cx)?,
22-
align: self.align,
23-
})
24-
}
25-
}
26-
279
pub fn bytes_to_f32(bits: u128) -> ConstFloat {
2810
ConstFloat {
2911
bits,
@@ -49,7 +31,7 @@ pub fn bytes_to_f64(bits: u128) -> ConstFloat {
4931
/// operations and fat pointers. This idea was taken from rustc's trans.
5032
#[derive(Clone, Copy, Debug)]
5133
pub enum Value {
52-
ByRef(PtrAndAlign),
34+
ByRef(Pointer, Align),
5335
ByVal(PrimVal),
5436
ByValPair(PrimVal, PrimVal),
5537
}

src/librustc_mir/interpret/const_eval.rs

+38-60
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ use rustc_data_structures::indexed_vec::Idx;
1212
use syntax::ast::Mutability;
1313
use syntax::codemap::Span;
1414

15-
use rustc::mir::interpret::{EvalResult, EvalError, EvalErrorKind, GlobalId, Value, Pointer, PrimVal, PtrAndAlign};
16-
use super::{Place, PlaceExtra, EvalContext, StackPopCleanup, ValTy, HasMemory};
15+
use rustc::mir::interpret::{EvalResult, EvalError, EvalErrorKind, GlobalId, Value, Pointer, PrimVal};
16+
use super::{Place, EvalContext, StackPopCleanup, ValTy};
1717

1818
use rustc_const_math::ConstInt;
1919

@@ -357,11 +357,9 @@ pub fn const_eval_provider<'a, 'tcx>(
357357
(_, Err(err)) => Err(err),
358358
(Ok((miri_val, miri_ty)), Ok(ctfe)) => {
359359
let mut ecx = mk_eval_cx(tcx, instance, key.param_env).unwrap();
360-
let miri_ptr = PtrAndAlign {
361-
ptr: miri_val,
362-
align: ecx.layout_of(miri_ty).unwrap().align
363-
};
364-
check_ctfe_against_miri(&mut ecx, miri_ptr, miri_ty, ctfe.val);
360+
let layout = ecx.layout_of(miri_ty).unwrap();
361+
let miri_place = Place::from_primval_ptr(miri_val, layout.align);
362+
check_ctfe_against_miri(&mut ecx, miri_place, miri_ty, ctfe.val);
365363
Ok(ctfe)
366364
}
367365
}
@@ -372,60 +370,49 @@ pub fn const_eval_provider<'a, 'tcx>(
372370

373371
fn check_ctfe_against_miri<'a, 'tcx>(
374372
ecx: &mut EvalContext<'a, 'tcx, CompileTimeEvaluator>,
375-
miri_val: PtrAndAlign,
373+
miri_place: Place,
376374
miri_ty: Ty<'tcx>,
377375
ctfe: ConstVal<'tcx>,
378376
) {
379377
use rustc::middle::const_val::ConstAggregate::*;
380378
use rustc_const_math::ConstFloat;
381379
use rustc::ty::TypeVariants::*;
380+
let miri_val = ValTy {
381+
value: ecx.read_place(miri_place).unwrap(),
382+
ty: miri_ty
383+
};
382384
match miri_ty.sty {
383385
TyInt(int_ty) => {
384-
let value = ecx.read_with_align(miri_val.align, |ectx| {
385-
ectx.try_read_value(miri_val.ptr, miri_ty)
386-
});
387-
let prim = get_prim(ecx, value);
386+
let prim = get_prim(ecx, miri_val);
388387
let c = ConstInt::new_signed_truncating(prim as i128,
389388
int_ty,
390389
ecx.tcx.sess.target.isize_ty);
391390
let c = ConstVal::Integral(c);
392391
assert_eq!(c, ctfe, "miri evaluated to {:?}, but ctfe yielded {:?}", c, ctfe);
393392
},
394393
TyUint(uint_ty) => {
395-
let value = ecx.read_with_align(miri_val.align, |ectx| {
396-
ectx.try_read_value(miri_val.ptr, miri_ty)
397-
});
398-
let prim = get_prim(ecx, value);
394+
let prim = get_prim(ecx, miri_val);
399395
let c = ConstInt::new_unsigned_truncating(prim,
400396
uint_ty,
401397
ecx.tcx.sess.target.usize_ty);
402398
let c = ConstVal::Integral(c);
403399
assert_eq!(c, ctfe, "miri evaluated to {:?}, but ctfe yielded {:?}", c, ctfe);
404400
},
405401
TyFloat(ty) => {
406-
let value = ecx.read_with_align(miri_val.align, |ectx| {
407-
ectx.try_read_value(miri_val.ptr, miri_ty)
408-
});
409-
let prim = get_prim(ecx, value);
402+
let prim = get_prim(ecx, miri_val);
410403
let f = ConstVal::Float(ConstFloat { bits: prim, ty });
411404
assert_eq!(f, ctfe, "miri evaluated to {:?}, but ctfe yielded {:?}", f, ctfe);
412405
},
413406
TyBool => {
414-
let value = ecx.read_with_align(miri_val.align, |ectx| {
415-
ectx.try_read_value(miri_val.ptr, miri_ty)
416-
});
417-
let bits = get_prim(ecx, value);
407+
let bits = get_prim(ecx, miri_val);
418408
if bits > 1 {
419409
bug!("miri evaluated to {}, but expected a bool {:?}", bits, ctfe);
420410
}
421411
let b = ConstVal::Bool(bits == 1);
422412
assert_eq!(b, ctfe, "miri evaluated to {:?}, but ctfe yielded {:?}", b, ctfe);
423413
},
424414
TyChar => {
425-
let value = ecx.read_with_align(miri_val.align, |ectx| {
426-
ectx.try_read_value(miri_val.ptr, miri_ty)
427-
});
428-
let bits = get_prim(ecx, value);
415+
let bits = get_prim(ecx, miri_val);
429416
if let Some(cm) = ::std::char::from_u32(bits as u32) {
430417
assert_eq!(
431418
ConstVal::Char(cm), ctfe,
@@ -436,10 +423,8 @@ fn check_ctfe_against_miri<'a, 'tcx>(
436423
}
437424
},
438425
TyStr => {
439-
let value = ecx.read_with_align(miri_val.align, |ectx| {
440-
ectx.try_read_value(miri_val.ptr, miri_ty)
441-
});
442-
if let Ok(Some(Value::ByValPair(PrimVal::Ptr(ptr), PrimVal::Bytes(len)))) = value {
426+
let value = ecx.follow_by_ref_value(miri_val.value, miri_val.ty);
427+
if let Ok(Value::ByValPair(PrimVal::Ptr(ptr), PrimVal::Bytes(len))) = value {
443428
let bytes = ecx
444429
.memory
445430
.read_bytes(ptr.into(), len as u64)
@@ -463,7 +448,6 @@ fn check_ctfe_against_miri<'a, 'tcx>(
463448
},
464449
TyArray(elem_ty, n) => {
465450
let n = n.val.to_const_int().unwrap().to_u64().unwrap();
466-
let size = ecx.layout_of(elem_ty).unwrap().size.bytes();
467451
let vec: Vec<(ConstVal, Ty<'tcx>)> = match ctfe {
468452
ConstVal::ByteStr(arr) => arr.data.iter().map(|&b| {
469453
(ConstVal::Integral(ConstInt::U8(b)), ecx.tcx.types.u8)
@@ -476,10 +460,12 @@ fn check_ctfe_against_miri<'a, 'tcx>(
476460
},
477461
_ => bug!("miri produced {:?}, but ctfe yielded {:?}", miri_ty, ctfe),
478462
};
463+
let layout = ecx.layout_of(miri_ty).unwrap();
479464
for (i, elem) in vec.into_iter().enumerate() {
480465
assert!((i as u64) < n);
481-
let ptr = miri_val.offset(size * i as u64, &ecx).unwrap();
482-
check_ctfe_against_miri(ecx, ptr, elem_ty, elem.0);
466+
let (field_place, _) =
467+
ecx.place_field(miri_place, Field::new(i), layout).unwrap();
468+
check_ctfe_against_miri(ecx, field_place, elem_ty, elem.0);
483469
}
484470
},
485471
TyTuple(..) => {
@@ -489,22 +475,22 @@ fn check_ctfe_against_miri<'a, 'tcx>(
489475
};
490476
let layout = ecx.layout_of(miri_ty).unwrap();
491477
for (i, elem) in vec.into_iter().enumerate() {
492-
let offset = layout.fields.offset(i);
493-
let ptr = miri_val.offset(offset.bytes(), &ecx).unwrap();
494-
check_ctfe_against_miri(ecx, ptr, elem.ty, elem.val);
478+
let (field_place, _) =
479+
ecx.place_field(miri_place, Field::new(i), layout).unwrap();
480+
check_ctfe_against_miri(ecx, field_place, elem.ty, elem.val);
495481
}
496482
},
497483
TyAdt(def, _) => {
498-
let (struct_variant, extra) = if def.is_enum() {
499-
let discr = ecx.read_discriminant_value(
500-
Place::Ptr { ptr: miri_val, extra: PlaceExtra::None },
501-
miri_ty).unwrap();
484+
let mut miri_place = miri_place;
485+
let struct_variant = if def.is_enum() {
486+
let discr = ecx.read_discriminant_value(miri_place, miri_ty).unwrap();
502487
let variant = def.discriminants(ecx.tcx).position(|variant_discr| {
503488
variant_discr.to_u128_unchecked() == discr
504489
}).expect("miri produced invalid enum discriminant");
505-
(&def.variants[variant], PlaceExtra::DowncastVariant(variant))
490+
miri_place = ecx.place_downcast(miri_place, variant).unwrap();
491+
&def.variants[variant]
506492
} else {
507-
(def.struct_variant(), PlaceExtra::None)
493+
def.struct_variant()
508494
};
509495
let vec = match ctfe {
510496
ConstVal::Aggregate(Struct(v)) => v,
@@ -518,12 +504,9 @@ fn check_ctfe_against_miri<'a, 'tcx>(
518504
let layout = ecx.layout_of(miri_ty).unwrap();
519505
for &(name, elem) in vec.into_iter() {
520506
let field = struct_variant.fields.iter().position(|f| f.name == name).unwrap();
521-
let (place, _) = ecx.place_field(
522-
Place::Ptr { ptr: miri_val, extra },
523-
Field::new(field),
524-
layout,
525-
).unwrap();
526-
check_ctfe_against_miri(ecx, place.to_ptr_align(), elem.ty, elem.val);
507+
let (field_place, _) =
508+
ecx.place_field(miri_place, Field::new(field), layout).unwrap();
509+
check_ctfe_against_miri(ecx, field_place, elem.ty, elem.val);
527510
}
528511
},
529512
TySlice(_) => bug!("miri produced a slice?"),
@@ -543,11 +526,9 @@ fn check_ctfe_against_miri<'a, 'tcx>(
543526
// should be fine
544527
TyFnDef(..) => {}
545528
TyFnPtr(_) => {
546-
let value = ecx.read_with_align(miri_val.align, |ectx| {
547-
ectx.try_read_value(miri_val.ptr, miri_ty)
548-
});
529+
let value = ecx.value_to_primval(miri_val);
549530
let ptr = match value {
550-
Ok(Some(Value::ByVal(PrimVal::Ptr(ptr)))) => ptr,
531+
Ok(PrimVal::Ptr(ptr)) => ptr,
551532
value => bug!("expected fn ptr, got {:?}", value),
552533
};
553534
let inst = ecx.memory.get_fn(ptr).unwrap();
@@ -569,13 +550,10 @@ fn check_ctfe_against_miri<'a, 'tcx>(
569550

570551
fn get_prim<'a, 'tcx>(
571552
ecx: &mut EvalContext<'a, 'tcx, CompileTimeEvaluator>,
572-
res: Result<Option<Value>, EvalError<'tcx>>,
553+
val: ValTy<'tcx>,
573554
) -> u128 {
574-
match res {
575-
Ok(Some(Value::ByVal(prim))) => unwrap_miri(ecx, prim.to_bytes()),
576-
Err(err) => unwrap_miri(ecx, Err(err)),
577-
val => bug!("got {:?}", val),
578-
}
555+
let res = ecx.value_to_primval(val).and_then(|prim| prim.to_bytes());
556+
unwrap_miri(ecx, res)
579557
}
580558

581559
fn unwrap_miri<'a, 'tcx, T>(

0 commit comments

Comments
 (0)