Skip to content

Commit 674ef66

Browse files
committed
Auto merge of #53424 - RalfJung:miri-refactor, r=oli-obk
CTFE engine refactor * Value gets renamed to `Operand`, so that now `interpret::{Place, Operand}` are the "dynamic" versions of `mir::{Place, Operand}`. * `Operand` and `Place` share the data for their "stuff is in memory"-base in a new type, `MemPlace`. This also makes it possible to give some more precise types in other areas. Both `Operand` and `MemPlace` have methods available to project into fields (and other kinds of projections) without causing further allocations. * The type for "a `Scalar` or a `ScalarPair`" is called `Value`, and again used to give some more precise types. * All of these have versions with an attached layout, so that we can more often drag the layout along instead of recomputing it. This lets us get rid of `PlaceExtra::Downcast`. `MPlaceTy` and `PlaceTy` can only be constructed in place.rs, making sure the layout is handled properly. (The same should eventually be done for `ValTy` and `OpTy`.) This is used to check, when copying an operand to a place, that the sizes match (which caught a bunch of bugs). * All the high-level functions to write typed memory take a `Place`, and live in `place.rs`. All the high-level typed functions to read typed memory take an `Operand`, and live in `operands.rs`. * Remove `cur_frame` and handling of signedess from memory (catching a bug in the float casting code). * [Only functional change] Enable sanity check to recurse below dyn traits and slices. r? @oli-obk Cc @eddyb
2 parents 71a1ef1 + 4fec615 commit 674ef66

39 files changed

+2827
-2444
lines changed

src/librustc/dep_graph/dep_node.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,7 @@ define_dep_nodes!( <'tcx>
632632
// queries). Making them anonymous avoids hashing the result, which
633633
// may save a bit of time.
634634
[anon] EraseRegionsTy { ty: Ty<'tcx> },
635-
[anon] ConstValueToAllocation { val: &'tcx ty::Const<'tcx> },
635+
[anon] ConstToAllocation { val: &'tcx ty::Const<'tcx> },
636636

637637
[input] Freevars(DefId),
638638
[input] MaybeUnusedTraitImport(DefId),

src/librustc/ich/impls_ty.rs

-6
Original file line numberDiff line numberDiff line change
@@ -397,12 +397,6 @@ impl_stable_hash_for!(enum mir::interpret::ScalarMaybeUndef {
397397
Undef
398398
});
399399

400-
impl_stable_hash_for!(enum mir::interpret::Value {
401-
Scalar(v),
402-
ScalarPair(a, b),
403-
ByRef(ptr, align)
404-
});
405-
406400
impl_stable_hash_for!(struct mir::interpret::Pointer {
407401
alloc_id,
408402
offset

src/librustc/mir/interpret/mod.rs

+23-15
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ pub use self::error::{
1313
FrameInfo, ConstEvalResult,
1414
};
1515

16-
pub use self::value::{Scalar, Value, ConstValue, ScalarMaybeUndef};
16+
pub use self::value::{Scalar, ConstValue, ScalarMaybeUndef};
1717

1818
use std::fmt;
1919
use mir;
@@ -135,7 +135,7 @@ impl<'tcx> Pointer {
135135
Pointer { alloc_id, offset }
136136
}
137137

138-
pub(crate) fn wrapping_signed_offset<C: HasDataLayout>(self, i: i64, cx: C) -> Self {
138+
pub fn wrapping_signed_offset<C: HasDataLayout>(self, i: i64, cx: C) -> Self {
139139
Pointer::new(
140140
self.alloc_id,
141141
Size::from_bytes(cx.data_layout().wrapping_signed_offset(self.offset.bytes(), i)),
@@ -147,7 +147,7 @@ impl<'tcx> Pointer {
147147
(Pointer::new(self.alloc_id, Size::from_bytes(res)), over)
148148
}
149149

150-
pub(crate) fn signed_offset<C: HasDataLayout>(self, i: i64, cx: C) -> EvalResult<'tcx, Self> {
150+
pub fn signed_offset<C: HasDataLayout>(self, i: i64, cx: C) -> EvalResult<'tcx, Self> {
151151
Ok(Pointer::new(
152152
self.alloc_id,
153153
Size::from_bytes(cx.data_layout().signed_offset(self.offset.bytes(), i)?),
@@ -567,25 +567,33 @@ pub fn write_target_uint(
567567
}
568568
}
569569

570-
pub fn write_target_int(
571-
endianness: layout::Endian,
572-
mut target: &mut [u8],
573-
data: i128,
574-
) -> Result<(), io::Error> {
575-
let len = target.len();
576-
match endianness {
577-
layout::Endian::Little => target.write_int128::<LittleEndian>(data, len),
578-
layout::Endian::Big => target.write_int128::<BigEndian>(data, len),
579-
}
580-
}
581-
582570
pub fn read_target_uint(endianness: layout::Endian, mut source: &[u8]) -> Result<u128, io::Error> {
583571
match endianness {
584572
layout::Endian::Little => source.read_uint128::<LittleEndian>(source.len()),
585573
layout::Endian::Big => source.read_uint128::<BigEndian>(source.len()),
586574
}
587575
}
588576

577+
////////////////////////////////////////////////////////////////////////////////
578+
// Methods to faciliate working with signed integers stored in a u128
579+
////////////////////////////////////////////////////////////////////////////////
580+
581+
pub fn sign_extend(value: u128, size: Size) -> u128 {
582+
let size = size.bits();
583+
// sign extend
584+
let shift = 128 - size;
585+
// shift the unsigned value to the left
586+
// and back to the right as signed (essentially fills with FF on the left)
587+
(((value << shift) as i128) >> shift) as u128
588+
}
589+
590+
pub fn truncate(value: u128, size: Size) -> u128 {
591+
let size = size.bits();
592+
let shift = 128 - size;
593+
// truncate (shift left to drop out leftover values, shift right to fill with zeroes)
594+
(value << shift) >> shift
595+
}
596+
589597
////////////////////////////////////////////////////////////////////////////////
590598
// Undefined byte tracking
591599
////////////////////////////////////////////////////////////////////////////////

0 commit comments

Comments
 (0)