Skip to content

Commit 815a51c

Browse files
committed
switch intptrcast to helper trait pattern like everything else
1 parent 1cbb8fa commit 815a51c

File tree

3 files changed

+80
-95
lines changed

3 files changed

+80
-95
lines changed

src/intptrcast.rs

Lines changed: 75 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,21 @@ impl GlobalStateInner {
6262
}
6363
}
6464

65-
impl<'mir, 'tcx> GlobalStateInner {
65+
/// Shifts `addr` to make it aligned with `align` by rounding `addr` to the smallest multiple
66+
/// of `align` that is larger or equal to `addr`
67+
fn align_addr(addr: u64, align: u64) -> u64 {
68+
match addr % align {
69+
0 => addr,
70+
rem => addr.checked_add(align).unwrap() - rem,
71+
}
72+
}
73+
74+
impl<'mir, 'tcx: 'mir> EvalContextExtPriv<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
75+
trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
6676
// Returns the exposed `AllocId` that corresponds to the specified addr,
6777
// or `None` if the addr is out of bounds
68-
fn alloc_id_from_addr(ecx: &MiriInterpCx<'mir, 'tcx>, addr: u64) -> Option<AllocId> {
78+
fn alloc_id_from_addr(&self, addr: u64) -> Option<AllocId> {
79+
let ecx = self.eval_context_ref();
6980
let global_state = ecx.machine.intptrcast.borrow();
7081
assert!(global_state.provenance_mode != ProvenanceMode::Strict);
7182

@@ -105,70 +116,8 @@ impl<'mir, 'tcx> GlobalStateInner {
105116
None
106117
}
107118

108-
pub fn expose_ptr(
109-
ecx: &mut MiriInterpCx<'mir, 'tcx>,
110-
alloc_id: AllocId,
111-
tag: BorTag,
112-
) -> InterpResult<'tcx> {
113-
let global_state = ecx.machine.intptrcast.get_mut();
114-
// In strict mode, we don't need this, so we can save some cycles by not tracking it.
115-
if global_state.provenance_mode != ProvenanceMode::Strict {
116-
trace!("Exposing allocation id {alloc_id:?}");
117-
global_state.exposed.insert(alloc_id);
118-
if ecx.machine.borrow_tracker.is_some() {
119-
ecx.expose_tag(alloc_id, tag)?;
120-
}
121-
}
122-
Ok(())
123-
}
124-
125-
pub fn ptr_from_addr_transmute(
126-
_ecx: &MiriInterpCx<'mir, 'tcx>,
127-
addr: u64,
128-
) -> Pointer<Option<Provenance>> {
129-
trace!("Transmuting {:#x} to a pointer", addr);
130-
131-
// We consider transmuted pointers to be "invalid" (`None` provenance).
132-
Pointer::new(None, Size::from_bytes(addr))
133-
}
134-
135-
pub fn ptr_from_addr_cast(
136-
ecx: &MiriInterpCx<'mir, 'tcx>,
137-
addr: u64,
138-
) -> InterpResult<'tcx, Pointer<Option<Provenance>>> {
139-
trace!("Casting {:#x} to a pointer", addr);
140-
141-
let global_state = ecx.machine.intptrcast.borrow();
142-
143-
match global_state.provenance_mode {
144-
ProvenanceMode::Default => {
145-
// The first time this happens at a particular location, print a warning.
146-
thread_local! {
147-
// `Span` is non-`Send`, so we use a thread-local instead.
148-
static PAST_WARNINGS: RefCell<FxHashSet<Span>> = RefCell::default();
149-
}
150-
PAST_WARNINGS.with_borrow_mut(|past_warnings| {
151-
let first = past_warnings.is_empty();
152-
if past_warnings.insert(ecx.cur_span()) {
153-
// Newly inserted, so first time we see this span.
154-
ecx.emit_diagnostic(NonHaltingDiagnostic::Int2Ptr { details: first });
155-
}
156-
});
157-
}
158-
ProvenanceMode::Strict => {
159-
throw_machine_stop!(TerminationInfo::Int2PtrWithStrictProvenance);
160-
}
161-
ProvenanceMode::Permissive => {}
162-
}
163-
164-
// This is how wildcard pointers are born.
165-
Ok(Pointer::new(Some(Provenance::Wildcard), Size::from_bytes(addr)))
166-
}
167-
168-
fn alloc_base_addr(
169-
ecx: &MiriInterpCx<'mir, 'tcx>,
170-
alloc_id: AllocId,
171-
) -> InterpResult<'tcx, u64> {
119+
fn addr_from_alloc_id(&self, alloc_id: AllocId) -> InterpResult<'tcx, u64> {
120+
let ecx = self.eval_context_ref();
172121
let mut global_state = ecx.machine.intptrcast.borrow_mut();
173122
let global_state = &mut *global_state;
174123

@@ -191,7 +140,7 @@ impl<'mir, 'tcx> GlobalStateInner {
191140
.next_base_addr
192141
.checked_add(slack)
193142
.ok_or_else(|| err_exhaust!(AddressSpaceFull))?;
194-
let base_addr = Self::align_addr(base_addr, align.bytes());
143+
let base_addr = align_addr(base_addr, align.bytes());
195144
entry.insert(base_addr);
196145
trace!(
197146
"Assigning base address {:#x} to allocation {:?} (size: {}, align: {}, slack: {})",
@@ -221,14 +170,61 @@ impl<'mir, 'tcx> GlobalStateInner {
221170
}
222171
})
223172
}
173+
}
174+
175+
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
176+
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
177+
fn expose_ptr(&mut self, alloc_id: AllocId, tag: BorTag) -> InterpResult<'tcx> {
178+
let ecx = self.eval_context_mut();
179+
let global_state = ecx.machine.intptrcast.get_mut();
180+
// In strict mode, we don't need this, so we can save some cycles by not tracking it.
181+
if global_state.provenance_mode != ProvenanceMode::Strict {
182+
trace!("Exposing allocation id {alloc_id:?}");
183+
global_state.exposed.insert(alloc_id);
184+
if ecx.machine.borrow_tracker.is_some() {
185+
ecx.expose_tag(alloc_id, tag)?;
186+
}
187+
}
188+
Ok(())
189+
}
190+
191+
fn ptr_from_addr_cast(&self, addr: u64) -> InterpResult<'tcx, Pointer<Option<Provenance>>> {
192+
trace!("Casting {:#x} to a pointer", addr);
193+
194+
let ecx = self.eval_context_ref();
195+
let global_state = ecx.machine.intptrcast.borrow();
196+
197+
match global_state.provenance_mode {
198+
ProvenanceMode::Default => {
199+
// The first time this happens at a particular location, print a warning.
200+
thread_local! {
201+
// `Span` is non-`Send`, so we use a thread-local instead.
202+
static PAST_WARNINGS: RefCell<FxHashSet<Span>> = RefCell::default();
203+
}
204+
PAST_WARNINGS.with_borrow_mut(|past_warnings| {
205+
let first = past_warnings.is_empty();
206+
if past_warnings.insert(ecx.cur_span()) {
207+
// Newly inserted, so first time we see this span.
208+
ecx.emit_diagnostic(NonHaltingDiagnostic::Int2Ptr { details: first });
209+
}
210+
});
211+
}
212+
ProvenanceMode::Strict => {
213+
throw_machine_stop!(TerminationInfo::Int2PtrWithStrictProvenance);
214+
}
215+
ProvenanceMode::Permissive => {}
216+
}
217+
218+
// This is how wildcard pointers are born.
219+
Ok(Pointer::new(Some(Provenance::Wildcard), Size::from_bytes(addr)))
220+
}
224221

225222
/// Convert a relative (tcx) pointer to an absolute address.
226-
pub fn rel_ptr_to_addr(
227-
ecx: &MiriInterpCx<'mir, 'tcx>,
228-
ptr: Pointer<AllocId>,
229-
) -> InterpResult<'tcx, u64> {
223+
fn rel_ptr_to_addr(&self, ptr: Pointer<AllocId>) -> InterpResult<'tcx, u64> {
224+
let ecx = self.eval_context_ref();
225+
230226
let (alloc_id, offset) = ptr.into_parts(); // offset is relative (AllocId provenance)
231-
let base_addr = GlobalStateInner::alloc_base_addr(ecx, alloc_id)?;
227+
let base_addr = ecx.addr_from_alloc_id(alloc_id)?;
232228

233229
// Add offset with the right kind of pointer-overflowing arithmetic.
234230
let dl = ecx.data_layout();
@@ -237,22 +233,21 @@ impl<'mir, 'tcx> GlobalStateInner {
237233

238234
/// When a pointer is used for a memory access, this computes where in which allocation the
239235
/// access is going.
240-
pub fn abs_ptr_to_rel(
241-
ecx: &MiriInterpCx<'mir, 'tcx>,
242-
ptr: Pointer<Provenance>,
243-
) -> Option<(AllocId, Size)> {
236+
fn abs_ptr_to_rel(&self, ptr: Pointer<Provenance>) -> Option<(AllocId, Size)> {
237+
let ecx = self.eval_context_ref();
238+
244239
let (tag, addr) = ptr.into_parts(); // addr is absolute (Tag provenance)
245240

246241
let alloc_id = if let Provenance::Concrete { alloc_id, .. } = tag {
247242
alloc_id
248243
} else {
249244
// A wildcard pointer.
250-
GlobalStateInner::alloc_id_from_addr(ecx, addr.bytes())?
245+
ecx.alloc_id_from_addr(addr.bytes())?
251246
};
252247

253248
// This cannot fail: since we already have a pointer with that provenance, rel_ptr_to_addr
254249
// must have been called in the past.
255-
let base_addr = GlobalStateInner::alloc_base_addr(ecx, alloc_id).unwrap();
250+
let base_addr = ecx.addr_from_alloc_id(alloc_id).unwrap();
256251

257252
// Wrapping "addr - base_addr"
258253
let dl = ecx.data_layout();
@@ -263,15 +258,6 @@ impl<'mir, 'tcx> GlobalStateInner {
263258
Size::from_bytes(dl.overflowing_signed_offset(addr.bytes(), neg_base_addr).0),
264259
))
265260
}
266-
267-
/// Shifts `addr` to make it aligned with `align` by rounding `addr` to the smallest multiple
268-
/// of `align` that is larger or equal to `addr`
269-
fn align_addr(addr: u64, align: u64) -> u64 {
270-
match addr % align {
271-
0 => addr,
272-
rem => addr.checked_add(align).unwrap() - rem,
273-
}
274-
}
275261
}
276262

277263
#[cfg(test)]
@@ -280,7 +266,7 @@ mod tests {
280266

281267
#[test]
282268
fn test_align_addr() {
283-
assert_eq!(GlobalStateInner::align_addr(37, 4), 40);
284-
assert_eq!(GlobalStateInner::align_addr(44, 4), 44);
269+
assert_eq!(align_addr(37, 4), 40);
270+
assert_eq!(align_addr(44, 4), 44);
285271
}
286272
}

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ pub use crate::eval::{
117117
create_ecx, eval_entry, AlignmentCheck, BacktraceStyle, IsolatedOp, MiriConfig, RejectOpWith,
118118
};
119119
pub use crate::helpers::EvalContextExt as _;
120-
pub use crate::intptrcast::ProvenanceMode;
120+
pub use crate::intptrcast::{EvalContextExt as _, ProvenanceMode};
121121
pub use crate::machine::{
122122
AllocExtra, FrameExtra, MiriInterpCx, MiriInterpCxExt, MiriMachine, MiriMemoryKind,
123123
PrimitiveLayouts, Provenance, ProvenanceExtra,

src/machine.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1125,7 +1125,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
11251125
_ => {}
11261126
}
11271127
}
1128-
let absolute_addr = intptrcast::GlobalStateInner::rel_ptr_to_addr(ecx, ptr)?;
1128+
let absolute_addr = ecx.rel_ptr_to_addr(ptr)?;
11291129
let tag = if let Some(borrow_tracker) = &ecx.machine.borrow_tracker {
11301130
borrow_tracker.borrow_mut().base_ptr_tag(ptr.provenance, &ecx.machine)
11311131
} else {
@@ -1143,16 +1143,15 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
11431143
ecx: &MiriInterpCx<'mir, 'tcx>,
11441144
addr: u64,
11451145
) -> InterpResult<'tcx, Pointer<Option<Self::Provenance>>> {
1146-
intptrcast::GlobalStateInner::ptr_from_addr_cast(ecx, addr)
1146+
ecx.ptr_from_addr_cast(addr)
11471147
}
11481148

11491149
fn expose_ptr(
11501150
ecx: &mut InterpCx<'mir, 'tcx, Self>,
11511151
ptr: Pointer<Self::Provenance>,
11521152
) -> InterpResult<'tcx> {
11531153
match ptr.provenance {
1154-
Provenance::Concrete { alloc_id, tag } =>
1155-
intptrcast::GlobalStateInner::expose_ptr(ecx, alloc_id, tag),
1154+
Provenance::Concrete { alloc_id, tag } => ecx.expose_ptr(alloc_id, tag),
11561155
Provenance::Wildcard => {
11571156
// No need to do anything for wildcard pointers as
11581157
// their provenances have already been previously exposed.
@@ -1167,7 +1166,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
11671166
ecx: &MiriInterpCx<'mir, 'tcx>,
11681167
ptr: Pointer<Self::Provenance>,
11691168
) -> Option<(AllocId, Size, Self::ProvenanceExtra)> {
1170-
let rel = intptrcast::GlobalStateInner::abs_ptr_to_rel(ecx, ptr);
1169+
let rel = ecx.abs_ptr_to_rel(ptr);
11711170

11721171
rel.map(|(alloc_id, size)| {
11731172
let tag = match ptr.provenance {

0 commit comments

Comments
 (0)