Skip to content

Commit 19485cc

Browse files
committed
Miri: refactor new allocation tagging
1 parent ee621f4 commit 19485cc

File tree

9 files changed

+99
-164
lines changed

9 files changed

+99
-164
lines changed

src/librustc/mir/interpret/allocation.rs

+20-53
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,10 @@ pub struct Allocation<Tag=(),Extra=()> {
4545
}
4646

4747

48-
pub trait AllocationExtra<Tag, MemoryExtra>: ::std::fmt::Debug + Clone {
49-
/// Hook to initialize the extra data when an allocation gets created.
50-
fn memory_allocated(
51-
_size: Size,
52-
_memory_extra: &MemoryExtra
53-
) -> Self;
48+
pub trait AllocationExtra<Tag>: ::std::fmt::Debug + Clone {
49+
// There is no constructor in here because the constructor's type depends
50+
// on `MemoryKind`, and making things sufficiently generic leads to painful
51+
// inference failure.
5452

5553
/// Hook for performing extra checks on a memory read access.
5654
///
@@ -88,15 +86,8 @@ pub trait AllocationExtra<Tag, MemoryExtra>: ::std::fmt::Debug + Clone {
8886
}
8987
}
9088

91-
impl AllocationExtra<(), ()> for () {
92-
#[inline(always)]
93-
fn memory_allocated(
94-
_size: Size,
95-
_memory_extra: &()
96-
) -> Self {
97-
()
98-
}
99-
}
89+
// For Tag=() and no extra state, we have is a trivial implementation.
90+
impl AllocationExtra<()> for () { }
10091

10192
impl<Tag, Extra> Allocation<Tag, Extra> {
10293
/// Creates a read-only allocation initialized by the given bytes
@@ -159,23 +150,21 @@ impl<'tcx, Tag, Extra> Allocation<Tag, Extra> {
159150
}
160151

161152
/// Byte accessors
162-
impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
153+
impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
163154
/// The last argument controls whether we error out when there are undefined
164155
/// or pointer bytes. You should never call this, call `get_bytes` or
165156
/// `get_bytes_with_undef_and_ptr` instead,
166157
///
167158
/// This function also guarantees that the resulting pointer will remain stable
168159
/// even when new allocations are pushed to the `HashMap`. `copy_repeatedly` relies
169160
/// on that.
170-
fn get_bytes_internal<MemoryExtra>(
161+
fn get_bytes_internal(
171162
&self,
172163
cx: &impl HasDataLayout,
173164
ptr: Pointer<Tag>,
174165
size: Size,
175166
check_defined_and_ptr: bool,
176167
) -> EvalResult<'tcx, &[u8]>
177-
// FIXME: Working around https://github.com/rust-lang/rust/issues/56209
178-
where Extra: AllocationExtra<Tag, MemoryExtra>
179168
{
180169
self.check_bounds(cx, ptr, size)?;
181170

@@ -196,43 +185,37 @@ impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
196185
}
197186

198187
#[inline]
199-
pub fn get_bytes<MemoryExtra>(
188+
pub fn get_bytes(
200189
&self,
201190
cx: &impl HasDataLayout,
202191
ptr: Pointer<Tag>,
203192
size: Size,
204193
) -> EvalResult<'tcx, &[u8]>
205-
// FIXME: Working around https://github.com/rust-lang/rust/issues/56209
206-
where Extra: AllocationExtra<Tag, MemoryExtra>
207194
{
208195
self.get_bytes_internal(cx, ptr, size, true)
209196
}
210197

211198
/// It is the caller's responsibility to handle undefined and pointer bytes.
212199
/// However, this still checks that there are no relocations on the *edges*.
213200
#[inline]
214-
pub fn get_bytes_with_undef_and_ptr<MemoryExtra>(
201+
pub fn get_bytes_with_undef_and_ptr(
215202
&self,
216203
cx: &impl HasDataLayout,
217204
ptr: Pointer<Tag>,
218205
size: Size,
219206
) -> EvalResult<'tcx, &[u8]>
220-
// FIXME: Working around https://github.com/rust-lang/rust/issues/56209
221-
where Extra: AllocationExtra<Tag, MemoryExtra>
222207
{
223208
self.get_bytes_internal(cx, ptr, size, false)
224209
}
225210

226211
/// Just calling this already marks everything as defined and removes relocations,
227212
/// so be sure to actually put data there!
228-
pub fn get_bytes_mut<MemoryExtra>(
213+
pub fn get_bytes_mut(
229214
&mut self,
230215
cx: &impl HasDataLayout,
231216
ptr: Pointer<Tag>,
232217
size: Size,
233218
) -> EvalResult<'tcx, &mut [u8]>
234-
// FIXME: Working around https://github.com/rust-lang/rust/issues/56209
235-
where Extra: AllocationExtra<Tag, MemoryExtra>
236219
{
237220
assert_ne!(size.bytes(), 0, "0-sized accesses should never even get a `Pointer`");
238221
self.check_bounds(cx, ptr, size)?;
@@ -250,16 +233,14 @@ impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
250233
}
251234

252235
/// Reading and writing
253-
impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
236+
impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
254237
/// Reads bytes until a `0` is encountered. Will error if the end of the allocation is reached
255238
/// before a `0` is found.
256-
pub fn read_c_str<MemoryExtra>(
239+
pub fn read_c_str(
257240
&self,
258241
cx: &impl HasDataLayout,
259242
ptr: Pointer<Tag>,
260243
) -> EvalResult<'tcx, &[u8]>
261-
// FIXME: Working around https://github.com/rust-lang/rust/issues/56209
262-
where Extra: AllocationExtra<Tag, MemoryExtra>
263244
{
264245
assert_eq!(ptr.offset.bytes() as usize as u64, ptr.offset.bytes());
265246
let offset = ptr.offset.bytes() as usize;
@@ -278,15 +259,13 @@ impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
278259
/// Validates that `ptr.offset` and `ptr.offset + size` do not point to the middle of a
279260
/// relocation. If `allow_ptr_and_undef` is `false`, also enforces that the memory in the
280261
/// given range contains neither relocations nor undef bytes.
281-
pub fn check_bytes<MemoryExtra>(
262+
pub fn check_bytes(
282263
&self,
283264
cx: &impl HasDataLayout,
284265
ptr: Pointer<Tag>,
285266
size: Size,
286267
allow_ptr_and_undef: bool,
287268
) -> EvalResult<'tcx>
288-
// FIXME: Working around https://github.com/rust-lang/rust/issues/56209
289-
where Extra: AllocationExtra<Tag, MemoryExtra>
290269
{
291270
// Check bounds and relocations on the edges
292271
self.get_bytes_with_undef_and_ptr(cx, ptr, size)?;
@@ -301,30 +280,26 @@ impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
301280
/// Writes `src` to the memory starting at `ptr.offset`.
302281
///
303282
/// Will do bounds checks on the allocation.
304-
pub fn write_bytes<MemoryExtra>(
283+
pub fn write_bytes(
305284
&mut self,
306285
cx: &impl HasDataLayout,
307286
ptr: Pointer<Tag>,
308287
src: &[u8],
309288
) -> EvalResult<'tcx>
310-
// FIXME: Working around https://github.com/rust-lang/rust/issues/56209
311-
where Extra: AllocationExtra<Tag, MemoryExtra>
312289
{
313290
let bytes = self.get_bytes_mut(cx, ptr, Size::from_bytes(src.len() as u64))?;
314291
bytes.clone_from_slice(src);
315292
Ok(())
316293
}
317294

318295
/// Sets `count` bytes starting at `ptr.offset` with `val`. Basically `memset`.
319-
pub fn write_repeat<MemoryExtra>(
296+
pub fn write_repeat(
320297
&mut self,
321298
cx: &impl HasDataLayout,
322299
ptr: Pointer<Tag>,
323300
val: u8,
324301
count: Size
325302
) -> EvalResult<'tcx>
326-
// FIXME: Working around https://github.com/rust-lang/rust/issues/56209
327-
where Extra: AllocationExtra<Tag, MemoryExtra>
328303
{
329304
let bytes = self.get_bytes_mut(cx, ptr, count)?;
330305
for b in bytes {
@@ -341,14 +316,12 @@ impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
341316
/// being valid for ZSTs
342317
///
343318
/// Note: This function does not do *any* alignment checks, you need to do these before calling
344-
pub fn read_scalar<MemoryExtra>(
319+
pub fn read_scalar(
345320
&self,
346321
cx: &impl HasDataLayout,
347322
ptr: Pointer<Tag>,
348323
size: Size
349324
) -> EvalResult<'tcx, ScalarMaybeUndef<Tag>>
350-
// FIXME: Working around https://github.com/rust-lang/rust/issues/56209
351-
where Extra: AllocationExtra<Tag, MemoryExtra>
352325
{
353326
// get_bytes_unchecked tests relocation edges
354327
let bytes = self.get_bytes_with_undef_and_ptr(cx, ptr, size)?;
@@ -379,13 +352,11 @@ impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
379352
}
380353

381354
/// Note: This function does not do *any* alignment checks, you need to do these before calling
382-
pub fn read_ptr_sized<MemoryExtra>(
355+
pub fn read_ptr_sized(
383356
&self,
384357
cx: &impl HasDataLayout,
385358
ptr: Pointer<Tag>,
386359
) -> EvalResult<'tcx, ScalarMaybeUndef<Tag>>
387-
// FIXME: Working around https://github.com/rust-lang/rust/issues/56209
388-
where Extra: AllocationExtra<Tag, MemoryExtra>
389360
{
390361
self.read_scalar(cx, ptr, cx.data_layout().pointer_size)
391362
}
@@ -398,15 +369,13 @@ impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
398369
/// being valid for ZSTs
399370
///
400371
/// Note: This function does not do *any* alignment checks, you need to do these before calling
401-
pub fn write_scalar<MemoryExtra>(
372+
pub fn write_scalar(
402373
&mut self,
403374
cx: &impl HasDataLayout,
404375
ptr: Pointer<Tag>,
405376
val: ScalarMaybeUndef<Tag>,
406377
type_size: Size,
407378
) -> EvalResult<'tcx>
408-
// FIXME: Working around https://github.com/rust-lang/rust/issues/56209
409-
where Extra: AllocationExtra<Tag, MemoryExtra>
410379
{
411380
let val = match val {
412381
ScalarMaybeUndef::Scalar(scalar) => scalar,
@@ -446,14 +415,12 @@ impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
446415
}
447416

448417
/// Note: This function does not do *any* alignment checks, you need to do these before calling
449-
pub fn write_ptr_sized<MemoryExtra>(
418+
pub fn write_ptr_sized(
450419
&mut self,
451420
cx: &impl HasDataLayout,
452421
ptr: Pointer<Tag>,
453422
val: ScalarMaybeUndef<Tag>
454423
) -> EvalResult<'tcx>
455-
// FIXME: Working around https://github.com/rust-lang/rust/issues/56209
456-
where Extra: AllocationExtra<Tag, MemoryExtra>
457424
{
458425
let ptr_size = cx.data_layout().pointer_size;
459426
self.write_scalar(cx, ptr.into(), val, ptr_size)

src/librustc/mir/interpret/pointer.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -94,11 +94,17 @@ impl<'tcx> Pointer<()> {
9494
Pointer { alloc_id, offset, tag: () }
9595
}
9696

97+
#[inline(always)]
98+
pub fn with_tag<Tag>(self, tag: Tag) -> Pointer<Tag>
99+
{
100+
Pointer::new_with_tag(self.alloc_id, self.offset, tag)
101+
}
102+
97103
#[inline(always)]
98104
pub fn with_default_tag<Tag>(self) -> Pointer<Tag>
99105
where Tag: Default
100106
{
101-
Pointer::new_with_tag(self.alloc_id, self.offset, Default::default())
107+
self.with_tag(Tag::default())
102108
}
103109
}
104110

src/librustc/mir/interpret/value.rs

+18-16
Original file line numberDiff line numberDiff line change
@@ -119,14 +119,19 @@ impl<Tag> fmt::Display for Scalar<Tag> {
119119

120120
impl<'tcx> Scalar<()> {
121121
#[inline]
122-
pub fn with_default_tag<Tag>(self) -> Scalar<Tag>
123-
where Tag: Default
124-
{
122+
pub fn with_tag<Tag>(self, new_tag: Tag) -> Scalar<Tag> {
125123
match self {
126-
Scalar::Ptr(ptr) => Scalar::Ptr(ptr.with_default_tag()),
124+
Scalar::Ptr(ptr) => Scalar::Ptr(ptr.with_tag(new_tag)),
127125
Scalar::Bits { bits, size } => Scalar::Bits { bits, size },
128126
}
129127
}
128+
129+
#[inline(always)]
130+
pub fn with_default_tag<Tag>(self) -> Scalar<Tag>
131+
where Tag: Default
132+
{
133+
self.with_tag(Tag::default())
134+
}
130135
}
131136

132137
impl<'tcx, Tag> Scalar<Tag> {
@@ -138,14 +143,6 @@ impl<'tcx, Tag> Scalar<Tag> {
138143
}
139144
}
140145

141-
#[inline]
142-
pub fn with_tag(self, new_tag: Tag) -> Self {
143-
match self {
144-
Scalar::Ptr(ptr) => Scalar::Ptr(Pointer { tag: new_tag, ..ptr }),
145-
Scalar::Bits { bits, size } => Scalar::Bits { bits, size },
146-
}
147-
}
148-
149146
#[inline]
150147
pub fn ptr_null(cx: &impl HasDataLayout) -> Self {
151148
Scalar::Bits {
@@ -434,14 +431,19 @@ impl<Tag> fmt::Display for ScalarMaybeUndef<Tag> {
434431

435432
impl<'tcx> ScalarMaybeUndef<()> {
436433
#[inline]
437-
pub fn with_default_tag<Tag>(self) -> ScalarMaybeUndef<Tag>
438-
where Tag: Default
439-
{
434+
pub fn with_tag<Tag>(self, new_tag: Tag) -> ScalarMaybeUndef<Tag> {
440435
match self {
441-
ScalarMaybeUndef::Scalar(s) => ScalarMaybeUndef::Scalar(s.with_default_tag()),
436+
ScalarMaybeUndef::Scalar(s) => ScalarMaybeUndef::Scalar(s.with_tag(new_tag)),
442437
ScalarMaybeUndef::Undef => ScalarMaybeUndef::Undef,
443438
}
444439
}
440+
441+
#[inline(always)]
442+
pub fn with_default_tag<Tag>(self) -> ScalarMaybeUndef<Tag>
443+
where Tag: Default
444+
{
445+
self.with_tag(Tag::default())
446+
}
445447
}
446448

447449
impl<'tcx, Tag> ScalarMaybeUndef<Tag> {

src/librustc_mir/const_eval.rs

+11-11
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc::hir::def::Def;
1111
use rustc::mir::interpret::{ConstEvalErr, ErrorHandled};
1212
use rustc::mir;
1313
use rustc::ty::{self, TyCtxt, query::TyCtxtAt};
14-
use rustc::ty::layout::{self, LayoutOf, VariantIdx};
14+
use rustc::ty::layout::{self, LayoutOf, VariantIdx, Size};
1515
use rustc::ty::subst::Subst;
1616
use rustc::traits::Reveal;
1717
use rustc::util::common::ErrorReported;
@@ -21,7 +21,7 @@ use syntax::ast::Mutability;
2121
use syntax::source_map::{Span, DUMMY_SP};
2222

2323
use crate::interpret::{self,
24-
PlaceTy, MPlaceTy, MemPlace, OpTy, ImmTy, Immediate, Scalar, Pointer,
24+
PlaceTy, MPlaceTy, MemPlace, OpTy, ImmTy, Immediate, Scalar,
2525
RawConst, ConstValue,
2626
EvalResult, EvalError, InterpError, GlobalId, InterpretCx, StackPopCleanup,
2727
Allocation, AllocId, MemoryKind,
@@ -406,6 +406,15 @@ impl<'a, 'mir, 'tcx> interpret::Machine<'a, 'mir, 'tcx>
406406
Cow::Borrowed(alloc)
407407
}
408408

409+
#[inline(always)]
410+
fn new_allocation(
411+
_size: Size,
412+
_extra: &Self::MemoryExtra,
413+
_kind: MemoryKind<!>,
414+
) -> (Self::AllocExtra, Self::PointerTag) {
415+
((), ())
416+
}
417+
409418
fn box_alloc(
410419
_ecx: &mut InterpretCx<'a, 'mir, 'tcx, Self>,
411420
_dest: PlaceTy<'tcx>,
@@ -439,15 +448,6 @@ impl<'a, 'mir, 'tcx> interpret::Machine<'a, 'mir, 'tcx>
439448
)
440449
}
441450

442-
#[inline(always)]
443-
fn tag_new_allocation(
444-
_ecx: &mut InterpretCx<'a, 'mir, 'tcx, Self>,
445-
ptr: Pointer,
446-
_kind: MemoryKind<Self::MemoryKinds>,
447-
) -> Pointer {
448-
ptr
449-
}
450-
451451
#[inline(always)]
452452
fn stack_push(
453453
_ecx: &mut InterpretCx<'a, 'mir, 'tcx, Self>,

0 commit comments

Comments
 (0)