Address review comments

This commit is contained in:
Oliver Schneider 2018-02-22 17:29:39 +01:00
parent 208d764833
commit 47913ee8f4
No known key found for this signature in database
GPG key ID: A69F8D225B3AD7D9
7 changed files with 33 additions and 71 deletions

View file

@ -1831,6 +1831,7 @@ impl<'a, 'gcx, 'tcx> AdtDef {
) -> Option<Discr<'tcx>> {
let param_env = ParamEnv::empty(traits::Reveal::UserFacing);
let repr_type = self.repr.discr_type();
let bit_size = layout::Integer::from_attr(tcx, repr_type).size().bits();
let substs = Substs::identity_for_item(tcx.global_tcx(), expr_did);
let instance = ty::Instance::new(expr_did, substs);
let cid = GlobalId {
@ -1844,22 +1845,10 @@ impl<'a, 'gcx, 'tcx> AdtDef {
}) => {
trace!("discriminants: {} ({:?})", b, repr_type);
let ty = repr_type.to_ty(tcx);
if ty.is_signed() {
let (ty, param_env) = tcx
.lift_to_global(&(ty, param_env))
.unwrap_or_else(|| {
bug!("MIR: discriminants({:?}, {:?}) got \
type with inference types/regions",
ty, param_env);
});
let size = tcx.global_tcx()
.layout_of(param_env.and(ty))
.expect("int layout")
.size
.bits();
if repr_type.is_signed() {
let val = b as i128;
// sign extend to i128
let amt = 128 - size;
let amt = 128 - bit_size;
let val = (val << amt) >> amt;
Some(Discr {
val: val as u128,

View file

@ -151,22 +151,13 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
pub fn type_bit_size(
&self,
ty: Ty<'tcx>,
ty: Ty,
) -> u64 {
let tcx = self.tcx.global_tcx();
let (ty, param_env) = self
.tcx
.lift_to_global(&(ty, self.param_env))
.unwrap_or_else(|| {
bug!("MIR: Cx::const_eval_literal({:?}, {:?}) got \
type with inference types/regions",
ty, self.param_env);
});
tcx
.layout_of(param_env.and(ty))
.expect("int layout")
.size
.bits()
match ty.sty {
ty::TyInt(ity) => ity.bit_width(),
ty::TyUint(uty) => uty.bit_width(),
_ => bug!("{} is not an integer", ty),
}.map_or(self.tcx.data_layout.pointer_size.bits(), |n| n as u64)
}
pub fn const_eval_literal(

View file

@ -1256,7 +1256,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
pointee_ty: Ty<'tcx>,
) -> EvalResult<'tcx, Value> {
let ptr_size = self.memory.pointer_size();
let p: Pointer = self.memory.read_ptr_sized_unsigned(ptr, ptr_align)?.into();
let p: Pointer = self.memory.read_ptr_sized(ptr, ptr_align)?.into();
if self.type_is_sized(pointee_ty) {
Ok(p.to_value())
} else {
@ -1264,12 +1264,12 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
let extra = ptr.offset(ptr_size, self)?;
match self.tcx.struct_tail(pointee_ty).sty {
ty::TyDynamic(..) => Ok(p.to_value_with_vtable(
self.memory.read_ptr_sized_unsigned(extra, ptr_align)?.to_ptr()?,
self.memory.read_ptr_sized(extra, ptr_align)?.to_ptr()?,
)),
ty::TySlice(..) | ty::TyStr => {
let len = self
.memory
.read_ptr_sized_unsigned(extra, ptr_align)?
.read_ptr_sized(extra, ptr_align)?
.to_bytes()?;
Ok(p.to_value_with_len(len as u64))
},
@ -1284,7 +1284,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
let ptr = ptr.to_ptr()?;
let val = match ty.sty {
ty::TyBool => {
let val = self.memory.read_primval(ptr, ptr_align, 1, false)?;
let val = self.memory.read_primval(ptr, ptr_align, 1)?;
let val = match val {
PrimVal::Bytes(0) => false,
PrimVal::Bytes(1) => true,
@ -1294,7 +1294,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
PrimVal::from_bool(val)
}
ty::TyChar => {
let c = self.memory.read_primval(ptr, ptr_align, 4, false)?.to_bytes()? as u32;
let c = self.memory.read_primval(ptr, ptr_align, 4)?.to_bytes()? as u32;
match ::std::char::from_u32(c) {
Some(ch) => PrimVal::from_char(ch),
None => return err!(InvalidChar(c as u128)),
@ -1311,7 +1311,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
I128 => 16,
Isize => self.memory.pointer_size(),
};
self.memory.read_primval(ptr, ptr_align, size, true)?
self.memory.read_primval(ptr, ptr_align, size)?
}
ty::TyUint(uint_ty) => {
@ -1324,17 +1324,17 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
U128 => 16,
Usize => self.memory.pointer_size(),
};
self.memory.read_primval(ptr, ptr_align, size, false)?
self.memory.read_primval(ptr, ptr_align, size)?
}
ty::TyFloat(FloatTy::F32) => {
PrimVal::Bytes(self.memory.read_primval(ptr, ptr_align, 4, false)?.to_bytes()?)
PrimVal::Bytes(self.memory.read_primval(ptr, ptr_align, 4)?.to_bytes()?)
}
ty::TyFloat(FloatTy::F64) => {
PrimVal::Bytes(self.memory.read_primval(ptr, ptr_align, 8, false)?.to_bytes()?)
PrimVal::Bytes(self.memory.read_primval(ptr, ptr_align, 8)?.to_bytes()?)
}
ty::TyFnPtr(_) => self.memory.read_ptr_sized_unsigned(ptr, ptr_align)?,
ty::TyFnPtr(_) => self.memory.read_ptr_sized(ptr, ptr_align)?,
ty::TyRef(_, ref tam) |
ty::TyRawPtr(ref tam) => return self.read_ptr(ptr, ptr_align, tam.ty).map(Some),
@ -1344,12 +1344,8 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
}
if let layout::Abi::Scalar(ref scalar) = self.layout_of(ty)?.abi {
let mut signed = false;
if let layout::Int(_, s) = scalar.value {
signed = s;
}
let size = scalar.value.size(self).bytes();
self.memory.read_primval(ptr, ptr_align, size, signed)?
self.memory.read_primval(ptr, ptr_align, size)?
} else {
return Ok(None);
}

View file

@ -655,7 +655,7 @@ 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: u64, signed: bool) -> EvalResult<'tcx, PrimVal> {
pub fn read_primval(&self, ptr: MemoryPointer, ptr_align: Align, size: u64) -> EvalResult<'tcx, PrimVal> {
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)))?;
@ -665,14 +665,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
return Ok(PrimVal::Undef.into());
}
// Now we do the actual reading
let bytes = if signed {
let bytes = read_target_int(endianness, bytes).unwrap() as u128;
let amt = 128 - (size * 8);
// truncate (shift left to drop out leftover values, shift right to fill with zeroes)
(bytes << amt) >> amt
} else {
read_target_uint(endianness, bytes).unwrap()
};
let bytes = read_target_uint(endianness, bytes).unwrap();
// See if we got a pointer
if size != self.pointer_size() {
if self.relocations(ptr, size)?.count() != 0 {
@ -689,8 +682,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
Ok(PrimVal::Bytes(bytes))
}
pub fn read_ptr_sized_unsigned(&self, ptr: MemoryPointer, ptr_align: Align) -> EvalResult<'tcx, PrimVal> {
self.read_primval(ptr, ptr_align, self.pointer_size(), false)
pub fn read_ptr_sized(&self, ptr: MemoryPointer, ptr_align: Align) -> EvalResult<'tcx, PrimVal> {
self.read_primval(ptr, ptr_align, self.pointer_size())
}
pub fn write_primval(&mut self, ptr: MemoryPointer, ptr_align: Align, val: PrimVal, size: u64, signed: bool) -> EvalResult<'tcx> {
@ -901,13 +894,6 @@ pub fn read_target_uint(endianness: layout::Endian, mut source: &[u8]) -> Result
}
}
pub fn read_target_int(endianness: layout::Endian, mut source: &[u8]) -> Result<i128, io::Error> {
match endianness {
layout::Endian::Little => source.read_int128::<LittleEndian>(source.len()),
layout::Endian::Big => source.read_int128::<BigEndian>(source.len()),
}
}
////////////////////////////////////////////////////////////////////////////////
// Unaligned accesses
////////////////////////////////////////////////////////////////////////////////
@ -924,7 +910,7 @@ pub trait HasMemory<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'mir, 'tcx>> {
) -> EvalResult<'tcx, Pointer> {
Ok(match value {
Value::ByRef(ptr, align) => {
self.memory().read_ptr_sized_unsigned(ptr.to_ptr()?, align)?
self.memory().read_ptr_sized(ptr.to_ptr()?, align)?
}
Value::ByVal(ptr) |
Value::ByValPair(ptr, _) => ptr,
@ -938,8 +924,8 @@ pub trait HasMemory<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'mir, 'tcx>> {
match value {
Value::ByRef(ref_ptr, align) => {
let mem = self.memory();
let ptr = mem.read_ptr_sized_unsigned(ref_ptr.to_ptr()?, align)?.into();
let vtable = mem.read_ptr_sized_unsigned(
let ptr = mem.read_ptr_sized(ref_ptr.to_ptr()?, align)?.into();
let vtable = mem.read_ptr_sized(
ref_ptr.offset(mem.pointer_size(), &mem.tcx.data_layout)?.to_ptr()?,
align
)?.to_ptr()?;
@ -960,8 +946,8 @@ pub trait HasMemory<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'mir, 'tcx>> {
match value {
Value::ByRef(ref_ptr, align) => {
let mem = self.memory();
let ptr = mem.read_ptr_sized_unsigned(ref_ptr.to_ptr()?, align)?.into();
let len = mem.read_ptr_sized_unsigned(
let ptr = mem.read_ptr_sized(ref_ptr.to_ptr()?, align)?.into();
let len = mem.read_ptr_sized(
ref_ptr.offset(mem.pointer_size(), &mem.tcx.data_layout)?.to_ptr()?,
align
)?.to_bytes()? as u64;

View file

@ -30,4 +30,4 @@ pub use self::const_eval::{
pub use self::machine::Machine;
pub use self::memory::{write_target_uint, write_target_int, read_target_uint, read_target_int};
pub use self::memory::{write_target_uint, write_target_int, read_target_uint};

View file

@ -401,7 +401,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
let ptr_size = self.memory.pointer_size();
let ptr_align = self.tcx.data_layout.pointer_align;
let (ptr, vtable) = self.into_ptr_vtable_pair(args[0].value)?;
let fn_ptr = self.memory.read_ptr_sized_unsigned(
let fn_ptr = self.memory.read_ptr_sized(
vtable.offset(ptr_size * (idx as u64 + 3), &self)?,
ptr_align
)?.to_ptr()?;

View file

@ -79,8 +79,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
) -> EvalResult<'tcx, (Size, Align)> {
let pointer_size = self.memory.pointer_size();
let pointer_align = self.tcx.data_layout.pointer_align;
let size = self.memory.read_ptr_sized_unsigned(vtable.offset(pointer_size, self)?, pointer_align)?.to_bytes()? as u64;
let align = self.memory.read_ptr_sized_unsigned(
let size = self.memory.read_ptr_sized(vtable.offset(pointer_size, self)?, pointer_align)?.to_bytes()? as u64;
let align = self.memory.read_ptr_sized(
vtable.offset(pointer_size * 2, self)?,
pointer_align
)?.to_bytes()? as u64;