Rename PrimVal to Scalar

This commit is contained in:
Oliver Schneider 2018-05-20 23:43:16 +02:00
parent 9cc5d927c9
commit 1606e137e7
20 changed files with 279 additions and 273 deletions

View file

@ -475,7 +475,7 @@ impl_stable_hash_for!(enum ::syntax::ast::Mutability {
impl_stable_hash_for!(struct mir::interpret::Pointer{primval});
impl_stable_hash_for!(enum mir::interpret::PrimVal {
impl_stable_hash_for!(enum mir::interpret::Scalar {
Bytes(b),
Ptr(p),
Undef

View file

@ -10,7 +10,7 @@ mod value;
pub use self::error::{EvalError, EvalResult, EvalErrorKind, AssertMessage};
pub use self::value::{PrimVal, PrimValKind, Value, Pointer, ConstValue};
pub use self::value::{Scalar, ScalarKind, Value, Pointer, ConstValue};
use std::fmt;
use mir;

View file

@ -9,10 +9,10 @@ use super::{EvalResult, MemoryPointer, PointerArithmetic, Allocation};
/// matches Value's optimizations for easy conversions between these two types
#[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash)]
pub enum ConstValue<'tcx> {
/// Used only for types with layout::abi::Scalar ABI and ZSTs which use PrimVal::Undef
ByVal(PrimVal),
/// Used only for types with layout::abi::Scalar ABI and ZSTs which use Scalar::Undef
ByVal(Scalar),
/// Used only for types with layout::abi::ScalarPair
ByValPair(PrimVal, PrimVal),
ByValPair(Scalar, Scalar),
/// Used only for the remaining cases. An allocation + offset into the allocation
ByRef(&'tcx Allocation, Size),
}
@ -37,12 +37,12 @@ impl<'tcx> ConstValue<'tcx> {
}
#[inline]
pub fn from_primval(val: PrimVal) -> Self {
pub fn from_primval(val: Scalar) -> Self {
ConstValue::ByVal(val)
}
#[inline]
pub fn to_primval(&self) -> Option<PrimVal> {
pub fn to_primval(&self) -> Option<Scalar> {
match *self {
ConstValue::ByRef(..) => None,
ConstValue::ByValPair(..) => None,
@ -53,7 +53,7 @@ impl<'tcx> ConstValue<'tcx> {
#[inline]
pub fn to_bits(&self) -> Option<u128> {
match self.to_primval() {
Some(PrimVal::Bytes(val)) => Some(val),
Some(Scalar::Bytes(val)) => Some(val),
_ => None,
}
}
@ -61,7 +61,7 @@ impl<'tcx> ConstValue<'tcx> {
#[inline]
pub fn to_ptr(&self) -> Option<MemoryPointer> {
match self.to_primval() {
Some(PrimVal::Ptr(ptr)) => Some(ptr),
Some(Scalar::Ptr(ptr)) => Some(ptr),
_ => None,
}
}
@ -79,8 +79,8 @@ impl<'tcx> ConstValue<'tcx> {
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, RustcEncodable, RustcDecodable, Hash)]
pub enum Value {
ByRef(Pointer, Align),
ByVal(PrimVal),
ByValPair(PrimVal, PrimVal),
ByVal(Scalar),
ByValPair(Scalar, Scalar),
}
impl<'tcx> ty::TypeFoldable<'tcx> for Value {
@ -92,8 +92,8 @@ impl<'tcx> ty::TypeFoldable<'tcx> for Value {
}
}
/// A wrapper type around `PrimVal` that cannot be turned back into a `PrimVal` accidentally.
/// This type clears up a few APIs where having a `PrimVal` argument for something that is
/// A wrapper type around `Scalar` that cannot be turned back into a `Scalar` accidentally.
/// This type clears up a few APIs where having a `Scalar` argument for something that is
/// potentially an integer pointer or a pointer to an allocation was unclear.
///
/// I (@oli-obk) believe it is less easy to mix up generic primvals and primvals that are just
@ -101,76 +101,76 @@ impl<'tcx> ty::TypeFoldable<'tcx> for Value {
/// are explicit now (and rare!)
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, RustcEncodable, RustcDecodable, Hash)]
pub struct Pointer {
pub primval: PrimVal,
pub primval: Scalar,
}
impl<'tcx> Pointer {
pub fn null() -> Self {
PrimVal::Bytes(0).into()
Scalar::Bytes(0).into()
}
pub fn to_ptr(self) -> EvalResult<'tcx, MemoryPointer> {
self.primval.to_ptr()
}
pub fn into_inner_primval(self) -> PrimVal {
pub fn into_inner_primval(self) -> Scalar {
self.primval
}
pub fn signed_offset<C: HasDataLayout>(self, i: i64, cx: C) -> EvalResult<'tcx, Self> {
let layout = cx.data_layout();
match self.primval {
PrimVal::Bytes(b) => {
Scalar::Bytes(b) => {
assert_eq!(b as u64 as u128, b);
Ok(Pointer::from(
PrimVal::Bytes(layout.signed_offset(b as u64, i)? as u128),
Scalar::Bytes(layout.signed_offset(b as u64, i)? as u128),
))
}
PrimVal::Ptr(ptr) => ptr.signed_offset(i, layout).map(Pointer::from),
PrimVal::Undef => err!(ReadUndefBytes),
Scalar::Ptr(ptr) => ptr.signed_offset(i, layout).map(Pointer::from),
Scalar::Undef => err!(ReadUndefBytes),
}
}
pub fn offset<C: HasDataLayout>(self, i: Size, cx: C) -> EvalResult<'tcx, Self> {
let layout = cx.data_layout();
match self.primval {
PrimVal::Bytes(b) => {
Scalar::Bytes(b) => {
assert_eq!(b as u64 as u128, b);
Ok(Pointer::from(
PrimVal::Bytes(layout.offset(b as u64, i.bytes())? as u128),
Scalar::Bytes(layout.offset(b as u64, i.bytes())? as u128),
))
}
PrimVal::Ptr(ptr) => ptr.offset(i, layout).map(Pointer::from),
PrimVal::Undef => err!(ReadUndefBytes),
Scalar::Ptr(ptr) => ptr.offset(i, layout).map(Pointer::from),
Scalar::Undef => err!(ReadUndefBytes),
}
}
pub fn wrapping_signed_offset<C: HasDataLayout>(self, i: i64, cx: C) -> EvalResult<'tcx, Self> {
let layout = cx.data_layout();
match self.primval {
PrimVal::Bytes(b) => {
Scalar::Bytes(b) => {
assert_eq!(b as u64 as u128, b);
Ok(Pointer::from(PrimVal::Bytes(
Ok(Pointer::from(Scalar::Bytes(
layout.wrapping_signed_offset(b as u64, i) as u128,
)))
}
PrimVal::Ptr(ptr) => Ok(Pointer::from(ptr.wrapping_signed_offset(i, layout))),
PrimVal::Undef => err!(ReadUndefBytes),
Scalar::Ptr(ptr) => Ok(Pointer::from(ptr.wrapping_signed_offset(i, layout))),
Scalar::Undef => err!(ReadUndefBytes),
}
}
pub fn is_null(self) -> EvalResult<'tcx, bool> {
match self.primval {
PrimVal::Bytes(b) => Ok(b == 0),
PrimVal::Ptr(_) => Ok(false),
PrimVal::Undef => err!(ReadUndefBytes),
Scalar::Bytes(b) => Ok(b == 0),
Scalar::Ptr(_) => Ok(false),
Scalar::Undef => err!(ReadUndefBytes),
}
}
pub fn to_value_with_len(self, len: u64) -> Value {
Value::ByValPair(self.primval, PrimVal::from_u128(len as u128))
Value::ByValPair(self.primval, Scalar::from_u128(len as u128))
}
pub fn to_value_with_vtable(self, vtable: MemoryPointer) -> Value {
Value::ByValPair(self.primval, PrimVal::Ptr(vtable))
Value::ByValPair(self.primval, Scalar::Ptr(vtable))
}
pub fn to_value(self) -> Value {
@ -178,39 +178,39 @@ impl<'tcx> Pointer {
}
}
impl ::std::convert::From<PrimVal> for Pointer {
fn from(primval: PrimVal) -> Self {
impl ::std::convert::From<Scalar> for Pointer {
fn from(primval: Scalar) -> Self {
Pointer { primval }
}
}
impl ::std::convert::From<MemoryPointer> for Pointer {
fn from(ptr: MemoryPointer) -> Self {
PrimVal::Ptr(ptr).into()
Scalar::Ptr(ptr).into()
}
}
/// A `PrimVal` represents an immediate, primitive value existing outside of a
/// A `Scalar` represents an immediate, primitive value existing outside of a
/// `memory::Allocation`. It is in many ways like a small chunk of a `Allocation`, up to 8 bytes in
/// size. Like a range of bytes in an `Allocation`, a `PrimVal` can either represent the raw bytes
/// size. Like a range of bytes in an `Allocation`, a `Scalar` can either represent the raw bytes
/// of a simple value, a pointer into another `Allocation`, or be undefined.
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, RustcEncodable, RustcDecodable, Hash)]
pub enum PrimVal {
pub enum Scalar {
/// The raw bytes of a simple value.
Bytes(u128),
/// A pointer into an `Allocation`. An `Allocation` in the `memory` module has a list of
/// relocations, but a `PrimVal` is only large enough to contain one, so we just represent the
/// relocations, but a `Scalar` is only large enough to contain one, so we just represent the
/// relocation and its associated offset together as a `MemoryPointer` here.
Ptr(MemoryPointer),
/// An undefined `PrimVal`, for representing values that aren't safe to examine, but are safe
/// An undefined `Scalar`, for representing values that aren't safe to examine, but are safe
/// to copy around, just like undefined bytes in an `Allocation`.
Undef,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum PrimValKind {
pub enum ScalarKind {
I8, I16, I32, I64, I128,
U8, U16, U32, U64, U128,
F32, F64,
@ -219,56 +219,56 @@ pub enum PrimValKind {
Char,
}
impl<'tcx> PrimVal {
impl<'tcx> Scalar {
pub fn from_u128(n: u128) -> Self {
PrimVal::Bytes(n)
Scalar::Bytes(n)
}
pub fn from_i128(n: i128) -> Self {
PrimVal::Bytes(n as u128)
Scalar::Bytes(n as u128)
}
pub fn from_bool(b: bool) -> Self {
PrimVal::Bytes(b as u128)
Scalar::Bytes(b as u128)
}
pub fn from_char(c: char) -> Self {
PrimVal::Bytes(c as u128)
Scalar::Bytes(c as u128)
}
pub fn to_bytes(self) -> EvalResult<'tcx, u128> {
match self {
PrimVal::Bytes(b) => Ok(b),
PrimVal::Ptr(_) => err!(ReadPointerAsBytes),
PrimVal::Undef => err!(ReadUndefBytes),
Scalar::Bytes(b) => Ok(b),
Scalar::Ptr(_) => err!(ReadPointerAsBytes),
Scalar::Undef => err!(ReadUndefBytes),
}
}
pub fn to_ptr(self) -> EvalResult<'tcx, MemoryPointer> {
match self {
PrimVal::Bytes(_) => err!(ReadBytesAsPointer),
PrimVal::Ptr(p) => Ok(p),
PrimVal::Undef => err!(ReadUndefBytes),
Scalar::Bytes(_) => err!(ReadBytesAsPointer),
Scalar::Ptr(p) => Ok(p),
Scalar::Undef => err!(ReadUndefBytes),
}
}
pub fn is_bytes(self) -> bool {
match self {
PrimVal::Bytes(_) => true,
Scalar::Bytes(_) => true,
_ => false,
}
}
pub fn is_ptr(self) -> bool {
match self {
PrimVal::Ptr(_) => true,
Scalar::Ptr(_) => true,
_ => false,
}
}
pub fn is_undef(self) -> bool {
match self {
PrimVal::Undef => true,
Scalar::Undef => true,
_ => false,
}
}
@ -311,9 +311,9 @@ impl<'tcx> PrimVal {
}
}
impl PrimValKind {
impl ScalarKind {
pub fn is_int(self) -> bool {
use self::PrimValKind::*;
use self::ScalarKind::*;
match self {
I8 | I16 | I32 | I64 | I128 | U8 | U16 | U32 | U64 | U128 => true,
_ => false,
@ -321,7 +321,7 @@ impl PrimValKind {
}
pub fn is_signed_int(self) -> bool {
use self::PrimValKind::*;
use self::ScalarKind::*;
match self {
I8 | I16 | I32 | I64 | I128 => true,
_ => false,
@ -329,7 +329,7 @@ impl PrimValKind {
}
pub fn is_float(self) -> bool {
use self::PrimValKind::*;
use self::ScalarKind::*;
match self {
F32 | F64 => true,
_ => false,
@ -338,28 +338,28 @@ impl PrimValKind {
pub fn from_uint_size(size: Size) -> Self {
match size.bytes() {
1 => PrimValKind::U8,
2 => PrimValKind::U16,
4 => PrimValKind::U32,
8 => PrimValKind::U64,
16 => PrimValKind::U128,
1 => ScalarKind::U8,
2 => ScalarKind::U16,
4 => ScalarKind::U32,
8 => ScalarKind::U64,
16 => ScalarKind::U128,
_ => bug!("can't make uint with size {}", size.bytes()),
}
}
pub fn from_int_size(size: Size) -> Self {
match size.bytes() {
1 => PrimValKind::I8,
2 => PrimValKind::I16,
4 => PrimValKind::I32,
8 => PrimValKind::I64,
16 => PrimValKind::I128,
1 => ScalarKind::I8,
2 => ScalarKind::I16,
4 => ScalarKind::I32,
8 => ScalarKind::I64,
16 => ScalarKind::I128,
_ => bug!("can't make int with size {}", size.bytes()),
}
}
pub fn is_ptr(self) -> bool {
use self::PrimValKind::*;
use self::ScalarKind::*;
match self {
Ptr | FnPtr => true,
_ => false,

View file

@ -24,7 +24,7 @@ use rustc_serialize as serialize;
use hir::def::CtorKind;
use hir::def_id::DefId;
use mir::visit::MirVisitable;
use mir::interpret::{Value, PrimVal, EvalErrorKind};
use mir::interpret::{Value, Scalar, EvalErrorKind};
use ty::subst::{Subst, Substs};
use ty::{self, AdtDef, CanonicalTy, ClosureSubsts, GeneratorSubsts, Region, Ty, TyCtxt};
use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
@ -1153,7 +1153,7 @@ impl<'tcx> TerminatorKind<'tcx> {
.map(|&u| {
let mut s = String::new();
print_miri_value(
Value::ByVal(PrimVal::Bytes(u)),
Value::ByVal(Scalar::Bytes(u)),
switch_ty,
&mut s,
).unwrap();
@ -1893,19 +1893,19 @@ pub fn fmt_const_val<W: Write>(fmt: &mut W, const_val: &ty::Const) -> fmt::Resul
pub fn print_miri_value<W: Write>(value: Value, ty: Ty, f: &mut W) -> fmt::Result {
use ty::TypeVariants::*;
match (value, &ty.sty) {
(Value::ByVal(PrimVal::Bytes(0)), &TyBool) => write!(f, "false"),
(Value::ByVal(PrimVal::Bytes(1)), &TyBool) => write!(f, "true"),
(Value::ByVal(PrimVal::Bytes(bits)), &TyFloat(ast::FloatTy::F32)) =>
(Value::ByVal(Scalar::Bytes(0)), &TyBool) => write!(f, "false"),
(Value::ByVal(Scalar::Bytes(1)), &TyBool) => write!(f, "true"),
(Value::ByVal(Scalar::Bytes(bits)), &TyFloat(ast::FloatTy::F32)) =>
write!(f, "{}f32", Single::from_bits(bits)),
(Value::ByVal(PrimVal::Bytes(bits)), &TyFloat(ast::FloatTy::F64)) =>
(Value::ByVal(Scalar::Bytes(bits)), &TyFloat(ast::FloatTy::F64)) =>
write!(f, "{}f64", Double::from_bits(bits)),
(Value::ByVal(PrimVal::Bytes(n)), &TyUint(ui)) => write!(f, "{:?}{}", n, ui),
(Value::ByVal(PrimVal::Bytes(n)), &TyInt(i)) => write!(f, "{:?}{}", n as i128, i),
(Value::ByVal(PrimVal::Bytes(n)), &TyChar) =>
(Value::ByVal(Scalar::Bytes(n)), &TyUint(ui)) => write!(f, "{:?}{}", n, ui),
(Value::ByVal(Scalar::Bytes(n)), &TyInt(i)) => write!(f, "{:?}{}", n as i128, i),
(Value::ByVal(Scalar::Bytes(n)), &TyChar) =>
write!(f, "{:?}", ::std::char::from_u32(n as u32).unwrap()),
(Value::ByVal(PrimVal::Undef), &TyFnDef(did, _)) =>
(Value::ByVal(Scalar::Undef), &TyFnDef(did, _)) =>
write!(f, "{}", item_path_str(did)),
(Value::ByValPair(PrimVal::Ptr(ptr), PrimVal::Bytes(len)),
(Value::ByValPair(Scalar::Ptr(ptr), Scalar::Bytes(len)),
&TyRef(_, &ty::TyS { sty: TyStr, .. }, _)) => {
ty::tls::with(|tcx| {
match tcx.alloc_map.lock().get(ptr.alloc_id) {

View file

@ -19,7 +19,7 @@ use ty::subst::{Substs, Subst, Kind, UnpackedKind};
use ty::{self, AdtDef, TypeFlags, Ty, TyCtxt, TypeFoldable};
use ty::{Slice, TyS};
use util::captures::Captures;
use mir::interpret::{PrimVal, MemoryPointer, Value, ConstValue};
use mir::interpret::{Scalar, MemoryPointer, Value, ConstValue};
use std::iter;
use std::cmp::Ordering;
@ -1811,7 +1811,7 @@ impl<'tcx> Const<'tcx> {
#[inline]
pub fn from_primval(
tcx: TyCtxt<'_, '_, 'tcx>,
val: PrimVal,
val: Scalar,
ty: Ty<'tcx>,
) -> &'tcx Self {
Self::from_const_value(tcx, ConstValue::from_primval(val), ty)
@ -1823,12 +1823,12 @@ impl<'tcx> Const<'tcx> {
val: u128,
ty: Ty<'tcx>,
) -> &'tcx Self {
Self::from_primval(tcx, PrimVal::Bytes(val), ty)
Self::from_primval(tcx, Scalar::Bytes(val), ty)
}
#[inline]
pub fn zero_sized(tcx: TyCtxt<'_, '_, 'tcx>, ty: Ty<'tcx>) -> &'tcx Self {
Self::from_primval(tcx, PrimVal::Undef, ty)
Self::from_primval(tcx, Scalar::Undef, ty)
}
#[inline]
@ -1869,7 +1869,7 @@ impl<'tcx> Const<'tcx> {
}
#[inline]
pub fn to_primval(&self) -> Option<PrimVal> {
pub fn to_primval(&self) -> Option<Scalar> {
match self.val {
ConstVal::Value(val) => val.to_primval(),
_ => None,

View file

@ -14,7 +14,7 @@ use rustc_mir::interpret::{read_target_uint, const_val_field};
use rustc::hir::def_id::DefId;
use rustc::mir;
use rustc_data_structures::indexed_vec::Idx;
use rustc::mir::interpret::{GlobalId, MemoryPointer, PrimVal, Allocation, ConstValue, AllocType};
use rustc::mir::interpret::{GlobalId, MemoryPointer, Scalar, Allocation, ConstValue, AllocType};
use rustc::ty::{self, Ty};
use rustc::ty::layout::{self, HasDataLayout, LayoutOf, Scalar, Size};
use builder::Builder;
@ -29,13 +29,13 @@ use super::super::callee;
use super::FunctionCx;
pub fn primval_to_llvm(cx: &CodegenCx,
cv: PrimVal,
cv: Scalar,
scalar: &Scalar,
llty: Type) -> ValueRef {
let bits = if scalar.is_bool() { 1 } else { scalar.value.size(cx).bits() };
match cv {
PrimVal::Undef => C_undef(Type::ix(cx, bits)),
PrimVal::Bytes(b) => {
Scalar::Undef => C_undef(Type::ix(cx, bits)),
Scalar::Bytes(b) => {
let llval = C_uint_big(Type::ix(cx, bits), b);
if scalar.value == layout::Pointer {
unsafe { llvm::LLVMConstIntToPtr(llval, llty.to_ref()) }
@ -43,7 +43,7 @@ pub fn primval_to_llvm(cx: &CodegenCx,
consts::bitcast(llval, llty)
}
},
PrimVal::Ptr(ptr) => {
Scalar::Ptr(ptr) => {
let alloc_type = cx.tcx.alloc_map.lock().get(ptr.alloc_id);
let base_addr = match alloc_type {
Some(AllocType::Memory(alloc)) => {
@ -96,7 +96,7 @@ pub fn const_alloc_to_llvm(cx: &CodegenCx, alloc: &Allocation) -> ValueRef {
).expect("const_alloc_to_llvm: could not read relocation pointer") as u64;
llvals.push(primval_to_llvm(
cx,
PrimVal::Ptr(MemoryPointer { alloc_id, offset: Size::from_bytes(ptr_offset) }),
Scalar::Ptr(MemoryPointer { alloc_id, offset: Size::from_bytes(ptr_offset) }),
&Scalar {
value: layout::Primitive::Pointer,
valid_range: 0..=!0

View file

@ -184,23 +184,23 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
let id = self.tcx.allocate_bytes(s.as_bytes());
let ptr = MemoryPointer::zero(id);
ConstValue::ByValPair(
PrimVal::Ptr(ptr),
PrimVal::from_u128(s.len() as u128),
Scalar::Ptr(ptr),
Scalar::from_u128(s.len() as u128),
)
},
LitKind::ByteStr(ref data) => {
let id = self.tcx.allocate_bytes(data);
let ptr = MemoryPointer::zero(id);
ConstValue::ByVal(PrimVal::Ptr(ptr))
ConstValue::ByVal(Scalar::Ptr(ptr))
},
LitKind::Byte(n) => ConstValue::ByVal(PrimVal::Bytes(n as u128)),
LitKind::Byte(n) => ConstValue::ByVal(Scalar::Bytes(n as u128)),
LitKind::Int(n, _) if neg => {
let n = n as i128;
let n = n.overflowing_neg().0;
let n = clamp(n as u128);
ConstValue::ByVal(PrimVal::Bytes(n))
ConstValue::ByVal(Scalar::Bytes(n))
},
LitKind::Int(n, _) => ConstValue::ByVal(PrimVal::Bytes(clamp(n))),
LitKind::Int(n, _) => ConstValue::ByVal(Scalar::Bytes(clamp(n))),
LitKind::Float(n, fty) => {
parse_float(n, fty)
}
@ -211,8 +211,8 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
};
parse_float(n, fty)
}
LitKind::Bool(b) => ConstValue::ByVal(PrimVal::Bytes(b as u128)),
LitKind::Char(c) => ConstValue::ByVal(PrimVal::Bytes(c as u128)),
LitKind::Bool(b) => ConstValue::ByVal(Scalar::Bytes(b as u128)),
LitKind::Char(c) => ConstValue::ByVal(Scalar::Bytes(c as u128)),
};
Literal::Value {
value: ty::Const::from_const_value(self.tcx, lit, ty)

View file

@ -20,7 +20,7 @@ use interpret::{const_val_field, const_variant_index, self};
use rustc::middle::const_val::ConstVal;
use rustc::mir::{fmt_const_val, Field, BorrowKind, Mutability};
use rustc::mir::interpret::{PrimVal, GlobalId, ConstValue, Value};
use rustc::mir::interpret::{Scalar, GlobalId, ConstValue, Value};
use rustc::ty::{self, TyCtxt, AdtDef, Ty, Region};
use rustc::ty::subst::{Substs, Kind};
use rustc::hir::{self, PatKind, RangeEnd};
@ -1084,13 +1084,19 @@ pub fn compare_const_vals<'a, 'tcx>(
match (a.to_byval_value(), b.to_byval_value()) {
(
Some(Value::ByValPair(
PrimVal::Ptr(ptr_a),
PrimVal::Bytes(size_a))
),
Scalar::Ptr(ptr_a),
Scalar::Bits {
bits: size_a,
defined: tcx.data_layout.pointer_size.bits() as u8,
},
)),
Some(Value::ByValPair(
PrimVal::Ptr(ptr_b),
PrimVal::Bytes(size_b))
)
Scalar::Ptr(ptr_b),
Scalar::Bits {
bits: size_b,
defined: tcx.data_layout.pointer_size.bits() as u8,
},
))
) if size_a == size_b => {
if ptr_a.offset == Size::from_bytes(0) && ptr_b.offset == Size::from_bytes(0) {
let map = tcx.alloc_map.lock();
@ -1124,16 +1130,16 @@ fn lit_to_const<'a, 'tcx>(lit: &'tcx ast::LitKind,
let id = tcx.allocate_bytes(s.as_bytes());
let ptr = MemoryPointer::zero(id);
ConstValue::ByValPair(
PrimVal::Ptr(ptr),
PrimVal::from_u128(s.len() as u128),
Scalar::Ptr(ptr),
Scalar::from_u128(s.len() as u128),
)
},
LitKind::ByteStr(ref data) => {
let id = tcx.allocate_bytes(data);
let ptr = MemoryPointer::zero(id);
ConstValue::ByVal(PrimVal::Ptr(ptr))
ConstValue::ByVal(Scalar::Ptr(ptr))
},
LitKind::Byte(n) => ConstValue::ByVal(PrimVal::Bytes(n as u128)),
LitKind::Byte(n) => ConstValue::ByVal(Scalar::Bytes(n as u128)),
LitKind::Int(n, _) => {
enum Int {
Signed(IntTy),
@ -1147,7 +1153,7 @@ fn lit_to_const<'a, 'tcx>(lit: &'tcx ast::LitKind,
_ => bug!(),
};
// This converts from LitKind::Int (which is sign extended) to
// PrimVal::Bytes (which is zero extended)
// Scalar::Bytes (which is zero extended)
let n = match ty {
// FIXME(oli-obk): are these casts correct?
Int::Signed(IntTy::I8) if neg =>
@ -1167,7 +1173,7 @@ fn lit_to_const<'a, 'tcx>(lit: &'tcx ast::LitKind,
Int::Signed(IntTy::I128)| Int::Unsigned(UintTy::U128) => n,
_ => bug!(),
};
ConstValue::ByVal(PrimVal::Bytes(n))
ConstValue::ByVal(Scalar::Bytes(n))
},
LitKind::Float(n, fty) => {
parse_float(n, fty, neg)?
@ -1179,8 +1185,8 @@ fn lit_to_const<'a, 'tcx>(lit: &'tcx ast::LitKind,
};
parse_float(n, fty, neg)?
}
LitKind::Bool(b) => ConstValue::ByVal(PrimVal::Bytes(b as u128)),
LitKind::Char(c) => ConstValue::ByVal(PrimVal::Bytes(c as u128)),
LitKind::Bool(b) => ConstValue::ByVal(Scalar::Bytes(b as u128)),
LitKind::Char(c) => ConstValue::ByVal(Scalar::Bytes(c as u128)),
};
Ok(ty::Const::from_const_value(tcx, lit, ty))
}
@ -1216,5 +1222,5 @@ pub fn parse_float<'tcx>(
}
};
Ok(ConstValue::ByVal(PrimVal::Bytes(bits)))
Ok(ConstValue::ByVal(Scalar::Bytes(bits)))
}

View file

@ -4,23 +4,23 @@ use syntax::ast::{FloatTy, IntTy, UintTy};
use rustc_apfloat::ieee::{Single, Double};
use super::{EvalContext, Machine};
use rustc::mir::interpret::{PrimVal, EvalResult, MemoryPointer, PointerArithmetic};
use rustc::mir::interpret::{Scalar, EvalResult, MemoryPointer, PointerArithmetic};
use rustc_apfloat::Float;
impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
pub(super) fn cast_primval(
&self,
val: PrimVal,
val: Scalar,
src_ty: Ty<'tcx>,
dest_ty: Ty<'tcx>,
) -> EvalResult<'tcx, PrimVal> {
) -> EvalResult<'tcx, Scalar> {
use rustc::ty::TypeVariants::*;
trace!("Casting {:?}: {:?} to {:?}", val, src_ty, dest_ty);
match val {
PrimVal::Undef => Ok(PrimVal::Undef),
PrimVal::Ptr(ptr) => self.cast_from_ptr(ptr, dest_ty),
PrimVal::Bytes(b) => {
Scalar::Undef => Ok(Scalar::Undef),
Scalar::Ptr(ptr) => self.cast_from_ptr(ptr, dest_ty),
Scalar::Bytes(b) => {
match src_ty.sty {
TyFloat(fty) => self.cast_from_float(b, fty, dest_ty),
_ => self.cast_from_int(b, src_ty, dest_ty),
@ -34,7 +34,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
v: u128,
src_ty: Ty<'tcx>,
dest_ty: Ty<'tcx>,
) -> EvalResult<'tcx, PrimVal> {
) -> EvalResult<'tcx, Scalar> {
let signed = self.layout_of(src_ty)?.abi.is_signed();
let v = if signed {
self.sign_extend(v, src_ty)?
@ -46,20 +46,20 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
match dest_ty.sty {
TyInt(_) | TyUint(_) => {
let v = self.truncate(v, dest_ty)?;
Ok(PrimVal::Bytes(v))
Ok(Scalar::Bytes(v))
}
TyFloat(FloatTy::F32) if signed => Ok(PrimVal::Bytes(Single::from_i128(v as i128).value.to_bits())),
TyFloat(FloatTy::F64) if signed => Ok(PrimVal::Bytes(Double::from_i128(v as i128).value.to_bits())),
TyFloat(FloatTy::F32) => Ok(PrimVal::Bytes(Single::from_u128(v).value.to_bits())),
TyFloat(FloatTy::F64) => Ok(PrimVal::Bytes(Double::from_u128(v).value.to_bits())),
TyFloat(FloatTy::F32) if signed => Ok(Scalar::Bytes(Single::from_i128(v as i128).value.to_bits())),
TyFloat(FloatTy::F64) if signed => Ok(Scalar::Bytes(Double::from_i128(v as i128).value.to_bits())),
TyFloat(FloatTy::F32) => Ok(Scalar::Bytes(Single::from_u128(v).value.to_bits())),
TyFloat(FloatTy::F64) => Ok(Scalar::Bytes(Double::from_u128(v).value.to_bits())),
TyChar if v as u8 as u128 == v => Ok(PrimVal::Bytes(v)),
TyChar if v as u8 as u128 == v => Ok(Scalar::Bytes(v)),
TyChar => err!(InvalidChar(v)),
// No alignment check needed for raw pointers. But we have to truncate to target ptr size.
TyRawPtr(_) => {
Ok(PrimVal::Bytes(self.memory.truncate_to_ptr(v).0 as u128))
Ok(Scalar::Bytes(self.memory.truncate_to_ptr(v).0 as u128))
},
// Casts to bool are not permitted by rustc, no need to handle them here.
@ -67,7 +67,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
}
}
fn cast_from_float(&self, bits: u128, fty: FloatTy, dest_ty: Ty<'tcx>) -> EvalResult<'tcx, PrimVal> {
fn cast_from_float(&self, bits: u128, fty: FloatTy, dest_ty: Ty<'tcx>) -> EvalResult<'tcx, Scalar> {
use rustc::ty::TypeVariants::*;
use rustc_apfloat::FloatConvert;
match dest_ty.sty {
@ -75,39 +75,39 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
TyUint(t) => {
let width = t.bit_width().unwrap_or(self.memory.pointer_size().bytes() as usize * 8);
match fty {
FloatTy::F32 => Ok(PrimVal::Bytes(Single::from_bits(bits).to_u128(width).value)),
FloatTy::F64 => Ok(PrimVal::Bytes(Double::from_bits(bits).to_u128(width).value)),
FloatTy::F32 => Ok(Scalar::Bytes(Single::from_bits(bits).to_u128(width).value)),
FloatTy::F64 => Ok(Scalar::Bytes(Double::from_bits(bits).to_u128(width).value)),
}
},
// float -> int
TyInt(t) => {
let width = t.bit_width().unwrap_or(self.memory.pointer_size().bytes() as usize * 8);
match fty {
FloatTy::F32 => Ok(PrimVal::from_i128(Single::from_bits(bits).to_i128(width).value)),
FloatTy::F64 => Ok(PrimVal::from_i128(Double::from_bits(bits).to_i128(width).value)),
FloatTy::F32 => Ok(Scalar::from_i128(Single::from_bits(bits).to_i128(width).value)),
FloatTy::F64 => Ok(Scalar::from_i128(Double::from_bits(bits).to_i128(width).value)),
}
},
// f64 -> f32
TyFloat(FloatTy::F32) if fty == FloatTy::F64 => {
Ok(PrimVal::Bytes(Single::to_bits(Double::from_bits(bits).convert(&mut false).value)))
Ok(Scalar::Bytes(Single::to_bits(Double::from_bits(bits).convert(&mut false).value)))
},
// f32 -> f64
TyFloat(FloatTy::F64) if fty == FloatTy::F32 => {
Ok(PrimVal::Bytes(Double::to_bits(Single::from_bits(bits).convert(&mut false).value)))
Ok(Scalar::Bytes(Double::to_bits(Single::from_bits(bits).convert(&mut false).value)))
},
// identity cast
TyFloat(_) => Ok(PrimVal::Bytes(bits)),
TyFloat(_) => Ok(Scalar::Bytes(bits)),
_ => err!(Unimplemented(format!("float to {:?} cast", dest_ty))),
}
}
fn cast_from_ptr(&self, ptr: MemoryPointer, ty: Ty<'tcx>) -> EvalResult<'tcx, PrimVal> {
fn cast_from_ptr(&self, ptr: MemoryPointer, ty: Ty<'tcx>) -> EvalResult<'tcx, Scalar> {
use rustc::ty::TypeVariants::*;
match ty.sty {
// Casting to a reference or fn pointer is not permitted by rustc, no need to support it here.
TyRawPtr(_) |
TyInt(IntTy::Isize) |
TyUint(UintTy::Usize) => Ok(PrimVal::Ptr(ptr)),
TyUint(UintTy::Usize) => Ok(Scalar::Ptr(ptr)),
TyInt(_) | TyUint(_) => err!(ReadPointerAsBytes),
_ => err!(Unimplemented(format!("ptr to {:?} cast", ty))),
}

View file

@ -12,7 +12,7 @@ use syntax::codemap::DUMMY_SP;
use rustc::mir::interpret::{
EvalResult, EvalError, EvalErrorKind, GlobalId,
Value, Pointer, PrimVal, AllocId, Allocation, ConstValue,
Value, Pointer, Scalar, AllocId, Allocation, ConstValue,
};
use super::{Place, EvalContext, StackPopCleanup, ValTy, PlaceExtra, Memory, MemoryKind};
@ -100,7 +100,7 @@ pub fn value_to_const_value<'tcx>(
) -> &'tcx ty::Const<'tcx> {
let layout = ecx.tcx.layout_of(ty::ParamEnv::reveal_all().and(ty)).unwrap();
match (val, &layout.abi) {
(Value::ByVal(PrimVal::Undef), _) if layout.is_zst() => {},
(Value::ByVal(Scalar::Undef), _) if layout.is_zst() => {},
(Value::ByRef(..), _) |
(Value::ByVal(_), &layout::Abi::Scalar(_)) |
(Value::ByValPair(..), &layout::Abi::ScalarPair(..)) => {},
@ -319,20 +319,20 @@ impl<'mir, 'tcx> super::Machine<'mir, 'tcx> for CompileTimeEvaluator {
"min_align_of" => {
let elem_ty = substs.type_at(0);
let elem_align = ecx.layout_of(elem_ty)?.align.abi();
let align_val = PrimVal::from_u128(elem_align as u128);
let align_val = Scalar::from_u128(elem_align as u128);
ecx.write_primval(dest, align_val, dest_layout.ty)?;
}
"size_of" => {
let ty = substs.type_at(0);
let size = ecx.layout_of(ty)?.size.bytes() as u128;
ecx.write_primval(dest, PrimVal::from_u128(size), dest_layout.ty)?;
ecx.write_primval(dest, Scalar::from_u128(size), dest_layout.ty)?;
}
"type_id" => {
let ty = substs.type_at(0);
let type_id = ecx.tcx.type_id_hash(ty) as u128;
ecx.write_primval(dest, PrimVal::from_u128(type_id), dest_layout.ty)?;
ecx.write_primval(dest, Scalar::from_u128(type_id), dest_layout.ty)?;
}
name => return Err(ConstEvalError::NeedsRfc(format!("calling intrinsic `{}`", name)).into()),
@ -349,11 +349,11 @@ impl<'mir, 'tcx> super::Machine<'mir, 'tcx> for CompileTimeEvaluator {
fn try_ptr_op<'a>(
_ecx: &EvalContext<'a, 'mir, 'tcx, Self>,
_bin_op: mir::BinOp,
left: PrimVal,
left: Scalar,
_left_ty: Ty<'tcx>,
right: PrimVal,
right: Scalar,
_right_ty: Ty<'tcx>,
) -> EvalResult<'tcx, Option<(PrimVal, bool)>> {
) -> EvalResult<'tcx, Option<(Scalar, bool)>> {
if left.is_bytes() && right.is_bytes() {
Ok(None)
} else {

View file

@ -14,7 +14,7 @@ use rustc::middle::const_val::FrameInfo;
use syntax::codemap::{self, Span};
use syntax::ast::Mutability;
use rustc::mir::interpret::{
GlobalId, Value, Pointer, PrimVal, PrimValKind,
GlobalId, Value, Pointer, Scalar, ScalarKind,
EvalError, EvalResult, EvalErrorKind, MemoryPointer, ConstValue,
};
use std::mem;
@ -74,9 +74,9 @@ pub struct Frame<'mir, 'tcx: 'mir> {
/// The list of locals for this stack frame, stored in order as
/// `[return_ptr, arguments..., variables..., temporaries...]`. The locals are stored as `Option<Value>`s.
/// `None` represents a local that is currently dead, while a live local
/// can either directly contain `PrimVal` or refer to some part of an `Allocation`.
/// can either directly contain `Scalar` or refer to some part of an `Allocation`.
///
/// Before being initialized, arguments are `Value::ByVal(PrimVal::Undef)` and other locals are `None`.
/// Before being initialized, arguments are `Value::ByVal(Scalar::Undef)` and other locals are `None`.
pub locals: IndexVec<mir::Local, Option<Value>>,
////////////////////////////////////////////////////////////////////////////////
@ -231,8 +231,8 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
pub fn str_to_value(&mut self, s: &str) -> EvalResult<'tcx, Value> {
let ptr = self.memory.allocate_bytes(s.as_bytes());
Ok(Value::ByValPair(
PrimVal::Ptr(ptr),
PrimVal::from_u128(s.len() as u128),
Scalar::Ptr(ptr),
Scalar::from_u128(s.len() as u128),
))
}
@ -408,7 +408,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
::log_settings::settings().indentation += 1;
let locals = if mir.local_decls.len() > 1 {
let mut locals = IndexVec::from_elem(Some(Value::ByVal(PrimVal::Undef)), &mir.local_decls);
let mut locals = IndexVec::from_elem(Some(Value::ByVal(Scalar::Undef)), &mir.local_decls);
match self.tcx.describe_def(instance.def_id()) {
// statics and constants don't have `Storage*` statements, no need to look for them
Some(Def::Static(..)) | Some(Def::Const(..)) | Some(Def::AssociatedConst(..)) => {},
@ -608,7 +608,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
let (_, len) = src.elem_ty_and_len(ty, self.tcx.tcx);
self.write_primval(
dest,
PrimVal::from_u128(len as u128),
Scalar::from_u128(len as u128),
dest_ty,
)?;
}
@ -646,7 +646,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
"SizeOf nullary MIR operator called for unsized type");
self.write_primval(
dest,
PrimVal::from_u128(layout.size.bytes() as u128),
Scalar::from_u128(layout.size.bytes() as u128),
dest_ty,
)?;
}
@ -696,7 +696,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
.val;
return self.write_primval(
dest,
PrimVal::Bytes(discr_val),
Scalar::Bytes(discr_val),
dest_ty);
}
}
@ -729,7 +729,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
).ok_or_else(|| EvalErrorKind::TypeckError.into());
let fn_ptr = self.memory.create_fn_alloc(instance?);
let valty = ValTy {
value: Value::ByVal(PrimVal::Ptr(fn_ptr)),
value: Value::ByVal(Scalar::Ptr(fn_ptr)),
ty: dest_ty,
};
self.write_value(valty, dest)?;
@ -765,7 +765,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
);
let fn_ptr = self.memory.create_fn_alloc(instance);
let valty = ValTy {
value: Value::ByVal(PrimVal::Ptr(fn_ptr)),
value: Value::ByVal(Scalar::Ptr(fn_ptr)),
ty: dest_ty,
};
self.write_value(valty, dest)?;
@ -780,7 +780,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
let ty = self.place_ty(place);
let place = self.eval_place(place)?;
let discr_val = self.read_discriminant_value(place, ty)?;
self.write_primval(dest, PrimVal::Bytes(discr_val), dest_ty)?;
self.write_primval(dest, Scalar::Bytes(discr_val), dest_ty)?;
}
}
@ -801,7 +801,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
pub(super) fn eval_operand_to_primval(
&mut self,
op: &mir::Operand<'tcx>,
) -> EvalResult<'tcx, PrimVal> {
) -> EvalResult<'tcx, Scalar> {
let valty = self.eval_operand(op)?;
self.value_to_primval(valty)
}
@ -937,12 +937,12 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
let variants_start = *niche_variants.start() as u128;
let variants_end = *niche_variants.end() as u128;
match raw_discr {
PrimVal::Ptr(_) => {
Scalar::Ptr(_) => {
assert!(niche_start == 0);
assert!(variants_start == variants_end);
dataful_variant as u128
},
PrimVal::Bytes(raw_discr) => {
Scalar::Bytes(raw_discr) => {
let discr = raw_discr.wrapping_sub(niche_start)
.wrapping_add(variants_start);
if variants_start <= discr && discr <= variants_end {
@ -951,7 +951,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
dataful_variant as u128
}
},
PrimVal::Undef => return err!(ReadUndefBytes),
Scalar::Undef => return err!(ReadUndefBytes),
}
}
};
@ -990,7 +990,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
let discr_val = (discr_val << amt) >> amt;
let (discr_dest, tag) = self.place_field(dest, mir::Field::new(0), layout)?;
self.write_primval(discr_dest, PrimVal::Bytes(discr_val), tag.ty)?;
self.write_primval(discr_dest, Scalar::Bytes(discr_val), tag.ty)?;
}
layout::Variants::NicheFilling {
dataful_variant,
@ -1003,7 +1003,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
self.place_field(dest, mir::Field::new(0), layout)?;
let niche_value = ((variant_index - niche_variants.start()) as u128)
.wrapping_add(niche_start);
self.write_primval(niche_dest, PrimVal::Bytes(niche_value), niche.ty)?;
self.write_primval(niche_dest, Scalar::Bytes(niche_value), niche.ty)?;
}
}
}
@ -1090,7 +1090,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
pub fn value_to_primval(
&self,
ValTy { value, ty } : ValTy<'tcx>,
) -> EvalResult<'tcx, PrimVal> {
) -> EvalResult<'tcx, Scalar> {
match self.follow_by_ref_value(value, ty)? {
Value::ByRef { .. } => bug!("follow_by_ref_value can't result in `ByRef`"),
@ -1115,7 +1115,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
pub fn write_primval(
&mut self,
dest: Place,
val: PrimVal,
val: Scalar,
dest_ty: Ty<'tcx>,
) -> EvalResult<'tcx> {
let valty = ValTy {
@ -1239,12 +1239,12 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
}
}
pub fn ty_to_primval_kind(&self, ty: Ty<'tcx>) -> EvalResult<'tcx, PrimValKind> {
pub fn ty_to_primval_kind(&self, ty: Ty<'tcx>) -> EvalResult<'tcx, ScalarKind> {
use syntax::ast::FloatTy;
let kind = match ty.sty {
ty::TyBool => PrimValKind::Bool,
ty::TyChar => PrimValKind::Char,
ty::TyBool => ScalarKind::Bool,
ty::TyChar => ScalarKind::Char,
ty::TyInt(int_ty) => {
use syntax::ast::IntTy::*;
@ -1256,7 +1256,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
I128 => Size::from_bytes(16),
Isize => self.memory.pointer_size(),
};
PrimValKind::from_int_size(size)
ScalarKind::from_int_size(size)
}
ty::TyUint(uint_ty) => {
@ -1269,31 +1269,31 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
U128 => Size::from_bytes(16),
Usize => self.memory.pointer_size(),
};
PrimValKind::from_uint_size(size)
ScalarKind::from_uint_size(size)
}
ty::TyFloat(FloatTy::F32) => PrimValKind::F32,
ty::TyFloat(FloatTy::F64) => PrimValKind::F64,
ty::TyFloat(FloatTy::F32) => ScalarKind::F32,
ty::TyFloat(FloatTy::F64) => ScalarKind::F64,
ty::TyFnPtr(_) => PrimValKind::FnPtr,
ty::TyFnPtr(_) => ScalarKind::FnPtr,
ty::TyRef(_, ty, _) |
ty::TyRawPtr(ty::TypeAndMut { ty, .. }) if self.type_is_sized(ty) => {
PrimValKind::Ptr
ScalarKind::Ptr
}
ty::TyAdt(def, _) if def.is_box() => PrimValKind::Ptr,
ty::TyAdt(def, _) if def.is_box() => ScalarKind::Ptr,
ty::TyAdt(..) => {
match self.layout_of(ty)?.abi {
layout::Abi::Scalar(ref scalar) => {
use rustc::ty::layout::Primitive::*;
match scalar.value {
Int(i, false) => PrimValKind::from_uint_size(i.size()),
Int(i, true) => PrimValKind::from_int_size(i.size()),
F32 => PrimValKind::F32,
F64 => PrimValKind::F64,
Pointer => PrimValKind::Ptr,
Int(i, false) => ScalarKind::from_uint_size(i.size()),
Int(i, true) => ScalarKind::from_int_size(i.size()),
F32 => ScalarKind::F32,
F64 => ScalarKind::F64,
Pointer => ScalarKind::Ptr,
}
}
@ -1307,7 +1307,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
Ok(kind)
}
fn ensure_valid_value(&self, val: PrimVal, ty: Ty<'tcx>) -> EvalResult<'tcx> {
fn ensure_valid_value(&self, val: Scalar, ty: Ty<'tcx>) -> EvalResult<'tcx> {
match ty.sty {
ty::TyBool if val.to_bytes()? > 1 => err!(InvalidBool),
@ -1366,7 +1366,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
ty::TyBool => {
let val = self.memory.read_primval(ptr, ptr_align, Size::from_bytes(1))?;
match val {
PrimVal::Bytes(0) | PrimVal::Bytes(1) => (),
Scalar::Bytes(0) | Scalar::Bytes(1) => (),
// TODO: This seems a little overeager, should reading at bool type already be insta-UB?
_ => return err!(InvalidBool),
}
@ -1419,7 +1419,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
self.memory.check_align(ptr, ptr_align)?;
if layout.size.bytes() == 0 {
return Ok(Some(Value::ByVal(PrimVal::Undef)));
return Ok(Some(Value::ByVal(Scalar::Undef)));
}
let ptr = ptr.to_ptr()?;
@ -1615,7 +1615,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
}
Ok(Value::ByRef(ptr, align)) => {
match ptr.into_inner_primval() {
PrimVal::Ptr(ptr) => {
Scalar::Ptr(ptr) => {
write!(msg, " by align({}) ref:", align.abi()).unwrap();
allocs.push(ptr.alloc_id);
}
@ -1624,16 +1624,16 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
}
Ok(Value::ByVal(val)) => {
write!(msg, " {:?}", val).unwrap();
if let PrimVal::Ptr(ptr) = val {
if let Scalar::Ptr(ptr) = val {
allocs.push(ptr.alloc_id);
}
}
Ok(Value::ByValPair(val1, val2)) => {
write!(msg, " ({:?}, {:?})", val1, val2).unwrap();
if let PrimVal::Ptr(ptr) = val1 {
if let Scalar::Ptr(ptr) = val1 {
allocs.push(ptr.alloc_id);
}
if let PrimVal::Ptr(ptr) = val2 {
if let Scalar::Ptr(ptr) = val2 {
allocs.push(ptr.alloc_id);
}
}
@ -1644,7 +1644,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
}
Place::Ptr { ptr, align, .. } => {
match ptr.into_inner_primval() {
PrimVal::Ptr(ptr) => {
Scalar::Ptr(ptr) => {
trace!("by align({}) ref:", align.abi());
self.memory.dump_alloc(ptr.alloc_id);
}
@ -1797,7 +1797,7 @@ impl<'mir, 'tcx> Frame<'mir, 'tcx> {
trace!("{:?} is now live", local);
// StorageLive *always* kills the value that's currently stored
mem::replace(&mut self.locals[local], Some(Value::ByVal(PrimVal::Undef)))
mem::replace(&mut self.locals[local], Some(Value::ByVal(Scalar::Undef)))
}
/// Returns the old value of the local

View file

@ -2,7 +2,7 @@
//! This separation exists to ensure that no fancy miri features like
//! interpreting common C functions leak into CTFE.
use rustc::mir::interpret::{AllocId, EvalResult, PrimVal, MemoryPointer, AccessKind, GlobalId};
use rustc::mir::interpret::{AllocId, EvalResult, Scalar, MemoryPointer, AccessKind, GlobalId};
use super::{EvalContext, Place, ValTy, Memory};
use rustc::mir;
@ -54,11 +54,11 @@ pub trait Machine<'mir, 'tcx>: Sized {
fn try_ptr_op<'a>(
ecx: &EvalContext<'a, 'mir, 'tcx, Self>,
bin_op: mir::BinOp,
left: PrimVal,
left: Scalar,
left_ty: Ty<'tcx>,
right: PrimVal,
right: Scalar,
right_ty: Ty<'tcx>,
) -> EvalResult<'tcx, Option<(PrimVal, bool)>>;
) -> EvalResult<'tcx, Option<(Scalar, bool)>>;
/// Called when trying to mark machine defined `MemoryKinds` as static
fn mark_static_initialized<'a>(

View file

@ -11,7 +11,7 @@ use rustc::middle::const_val::{ConstVal, ErrKind};
use rustc_data_structures::fx::{FxHashSet, FxHashMap};
use rustc::mir::interpret::{MemoryPointer, AllocId, Allocation, AccessKind, Value, Pointer,
EvalResult, PrimVal, EvalErrorKind, GlobalId, AllocType};
EvalResult, Scalar, EvalErrorKind, GlobalId, AllocType};
pub use rustc::mir::interpret::{write_target_uint, write_target_int, read_target_uint};
use super::{EvalContext, Machine};
@ -231,11 +231,11 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
pub fn check_align(&self, ptr: Pointer, required_align: Align) -> EvalResult<'tcx> {
// Check non-NULL/Undef, extract offset
let (offset, alloc_align) = match ptr.into_inner_primval() {
PrimVal::Ptr(ptr) => {
Scalar::Ptr(ptr) => {
let alloc = self.get(ptr.alloc_id)?;
(ptr.offset.bytes(), alloc.align)
}
PrimVal::Bytes(bytes) => {
Scalar::Bytes(bytes) => {
let v = ((bytes as u128) % (1 << self.pointer_size().bytes())) as u64;
if v == 0 {
return err!(InvalidNullPointerUsage);
@ -243,7 +243,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
// the base address if the "integer allocation" is 0 and hence always aligned
(v, required_align)
}
PrimVal::Undef => return err!(ReadUndefBytes),
Scalar::Undef => return err!(ReadUndefBytes),
};
// Check alignment
if alloc_align.abi() < required_align.abi() {
@ -707,14 +707,14 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
Ok(())
}
pub fn read_primval(&self, ptr: MemoryPointer, ptr_align: Align, size: Size) -> EvalResult<'tcx, PrimVal> {
pub fn read_primval(&self, ptr: MemoryPointer, ptr_align: Align, size: Size) -> EvalResult<'tcx, Scalar> {
self.check_relocation_edges(ptr, size)?; // Make sure we don't read part of a pointer as a pointer
let endianness = self.endianness();
let bytes = self.get_bytes_unchecked(ptr, size, ptr_align.min(self.int_align(size)))?;
// Undef check happens *after* we established that the alignment is correct.
// We must not return Ok() for unaligned pointers!
if self.check_defined(ptr, size).is_err() {
return Ok(PrimVal::Undef.into());
return Ok(Scalar::Undef.into());
}
// Now we do the actual reading
let bytes = read_target_uint(endianness, bytes).unwrap();
@ -726,30 +726,30 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
} else {
let alloc = self.get(ptr.alloc_id)?;
match alloc.relocations.get(&ptr.offset) {
Some(&alloc_id) => return Ok(PrimVal::Ptr(MemoryPointer::new(alloc_id, Size::from_bytes(bytes as u64)))),
Some(&alloc_id) => return Ok(Scalar::Ptr(MemoryPointer::new(alloc_id, Size::from_bytes(bytes as u64)))),
None => {},
}
}
// We don't. Just return the bytes.
Ok(PrimVal::Bytes(bytes))
Ok(Scalar::Bytes(bytes))
}
pub fn read_ptr_sized(&self, ptr: MemoryPointer, ptr_align: Align) -> EvalResult<'tcx, PrimVal> {
pub fn read_ptr_sized(&self, ptr: MemoryPointer, ptr_align: Align) -> EvalResult<'tcx, Scalar> {
self.read_primval(ptr, ptr_align, self.pointer_size())
}
pub fn write_primval(&mut self, ptr: Pointer, ptr_align: Align, val: PrimVal, size: Size, signed: bool) -> EvalResult<'tcx> {
pub fn write_primval(&mut self, ptr: Pointer, ptr_align: Align, val: Scalar, size: Size, signed: bool) -> EvalResult<'tcx> {
let endianness = self.endianness();
let bytes = match val {
PrimVal::Ptr(val) => {
Scalar::Ptr(val) => {
assert_eq!(size, self.pointer_size());
val.offset.bytes() as u128
}
PrimVal::Bytes(bytes) => bytes,
Scalar::Bytes(bytes) => bytes,
PrimVal::Undef => {
Scalar::Undef => {
self.check_align(ptr.into(), ptr_align)?;
self.mark_definedness(ptr, size, false)?;
return Ok(());
@ -770,7 +770,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
// See if we have to also write a relocation
match val {
PrimVal::Ptr(val) => {
Scalar::Ptr(val) => {
self.get_mut(ptr.alloc_id)?.relocations.insert(
ptr.offset,
val.alloc_id,
@ -782,7 +782,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
Ok(())
}
pub fn write_ptr_sized_unsigned(&mut self, ptr: MemoryPointer, ptr_align: Align, val: PrimVal) -> EvalResult<'tcx> {
pub fn write_ptr_sized_unsigned(&mut self, ptr: MemoryPointer, ptr_align: Align, val: Scalar) -> EvalResult<'tcx> {
let ptr_size = self.pointer_size();
self.write_primval(ptr.into(), ptr_align, val, ptr_size, false)
}
@ -954,7 +954,7 @@ pub trait HasMemory<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'mir, 'tcx>> {
Value::ByValPair(ptr, vtable) => Ok((ptr.into(), vtable.to_ptr()?)),
Value::ByVal(PrimVal::Undef) => err!(ReadUndefBytes),
Value::ByVal(Scalar::Undef) => err!(ReadUndefBytes),
_ => bug!("expected ptr and vtable, got {:?}", value),
}
}
@ -978,7 +978,7 @@ pub trait HasMemory<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'mir, 'tcx>> {
assert_eq!(len as u64 as u128, len);
Ok((ptr.into(), len as u64))
}
Value::ByVal(PrimVal::Undef) => err!(ReadUndefBytes),
Value::ByVal(Scalar::Undef) => err!(ReadUndefBytes),
Value::ByVal(_) => bug!("expected ptr and length, got {:?}", value),
}
}

View file

@ -7,7 +7,7 @@ use rustc_apfloat::Float;
use super::{EvalContext, Place, Machine, ValTy};
use rustc::mir::interpret::{EvalResult, PrimVal, Value};
use rustc::mir::interpret::{EvalResult, Scalar, Value};
impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
fn binop_with_overflow(
@ -15,7 +15,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
op: mir::BinOp,
left: ValTy<'tcx>,
right: ValTy<'tcx>,
) -> EvalResult<'tcx, (PrimVal, bool)> {
) -> EvalResult<'tcx, (Scalar, bool)> {
let left_val = self.value_to_primval(left)?;
let right_val = self.value_to_primval(right)?;
self.binary_op(op, left_val, left.ty, right_val, right.ty)
@ -32,7 +32,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
dest_ty: Ty<'tcx>,
) -> EvalResult<'tcx> {
let (val, overflowed) = self.binop_with_overflow(op, left, right)?;
let val = Value::ByValPair(val, PrimVal::from_bool(overflowed));
let val = Value::ByValPair(val, Scalar::from_bool(overflowed));
let valty = ValTy {
value: val,
ty: dest_ty,
@ -61,11 +61,11 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
pub fn binary_op(
&self,
bin_op: mir::BinOp,
left: PrimVal,
left: Scalar,
left_ty: Ty<'tcx>,
right: PrimVal,
right: Scalar,
right_ty: Ty<'tcx>,
) -> EvalResult<'tcx, (PrimVal, bool)> {
) -> EvalResult<'tcx, (Scalar, bool)> {
use rustc::mir::BinOp::*;
let left_kind = self.ty_to_primval_kind(left_ty)?;
@ -110,7 +110,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
}
};
let truncated = self.truncate(result, left_ty)?;
return Ok((PrimVal::Bytes(truncated), oflo));
return Ok((Scalar::Bytes(truncated), oflo));
}
if left_kind != right_kind {
@ -136,7 +136,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
if let Some(op) = op {
let l = self.sign_extend(l, left_ty)? as i128;
let r = self.sign_extend(r, right_ty)? as i128;
return Ok((PrimVal::from_bool(op(&l, &r)), false));
return Ok((Scalar::from_bool(op(&l, &r)), false));
}
let op: Option<fn(i128, i128) -> (i128, bool)> = match bin_op {
Div if r == 0 => return err!(DivisionByZero),
@ -156,7 +156,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
Rem | Div => {
// int_min / -1
if r == -1 && l == (1 << (size - 1)) {
return Ok((PrimVal::Bytes(l), true));
return Ok((Scalar::Bytes(l), true));
}
},
_ => {},
@ -170,7 +170,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
}
let result = result as u128;
let truncated = self.truncate(result, left_ty)?;
return Ok((PrimVal::Bytes(truncated), oflo));
return Ok((Scalar::Bytes(truncated), oflo));
}
}
@ -180,17 +180,17 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
let l = <$ty>::from_bits(l);
let r = <$ty>::from_bits(r);
let val = match bin_op {
Eq => PrimVal::from_bool(l == r),
Ne => PrimVal::from_bool(l != r),
Lt => PrimVal::from_bool(l < r),
Le => PrimVal::from_bool(l <= r),
Gt => PrimVal::from_bool(l > r),
Ge => PrimVal::from_bool(l >= r),
Add => PrimVal::Bytes((l + r).value.to_bits()),
Sub => PrimVal::Bytes((l - r).value.to_bits()),
Mul => PrimVal::Bytes((l * r).value.to_bits()),
Div => PrimVal::Bytes((l / r).value.to_bits()),
Rem => PrimVal::Bytes((l % r).value.to_bits()),
Eq => Scalar::from_bool(l == r),
Ne => Scalar::from_bool(l != r),
Lt => Scalar::from_bool(l < r),
Le => Scalar::from_bool(l <= r),
Gt => Scalar::from_bool(l > r),
Ge => Scalar::from_bool(l >= r),
Add => Scalar::Bytes((l + r).value.to_bits()),
Sub => Scalar::Bytes((l - r).value.to_bits()),
Mul => Scalar::Bytes((l * r).value.to_bits()),
Div => Scalar::Bytes((l / r).value.to_bits()),
Rem => Scalar::Bytes((l % r).value.to_bits()),
_ => bug!("invalid float op: `{:?}`", bin_op),
};
return Ok((val, false));
@ -204,17 +204,17 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
// only ints left
let val = match bin_op {
Eq => PrimVal::from_bool(l == r),
Ne => PrimVal::from_bool(l != r),
Eq => Scalar::from_bool(l == r),
Ne => Scalar::from_bool(l != r),
Lt => PrimVal::from_bool(l < r),
Le => PrimVal::from_bool(l <= r),
Gt => PrimVal::from_bool(l > r),
Ge => PrimVal::from_bool(l >= r),
Lt => Scalar::from_bool(l < r),
Le => Scalar::from_bool(l <= r),
Gt => Scalar::from_bool(l > r),
Ge => Scalar::from_bool(l >= r),
BitOr => PrimVal::Bytes(l | r),
BitAnd => PrimVal::Bytes(l & r),
BitXor => PrimVal::Bytes(l ^ r),
BitOr => Scalar::Bytes(l | r),
BitAnd => Scalar::Bytes(l & r),
BitXor => Scalar::Bytes(l ^ r),
Add | Sub | Mul | Rem | Div => {
let op: fn(u128, u128) -> (u128, bool) = match bin_op {
@ -229,7 +229,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
};
let (result, oflo) = op(l, r);
let truncated = self.truncate(result, left_ty)?;
return Ok((PrimVal::Bytes(truncated), oflo || truncated != result));
return Ok((Scalar::Bytes(truncated), oflo || truncated != result));
}
_ => {
@ -251,9 +251,9 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
pub fn unary_op(
&self,
un_op: mir::UnOp,
val: PrimVal,
val: Scalar,
ty: Ty<'tcx>,
) -> EvalResult<'tcx, PrimVal> {
) -> EvalResult<'tcx, Scalar> {
use rustc::mir::UnOp::*;
use rustc_apfloat::ieee::{Single, Double};
use rustc_apfloat::Float;
@ -274,6 +274,6 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
(Neg, _) => (-(bytes as i128)) as u128,
};
Ok(PrimVal::Bytes(self.truncate(result_bytes, ty)?))
Ok(Scalar::Bytes(self.truncate(result_bytes, ty)?))
}
}

View file

@ -3,7 +3,7 @@ use rustc::ty::{self, Ty, TyCtxt};
use rustc::ty::layout::{self, Align, LayoutOf, TyLayout};
use rustc_data_structures::indexed_vec::Idx;
use rustc::mir::interpret::{GlobalId, Value, PrimVal, EvalResult, Pointer, MemoryPointer};
use rustc::mir::interpret::{GlobalId, Value, Scalar, EvalResult, Pointer, MemoryPointer};
use super::{EvalContext, Machine, ValTy};
use interpret::memory::HasMemory;
@ -35,7 +35,7 @@ pub enum PlaceExtra {
impl<'tcx> Place {
/// Produces a Place that will error if attempted to be read from
pub fn undef() -> Self {
Self::from_primval_ptr(PrimVal::Undef.into(), Align::from_bytes(1, 1).unwrap())
Self::from_primval_ptr(Scalar::Undef.into(), Align::from_bytes(1, 1).unwrap())
}
pub fn from_primval_ptr(ptr: Pointer, align: Align) -> Self {
@ -128,7 +128,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
let field_index = field.index();
let field = base_layout.field(self, field_index)?;
if field.size.bytes() == 0 {
return Ok(Some((Value::ByVal(PrimVal::Undef), field.ty)))
return Ok(Some((Value::ByVal(Scalar::Undef), field.ty)))
}
let offset = base_layout.fields.offset(field_index);
match base {

View file

@ -2,7 +2,7 @@ use rustc::mir::BasicBlock;
use rustc::ty::{self, Ty};
use syntax::codemap::Span;
use rustc::mir::interpret::{EvalResult, PrimVal, Value};
use rustc::mir::interpret::{EvalResult, Scalar, Value};
use interpret::{Machine, ValTy, EvalContext, Place, PlaceExtra};
impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
@ -52,7 +52,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
let instance = match ty.sty {
ty::TyDynamic(..) => {
let vtable = match arg {
Value::ByValPair(_, PrimVal::Ptr(vtable)) => vtable,
Value::ByValPair(_, Scalar::Ptr(vtable)) => vtable,
_ => bug!("expected fat ptr, got {:?}", arg),
};
match self.read_drop_type_from_vtable(vtable)? {

View file

@ -4,7 +4,7 @@ use rustc::ty::layout::LayoutOf;
use syntax::codemap::Span;
use rustc_target::spec::abi::Abi;
use rustc::mir::interpret::{EvalResult, PrimVal, Value};
use rustc::mir::interpret::{EvalResult, Scalar, Value};
use super::{EvalContext, Place, Machine, ValTy};
use rustc_data_structures::indexed_vec::Idx;
@ -359,7 +359,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
self.write_value(valty, dest)?;
}
}
Value::ByVal(PrimVal::Undef) => {}
Value::ByVal(Scalar::Undef) => {}
other => {
trace!("{:#?}, {:#?}", other, layout);
let mut layout = layout;

View file

@ -2,7 +2,7 @@ use rustc::ty::{self, Ty};
use rustc::ty::layout::{Size, Align, LayoutOf};
use syntax::ast::Mutability;
use rustc::mir::interpret::{PrimVal, Value, MemoryPointer, EvalResult};
use rustc::mir::interpret::{Scalar, Value, MemoryPointer, EvalResult};
use super::{EvalContext, Machine};
impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
@ -35,19 +35,19 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
let drop = ::monomorphize::resolve_drop_in_place(*self.tcx, ty);
let drop = self.memory.create_fn_alloc(drop);
self.memory.write_ptr_sized_unsigned(vtable, ptr_align, PrimVal::Ptr(drop))?;
self.memory.write_ptr_sized_unsigned(vtable, ptr_align, Scalar::Ptr(drop))?;
let size_ptr = vtable.offset(ptr_size, &self)?;
self.memory.write_ptr_sized_unsigned(size_ptr, ptr_align, PrimVal::Bytes(size as u128))?;
self.memory.write_ptr_sized_unsigned(size_ptr, ptr_align, Scalar::Bytes(size as u128))?;
let align_ptr = vtable.offset(ptr_size * 2, &self)?;
self.memory.write_ptr_sized_unsigned(align_ptr, ptr_align, PrimVal::Bytes(align as u128))?;
self.memory.write_ptr_sized_unsigned(align_ptr, ptr_align, Scalar::Bytes(align as u128))?;
for (i, method) in methods.iter().enumerate() {
if let Some((def_id, substs)) = *method {
let instance = self.resolve(def_id, substs)?;
let fn_ptr = self.memory.create_fn_alloc(instance);
let method_ptr = vtable.offset(ptr_size * (3 + i as u64), &self)?;
self.memory.write_ptr_sized_unsigned(method_ptr, ptr_align, PrimVal::Ptr(fn_ptr))?;
self.memory.write_ptr_sized_unsigned(method_ptr, ptr_align, Scalar::Ptr(fn_ptr))?;
}
}
@ -67,8 +67,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
let pointer_align = self.tcx.data_layout.pointer_align;
match self.read_ptr(vtable, pointer_align, self.tcx.mk_nil_ptr())? {
// some values don't need to call a drop impl, so the value is null
Value::ByVal(PrimVal::Bytes(0)) => Ok(None),
Value::ByVal(PrimVal::Ptr(drop_fn)) => self.memory.get_fn(drop_fn).map(Some),
Value::ByVal(Scalar::Bytes(0)) => Ok(None),
Value::ByVal(Scalar::Ptr(drop_fn)) => self.memory.get_fn(drop_fn).map(Some),
_ => err!(ReadBytesAsPointer),
}
}

View file

@ -203,7 +203,7 @@ use rustc::session::config;
use rustc::mir::{self, Location, Promoted};
use rustc::mir::visit::Visitor as MirVisitor;
use rustc::mir::mono::MonoItem;
use rustc::mir::interpret::{PrimVal, GlobalId, AllocType};
use rustc::mir::interpret::{Scalar, GlobalId, AllocType};
use monomorphize::{self, Instance};
use rustc::util::nodemap::{FxHashSet, FxHashMap, DefIdMap};
@ -1245,13 +1245,13 @@ fn collect_const<'a, 'tcx>(
};
match val {
ConstVal::Unevaluated(..) => bug!("const eval yielded unevaluated const"),
ConstVal::Value(ConstValue::ByValPair(PrimVal::Ptr(a), PrimVal::Ptr(b))) => {
ConstVal::Value(ConstValue::ByValPair(Scalar::Ptr(a), Scalar::Ptr(b))) => {
collect_miri(tcx, a.alloc_id, output);
collect_miri(tcx, b.alloc_id, output);
}
ConstVal::Value(ConstValue::ByValPair(_, PrimVal::Ptr(ptr))) |
ConstVal::Value(ConstValue::ByValPair(PrimVal::Ptr(ptr), _)) |
ConstVal::Value(ConstValue::ByVal(PrimVal::Ptr(ptr))) =>
ConstVal::Value(ConstValue::ByValPair(_, Scalar::Ptr(ptr))) |
ConstVal::Value(ConstValue::ByValPair(Scalar::Ptr(ptr), _)) |
ConstVal::Value(ConstValue::ByVal(Scalar::Ptr(ptr))) =>
collect_miri(tcx, ptr.alloc_id, output),
ConstVal::Value(ConstValue::ByRef(alloc, _offset)) => {
for &id in alloc.relocations.values() {

View file

@ -19,7 +19,7 @@ use rustc::mir::{TerminatorKind, ClearCrossCrate, SourceInfo, BinOp, ProjectionE
use rustc::mir::visit::{Visitor, PlaceContext};
use rustc::middle::const_val::ConstVal;
use rustc::ty::{TyCtxt, self, Instance};
use rustc::mir::interpret::{Value, PrimVal, GlobalId, EvalResult};
use rustc::mir::interpret::{Value, Scalar, GlobalId, EvalResult};
use interpret::EvalContext;
use interpret::CompileTimeEvaluator;
use interpret::{eval_promoted, mk_borrowck_eval_cx, ValTy};
@ -283,7 +283,7 @@ impl<'b, 'a, 'tcx:'b> ConstPropagator<'b, 'a, 'tcx> {
Rvalue::NullaryOp(NullOp::SizeOf, ty) => {
let param_env = self.tcx.param_env(self.source.def_id);
type_size_of(self.tcx, param_env, ty).map(|n| (
Value::ByVal(PrimVal::Bytes(n as u128)),
Value::ByVal(Scalar::Bytes(n as u128)),
self.tcx.types.usize,
span,
))
@ -359,7 +359,7 @@ impl<'b, 'a, 'tcx:'b> ConstPropagator<'b, 'a, 'tcx> {
let val = if let Rvalue::CheckedBinaryOp(..) = *rvalue {
Value::ByValPair(
val,
PrimVal::from_bool(overflow),
Scalar::from_bool(overflow),
)
} else {
if overflow {
@ -485,7 +485,7 @@ impl<'b, 'a, 'tcx> Visitor<'tcx> for ConstPropagator<'b, 'a, 'tcx> {
if let TerminatorKind::Assert { expected, msg, cond, .. } = kind {
if let Some(value) = self.eval_operand(cond) {
trace!("assertion on {:?} should be {:?}", value, expected);
if Value::ByVal(PrimVal::from_bool(*expected)) != value.0 {
if Value::ByVal(Scalar::from_bool(*expected)) != value.0 {
// poison all places this operand references so that further code
// doesn't use the invalid value
match cond {
@ -520,14 +520,14 @@ impl<'b, 'a, 'tcx> Visitor<'tcx> for ConstPropagator<'b, 'a, 'tcx> {
BoundsCheck { ref len, ref index } => {
let len = self.eval_operand(len).expect("len must be const");
let len = match len.0 {
Value::ByVal(PrimVal::Bytes(n)) => n,
Value::ByVal(Scalar::Bytes(n)) => n,
_ => bug!("const len not primitive: {:?}", len),
};
let index = self
.eval_operand(index)
.expect("index must be const");
let index = match index.0 {
Value::ByVal(PrimVal::Bytes(n)) => n,
Value::ByVal(Scalar::Bytes(n)) => n,
_ => bug!("const index not primitive: {:?}", index),
};
format!(