Skip to content

Commit 752accf

Browse files
authored
Merge pull request #434 from solson/rustup
rustup for big refactor; kill most of validation
2 parents 66ca0fb + 2a244dc commit 752accf

29 files changed

+746
-2194
lines changed

rust-toolchain

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
nightly-2018-08-14
1+
nightly-2018-08-30

src/fn_call.rs

Lines changed: 207 additions & 278 deletions
Large diffs are not rendered by default.

src/helpers.rs

Lines changed: 52 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -1,128 +1,71 @@
1-
use mir;
2-
use rustc::ty::Ty;
3-
use rustc::ty::layout::{LayoutOf, Size};
1+
use rustc::ty::layout::Size;
42

5-
use super::{Scalar, ScalarExt, EvalResult, EvalContext, ValTy};
6-
use rustc_mir::interpret::sign_extend;
3+
use super::{Scalar, ScalarMaybeUndef, EvalResult};
74

8-
pub trait EvalContextExt<'tcx> {
9-
fn wrapping_pointer_offset(
10-
&self,
11-
ptr: Scalar,
12-
pointee_ty: Ty<'tcx>,
13-
offset: i64,
14-
) -> EvalResult<'tcx, Scalar>;
15-
16-
fn pointer_offset(
17-
&self,
18-
ptr: Scalar,
19-
pointee_ty: Ty<'tcx>,
20-
offset: i64,
21-
) -> EvalResult<'tcx, Scalar>;
22-
23-
fn value_to_isize(
24-
&self,
25-
value: ValTy<'tcx>,
26-
) -> EvalResult<'tcx, i64>;
5+
pub trait ScalarExt {
6+
fn null(size: Size) -> Self;
7+
fn from_i32(i: i32) -> Self;
8+
fn from_uint(i: impl Into<u128>, ptr_size: Size) -> Self;
9+
fn from_int(i: impl Into<i128>, ptr_size: Size) -> Self;
10+
fn from_f32(f: f32) -> Self;
11+
fn from_f64(f: f64) -> Self;
12+
fn is_null(self) -> bool;
13+
}
2714

28-
fn value_to_usize(
29-
&self,
30-
value: ValTy<'tcx>,
31-
) -> EvalResult<'tcx, u64>;
15+
pub trait FalibleScalarExt {
16+
/// HACK: this function just extracts all bits if `defined != 0`
17+
/// Mainly used for args of C-functions and we should totally correctly fetch the size
18+
/// of their arguments
19+
fn to_bytes(self) -> EvalResult<'static, u128>;
20+
}
3221

33-
fn value_to_i32(
34-
&self,
35-
value: ValTy<'tcx>,
36-
) -> EvalResult<'tcx, i32>;
22+
impl ScalarExt for Scalar {
23+
fn null(size: Size) -> Self {
24+
Scalar::Bits { bits: 0, size: size.bytes() as u8 }
25+
}
3726

38-
fn value_to_u8(
39-
&self,
40-
value: ValTy<'tcx>,
41-
) -> EvalResult<'tcx, u8>;
42-
}
27+
fn from_i32(i: i32) -> Self {
28+
Scalar::Bits { bits: i as u32 as u128, size: 4 }
29+
}
4330

44-
impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for EvalContext<'a, 'mir, 'tcx, super::Evaluator<'tcx>> {
45-
fn wrapping_pointer_offset(
46-
&self,
47-
ptr: Scalar,
48-
pointee_ty: Ty<'tcx>,
49-
offset: i64,
50-
) -> EvalResult<'tcx, Scalar> {
51-
// FIXME: assuming here that type size is < i64::max_value()
52-
let pointee_size = self.layout_of(pointee_ty)?.size.bytes() as i64;
53-
let offset = offset.overflowing_mul(pointee_size).0;
54-
Ok(ptr.ptr_wrapping_signed_offset(offset, self))
31+
fn from_uint(i: impl Into<u128>, size: Size) -> Self {
32+
Scalar::Bits { bits: i.into(), size: size.bytes() as u8 }
5533
}
5634

57-
fn pointer_offset(
58-
&self,
59-
ptr: Scalar,
60-
pointee_ty: Ty<'tcx>,
61-
offset: i64,
62-
) -> EvalResult<'tcx, Scalar> {
63-
// This function raises an error if the offset moves the pointer outside of its allocation. We consider
64-
// ZSTs their own huge allocation that doesn't overlap with anything (and nothing moves in there because the size is 0).
65-
// We also consider the NULL pointer its own separate allocation, and all the remaining integers pointers their own
66-
// allocation.
35+
fn from_int(i: impl Into<i128>, size: Size) -> Self {
36+
Scalar::Bits { bits: i.into() as u128, size: size.bytes() as u8 }
37+
}
6738

68-
if ptr.is_null() {
69-
// NULL pointers must only be offset by 0
70-
return if offset == 0 {
71-
Ok(ptr)
72-
} else {
73-
err!(InvalidNullPointerUsage)
74-
};
75-
}
76-
// FIXME: assuming here that type size is < i64::max_value()
77-
let pointee_size = self.layout_of(pointee_ty)?.size.bytes() as i64;
78-
if let Some(offset) = offset.checked_mul(pointee_size) {
79-
let ptr = ptr.ptr_signed_offset(offset, self)?;
80-
// Do not do bounds-checking for integers; they can never alias a normal pointer anyway.
81-
if let Scalar::Ptr(ptr) = ptr {
82-
self.memory.check_bounds(ptr, false)?;
83-
} else if ptr.is_null() {
84-
// We moved *to* a NULL pointer. That seems wrong, LLVM considers the NULL pointer its own small allocation. Reject this, for now.
85-
return err!(InvalidNullPointerUsage);
86-
}
87-
Ok(ptr)
88-
} else {
89-
err!(Overflow(mir::BinOp::Mul))
90-
}
39+
fn from_f32(f: f32) -> Self {
40+
Scalar::Bits { bits: f.to_bits() as u128, size: 4 }
9141
}
9242

93-
fn value_to_isize(
94-
&self,
95-
value: ValTy<'tcx>,
96-
) -> EvalResult<'tcx, i64> {
97-
assert_eq!(value.ty, self.tcx.types.isize);
98-
let raw = self.value_to_scalar(value)?.to_bits(self.memory.pointer_size())?;
99-
let raw = sign_extend(raw, self.layout_of(self.tcx.types.isize).unwrap());
100-
Ok(raw as i64)
43+
fn from_f64(f: f64) -> Self {
44+
Scalar::Bits { bits: f.to_bits() as u128, size: 8 }
10145
}
10246

103-
fn value_to_usize(
104-
&self,
105-
value: ValTy<'tcx>,
106-
) -> EvalResult<'tcx, u64> {
107-
assert_eq!(value.ty, self.tcx.types.usize);
108-
self.value_to_scalar(value)?.to_bits(self.memory.pointer_size()).map(|v| v as u64)
47+
fn is_null(self) -> bool {
48+
match self {
49+
Scalar::Bits { bits, .. } => bits == 0,
50+
Scalar::Ptr(_) => false
51+
}
10952
}
53+
}
11054

111-
fn value_to_i32(
112-
&self,
113-
value: ValTy<'tcx>,
114-
) -> EvalResult<'tcx, i32> {
115-
assert_eq!(value.ty, self.tcx.types.i32);
116-
let raw = self.value_to_scalar(value)?.to_bits(Size::from_bits(32))?;
117-
let raw = sign_extend(raw, self.layout_of(self.tcx.types.i32).unwrap());
118-
Ok(raw as i32)
55+
impl FalibleScalarExt for Scalar {
56+
fn to_bytes(self) -> EvalResult<'static, u128> {
57+
match self {
58+
Scalar::Bits { bits, size } => {
59+
assert_ne!(size, 0);
60+
Ok(bits)
61+
},
62+
Scalar::Ptr(_) => err!(ReadPointerAsBytes),
63+
}
11964
}
65+
}
12066

121-
fn value_to_u8(
122-
&self,
123-
value: ValTy<'tcx>,
124-
) -> EvalResult<'tcx, u8> {
125-
assert_eq!(value.ty, self.tcx.types.u8);
126-
self.value_to_scalar(value)?.to_bits(Size::from_bits(8)).map(|v| v as u8)
67+
impl FalibleScalarExt for ScalarMaybeUndef {
68+
fn to_bytes(self) -> EvalResult<'static, u128> {
69+
self.not_undef()?.to_bytes()
12770
}
12871
}

0 commit comments

Comments
 (0)