Skip to content

Commit

Permalink
Merge pull request #568 from RalfJung/cleanup
Browse files Browse the repository at this point in the history
Cleanup: Avoid repeating signatures, get rid of to_bytes hack
  • Loading branch information
RalfJung authored Dec 11, 2018
2 parents 4f61314 + 6b376dc commit 6eb3274
Show file tree
Hide file tree
Showing 6 changed files with 402 additions and 484 deletions.
337 changes: 160 additions & 177 deletions src/fn_call.rs

Large diffs are not rendered by default.

70 changes: 18 additions & 52 deletions src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,68 +5,31 @@ use rustc::hir::def_id::{DefId, CRATE_DEF_INDEX};

use crate::*;

pub trait ScalarExt {
/// HACK: this function just extracts all bits if `defined != 0`
/// Mainly used for args of C-functions and we should totally correctly fetch the size
/// of their arguments
fn to_bytes(self) -> EvalResult<'static, u128>;
}

impl<Tag> ScalarExt for Scalar<Tag> {
fn to_bytes(self) -> EvalResult<'static, u128> {
match self {
Scalar::Bits { bits, size } => {
assert_ne!(size, 0);
Ok(bits)
},
Scalar::Ptr(_) => err!(ReadPointerAsBytes),
}
}
}

impl<Tag> ScalarExt for ScalarMaybeUndef<Tag> {
fn to_bytes(self) -> EvalResult<'static, u128> {
self.not_undef()?.to_bytes()
}
}

pub trait EvalContextExt<'tcx> {
fn resolve_path(&self, path: &[&str]) -> EvalResult<'tcx, ty::Instance<'tcx>>;

/// Visit the memory covered by `place`, sensitive to freezing: The 3rd parameter
/// will be true if this is frozen, false if this is in an `UnsafeCell`.
fn visit_freeze_sensitive(
&self,
place: MPlaceTy<'tcx, Borrow>,
size: Size,
action: impl FnMut(Pointer<Borrow>, Size, bool) -> EvalResult<'tcx>,
) -> EvalResult<'tcx>;
}


impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'mir, 'tcx, super::Evaluator<'tcx>> {
impl<'a, 'mir, 'tcx> EvalContextExt<'a, 'mir, 'tcx> for crate::MiriEvalContext<'a, 'mir, 'tcx> {}
pub trait EvalContextExt<'a, 'mir, 'tcx: 'a+'mir>: crate::MiriEvalContextExt<'a, 'mir, 'tcx> {
/// Get an instance for a path.
fn resolve_path(&self, path: &[&str]) -> EvalResult<'tcx, ty::Instance<'tcx>> {
self.tcx
let this = self.eval_context_ref();
this.tcx
.crates()
.iter()
.find(|&&krate| self.tcx.original_crate_name(krate) == path[0])
.find(|&&krate| this.tcx.original_crate_name(krate) == path[0])
.and_then(|krate| {
let krate = DefId {
krate: *krate,
index: CRATE_DEF_INDEX,
};
let mut items = self.tcx.item_children(krate);
let mut items = this.tcx.item_children(krate);
let mut path_it = path.iter().skip(1).peekable();

while let Some(segment) = path_it.next() {
for item in mem::replace(&mut items, Default::default()).iter() {
if item.ident.name == *segment {
if path_it.peek().is_none() {
return Some(ty::Instance::mono(self.tcx.tcx, item.def.def_id()));
return Some(ty::Instance::mono(this.tcx.tcx, item.def.def_id()));
}

items = self.tcx.item_children(item.def.def_id());
items = this.tcx.item_children(item.def.def_id());
break;
}
}
Expand All @@ -79,15 +42,18 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'mir, 'tcx, super:
})
}

/// Visit the memory covered by `place`, sensitive to freezing: The 3rd parameter
/// will be true if this is frozen, false if this is in an `UnsafeCell`.
fn visit_freeze_sensitive(
&self,
place: MPlaceTy<'tcx, Borrow>,
size: Size,
mut action: impl FnMut(Pointer<Borrow>, Size, bool) -> EvalResult<'tcx>,
) -> EvalResult<'tcx> {
let this = self.eval_context_ref();
trace!("visit_frozen(place={:?}, size={:?})", *place, size);
debug_assert_eq!(size,
self.size_and_align_of_mplace(place)?
this.size_and_align_of_mplace(place)?
.map(|(size, _)| size)
.unwrap_or_else(|| place.layout.size)
);
Expand All @@ -106,8 +72,8 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'mir, 'tcx, super:
}
// We assume that we are given the fields in increasing offset order,
// and nothing else changes.
let unsafe_cell_offset = unsafe_cell_ptr.get_ptr_offset(self);
let end_offset = end_ptr.get_ptr_offset(self);
let unsafe_cell_offset = unsafe_cell_ptr.get_ptr_offset(this);
let end_offset = end_ptr.get_ptr_offset(this);
assert!(unsafe_cell_offset >= end_offset);
let frozen_size = unsafe_cell_offset - end_offset;
// Everything between the end_ptr and this `UnsafeCell` is frozen.
Expand All @@ -119,18 +85,18 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'mir, 'tcx, super:
action(unsafe_cell_ptr.to_ptr()?, unsafe_cell_size, /*frozen*/false)?;
}
// Update end end_ptr.
end_ptr = unsafe_cell_ptr.ptr_wrapping_offset(unsafe_cell_size, self);
end_ptr = unsafe_cell_ptr.ptr_wrapping_offset(unsafe_cell_size, this);
// Done
Ok(())
};
// Run a visitor
{
let mut visitor = UnsafeCellVisitor {
ecx: self,
ecx: this,
unsafe_cell_action: |place| {
trace!("unsafe_cell_action on {:?}", place.ptr);
// We need a size to go on.
let unsafe_cell_size = self.size_and_align_of_mplace(place)?
let unsafe_cell_size = this.size_and_align_of_mplace(place)?
.map(|(size, _)| size)
// for extern types, just cover what we can
.unwrap_or_else(|| place.layout.size);
Expand All @@ -146,7 +112,7 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'mir, 'tcx, super:
}
// The part between the end_ptr and the end of the place is also frozen.
// So pretend there is a 0-sized `UnsafeCell` at the end.
unsafe_cell_action(place.ptr.ptr_wrapping_offset(size, self), Size::ZERO)?;
unsafe_cell_action(place.ptr.ptr_wrapping_offset(size, this), Size::ZERO)?;
// Done!
return Ok(());

Expand Down
Loading

0 comments on commit 6eb3274

Please sign in to comment.