|
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