refactor memory write API to match read API
This commit is contained in:
parent
f036fe0d32
commit
b1ca65447a
@ -421,11 +421,11 @@ impl<'a, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'tcx, super::Evaluator>
|
|||||||
if key_size.bits() < 128 && key >= (1u128 << key_size.bits() as u128) {
|
if key_size.bits() < 128 && key >= (1u128 << key_size.bits() as u128) {
|
||||||
return err!(OutOfTls);
|
return err!(OutOfTls);
|
||||||
}
|
}
|
||||||
// TODO: Does this need checking for alignment?
|
self.memory.write_primval(
|
||||||
self.memory.write_uint(
|
|
||||||
key_ptr.to_ptr()?,
|
key_ptr.to_ptr()?,
|
||||||
key,
|
PrimVal::Bytes(key),
|
||||||
key_size.bytes(),
|
key_size.bytes(),
|
||||||
|
false,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Return success (0)
|
// Return success (0)
|
||||||
|
@ -579,12 +579,13 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
|
|||||||
discr_val: u128,
|
discr_val: u128,
|
||||||
variant_idx: usize,
|
variant_idx: usize,
|
||||||
discr_size: u64,
|
discr_size: u64,
|
||||||
|
discr_signed: bool,
|
||||||
) -> EvalResult<'tcx> {
|
) -> EvalResult<'tcx> {
|
||||||
// FIXME(solson)
|
// FIXME(solson)
|
||||||
let dest_ptr = self.force_allocation(dest)?.to_ptr()?;
|
let dest_ptr = self.force_allocation(dest)?.to_ptr()?;
|
||||||
|
|
||||||
let discr_dest = dest_ptr.offset(discr_offset, &self)?;
|
let discr_dest = dest_ptr.offset(discr_offset, &self)?;
|
||||||
self.memory.write_uint(discr_dest, discr_val, discr_size)?;
|
self.memory.write_primval(discr_dest, PrimVal::Bytes(discr_val), discr_size, discr_signed)?;
|
||||||
|
|
||||||
let dest = Lvalue::Ptr {
|
let dest = Lvalue::Ptr {
|
||||||
ptr: PtrAndAlign {
|
ptr: PtrAndAlign {
|
||||||
@ -724,6 +725,7 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
|
|||||||
discr_val,
|
discr_val,
|
||||||
variant,
|
variant,
|
||||||
discr_size,
|
discr_size,
|
||||||
|
false,
|
||||||
)?;
|
)?;
|
||||||
} else {
|
} else {
|
||||||
bug!("tried to assign {:?} to Layout::General", kind);
|
bug!("tried to assign {:?} to Layout::General", kind);
|
||||||
@ -783,7 +785,8 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
|
|||||||
);
|
);
|
||||||
self.memory.write_maybe_aligned_mut(
|
self.memory.write_maybe_aligned_mut(
|
||||||
!nonnull.packed,
|
!nonnull.packed,
|
||||||
|mem| mem.write_int(dest, 0, dest_size),
|
// The sign does not matter for 0
|
||||||
|
|mem| mem.write_primval(dest, PrimVal::Bytes(0), dest_size, false),
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1607,7 +1610,20 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
|
|||||||
}
|
}
|
||||||
Value::ByVal(primval) => {
|
Value::ByVal(primval) => {
|
||||||
let size = self.type_size(dest_ty)?.expect("dest type must be sized");
|
let size = self.type_size(dest_ty)?.expect("dest type must be sized");
|
||||||
self.memory.write_primval(dest, primval, size)
|
// TODO: This fn gets called with sizes like 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.
|
||||||
|
match primval {
|
||||||
|
PrimVal::Undef => {
|
||||||
|
self.memory.mark_definedness(dest, size, false)?;
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
// TODO: Do we need signedness?
|
||||||
|
self.memory.write_primval(dest.to_ptr()?, primval, size, false)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
Value::ByValPair(a, b) => self.write_pair_to_ptr(a, b, dest.to_ptr()?, dest_ty),
|
Value::ByValPair(a, b) => self.write_pair_to_ptr(a, b, dest.to_ptr()?, dest_ty),
|
||||||
}
|
}
|
||||||
@ -1645,11 +1661,12 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
|
|||||||
);
|
);
|
||||||
let field_0_ptr = ptr.offset(field_0.bytes(), &self)?.into();
|
let field_0_ptr = ptr.offset(field_0.bytes(), &self)?.into();
|
||||||
let field_1_ptr = ptr.offset(field_1.bytes(), &self)?.into();
|
let field_1_ptr = ptr.offset(field_1.bytes(), &self)?.into();
|
||||||
|
// TODO: What about signedess?
|
||||||
self.write_maybe_aligned_mut(!packed, |ectx| {
|
self.write_maybe_aligned_mut(!packed, |ectx| {
|
||||||
ectx.memory.write_primval(field_0_ptr, a, field_0_size)
|
ectx.memory.write_primval(field_0_ptr, a, field_0_size, false)
|
||||||
})?;
|
})?;
|
||||||
self.write_maybe_aligned_mut(!packed, |ectx| {
|
self.write_maybe_aligned_mut(!packed, |ectx| {
|
||||||
ectx.memory.write_primval(field_1_ptr, b, field_1_size)
|
ectx.memory.write_primval(field_1_ptr, b, field_1_size, false)
|
||||||
})?;
|
})?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1206,20 +1206,15 @@ impl<'a, 'tcx, M: Machine<'tcx>> Memory<'a, 'tcx, M> {
|
|||||||
self.read_primval(ptr, self.pointer_size(), false)
|
self.read_primval(ptr, self.pointer_size(), false)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_ptr(&mut self, dest: MemoryPointer, ptr: MemoryPointer) -> EvalResult<'tcx> {
|
pub fn write_primval(&mut self, ptr: MemoryPointer, val: PrimVal, size: u64, signed: bool) -> EvalResult<'tcx> {
|
||||||
self.write_usize(dest, ptr.offset as u64)?;
|
trace!("Writing {:?}, size {}", val, size);
|
||||||
self.get_mut(dest.alloc_id)?.relocations.insert(
|
let align = self.int_align(size)?;
|
||||||
dest.offset,
|
let endianess = self.endianess();
|
||||||
ptr.alloc_id,
|
|
||||||
);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn write_primval(&mut self, dest: Pointer, val: PrimVal, size: u64) -> EvalResult<'tcx> {
|
let bytes = match val {
|
||||||
match val {
|
PrimVal::Ptr(val) => {
|
||||||
PrimVal::Ptr(ptr) => {
|
|
||||||
assert_eq!(size, self.pointer_size());
|
assert_eq!(size, self.pointer_size());
|
||||||
self.write_ptr(dest.to_ptr()?, ptr)
|
val.offset as u128
|
||||||
}
|
}
|
||||||
|
|
||||||
PrimVal::Bytes(bytes) => {
|
PrimVal::Bytes(bytes) => {
|
||||||
@ -1233,11 +1228,41 @@ impl<'a, 'tcx, M: Machine<'tcx>> Memory<'a, 'tcx, M> {
|
|||||||
16 => !0,
|
16 => !0,
|
||||||
n => bug!("unexpected PrimVal::Bytes size: {}", n),
|
n => bug!("unexpected PrimVal::Bytes size: {}", n),
|
||||||
};
|
};
|
||||||
self.write_uint(dest.to_ptr()?, bytes & mask, size)
|
bytes & mask
|
||||||
}
|
}
|
||||||
|
|
||||||
PrimVal::Undef => self.mark_definedness(dest, size, false),
|
PrimVal::Undef => {
|
||||||
|
self.mark_definedness(PrimVal::Ptr(ptr).into(), size, false)?;
|
||||||
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
let dst = self.get_bytes_mut(ptr, size, align)?;
|
||||||
|
if signed {
|
||||||
|
write_target_int(endianess, dst, bytes as i128).unwrap();
|
||||||
|
} else {
|
||||||
|
write_target_uint(endianess, dst, bytes).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// See if we have to also write a relocation
|
||||||
|
match val {
|
||||||
|
PrimVal::Ptr(val) => {
|
||||||
|
self.get_mut(ptr.alloc_id)?.relocations.insert(
|
||||||
|
ptr.offset,
|
||||||
|
val.alloc_id,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn write_ptr_sized_unsigned(&mut self, ptr: MemoryPointer, val: PrimVal) -> EvalResult<'tcx> {
|
||||||
|
let ptr_size = self.pointer_size();
|
||||||
|
self.write_primval(ptr, val, ptr_size, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_bool(&self, ptr: MemoryPointer) -> EvalResult<'tcx, bool> {
|
pub fn read_bool(&self, ptr: MemoryPointer) -> EvalResult<'tcx, bool> {
|
||||||
@ -1269,32 +1294,6 @@ impl<'a, 'tcx, M: Machine<'tcx>> Memory<'a, 'tcx, M> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_int(&mut self, ptr: MemoryPointer, n: i128, size: u64) -> EvalResult<'tcx> {
|
|
||||||
let align = self.int_align(size)?;
|
|
||||||
let endianess = self.endianess();
|
|
||||||
let b = self.get_bytes_mut(ptr, size, align)?;
|
|
||||||
write_target_int(endianess, b, n).unwrap();
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn write_uint(&mut self, ptr: MemoryPointer, n: u128, size: u64) -> EvalResult<'tcx> {
|
|
||||||
let align = self.int_align(size)?;
|
|
||||||
let endianess = self.endianess();
|
|
||||||
let b = self.get_bytes_mut(ptr, size, align)?;
|
|
||||||
write_target_uint(endianess, b, n).unwrap();
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn write_isize(&mut self, ptr: MemoryPointer, n: i64) -> EvalResult<'tcx> {
|
|
||||||
let size = self.pointer_size();
|
|
||||||
self.write_int(ptr, n as i128, size)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn write_usize(&mut self, ptr: MemoryPointer, n: u64) -> EvalResult<'tcx> {
|
|
||||||
let size = self.pointer_size();
|
|
||||||
self.write_uint(ptr, n as u128, size)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn write_f32(&mut self, ptr: MemoryPointer, f: f32) -> EvalResult<'tcx> {
|
pub fn write_f32(&mut self, ptr: MemoryPointer, f: f32) -> EvalResult<'tcx> {
|
||||||
let endianess = self.endianess();
|
let endianess = self.endianess();
|
||||||
let align = self.layout.f32_align.abi();
|
let align = self.layout.f32_align.abi();
|
||||||
|
@ -12,7 +12,7 @@ use rustc::ty::layout::Layout;
|
|||||||
use rustc::ty::subst::Substs;
|
use rustc::ty::subst::Substs;
|
||||||
|
|
||||||
use super::{EvalResult, EvalContext, StackPopCleanup, TyAndPacked, PtrAndAlign, GlobalId, Lvalue,
|
use super::{EvalResult, EvalContext, StackPopCleanup, TyAndPacked, PtrAndAlign, GlobalId, Lvalue,
|
||||||
HasMemory, MemoryKind, Machine};
|
HasMemory, MemoryKind, Machine, PrimVal};
|
||||||
|
|
||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
use syntax::ast::Mutability;
|
use syntax::ast::Mutability;
|
||||||
@ -106,10 +106,11 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
|
|||||||
Layout::General { discr, .. } => {
|
Layout::General { discr, .. } => {
|
||||||
let discr_size = discr.size().bytes();
|
let discr_size = discr.size().bytes();
|
||||||
let dest_ptr = self.force_allocation(dest)?.to_ptr()?;
|
let dest_ptr = self.force_allocation(dest)?.to_ptr()?;
|
||||||
self.memory.write_uint(
|
self.memory.write_primval(
|
||||||
dest_ptr,
|
dest_ptr,
|
||||||
variant_index as u128,
|
PrimVal::Bytes(variant_index as u128),
|
||||||
discr_size,
|
discr_size,
|
||||||
|
false
|
||||||
)?
|
)?
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,6 +125,7 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
|
|||||||
ref discrfield_source,
|
ref discrfield_source,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
|
// TODO: There's some duplication between here and eval_rvalue_into_lvalue
|
||||||
if variant_index as u64 != nndiscr {
|
if variant_index as u64 != nndiscr {
|
||||||
let (offset, TyAndPacked { ty, packed }) = self.nonnull_offset_and_ty(
|
let (offset, TyAndPacked { ty, packed }) = self.nonnull_offset_and_ty(
|
||||||
dest_ty,
|
dest_ty,
|
||||||
@ -140,7 +142,8 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
|
|||||||
"bad StructWrappedNullablePointer discrfield",
|
"bad StructWrappedNullablePointer discrfield",
|
||||||
);
|
);
|
||||||
self.write_maybe_aligned_mut(!packed, |ectx| {
|
self.write_maybe_aligned_mut(!packed, |ectx| {
|
||||||
ectx.memory.write_uint(nonnull, 0, discr_size)
|
// We're writing 0, signedness does not matter
|
||||||
|
ectx.memory.write_primval(nonnull, PrimVal::Bytes(0), discr_size, false)
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -229,7 +232,7 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
|
|||||||
ptr_size,
|
ptr_size,
|
||||||
MemoryKind::UninitializedStatic,
|
MemoryKind::UninitializedStatic,
|
||||||
)?;
|
)?;
|
||||||
self.memory.write_usize(ptr, 0)?;
|
self.memory.write_ptr_sized_unsigned(ptr, PrimVal::Bytes(0))?;
|
||||||
self.memory.mark_static_initalized(ptr.alloc_id, mutability)?;
|
self.memory.mark_static_initalized(ptr.alloc_id, mutability)?;
|
||||||
self.globals.insert(
|
self.globals.insert(
|
||||||
cid,
|
cid,
|
||||||
|
@ -63,19 +63,19 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
|
|||||||
|
|
||||||
let drop = eval_context::resolve_drop_in_place(self.tcx, ty);
|
let drop = eval_context::resolve_drop_in_place(self.tcx, ty);
|
||||||
let drop = self.memory.create_fn_alloc(drop);
|
let drop = self.memory.create_fn_alloc(drop);
|
||||||
self.memory.write_ptr(vtable, drop)?;
|
self.memory.write_ptr_sized_unsigned(vtable, PrimVal::Ptr(drop))?;
|
||||||
|
|
||||||
let size_ptr = vtable.offset(ptr_size, &self)?;
|
let size_ptr = vtable.offset(ptr_size, &self)?;
|
||||||
self.memory.write_usize(size_ptr, size)?;
|
self.memory.write_ptr_sized_unsigned(size_ptr, PrimVal::Bytes(size as u128))?;
|
||||||
let align_ptr = vtable.offset(ptr_size * 2, &self)?;
|
let align_ptr = vtable.offset(ptr_size * 2, &self)?;
|
||||||
self.memory.write_usize(align_ptr, align)?;
|
self.memory.write_ptr_sized_unsigned(align_ptr, PrimVal::Bytes(align as u128))?;
|
||||||
|
|
||||||
for (i, method) in ::rustc::traits::get_vtable_methods(self.tcx, trait_ref).enumerate() {
|
for (i, method) in ::rustc::traits::get_vtable_methods(self.tcx, trait_ref).enumerate() {
|
||||||
if let Some((def_id, substs)) = method {
|
if let Some((def_id, substs)) = method {
|
||||||
let instance = eval_context::resolve(self.tcx, def_id, substs);
|
let instance = eval_context::resolve(self.tcx, def_id, substs);
|
||||||
let fn_ptr = self.memory.create_fn_alloc(instance);
|
let fn_ptr = self.memory.create_fn_alloc(instance);
|
||||||
let method_ptr = vtable.offset(ptr_size * (3 + i as u64), &self)?;
|
let method_ptr = vtable.offset(ptr_size * (3 + i as u64), &self)?;
|
||||||
self.memory.write_ptr(method_ptr, fn_ptr)?;
|
self.memory.write_ptr_sized_unsigned(method_ptr, PrimVal::Ptr(fn_ptr))?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user