Skip to content

Commit 07e7804

Browse files
committed
Adjust rustc_mir::interpret to changes in Allocation/Memory methods
1 parent 9ecde57 commit 07e7804

File tree

7 files changed

+146
-76
lines changed

7 files changed

+146
-76
lines changed

src/librustc/mir/interpret/allocation.rs

Lines changed: 69 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,12 @@
1010

1111
//! The virtual memory representation of the MIR interpreter
1212
13-
use super::{Pointer, EvalResult, AllocId};
13+
use super::{
14+
Pointer, EvalResult, AllocId, ScalarMaybeUndef, write_target_uint, read_target_uint, Scalar,
15+
truncate,
16+
};
1417

15-
use ty::layout::{Size, Align};
18+
use ty::layout::{self, Size, Align};
1619
use syntax::ast::Mutability;
1720
use std::iter;
1821
use mir;
@@ -88,24 +91,28 @@ impl<'tcx, Tag, Extra> Allocation<Tag, Extra> {
8891

8992
/// Reading and writing
9093
impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
91-
pub fn read_c_str(&self, ptr: Pointer<M::PointerTag>) -> EvalResult<'tcx, &[u8]> {
92-
let alloc = self.get(ptr.alloc_id)?;
94+
pub fn read_c_str(
95+
&self,
96+
cx: &impl HasDataLayout,
97+
ptr: Pointer<Tag>,
98+
) -> EvalResult<'tcx, &[u8]> {
9399
assert_eq!(ptr.offset.bytes() as usize as u64, ptr.offset.bytes());
94100
let offset = ptr.offset.bytes() as usize;
95-
match alloc.bytes[offset..].iter().position(|&c| c == 0) {
101+
match self.bytes[offset..].iter().position(|&c| c == 0) {
96102
Some(size) => {
97103
let p1 = Size::from_bytes((size + 1) as u64);
98-
self.check_relocations(ptr, p1)?;
104+
self.check_relocations(cx, ptr, p1)?;
99105
self.check_defined(ptr, p1)?;
100-
Ok(&alloc.bytes[offset..offset + size])
106+
Ok(&self.bytes[offset..offset + size])
101107
}
102108
None => err!(UnterminatedCString(ptr.erase_tag())),
103109
}
104110
}
105111

106112
pub fn check_bytes(
107113
&self,
108-
ptr: Scalar<M::PointerTag>,
114+
cx: &impl HasDataLayout,
115+
ptr: Pointer<Tag>,
109116
size: Size,
110117
allow_ptr_and_undef: bool,
111118
) -> EvalResult<'tcx> {
@@ -115,42 +122,54 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
115122
self.check_align(ptr, align)?;
116123
return Ok(());
117124
}
118-
let ptr = ptr.to_ptr()?;
119125
// Check bounds, align and relocations on the edges
120-
self.get_bytes_with_undef_and_ptr(ptr, size, align)?;
126+
self.get_bytes_with_undef_and_ptr(cx, ptr, size, align)?;
121127
// Check undef and ptr
122128
if !allow_ptr_and_undef {
123129
self.check_defined(ptr, size)?;
124-
self.check_relocations(ptr, size)?;
130+
self.check_relocations(cx, ptr, size)?;
125131
}
126132
Ok(())
127133
}
128134

129-
pub fn read_bytes(&self, ptr: Scalar<M::PointerTag>, size: Size) -> EvalResult<'tcx, &[u8]> {
135+
pub fn read_bytes(
136+
&self,
137+
cx: &impl HasDataLayout,
138+
ptr: Pointer<Tag>,
139+
size: Size,
140+
) -> EvalResult<'tcx, &[u8]> {
130141
// Empty accesses don't need to be valid pointers, but they should still be non-NULL
131142
let align = Align::from_bytes(1).unwrap();
132143
if size.bytes() == 0 {
133144
self.check_align(ptr, align)?;
134145
return Ok(&[]);
135146
}
136-
self.get_bytes(ptr.to_ptr()?, size, align)
147+
self.get_bytes(cx, ptr, size, align)
137148
}
138149

139-
pub fn write_bytes(&mut self, ptr: Scalar<M::PointerTag>, src: &[u8]) -> EvalResult<'tcx> {
150+
pub fn write_bytes(
151+
&mut self,
152+
cx: &impl HasDataLayout,
153+
ptr: Pointer<Tag>,
154+
src: &[u8],
155+
) -> EvalResult<'tcx> {
140156
// Empty accesses don't need to be valid pointers, but they should still be non-NULL
141157
let align = Align::from_bytes(1).unwrap();
142158
if src.is_empty() {
143159
self.check_align(ptr, align)?;
144160
return Ok(());
145161
}
146-
let bytes = self.get_bytes_mut(ptr.to_ptr()?, Size::from_bytes(src.len() as u64), align)?;
162+
let bytes = self.get_bytes_mut(
163+
cx, ptr, Size::from_bytes(src.len() as u64), align,
164+
)?;
147165
bytes.clone_from_slice(src);
148166
Ok(())
149167
}
150168

151169
pub fn write_repeat(
152170
&mut self,
153-
ptr: Scalar<M::PointerTag>,
171+
cx: &impl HasDataLayout,
172+
ptr: Pointer<Tag>,
154173
val: u8,
155174
count: Size
156175
) -> EvalResult<'tcx> {
@@ -160,7 +179,7 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
160179
self.check_align(ptr, align)?;
161180
return Ok(());
162181
}
163-
let bytes = self.get_bytes_mut(ptr.to_ptr()?, count, align)?;
182+
let bytes = self.get_bytes_mut(cx, ptr, count, align)?;
164183
for b in bytes {
165184
*b = val;
166185
}
@@ -170,13 +189,14 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
170189
/// Read a *non-ZST* scalar
171190
pub fn read_scalar(
172191
&self,
173-
ptr: Pointer<M::PointerTag>,
192+
cx: &impl HasDataLayout,
193+
ptr: Pointer<Tag>,
174194
ptr_align: Align,
175195
size: Size
176-
) -> EvalResult<'tcx, ScalarMaybeUndef<M::PointerTag>> {
196+
) -> EvalResult<'tcx, ScalarMaybeUndef<Tag>> {
177197
// get_bytes_unchecked tests alignment and relocation edges
178198
let bytes = self.get_bytes_with_undef_and_ptr(
179-
ptr, size, ptr_align.min(self.int_align(size))
199+
cx, ptr, size, ptr_align.min(self.int_align(cx, size))
180200
)?;
181201
// Undef check happens *after* we established that the alignment is correct.
182202
// We must not return Ok() for unaligned pointers!
@@ -186,14 +206,13 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
186206
return Ok(ScalarMaybeUndef::Undef);
187207
}
188208
// Now we do the actual reading
189-
let bits = read_target_uint(self.tcx.data_layout.endian, bytes).unwrap();
209+
let bits = read_target_uint(cx.data_layout().endian, bytes).unwrap();
190210
// See if we got a pointer
191-
if size != self.pointer_size() {
211+
if size != cx.data_layout().pointer_size {
192212
// *Now* better make sure that the inside also is free of relocations.
193-
self.check_relocations(ptr, size)?;
213+
self.check_relocations(cx, ptr, size)?;
194214
} else {
195-
let alloc = self.get(ptr.alloc_id)?;
196-
match alloc.relocations.get(&ptr.offset) {
215+
match self.relocations.get(&ptr.offset) {
197216
Some(&(tag, alloc_id)) => {
198217
let ptr = Pointer::new_with_tag(alloc_id, Size::from_bytes(bits as u64), tag);
199218
return Ok(ScalarMaybeUndef::Scalar(ptr.into()))
@@ -207,18 +226,20 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
207226

208227
pub fn read_ptr_sized(
209228
&self,
210-
ptr: Pointer<M::PointerTag>,
229+
cx: &impl HasDataLayout,
230+
ptr: Pointer<Tag>,
211231
ptr_align: Align
212-
) -> EvalResult<'tcx, ScalarMaybeUndef<M::PointerTag>> {
213-
self.read_scalar(ptr, ptr_align, self.pointer_size())
232+
) -> EvalResult<'tcx, ScalarMaybeUndef<Tag>> {
233+
self.read_scalar(cx, ptr, ptr_align, cx.data_layout().pointer_size)
214234
}
215235

216236
/// Write a *non-ZST* scalar
217237
pub fn write_scalar(
218238
&mut self,
219-
ptr: Pointer<M::PointerTag>,
239+
cx: &impl HasDataLayout,
240+
ptr: Pointer<Tag>,
220241
ptr_align: Align,
221-
val: ScalarMaybeUndef<M::PointerTag>,
242+
val: ScalarMaybeUndef<Tag>,
222243
type_size: Size,
223244
) -> EvalResult<'tcx> {
224245
let val = match val {
@@ -228,7 +249,7 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
228249

229250
let bytes = match val {
230251
Scalar::Ptr(val) => {
231-
assert_eq!(type_size, self.pointer_size());
252+
assert_eq!(type_size, cx.data_layout().pointer_size);
232253
val.offset.bytes() as u128
233254
}
234255

@@ -242,15 +263,15 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
242263

243264
{
244265
// get_bytes_mut checks alignment
245-
let endian = self.tcx.data_layout.endian;
246-
let dst = self.get_bytes_mut(ptr, type_size, ptr_align)?;
266+
let endian = cx.data_layout().endian;
267+
let dst = self.get_bytes_mut(cx, ptr, type_size, ptr_align)?;
247268
write_target_uint(endian, dst, bytes).unwrap();
248269
}
249270

250271
// See if we have to also write a relocation
251272
match val {
252273
Scalar::Ptr(val) => {
253-
self.get_mut(ptr.alloc_id)?.relocations.insert(
274+
self.relocations.insert(
254275
ptr.offset,
255276
(val.tag, val.alloc_id),
256277
);
@@ -263,15 +284,20 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
263284

264285
pub fn write_ptr_sized(
265286
&mut self,
266-
ptr: Pointer<M::PointerTag>,
287+
cx: &impl HasDataLayout,
288+
ptr: Pointer<Tag>,
267289
ptr_align: Align,
268-
val: ScalarMaybeUndef<M::PointerTag>
290+
val: ScalarMaybeUndef<Tag>
269291
) -> EvalResult<'tcx> {
270-
let ptr_size = self.pointer_size();
271-
self.write_scalar(ptr.into(), ptr_align, val, ptr_size)
292+
let ptr_size = cx.data_layout().pointer_size;
293+
self.write_scalar(cx, ptr.into(), ptr_align, val, ptr_size)
272294
}
273295

274-
fn int_align(&self, size: Size) -> Align {
296+
fn int_align(
297+
&self,
298+
cx: &impl HasDataLayout,
299+
size: Size,
300+
) -> Align {
275301
// We assume pointer-sized integers have the same alignment as pointers.
276302
// We also assume signed and unsigned integers of the same size have the same alignment.
277303
let ity = match size.bytes() {
@@ -282,7 +308,7 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
282308
16 => layout::I128,
283309
_ => bug!("bad integer size: {}", size.bytes()),
284310
};
285-
ity.align(self).abi
311+
ity.align(cx).abi
286312
}
287313
}
288314

@@ -337,7 +363,7 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
337363
/// It is the caller's responsibility to handle undefined and pointer bytes.
338364
/// However, this still checks that there are no relocations on the *edges*.
339365
#[inline]
340-
fn get_bytes_with_undef_and_ptr(
366+
pub fn get_bytes_with_undef_and_ptr(
341367
&self,
342368
cx: &impl HasDataLayout,
343369
ptr: Pointer<Tag>,
@@ -349,7 +375,7 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
349375

350376
/// Just calling this already marks everything as defined and removes relocations,
351377
/// so be sure to actually put data there!
352-
fn get_bytes_mut(
378+
pub fn get_bytes_mut(
353379
&mut self,
354380
cx: &impl HasDataLayout,
355381
ptr: Pointer<Tag>,
@@ -375,7 +401,7 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
375401
/// Relocations
376402
impl<'tcx, Tag: Copy, Extra> Allocation<Tag, Extra> {
377403
/// Return all relocations overlapping with the given ptr-offset pair.
378-
fn relocations(
404+
pub fn relocations(
379405
&self,
380406
cx: &impl HasDataLayout,
381407
ptr: Pointer<Tag>,

src/librustc_mir/interpret/memory.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use std::ptr;
2121
use std::borrow::Cow;
2222

2323
use rustc::ty::{self, Instance, ParamEnv, query::TyCtxtAt};
24-
use rustc::ty::layout::{self, Align, TargetDataLayout, Size, HasDataLayout};
24+
use rustc::ty::layout::{Align, TargetDataLayout, Size, HasDataLayout};
2525
pub use rustc::mir::interpret::{truncate, write_target_uint, read_target_uint};
2626
use rustc_data_structures::fx::{FxHashSet, FxHashMap};
2727

@@ -30,7 +30,7 @@ use syntax::ast::Mutability;
3030
use super::{
3131
Pointer, AllocId, Allocation, GlobalId, AllocationExtra, InboundsCheck,
3232
EvalResult, Scalar, EvalErrorKind, AllocType, PointerArithmetic,
33-
Machine, AllocMap, MayLeak, ScalarMaybeUndef, ErrorHandled,
33+
Machine, AllocMap, MayLeak, ErrorHandled,
3434
};
3535

3636
#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)]
@@ -655,7 +655,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
655655
// (`get_bytes_with_undef_and_ptr` below checks that there are no
656656
// relocations overlapping the edges; those would not be handled correctly).
657657
let relocations = {
658-
let relocations = self.relocations(src, size)?;
658+
let relocations = self.get(src.alloc_id)?.relocations(self, src, size)?;
659659
let mut new_relocations = Vec::with_capacity(relocations.len() * (length as usize));
660660
for i in 0..length {
661661
new_relocations.extend(
@@ -671,9 +671,15 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
671671
new_relocations
672672
};
673673

674+
let tcx = self.tcx.tcx;
675+
674676
// This also checks alignment, and relocation edges on the src.
675-
let src_bytes = self.get_bytes_with_undef_and_ptr(src, size, src_align)?.as_ptr();
676-
let dest_bytes = self.get_bytes_mut(dest, size * length, dest_align)?.as_mut_ptr();
677+
let src_bytes = self.get(src.alloc_id)?
678+
.get_bytes_with_undef_and_ptr(&tcx, src, size, src_align)?
679+
.as_ptr();
680+
let dest_bytes = self.get_mut(dest.alloc_id)?
681+
.get_bytes_mut(&tcx, dest, size * length, dest_align)?
682+
.as_mut_ptr();
677683

678684
// SAFE: The above indexing would have panicked if there weren't at least `size` bytes
679685
// behind `src` and `dest`. Also, we use the overlapping-safe `ptr::copy` if `src` and

src/librustc_mir/interpret/operand.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,9 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
278278
let ptr = ptr.to_ptr()?;
279279
match mplace.layout.abi {
280280
layout::Abi::Scalar(..) => {
281-
let scalar = self.memory.read_scalar(ptr, ptr_align, mplace.layout.size)?;
281+
let scalar = self.memory
282+
.get(ptr.alloc_id)?
283+
.read_scalar(self, ptr, ptr_align, mplace.layout.size)?;
282284
Ok(Some(Immediate::Scalar(scalar)))
283285
}
284286
layout::Abi::ScalarPair(ref a, ref b) => {
@@ -288,8 +290,12 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
288290
let b_offset = a_size.align_to(b.align(self).abi);
289291
assert!(b_offset.bytes() > 0); // we later use the offset to test which field to use
290292
let b_ptr = ptr.offset(b_offset, self)?.into();
291-
let a_val = self.memory.read_scalar(a_ptr, ptr_align, a_size)?;
292-
let b_val = self.memory.read_scalar(b_ptr, ptr_align, b_size)?;
293+
let a_val = self.memory
294+
.get(ptr.alloc_id)?
295+
.read_scalar(self, a_ptr, ptr_align, a_size)?;
296+
let b_val = self.memory
297+
.get(ptr.alloc_id)?
298+
.read_scalar(self, b_ptr, ptr_align, b_size)?;
293299
Ok(Some(Immediate::ScalarPair(a_val, b_val)))
294300
}
295301
_ => Ok(None),
@@ -345,7 +351,10 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
345351
mplace: MPlaceTy<'tcx, M::PointerTag>,
346352
) -> EvalResult<'tcx, &str> {
347353
let len = mplace.len(self)?;
348-
let bytes = self.memory.read_bytes(mplace.ptr, Size::from_bytes(len as u64))?;
354+
let ptr = mplace.ptr.to_ptr()?;
355+
let bytes = self.memory
356+
.get(ptr.alloc_id)?
357+
.read_bytes(self, ptr, Size::from_bytes(len as u64))?;
349358
let str = ::std::str::from_utf8(bytes)
350359
.map_err(|err| EvalErrorKind::ValidationFailure(err.to_string()))?;
351360
Ok(str)

src/librustc_mir/interpret/place.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,7 @@ where
718718
}
719719

720720
let ptr = ptr.to_ptr()?;
721+
let tcx = &*self.tcx;
721722
// FIXME: We should check that there are dest.layout.size many bytes available in
722723
// memory. The code below is not sufficient, with enough padding it might not
723724
// cover all the bytes!
@@ -729,8 +730,8 @@ where
729730
dest.layout)
730731
}
731732

732-
self.memory.write_scalar(
733-
ptr, ptr_align.min(dest.layout.align.abi), scalar, dest.layout.size
733+
self.memory.get_mut(ptr.alloc_id)?.write_scalar(
734+
tcx, ptr, ptr_align.min(dest.layout.align.abi), scalar, dest.layout.size
734735
)
735736
}
736737
Immediate::ScalarPair(a_val, b_val) => {
@@ -742,14 +743,18 @@ where
742743
let (a_size, b_size) = (a.size(self), b.size(self));
743744
let (a_align, b_align) = (a.align(self).abi, b.align(self).abi);
744745
let b_offset = a_size.align_to(b_align);
745-
let b_ptr = ptr.offset(b_offset, self)?.into();
746+
let b_ptr = ptr.offset(b_offset, self)?;
746747

747748
// It is tempting to verify `b_offset` against `layout.fields.offset(1)`,
748749
// but that does not work: We could be a newtype around a pair, then the
749750
// fields do not match the `ScalarPair` components.
750751

751-
self.memory.write_scalar(ptr, ptr_align.min(a_align), a_val, a_size)?;
752-
self.memory.write_scalar(b_ptr, ptr_align.min(b_align), b_val, b_size)
752+
self.memory
753+
.get_mut(ptr.alloc_id)?
754+
.write_scalar(tcx, ptr, ptr_align.min(a_align), a_val, a_size)?;
755+
self.memory
756+
.get_mut(b_ptr.alloc_id)?
757+
.write_scalar(tcx, b_ptr, ptr_align.min(b_align), b_val, b_size)
753758
}
754759
}
755760
}

0 commit comments

Comments
 (0)