Skip to content

Commit 020313d

Browse files
committed
make freezing inherently part of the high-level reactivate/initiate operations
1 parent 09919c2 commit 020313d

File tree

2 files changed

+125
-109
lines changed

2 files changed

+125
-109
lines changed

src/helpers.rs

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,13 @@ impl<Tag> ScalarExt for ScalarMaybeUndef<Tag> {
3333
pub trait EvalContextExt<'tcx> {
3434
fn resolve_path(&self, path: &[&str]) -> EvalResult<'tcx, ty::Instance<'tcx>>;
3535

36-
/// Visit the memory covered by `place` that is frozen -- i.e., NOT
37-
/// what is inside an `UnsafeCell`.
38-
fn visit_frozen(
36+
/// Visit the memory covered by `place`, sensitive to freezing: The 3rd parameter
37+
/// will be true if this is frozen, false if this is in an `UnsafeCell`.
38+
fn visit_freeze_sensitive(
3939
&self,
4040
place: MPlaceTy<'tcx, Borrow>,
4141
size: Size,
42-
action: impl FnMut(Pointer<Borrow>, Size) -> EvalResult<'tcx>,
42+
action: impl FnMut(Pointer<Borrow>, Size, bool) -> EvalResult<'tcx>,
4343
) -> EvalResult<'tcx>;
4444
}
4545

@@ -79,13 +79,11 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'mir, 'tcx, super:
7979
})
8080
}
8181

82-
/// Visit the memory covered by `place` that is frozen -- i.e., NOT
83-
/// what is inside an `UnsafeCell`.
84-
fn visit_frozen(
82+
fn visit_freeze_sensitive(
8583
&self,
8684
place: MPlaceTy<'tcx, Borrow>,
8785
size: Size,
88-
mut frozen_action: impl FnMut(Pointer<Borrow>, Size) -> EvalResult<'tcx>,
86+
mut action: impl FnMut(Pointer<Borrow>, Size, bool) -> EvalResult<'tcx>,
8987
) -> EvalResult<'tcx> {
9088
trace!("visit_frozen(place={:?}, size={:?})", *place, size);
9189
debug_assert_eq!(size,
@@ -99,18 +97,29 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'mir, 'tcx, super:
9997
let mut end_ptr = place.ptr;
10098
// Called when we detected an `UnsafeCell` at the given offset and size.
10199
// Calls `action` and advances `end_ptr`.
102-
let mut unsafe_cell_action = |unsafe_cell_offset, unsafe_cell_size| {
100+
let mut unsafe_cell_action = |unsafe_cell_ptr: Scalar<Borrow>, unsafe_cell_size: Size| {
101+
if unsafe_cell_size != Size::ZERO {
102+
debug_assert_eq!(unsafe_cell_ptr.to_ptr().unwrap().alloc_id,
103+
end_ptr.to_ptr().unwrap().alloc_id);
104+
debug_assert_eq!(unsafe_cell_ptr.to_ptr().unwrap().tag,
105+
end_ptr.to_ptr().unwrap().tag);
106+
}
103107
// We assume that we are given the fields in increasing offset order,
104108
// and nothing else changes.
109+
let unsafe_cell_offset = unsafe_cell_ptr.get_ptr_offset(self);
105110
let end_offset = end_ptr.get_ptr_offset(self);
106111
assert!(unsafe_cell_offset >= end_offset);
107112
let frozen_size = unsafe_cell_offset - end_offset;
108113
// Everything between the end_ptr and this `UnsafeCell` is frozen.
109114
if frozen_size != Size::ZERO {
110-
frozen_action(end_ptr.to_ptr()?, frozen_size)?;
115+
action(end_ptr.to_ptr()?, frozen_size, /*frozen*/true)?;
116+
}
117+
// This `UnsafeCell` is NOT frozen.
118+
if unsafe_cell_size != Size::ZERO {
119+
action(unsafe_cell_ptr.to_ptr()?, unsafe_cell_size, /*frozen*/false)?;
111120
}
112121
// Update end end_ptr.
113-
end_ptr = end_ptr.ptr_wrapping_offset(frozen_size+unsafe_cell_size, self);
122+
end_ptr = unsafe_cell_ptr.ptr_wrapping_offset(unsafe_cell_size, self);
114123
// Done
115124
Ok(())
116125
};
@@ -126,7 +135,7 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'mir, 'tcx, super:
126135
.unwrap_or_else(|| place.layout.size_and_align());
127136
// Now handle this `UnsafeCell`, unless it is empty.
128137
if unsafe_cell_size != Size::ZERO {
129-
unsafe_cell_action(place.ptr.get_ptr_offset(self), unsafe_cell_size)
138+
unsafe_cell_action(place.ptr, unsafe_cell_size)
130139
} else {
131140
Ok(())
132141
}
@@ -136,7 +145,7 @@ impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'mir, 'tcx, super:
136145
}
137146
// The part between the end_ptr and the end of the place is also frozen.
138147
// So pretend there is a 0-sized `UnsafeCell` at the end.
139-
unsafe_cell_action(place.ptr.get_ptr_offset(self) + size, Size::ZERO)?;
148+
unsafe_cell_action(place.ptr.ptr_wrapping_offset(size, self), Size::ZERO)?;
140149
// Done!
141150
return Ok(());
142151

0 commit comments

Comments
 (0)