}
Value::ByVal(primval) => {
let size = self.type_size(dest_ty)?.expect("dest type must be sized");
- // TODO: This fn gets called with sizes like 6, which cannot be a primitive type
+ // TODO: This fn gets called with sizes like 0 and 6, which cannot be a primitive type
// and hence is not supported by write_primval.
// (E.g. in the arrays.rs testcase.) That seems to only happen for Undef though,
// so we special-case that here.
let ptr = ptr.to_ptr()?;
let val = match ty.sty {
- ty::TyBool => PrimVal::from_bool(self.memory.read_bool(ptr)?),
+ ty::TyBool => {
+ let val = self.memory.read_primval(ptr, 1, false)?;
+ let val = match val {
+ PrimVal::Bytes(0) => false,
+ PrimVal::Bytes(1) => true,
+ _ => return err!(InvalidBool),
+ };
+ PrimVal::from_bool(val)
+ }
ty::TyChar => {
let c = self.memory.read_primval(ptr, 4, false)?.to_bytes()? as u32;
match ::std::char::from_u32(c) {
self.memory.read_primval(ptr, size, false)?
}
- ty::TyFloat(FloatTy::F32) => PrimVal::from_f32(self.memory.read_f32(ptr)?),
- ty::TyFloat(FloatTy::F64) => PrimVal::from_f64(self.memory.read_f64(ptr)?),
+ ty::TyFloat(FloatTy::F32) => PrimVal::Bytes(self.memory.read_primval(ptr, 4, false)?.to_bytes()?),
+ ty::TyFloat(FloatTy::F64) => PrimVal::Bytes(self.memory.read_primval(ptr, 8, false)?.to_bytes()?),
ty::TyFnPtr(_) => self.memory.read_ptr_sized_unsigned(ptr)?,
ty::TyRef(_, ref tam) |
}
pub fn write_primval(&mut self, ptr: MemoryPointer, val: PrimVal, size: u64, signed: bool) -> EvalResult<'tcx> {
- trace!("Writing {:?}, size {}", val, size);
let align = self.int_align(size)?;
let endianess = self.endianess();
self.write_primval(ptr, val, ptr_size, false)
}
- pub fn read_bool(&self, ptr: MemoryPointer) -> EvalResult<'tcx, bool> {
- let bytes = self.get_bytes(ptr, 1, self.layout.i1_align.abi())?;
- match bytes[0] {
- 0 => Ok(false),
- 1 => Ok(true),
- _ => err!(InvalidBool),
- }
- }
-
- pub fn write_bool(&mut self, ptr: MemoryPointer, b: bool) -> EvalResult<'tcx> {
- let align = self.layout.i1_align.abi();
- self.get_bytes_mut(ptr, 1, align).map(
- |bytes| bytes[0] = b as u8,
- )
- }
-
fn int_align(&self, size: u64) -> EvalResult<'tcx, u64> {
// We assume pointer-sized integers have the same alignment as pointers.
// We also assume singed and unsigned integers of the same size have the same alignment.
_ => bug!("bad integer size: {}", size),
}
}
-
- pub fn write_f32(&mut self, ptr: MemoryPointer, f: f32) -> EvalResult<'tcx> {
- let endianess = self.endianess();
- let align = self.layout.f32_align.abi();
- let b = self.get_bytes_mut(ptr, 4, align)?;
- write_target_f32(endianess, b, f).unwrap();
- Ok(())
- }
-
- pub fn write_f64(&mut self, ptr: MemoryPointer, f: f64) -> EvalResult<'tcx> {
- let endianess = self.endianess();
- let align = self.layout.f64_align.abi();
- let b = self.get_bytes_mut(ptr, 8, align)?;
- write_target_f64(endianess, b, f).unwrap();
- Ok(())
- }
-
- pub fn read_f32(&self, ptr: MemoryPointer) -> EvalResult<'tcx, f32> {
- self.get_bytes(ptr, 4, self.layout.f32_align.abi()).map(
- |b| {
- read_target_f32(self.endianess(), b).unwrap()
- },
- )
- }
-
- pub fn read_f64(&self, ptr: MemoryPointer) -> EvalResult<'tcx, f64> {
- self.get_bytes(ptr, 8, self.layout.f64_align.abi()).map(
- |b| {
- read_target_f64(self.endianess(), b).unwrap()
- },
- )
- }
}
/// Relocations
}
}
-
-////////////////////////////////////////////////////////////////////////////////
-// Methods to access floats in the target endianess
-////////////////////////////////////////////////////////////////////////////////
-
-fn write_target_f32(
- endianess: layout::Endian,
- mut target: &mut [u8],
- data: f32,
-) -> Result<(), io::Error> {
- match endianess {
- layout::Endian::Little => target.write_f32::<LittleEndian>(data),
- layout::Endian::Big => target.write_f32::<BigEndian>(data),
- }
-}
-fn write_target_f64(
- endianess: layout::Endian,
- mut target: &mut [u8],
- data: f64,
-) -> Result<(), io::Error> {
- match endianess {
- layout::Endian::Little => target.write_f64::<LittleEndian>(data),
- layout::Endian::Big => target.write_f64::<BigEndian>(data),
- }
-}
-
-fn read_target_f32(endianess: layout::Endian, mut source: &[u8]) -> Result<f32, io::Error> {
- match endianess {
- layout::Endian::Little => source.read_f32::<LittleEndian>(),
- layout::Endian::Big => source.read_f32::<BigEndian>(),
- }
-}
-fn read_target_f64(endianess: layout::Endian, mut source: &[u8]) -> Result<f64, io::Error> {
- match endianess {
- layout::Endian::Little => source.read_f64::<LittleEndian>(),
- layout::Endian::Big => source.read_f64::<BigEndian>(),
- }
-}
-
////////////////////////////////////////////////////////////////////////////////
// Undefined byte tracking
////////////////////////////////////////////////////////////////////////////////