|
1 | 1 | use std::convert::TryFrom;
|
| 2 | +use std::fmt; |
2 | 3 |
|
3 | 4 | use rustc_apfloat::{
|
4 | 5 | ieee::{Double, Single},
|
5 | 6 | Float,
|
6 | 7 | };
|
7 | 8 | use rustc_macros::HashStable;
|
8 |
| -use std::fmt; |
| 9 | +use rustc_target::abi::TargetDataLayout; |
9 | 10 |
|
10 | 11 | use crate::ty::{
|
11 | 12 | layout::{HasDataLayout, Size},
|
@@ -200,68 +201,54 @@ impl<'tcx, Tag> Scalar<Tag> {
|
200 | 201 | Scalar::Raw { data: 0, size: 0 }
|
201 | 202 | }
|
202 | 203 |
|
203 |
| - #[inline] |
204 |
| - pub fn ptr_offset(self, i: Size, cx: &impl HasDataLayout) -> InterpResult<'tcx, Self> { |
205 |
| - let dl = cx.data_layout(); |
| 204 | + #[inline(always)] |
| 205 | + fn ptr_op( |
| 206 | + self, |
| 207 | + dl: &TargetDataLayout, |
| 208 | + f_int: impl FnOnce(u64) -> InterpResult<'tcx, u64>, |
| 209 | + f_ptr: impl FnOnce(Pointer<Tag>) -> InterpResult<'tcx, Pointer<Tag>>, |
| 210 | + ) -> InterpResult<'tcx, Self> { |
206 | 211 | match self {
|
207 | 212 | Scalar::Raw { data, size } => {
|
208 | 213 | assert_eq!(u64::from(size), dl.pointer_size.bytes());
|
209 |
| - Ok(Scalar::Raw { |
210 |
| - data: u128::from(dl.offset(u64::try_from(data).unwrap(), i.bytes())?), |
211 |
| - size, |
212 |
| - }) |
| 214 | + Ok(Scalar::Raw { data: u128::from(f_int(u64::try_from(data).unwrap())?), size }) |
213 | 215 | }
|
214 |
| - Scalar::Ptr(ptr) => ptr.offset(i, dl).map(Scalar::Ptr), |
| 216 | + Scalar::Ptr(ptr) => Ok(Scalar::Ptr(f_ptr(ptr)?)), |
215 | 217 | }
|
216 | 218 | }
|
217 | 219 |
|
| 220 | + #[inline] |
| 221 | + pub fn ptr_offset(self, i: Size, cx: &impl HasDataLayout) -> InterpResult<'tcx, Self> { |
| 222 | + let dl = cx.data_layout(); |
| 223 | + self.ptr_op(dl, |int| dl.offset(int, i.bytes()), |ptr| ptr.offset(i, dl)) |
| 224 | + } |
| 225 | + |
218 | 226 | #[inline]
|
219 | 227 | pub fn ptr_wrapping_offset(self, i: Size, cx: &impl HasDataLayout) -> Self {
|
220 | 228 | let dl = cx.data_layout();
|
221 |
| - match self { |
222 |
| - Scalar::Raw { data, size } => { |
223 |
| - assert_eq!(u64::from(size), dl.pointer_size.bytes()); |
224 |
| - Scalar::Raw { |
225 |
| - data: u128::from( |
226 |
| - dl.overflowing_offset(u64::try_from(data).unwrap(), i.bytes()).0, |
227 |
| - ), |
228 |
| - size, |
229 |
| - } |
230 |
| - } |
231 |
| - Scalar::Ptr(ptr) => Scalar::Ptr(ptr.wrapping_offset(i, dl)), |
232 |
| - } |
| 229 | + self.ptr_op( |
| 230 | + dl, |
| 231 | + |int| Ok(dl.overflowing_offset(int, i.bytes()).0), |
| 232 | + |ptr| Ok(ptr.wrapping_offset(i, dl)), |
| 233 | + ) |
| 234 | + .unwrap() |
233 | 235 | }
|
234 | 236 |
|
235 | 237 | #[inline]
|
236 | 238 | pub fn ptr_signed_offset(self, i: i64, cx: &impl HasDataLayout) -> InterpResult<'tcx, Self> {
|
237 | 239 | let dl = cx.data_layout();
|
238 |
| - match self { |
239 |
| - Scalar::Raw { data, size } => { |
240 |
| - assert_eq!(u64::from(size), dl.pointer_size.bytes()); |
241 |
| - Ok(Scalar::Raw { |
242 |
| - data: u128::from(dl.signed_offset(u64::try_from(data).unwrap(), i)?), |
243 |
| - size, |
244 |
| - }) |
245 |
| - } |
246 |
| - Scalar::Ptr(ptr) => ptr.signed_offset(i, dl).map(Scalar::Ptr), |
247 |
| - } |
| 240 | + self.ptr_op(dl, |int| dl.signed_offset(int, i), |ptr| ptr.signed_offset(i, dl)) |
248 | 241 | }
|
249 | 242 |
|
250 | 243 | #[inline]
|
251 | 244 | pub fn ptr_wrapping_signed_offset(self, i: i64, cx: &impl HasDataLayout) -> Self {
|
252 | 245 | let dl = cx.data_layout();
|
253 |
| - match self { |
254 |
| - Scalar::Raw { data, size } => { |
255 |
| - assert_eq!(u64::from(size), dl.pointer_size.bytes()); |
256 |
| - Scalar::Raw { |
257 |
| - data: u128::from( |
258 |
| - dl.overflowing_signed_offset(u64::try_from(data).unwrap(), i128::from(i)).0, |
259 |
| - ), |
260 |
| - size, |
261 |
| - } |
262 |
| - } |
263 |
| - Scalar::Ptr(ptr) => Scalar::Ptr(ptr.wrapping_signed_offset(i, dl)), |
264 |
| - } |
| 246 | + self.ptr_op( |
| 247 | + dl, |
| 248 | + |int| Ok(dl.overflowing_signed_offset(int, i).0), |
| 249 | + |ptr| Ok(ptr.wrapping_signed_offset(i, dl)), |
| 250 | + ) |
| 251 | + .unwrap() |
265 | 252 | }
|
266 | 253 |
|
267 | 254 | #[inline]
|
|
0 commit comments