Skip to content

Commit 7c25aa7

Browse files
committed
Use Size instead of u64 in mir interpretation
1 parent 3e933f4 commit 7c25aa7

File tree

17 files changed

+204
-197
lines changed

17 files changed

+204
-197
lines changed

src/librustc/mir/interpret/error.rs

+8-7
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use std::{fmt, env};
22

33
use mir;
44
use ty::{FnSig, Ty, layout};
5+
use ty::layout::{Size, Align};
56

67
use super::{
78
MemoryPointer, Lock, AccessKind
@@ -47,7 +48,7 @@ pub enum EvalErrorKind<'tcx, O> {
4748
PointerOutOfBounds {
4849
ptr: MemoryPointer,
4950
access: bool,
50-
allocation_size: u64,
51+
allocation_size: Size,
5152
},
5253
InvalidNullPointerUsage,
5354
ReadPointerAsBytes,
@@ -71,8 +72,8 @@ pub enum EvalErrorKind<'tcx, O> {
7172
TlsOutOfBounds,
7273
AbiViolation(String),
7374
AlignmentCheckFailed {
74-
required: u64,
75-
has: u64,
75+
required: Align,
76+
has: Align,
7677
},
7778
MemoryLockViolation {
7879
ptr: MemoryPointer,
@@ -108,7 +109,7 @@ pub enum EvalErrorKind<'tcx, O> {
108109
DeallocatedWrongMemoryKind(String, String),
109110
ReallocateNonBasePtr,
110111
DeallocateNonBasePtr,
111-
IncorrectAllocationInformation(u64, usize, u64, u64),
112+
IncorrectAllocationInformation(Size, Size, Align, Align),
112113
Layout(layout::LayoutError<'tcx>),
113114
HeapAllocZeroBytes,
114115
HeapAllocNonPowerOfTwoAlignment(u64),
@@ -269,7 +270,7 @@ impl<'tcx, O: fmt::Debug> fmt::Debug for EvalErrorKind<'tcx, O> {
269270
PointerOutOfBounds { ptr, access, allocation_size } => {
270271
write!(f, "{} at offset {}, outside bounds of allocation {} which has size {}",
271272
if access { "memory access" } else { "pointer computed" },
272-
ptr.offset, ptr.alloc_id, allocation_size)
273+
ptr.offset.bytes(), ptr.alloc_id, allocation_size.bytes())
273274
},
274275
MemoryLockViolation { ptr, len, frame, access, ref lock } => {
275276
write!(f, "{:?} access by frame {} at {:?}, size {}, is in conflict with lock {:?}",
@@ -305,7 +306,7 @@ impl<'tcx, O: fmt::Debug> fmt::Debug for EvalErrorKind<'tcx, O> {
305306
write!(f, "tried to interpret an invalid 32-bit value as a char: {}", c),
306307
AlignmentCheckFailed { required, has } =>
307308
write!(f, "tried to access memory with alignment {}, but alignment {} is required",
308-
has, required),
309+
has.abi(), required.abi()),
309310
TypeNotPrimitive(ty) =>
310311
write!(f, "expected primitive type, got {}", ty),
311312
Layout(ref err) =>
@@ -315,7 +316,7 @@ impl<'tcx, O: fmt::Debug> fmt::Debug for EvalErrorKind<'tcx, O> {
315316
MachineError(ref inner) =>
316317
write!(f, "{}", inner),
317318
IncorrectAllocationInformation(size, size2, align, align2) =>
318-
write!(f, "incorrect alloc info: expected size {} and align {}, got size {} and align {}", size, align, size2, align2),
319+
write!(f, "incorrect alloc info: expected size {} and align {}, got size {} and align {}", size.bytes(), align.abi(), size2.bytes(), align2.abi()),
319320
_ => write!(f, "{}", self.description()),
320321
}
321322
}

src/librustc/mir/interpret/mod.rs

+36-35
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use std::fmt;
1717
use mir;
1818
use hir::def_id::DefId;
1919
use ty::{self, TyCtxt};
20-
use ty::layout::{self, Align, HasDataLayout};
20+
use ty::layout::{self, Align, HasDataLayout, Size};
2121
use middle::region;
2222
use std::iter;
2323
use std::io;
@@ -109,42 +109,42 @@ impl<T: layout::HasDataLayout> PointerArithmetic for T {}
109109
#[derive(Copy, Clone, Debug, Eq, PartialEq, RustcEncodable, RustcDecodable, Hash)]
110110
pub struct MemoryPointer {
111111
pub alloc_id: AllocId,
112-
pub offset: u64,
112+
pub offset: Size,
113113
}
114114

115115
impl<'tcx> MemoryPointer {
116-
pub fn new(alloc_id: AllocId, offset: u64) -> Self {
116+
pub fn new(alloc_id: AllocId, offset: Size) -> Self {
117117
MemoryPointer { alloc_id, offset }
118118
}
119119

120120
pub(crate) fn wrapping_signed_offset<C: HasDataLayout>(self, i: i64, cx: C) -> Self {
121121
MemoryPointer::new(
122122
self.alloc_id,
123-
cx.data_layout().wrapping_signed_offset(self.offset, i),
123+
Size::from_bytes(cx.data_layout().wrapping_signed_offset(self.offset.bytes(), i)),
124124
)
125125
}
126126

127127
pub fn overflowing_signed_offset<C: HasDataLayout>(self, i: i128, cx: C) -> (Self, bool) {
128-
let (res, over) = cx.data_layout().overflowing_signed_offset(self.offset, i);
129-
(MemoryPointer::new(self.alloc_id, res), over)
128+
let (res, over) = cx.data_layout().overflowing_signed_offset(self.offset.bytes(), i);
129+
(MemoryPointer::new(self.alloc_id, Size::from_bytes(res)), over)
130130
}
131131

132132
pub(crate) fn signed_offset<C: HasDataLayout>(self, i: i64, cx: C) -> EvalResult<'tcx, Self> {
133133
Ok(MemoryPointer::new(
134134
self.alloc_id,
135-
cx.data_layout().signed_offset(self.offset, i)?,
135+
Size::from_bytes(cx.data_layout().signed_offset(self.offset.bytes(), i)?),
136136
))
137137
}
138138

139-
pub fn overflowing_offset<C: HasDataLayout>(self, i: u64, cx: C) -> (Self, bool) {
140-
let (res, over) = cx.data_layout().overflowing_offset(self.offset, i);
141-
(MemoryPointer::new(self.alloc_id, res), over)
139+
pub fn overflowing_offset<C: HasDataLayout>(self, i: Size, cx: C) -> (Self, bool) {
140+
let (res, over) = cx.data_layout().overflowing_offset(self.offset.bytes(), i.bytes());
141+
(MemoryPointer::new(self.alloc_id, Size::from_bytes(res)), over)
142142
}
143143

144-
pub fn offset<C: HasDataLayout>(self, i: u64, cx: C) -> EvalResult<'tcx, Self> {
144+
pub fn offset<C: HasDataLayout>(self, i: Size, cx: C) -> EvalResult<'tcx, Self> {
145145
Ok(MemoryPointer::new(
146146
self.alloc_id,
147-
cx.data_layout().offset(self.offset, i)?,
147+
Size::from_bytes(cx.data_layout().offset(self.offset.bytes(), i.bytes())?),
148148
))
149149
}
150150
}
@@ -244,7 +244,7 @@ pub struct Allocation {
244244
pub bytes: Vec<u8>,
245245
/// Maps from byte addresses to allocations.
246246
/// Only the first byte of a pointer is inserted into the map.
247-
pub relocations: BTreeMap<u64, AllocId>,
247+
pub relocations: BTreeMap<Size, AllocId>,
248248
/// Denotes undefined memory. Reading from undefined memory is forbidden in miri
249249
pub undef_mask: UndefMask,
250250
/// The alignment of the allocation to detect unaligned reads.
@@ -257,8 +257,8 @@ pub struct Allocation {
257257

258258
impl Allocation {
259259
pub fn from_bytes(slice: &[u8], align: Align) -> Self {
260-
let mut undef_mask = UndefMask::new(0);
261-
undef_mask.grow(slice.len() as u64, true);
260+
let mut undef_mask = UndefMask::new(Size::from_bytes(0));
261+
undef_mask.grow(Size::from_bytes(slice.len() as u64), true);
262262
Self {
263263
bytes: slice.to_owned(),
264264
relocations: BTreeMap::new(),
@@ -272,10 +272,10 @@ impl Allocation {
272272
Allocation::from_bytes(slice, Align::from_bytes(1, 1).unwrap())
273273
}
274274

275-
pub fn undef(size: u64, align: Align) -> Self {
276-
assert_eq!(size as usize as u64, size);
275+
pub fn undef(size: Size, align: Align) -> Self {
276+
assert_eq!(size.bytes() as usize as u64, size.bytes());
277277
Allocation {
278-
bytes: vec![0; size as usize],
278+
bytes: vec![0; size.bytes() as usize],
279279
relocations: BTreeMap::new(),
280280
undef_mask: UndefMask::new(size),
281281
align,
@@ -331,54 +331,54 @@ const BLOCK_SIZE: u64 = 64;
331331
#[derive(Clone, Debug, Eq, PartialEq, Hash, RustcEncodable, RustcDecodable)]
332332
pub struct UndefMask {
333333
blocks: Vec<Block>,
334-
len: u64,
334+
len: Size,
335335
}
336336

337337
impl_stable_hash_for!(struct mir::interpret::UndefMask{blocks, len});
338338

339339
impl UndefMask {
340-
pub fn new(size: u64) -> Self {
340+
pub fn new(size: Size) -> Self {
341341
let mut m = UndefMask {
342342
blocks: vec![],
343-
len: 0,
343+
len: Size::from_bytes(0),
344344
};
345345
m.grow(size, false);
346346
m
347347
}
348348

349349
/// Check whether the range `start..end` (end-exclusive) is entirely defined.
350-
pub fn is_range_defined(&self, start: u64, end: u64) -> bool {
350+
pub fn is_range_defined(&self, start: Size, end: Size) -> bool {
351351
if end > self.len {
352352
return false;
353353
}
354-
for i in start..end {
355-
if !self.get(i) {
354+
for i in start.bytes()..end.bytes() {
355+
if !self.get(Size::from_bytes(i)) {
356356
return false;
357357
}
358358
}
359359
true
360360
}
361361

362-
pub fn set_range(&mut self, start: u64, end: u64, new_state: bool) {
362+
pub fn set_range(&mut self, start: Size, end: Size, new_state: bool) {
363363
let len = self.len;
364364
if end > len {
365365
self.grow(end - len, new_state);
366366
}
367367
self.set_range_inbounds(start, end, new_state);
368368
}
369369

370-
pub fn set_range_inbounds(&mut self, start: u64, end: u64, new_state: bool) {
371-
for i in start..end {
372-
self.set(i, new_state);
370+
pub fn set_range_inbounds(&mut self, start: Size, end: Size, new_state: bool) {
371+
for i in start.bytes()..end.bytes() {
372+
self.set(Size::from_bytes(i), new_state);
373373
}
374374
}
375375

376-
pub fn get(&self, i: u64) -> bool {
376+
pub fn get(&self, i: Size) -> bool {
377377
let (block, bit) = bit_index(i);
378378
(self.blocks[block] & 1 << bit) != 0
379379
}
380380

381-
pub fn set(&mut self, i: u64, new_state: bool) {
381+
pub fn set(&mut self, i: Size, new_state: bool) {
382382
let (block, bit) = bit_index(i);
383383
if new_state {
384384
self.blocks[block] |= 1 << bit;
@@ -387,10 +387,10 @@ impl UndefMask {
387387
}
388388
}
389389

390-
pub fn grow(&mut self, amount: u64, new_state: bool) {
391-
let unused_trailing_bits = self.blocks.len() as u64 * BLOCK_SIZE - self.len;
392-
if amount > unused_trailing_bits {
393-
let additional_blocks = amount / BLOCK_SIZE + 1;
390+
pub fn grow(&mut self, amount: Size, new_state: bool) {
391+
let unused_trailing_bits = self.blocks.len() as u64 * BLOCK_SIZE - self.len.bytes();
392+
if amount.bytes() > unused_trailing_bits {
393+
let additional_blocks = amount.bytes() / BLOCK_SIZE + 1;
394394
assert_eq!(additional_blocks as usize as u64, additional_blocks);
395395
self.blocks.extend(
396396
iter::repeat(0).take(additional_blocks as usize),
@@ -402,7 +402,8 @@ impl UndefMask {
402402
}
403403
}
404404

405-
fn bit_index(bits: u64) -> (usize, usize) {
405+
fn bit_index(bits: Size) -> (usize, usize) {
406+
let bits = bits.bytes();
406407
let a = bits / BLOCK_SIZE;
407408
let b = bits % BLOCK_SIZE;
408409
assert_eq!(a as usize as u64, a);

src/librustc/mir/interpret/value.rs

+10-10
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#![allow(unknown_lints)]
22

3-
use ty::layout::{Align, HasDataLayout};
3+
use ty::layout::{Align, HasDataLayout, Size};
44
use ty;
55

66
use super::{EvalResult, MemoryPointer, PointerArithmetic, Allocation};
@@ -14,7 +14,7 @@ pub enum ConstValue<'tcx> {
1414
/// Used only for types with layout::abi::ScalarPair
1515
ByValPair(PrimVal, PrimVal),
1616
/// Used only for the remaining cases. An allocation + offset into the allocation
17-
ByRef(&'tcx Allocation, u64),
17+
ByRef(&'tcx Allocation, Size),
1818
}
1919

2020
impl<'tcx> ConstValue<'tcx> {
@@ -129,13 +129,13 @@ impl<'tcx> Pointer {
129129
}
130130
}
131131

132-
pub fn offset<C: HasDataLayout>(self, i: u64, cx: C) -> EvalResult<'tcx, Self> {
132+
pub fn offset<C: HasDataLayout>(self, i: Size, cx: C) -> EvalResult<'tcx, Self> {
133133
let layout = cx.data_layout();
134134
match self.primval {
135135
PrimVal::Bytes(b) => {
136136
assert_eq!(b as u64 as u128, b);
137137
Ok(Pointer::from(
138-
PrimVal::Bytes(layout.offset(b as u64, i)? as u128),
138+
PrimVal::Bytes(layout.offset(b as u64, i.bytes())? as u128),
139139
))
140140
}
141141
PrimVal::Ptr(ptr) => ptr.offset(i, layout).map(Pointer::from),
@@ -336,25 +336,25 @@ impl PrimValKind {
336336
}
337337
}
338338

339-
pub fn from_uint_size(size: u64) -> Self {
340-
match size {
339+
pub fn from_uint_size(size: Size) -> Self {
340+
match size.bytes() {
341341
1 => PrimValKind::U8,
342342
2 => PrimValKind::U16,
343343
4 => PrimValKind::U32,
344344
8 => PrimValKind::U64,
345345
16 => PrimValKind::U128,
346-
_ => bug!("can't make uint with size {}", size),
346+
_ => bug!("can't make uint with size {}", size.bytes()),
347347
}
348348
}
349349

350-
pub fn from_int_size(size: u64) -> Self {
351-
match size {
350+
pub fn from_int_size(size: Size) -> Self {
351+
match size.bytes() {
352352
1 => PrimValKind::I8,
353353
2 => PrimValKind::I16,
354354
4 => PrimValKind::I32,
355355
8 => PrimValKind::I64,
356356
16 => PrimValKind::I128,
357-
_ => bug!("can't make int with size {}", size),
357+
_ => bug!("can't make int with size {}", size.bytes()),
358358
}
359359
}
360360

src/librustc/mir/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1913,7 +1913,7 @@ pub fn print_miri_value<W: Write>(value: Value, ty: Ty, f: &mut W) -> fmt::Resul
19131913
.get_alloc(ptr.alloc_id);
19141914
if let Some(alloc) = alloc {
19151915
assert_eq!(len as usize as u128, len);
1916-
let slice = &alloc.bytes[(ptr.offset as usize)..][..(len as usize)];
1916+
let slice = &alloc.bytes[(ptr.offset.bytes() as usize)..][..(len as usize)];
19171917
let s = ::std::str::from_utf8(slice)
19181918
.expect("non utf8 str from miri");
19191919
write!(f, "{:?}", s)

src/librustc_codegen_llvm/mir/constant.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use rustc::mir;
1616
use rustc_data_structures::indexed_vec::Idx;
1717
use rustc::mir::interpret::{GlobalId, MemoryPointer, PrimVal, Allocation, ConstValue};
1818
use rustc::ty::{self, Ty};
19-
use rustc::ty::layout::{self, HasDataLayout, LayoutOf, Scalar};
19+
use rustc::ty::layout::{self, HasDataLayout, LayoutOf, Scalar, Size};
2020
use builder::Builder;
2121
use common::{CodegenCx};
2222
use common::{C_bytes, C_struct, C_uint_big, C_undef, C_usize};
@@ -68,7 +68,7 @@ pub fn primval_to_llvm(cx: &CodegenCx,
6868

6969
let llval = unsafe { llvm::LLVMConstInBoundsGEP(
7070
consts::bitcast(base_addr, Type::i8p(cx)),
71-
&C_usize(cx, ptr.offset),
71+
&C_usize(cx, ptr.offset.bytes()),
7272
1,
7373
) };
7474
if scalar.value != layout::Pointer {
@@ -88,6 +88,7 @@ pub fn const_alloc_to_llvm(cx: &CodegenCx, alloc: &Allocation) -> ValueRef {
8888

8989
let mut next_offset = 0;
9090
for (&offset, &alloc_id) in &alloc.relocations {
91+
let offset = offset.bytes();
9192
assert_eq!(offset as usize as u64, offset);
9293
let offset = offset as usize;
9394
if offset > next_offset {
@@ -99,7 +100,7 @@ pub fn const_alloc_to_llvm(cx: &CodegenCx, alloc: &Allocation) -> ValueRef {
99100
).expect("const_alloc_to_llvm: could not read relocation pointer") as u64;
100101
llvals.push(primval_to_llvm(
101102
cx,
102-
PrimVal::Ptr(MemoryPointer { alloc_id, offset: ptr_offset }),
103+
PrimVal::Ptr(MemoryPointer { alloc_id, offset: Size::from_bytes(ptr_offset) }),
103104
&Scalar {
104105
value: layout::Primitive::Pointer,
105106
valid_range: 0..=!0
@@ -129,7 +130,7 @@ pub fn codegen_static_initializer<'a, 'tcx>(
129130
let static_ = cx.tcx.const_eval(param_env.and(cid))?;
130131

131132
let alloc = match static_.val {
132-
ConstVal::Value(ConstValue::ByRef(alloc, 0)) => alloc,
133+
ConstVal::Value(ConstValue::ByRef(alloc, n)) if n.bytes() == 0 => alloc,
133134
_ => bug!("static const eval returned {:#?}", static_),
134135
};
135136
Ok(const_alloc_to_llvm(cx, alloc))

src/librustc_codegen_llvm/mir/operand.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ impl<'a, 'tcx> OperandRef<'tcx> {
143143

144144
let llval = unsafe { LLVMConstInBoundsGEP(
145145
consts::bitcast(base_addr, Type::i8p(bx.cx)),
146-
&C_usize(bx.cx, offset),
146+
&C_usize(bx.cx, offset.bytes()),
147147
1,
148148
)};
149149
let llval = consts::bitcast(llval, layout.llvm_type(bx.cx).ptr_to());

0 commit comments

Comments
 (0)