Skip to content

Commit

Permalink
Merge pull request #695 from RalfJung/stacked-borrows-2
Browse files Browse the repository at this point in the history
Stacked borrows 2 (alpha 1)
  • Loading branch information
RalfJung authored Apr 18, 2019
2 parents 3e8bd45 + 39ecd05 commit ae9e9cb
Show file tree
Hide file tree
Showing 56 changed files with 763 additions and 728 deletions.
2 changes: 1 addition & 1 deletion rust-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
ee621f42329069c296b4c2066b3743cc4ff0f369
efe2f32a6b8217425f361ec7c206910c611c03ee
28 changes: 13 additions & 15 deletions src/fn_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
fn find_fn(
&mut self,
instance: ty::Instance<'tcx>,
args: &[OpTy<'tcx, Borrow>],
dest: Option<PlaceTy<'tcx, Borrow>>,
args: &[OpTy<'tcx, Tag>],
dest: Option<PlaceTy<'tcx, Tag>>,
ret: Option<mir::BasicBlock>,
) -> EvalResult<'tcx, Option<&'mir mir::Mir<'tcx>>> {
let this = self.eval_context_mut();
Expand Down Expand Up @@ -55,8 +55,8 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
fn emulate_foreign_item(
&mut self,
def_id: DefId,
args: &[OpTy<'tcx, Borrow>],
dest: Option<PlaceTy<'tcx, Borrow>>,
args: &[OpTy<'tcx, Tag>],
dest: Option<PlaceTy<'tcx, Tag>>,
ret: Option<mir::BasicBlock>,
) -> EvalResult<'tcx> {
let this = self.eval_context_mut();
Expand Down Expand Up @@ -92,7 +92,7 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
} else {
let align = this.tcx.data_layout.pointer_align.abi;
let ptr = this.memory_mut().allocate(Size::from_bytes(size), align, MiriMemoryKind::C.into());
this.write_scalar(Scalar::Ptr(ptr.with_default_tag()), dest)?;
this.write_scalar(Scalar::Ptr(ptr), dest)?;
}
}
"calloc" => {
Expand All @@ -105,7 +105,7 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
} else {
let size = Size::from_bytes(bytes);
let align = this.tcx.data_layout.pointer_align.abi;
let ptr = this.memory_mut().allocate(size, align, MiriMemoryKind::C.into()).with_default_tag();
let ptr = this.memory_mut().allocate(size, align, MiriMemoryKind::C.into());
this.memory_mut().get_mut(ptr.alloc_id)?.write_repeat(tcx, ptr, 0, size)?;
this.write_scalar(Scalar::Ptr(ptr), dest)?;
}
Expand All @@ -132,7 +132,7 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
Align::from_bytes(align).unwrap(),
MiriMemoryKind::C.into()
);
this.write_scalar(Scalar::Ptr(ptr.with_default_tag()), ret.into())?;
this.write_scalar(Scalar::Ptr(ptr), ret.into())?;
}
this.write_null(dest)?;
}
Expand Down Expand Up @@ -162,8 +162,7 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
Size::from_bytes(size),
Align::from_bytes(align).unwrap(),
MiriMemoryKind::Rust.into()
)
.with_default_tag();
);
this.write_scalar(Scalar::Ptr(ptr), dest)?;
}
"__rust_alloc_zeroed" => {
Expand All @@ -180,8 +179,7 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
Size::from_bytes(size),
Align::from_bytes(align).unwrap(),
MiriMemoryKind::Rust.into()
)
.with_default_tag();
);
this.memory_mut()
.get_mut(ptr.alloc_id)?
.write_repeat(tcx, ptr, 0, Size::from_bytes(size))?;
Expand Down Expand Up @@ -222,7 +220,7 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
Align::from_bytes(align).unwrap(),
MiriMemoryKind::Rust.into(),
)?;
this.write_scalar(Scalar::Ptr(new_ptr.with_default_tag()), dest)?;
this.write_scalar(Scalar::Ptr(new_ptr), dest)?;
}

"syscall" => {
Expand Down Expand Up @@ -428,7 +426,7 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
Size::from_bytes((value.len() + 1) as u64),
Align::from_bytes(1).unwrap(),
MiriMemoryKind::Env.into(),
).with_default_tag();
);
{
let alloc = this.memory_mut().get_mut(value_copy.alloc_id)?;
alloc.write_bytes(tcx, value_copy, &value)?;
Expand Down Expand Up @@ -798,13 +796,13 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
Ok(())
}

fn write_null(&mut self, dest: PlaceTy<'tcx, Borrow>) -> EvalResult<'tcx> {
fn write_null(&mut self, dest: PlaceTy<'tcx, Tag>) -> EvalResult<'tcx> {
self.eval_context_mut().write_scalar(Scalar::from_int(0, dest.layout.size), dest)
}

/// Evaluates the scalar at the specified path. Returns Some(val)
/// if the path could be resolved, and None otherwise
fn eval_path_scalar(&mut self, path: &[&str]) -> EvalResult<'tcx, Option<ScalarMaybeUndef<stacked_borrows::Borrow>>> {
fn eval_path_scalar(&mut self, path: &[&str]) -> EvalResult<'tcx, Option<ScalarMaybeUndef<Tag>>> {
let this = self.eval_context_mut();
if let Ok(instance) = this.resolve_path(path) {
let cid = GlobalId {
Expand Down
24 changes: 12 additions & 12 deletions src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
/// will be true if this is frozen, false if this is in an `UnsafeCell`.
fn visit_freeze_sensitive(
&self,
place: MPlaceTy<'tcx, Borrow>,
place: MPlaceTy<'tcx, Tag>,
size: Size,
mut action: impl FnMut(Pointer<Borrow>, Size, bool) -> EvalResult<'tcx>,
mut action: impl FnMut(Pointer<Tag>, Size, bool) -> EvalResult<'tcx>,
) -> EvalResult<'tcx> {
let this = self.eval_context_ref();
trace!("visit_frozen(place={:?}, size={:?})", *place, size);
Expand All @@ -64,7 +64,7 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
let mut end_ptr = place.ptr;
// Called when we detected an `UnsafeCell` at the given offset and size.
// Calls `action` and advances `end_ptr`.
let mut unsafe_cell_action = |unsafe_cell_ptr: Scalar<Borrow>, unsafe_cell_size: Size| {
let mut unsafe_cell_action = |unsafe_cell_ptr: Scalar<Tag>, unsafe_cell_size: Size| {
if unsafe_cell_size != Size::ZERO {
debug_assert_eq!(unsafe_cell_ptr.to_ptr().unwrap().alloc_id,
end_ptr.to_ptr().unwrap().alloc_id);
Expand Down Expand Up @@ -120,7 +120,7 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
/// Visiting the memory covered by a `MemPlace`, being aware of
/// whether we are inside an `UnsafeCell` or not.
struct UnsafeCellVisitor<'ecx, 'a, 'mir, 'tcx, F>
where F: FnMut(MPlaceTy<'tcx, Borrow>) -> EvalResult<'tcx>
where F: FnMut(MPlaceTy<'tcx, Tag>) -> EvalResult<'tcx>
{
ecx: &'ecx MiriEvalContext<'a, 'mir, 'tcx>,
unsafe_cell_action: F,
Expand All @@ -131,17 +131,17 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
for
UnsafeCellVisitor<'ecx, 'a, 'mir, 'tcx, F>
where
F: FnMut(MPlaceTy<'tcx, Borrow>) -> EvalResult<'tcx>
F: FnMut(MPlaceTy<'tcx, Tag>) -> EvalResult<'tcx>
{
type V = MPlaceTy<'tcx, Borrow>;
type V = MPlaceTy<'tcx, Tag>;

#[inline(always)]
fn ecx(&self) -> &MiriEvalContext<'a, 'mir, 'tcx> {
&self.ecx
}

// Hook to detect `UnsafeCell`.
fn visit_value(&mut self, v: MPlaceTy<'tcx, Borrow>) -> EvalResult<'tcx>
fn visit_value(&mut self, v: MPlaceTy<'tcx, Tag>) -> EvalResult<'tcx>
{
trace!("UnsafeCellVisitor: {:?} {:?}", *v, v.layout.ty);
let is_unsafe_cell = match v.layout.ty.sty {
Expand All @@ -163,8 +163,8 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
// Make sure we visit aggregrates in increasing offset order.
fn visit_aggregate(
&mut self,
place: MPlaceTy<'tcx, Borrow>,
fields: impl Iterator<Item=EvalResult<'tcx, MPlaceTy<'tcx, Borrow>>>,
place: MPlaceTy<'tcx, Tag>,
fields: impl Iterator<Item=EvalResult<'tcx, MPlaceTy<'tcx, Tag>>>,
) -> EvalResult<'tcx> {
match place.layout.fields {
layout::FieldPlacement::Array { .. } => {
Expand All @@ -174,7 +174,7 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
}
layout::FieldPlacement::Arbitrary { .. } => {
// Gather the subplaces and sort them before visiting.
let mut places = fields.collect::<EvalResult<'tcx, Vec<MPlaceTy<'tcx, Borrow>>>>()?;
let mut places = fields.collect::<EvalResult<'tcx, Vec<MPlaceTy<'tcx, Tag>>>>()?;
places.sort_by_key(|place| place.ptr.get_ptr_offset(self.ecx()));
self.walk_aggregate(place, places.into_iter().map(Ok))
}
Expand All @@ -186,7 +186,7 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
}

// We have to do *something* for unions.
fn visit_union(&mut self, v: MPlaceTy<'tcx, Borrow>) -> EvalResult<'tcx>
fn visit_union(&mut self, v: MPlaceTy<'tcx, Tag>) -> EvalResult<'tcx>
{
// With unions, we fall back to whatever the type says, to hopefully be consistent
// with LLVM IR.
Expand All @@ -200,7 +200,7 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
}

// We should never get to a primitive, but always short-circuit somewhere above.
fn visit_primitive(&mut self, _v: MPlaceTy<'tcx, Borrow>) -> EvalResult<'tcx>
fn visit_primitive(&mut self, _v: MPlaceTy<'tcx, Tag>) -> EvalResult<'tcx>
{
bug!("we should always short-circuit before coming to a primitive")
}
Expand Down
6 changes: 3 additions & 3 deletions src/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use rustc::ty::layout::{self, LayoutOf, Size};
use rustc::ty;

use crate::{
PlaceTy, OpTy, ImmTy, Immediate, Scalar, ScalarMaybeUndef, Borrow,
PlaceTy, OpTy, ImmTy, Immediate, Scalar, ScalarMaybeUndef, Tag,
OperatorEvalContextExt
};

Expand All @@ -13,8 +13,8 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a+'mir>: crate::MiriEvalContextExt<'a,
fn call_intrinsic(
&mut self,
instance: ty::Instance<'tcx>,
args: &[OpTy<'tcx, Borrow>],
dest: PlaceTy<'tcx, Borrow>,
args: &[OpTy<'tcx, Tag>],
dest: PlaceTy<'tcx, Tag>,
) -> EvalResult<'tcx> {
let this = self.eval_context_mut();
if this.emulate_intrinsic(instance, args, dest)? {
Expand Down
Loading

0 comments on commit ae9e9cb

Please sign in to comment.