mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 07:14:28 +00:00
Auto merge of #3636 - RalfJung:provenance-type-aliases, r=RalfJung
avoid repeating the Provenance parameter everywhere
This commit is contained in:
commit
2c1a5a7e91
@ -257,7 +257,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn ptr_from_addr_cast(&self, addr: u64) -> InterpResult<'tcx, Pointer<Option<Provenance>>> {
|
||||
fn ptr_from_addr_cast(&self, addr: u64) -> InterpResult<'tcx, Pointer> {
|
||||
trace!("Casting {:#x} to a pointer", addr);
|
||||
|
||||
let ecx = self.eval_context_ref();
|
||||
@ -297,10 +297,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
/// Convert a relative (tcx) pointer to a Miri pointer.
|
||||
fn adjust_alloc_root_pointer(
|
||||
&self,
|
||||
ptr: Pointer<CtfeProvenance>,
|
||||
ptr: interpret::Pointer<CtfeProvenance>,
|
||||
tag: BorTag,
|
||||
kind: MemoryKind,
|
||||
) -> InterpResult<'tcx, Pointer<Provenance>> {
|
||||
) -> InterpResult<'tcx, interpret::Pointer<Provenance>> {
|
||||
let ecx = self.eval_context_ref();
|
||||
|
||||
let (prov, offset) = ptr.into_parts(); // offset is relative (AllocId provenance)
|
||||
@ -310,12 +310,15 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
// Add offset with the right kind of pointer-overflowing arithmetic.
|
||||
let dl = ecx.data_layout();
|
||||
let absolute_addr = dl.overflowing_offset(base_addr, offset.bytes()).0;
|
||||
Ok(Pointer::new(Provenance::Concrete { alloc_id, tag }, Size::from_bytes(absolute_addr)))
|
||||
Ok(interpret::Pointer::new(
|
||||
Provenance::Concrete { alloc_id, tag },
|
||||
Size::from_bytes(absolute_addr),
|
||||
))
|
||||
}
|
||||
|
||||
/// When a pointer is used for a memory access, this computes where in which allocation the
|
||||
/// access is going.
|
||||
fn ptr_get_alloc(&self, ptr: Pointer<Provenance>) -> Option<(AllocId, Size)> {
|
||||
fn ptr_get_alloc(&self, ptr: interpret::Pointer<Provenance>) -> Option<(AllocId, Size)> {
|
||||
let ecx = self.eval_context_ref();
|
||||
|
||||
let (tag, addr) = ptr.into_parts(); // addr is absolute (Tag provenance)
|
||||
|
@ -281,8 +281,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
fn retag_ptr_value(
|
||||
&mut self,
|
||||
kind: RetagKind,
|
||||
val: &ImmTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, ImmTy<'tcx, Provenance>> {
|
||||
val: &ImmTy<'tcx>,
|
||||
) -> InterpResult<'tcx, ImmTy<'tcx>> {
|
||||
let this = self.eval_context_mut();
|
||||
let method = this.machine.borrow_tracker.as_ref().unwrap().borrow().borrow_tracker_method;
|
||||
match method {
|
||||
@ -294,7 +294,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
fn retag_place_contents(
|
||||
&mut self,
|
||||
kind: RetagKind,
|
||||
place: &PlaceTy<'tcx, Provenance>,
|
||||
place: &PlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
let method = this.machine.borrow_tracker.as_ref().unwrap().borrow().borrow_tracker_method;
|
||||
@ -304,10 +304,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn protect_place(
|
||||
&mut self,
|
||||
place: &MPlaceTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, MPlaceTy<'tcx, Provenance>> {
|
||||
fn protect_place(&mut self, place: &MPlaceTy<'tcx>) -> InterpResult<'tcx, MPlaceTy<'tcx>> {
|
||||
let this = self.eval_context_mut();
|
||||
let method = this.machine.borrow_tracker.as_ref().unwrap().borrow().borrow_tracker_method;
|
||||
match method {
|
||||
@ -327,7 +324,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
|
||||
fn give_pointer_debug_name(
|
||||
&mut self,
|
||||
ptr: Pointer<Option<Provenance>>,
|
||||
ptr: Pointer,
|
||||
nth_parent: u8,
|
||||
name: &str,
|
||||
) -> InterpResult<'tcx> {
|
||||
|
@ -531,7 +531,7 @@ impl Stacks {
|
||||
trace!(
|
||||
"read access with tag {:?}: {:?}, size {}",
|
||||
tag,
|
||||
Pointer::new(alloc_id, range.start),
|
||||
interpret::Pointer::new(alloc_id, range.start),
|
||||
range.size.bytes()
|
||||
);
|
||||
let dcx = DiagnosticCxBuilder::read(machine, tag, range);
|
||||
@ -552,7 +552,7 @@ impl Stacks {
|
||||
trace!(
|
||||
"write access with tag {:?}: {:?}, size {}",
|
||||
tag,
|
||||
Pointer::new(alloc_id, range.start),
|
||||
interpret::Pointer::new(alloc_id, range.start),
|
||||
range.size.bytes()
|
||||
);
|
||||
let dcx = DiagnosticCxBuilder::write(machine, tag, range);
|
||||
@ -587,7 +587,7 @@ trait EvalContextPrivExt<'tcx, 'ecx>: crate::MiriInterpCxExt<'tcx> {
|
||||
/// Returns the provenance that should be used henceforth.
|
||||
fn sb_reborrow(
|
||||
&mut self,
|
||||
place: &MPlaceTy<'tcx, Provenance>,
|
||||
place: &MPlaceTy<'tcx>,
|
||||
size: Size,
|
||||
new_perm: NewPermission,
|
||||
new_tag: BorTag,
|
||||
@ -692,7 +692,7 @@ trait EvalContextPrivExt<'tcx, 'ecx>: crate::MiriInterpCxExt<'tcx> {
|
||||
new_tag,
|
||||
orig_tag,
|
||||
place.layout.ty,
|
||||
Pointer::new(alloc_id, base_offset),
|
||||
interpret::Pointer::new(alloc_id, base_offset),
|
||||
size.bytes()
|
||||
);
|
||||
|
||||
@ -809,10 +809,10 @@ trait EvalContextPrivExt<'tcx, 'ecx>: crate::MiriInterpCxExt<'tcx> {
|
||||
|
||||
fn sb_retag_place(
|
||||
&mut self,
|
||||
place: &MPlaceTy<'tcx, Provenance>,
|
||||
place: &MPlaceTy<'tcx>,
|
||||
new_perm: NewPermission,
|
||||
info: RetagInfo, // diagnostics info about this retag
|
||||
) -> InterpResult<'tcx, MPlaceTy<'tcx, Provenance>> {
|
||||
) -> InterpResult<'tcx, MPlaceTy<'tcx>> {
|
||||
let this = self.eval_context_mut();
|
||||
let size = this.size_and_align_of_mplace(place)?.map(|(size, _)| size);
|
||||
// FIXME: If we cannot determine the size (because the unsized tail is an `extern type`),
|
||||
@ -839,10 +839,10 @@ trait EvalContextPrivExt<'tcx, 'ecx>: crate::MiriInterpCxExt<'tcx> {
|
||||
/// `kind` indicates what kind of reference is being created.
|
||||
fn sb_retag_reference(
|
||||
&mut self,
|
||||
val: &ImmTy<'tcx, Provenance>,
|
||||
val: &ImmTy<'tcx>,
|
||||
new_perm: NewPermission,
|
||||
info: RetagInfo, // diagnostics info about this retag
|
||||
) -> InterpResult<'tcx, ImmTy<'tcx, Provenance>> {
|
||||
) -> InterpResult<'tcx, ImmTy<'tcx>> {
|
||||
let this = self.eval_context_mut();
|
||||
let place = this.ref_to_mplace(val)?;
|
||||
let new_place = this.sb_retag_place(&place, new_perm, info)?;
|
||||
@ -855,8 +855,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
fn sb_retag_ptr_value(
|
||||
&mut self,
|
||||
kind: RetagKind,
|
||||
val: &ImmTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, ImmTy<'tcx, Provenance>> {
|
||||
val: &ImmTy<'tcx>,
|
||||
) -> InterpResult<'tcx, ImmTy<'tcx>> {
|
||||
let this = self.eval_context_mut();
|
||||
let new_perm = NewPermission::from_ref_ty(val.layout.ty, kind, this);
|
||||
let cause = match kind {
|
||||
@ -870,7 +870,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
fn sb_retag_place_contents(
|
||||
&mut self,
|
||||
kind: RetagKind,
|
||||
place: &PlaceTy<'tcx, Provenance>,
|
||||
place: &PlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
let retag_fields = this.machine.borrow_tracker.as_mut().unwrap().get_mut().retag_fields;
|
||||
@ -895,7 +895,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
#[inline(always)] // yes this helps in our benchmarks
|
||||
fn retag_ptr_inplace(
|
||||
&mut self,
|
||||
place: &PlaceTy<'tcx, Provenance>,
|
||||
place: &PlaceTy<'tcx>,
|
||||
new_perm: NewPermission,
|
||||
) -> InterpResult<'tcx> {
|
||||
let val = self.ecx.read_immediate(&self.ecx.place_to_op(place)?)?;
|
||||
@ -909,18 +909,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
}
|
||||
}
|
||||
impl<'ecx, 'tcx> ValueVisitor<'tcx, MiriMachine<'tcx>> for RetagVisitor<'ecx, 'tcx> {
|
||||
type V = PlaceTy<'tcx, Provenance>;
|
||||
type V = PlaceTy<'tcx>;
|
||||
|
||||
#[inline(always)]
|
||||
fn ecx(&self) -> &MiriInterpCx<'tcx> {
|
||||
self.ecx
|
||||
}
|
||||
|
||||
fn visit_box(
|
||||
&mut self,
|
||||
box_ty: Ty<'tcx>,
|
||||
place: &PlaceTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx> {
|
||||
fn visit_box(&mut self, box_ty: Ty<'tcx>, place: &PlaceTy<'tcx>) -> InterpResult<'tcx> {
|
||||
// Only boxes for the global allocator get any special treatment.
|
||||
if box_ty.is_box_global(*self.ecx.tcx) {
|
||||
// Boxes get a weak protectors, since they may be deallocated.
|
||||
@ -930,7 +926,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn visit_value(&mut self, place: &PlaceTy<'tcx, Provenance>) -> InterpResult<'tcx> {
|
||||
fn visit_value(&mut self, place: &PlaceTy<'tcx>) -> InterpResult<'tcx> {
|
||||
// If this place is smaller than a pointer, we know that it can't contain any
|
||||
// pointers we need to retag, so we can stop recursion early.
|
||||
// This optimization is crucial for ZSTs, because they can contain way more fields
|
||||
@ -984,10 +980,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
/// call.
|
||||
///
|
||||
/// This is used to ensure soundness of in-place function argument/return passing.
|
||||
fn sb_protect_place(
|
||||
&mut self,
|
||||
place: &MPlaceTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, MPlaceTy<'tcx, Provenance>> {
|
||||
fn sb_protect_place(&mut self, place: &MPlaceTy<'tcx>) -> InterpResult<'tcx, MPlaceTy<'tcx>> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
// Retag it. With protection! That is the entire point.
|
||||
|
@ -56,7 +56,7 @@ impl<'tcx> Tree {
|
||||
"{} with tag {:?}: {:?}, size {}",
|
||||
access_kind,
|
||||
prov,
|
||||
Pointer::new(alloc_id, range.start),
|
||||
interpret::Pointer::new(alloc_id, range.start),
|
||||
range.size.bytes(),
|
||||
);
|
||||
// TODO: for now we bail out on wildcard pointers. Eventually we should
|
||||
@ -195,7 +195,7 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
/// Returns the provenance that should be used henceforth.
|
||||
fn tb_reborrow(
|
||||
&mut self,
|
||||
place: &MPlaceTy<'tcx, Provenance>, // parent tag extracted from here
|
||||
place: &MPlaceTy<'tcx>, // parent tag extracted from here
|
||||
ptr_size: Size,
|
||||
new_perm: NewPermission,
|
||||
new_tag: BorTag,
|
||||
@ -258,7 +258,7 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
new_tag,
|
||||
orig_tag,
|
||||
place.layout.ty,
|
||||
Pointer::new(alloc_id, base_offset),
|
||||
interpret::Pointer::new(alloc_id, base_offset),
|
||||
ptr_size.bytes()
|
||||
);
|
||||
|
||||
@ -327,9 +327,9 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
|
||||
fn tb_retag_place(
|
||||
&mut self,
|
||||
place: &MPlaceTy<'tcx, Provenance>,
|
||||
place: &MPlaceTy<'tcx>,
|
||||
new_perm: NewPermission,
|
||||
) -> InterpResult<'tcx, MPlaceTy<'tcx, Provenance>> {
|
||||
) -> InterpResult<'tcx, MPlaceTy<'tcx>> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
// Determine the size of the reborrow.
|
||||
@ -366,9 +366,9 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
/// Retags an individual pointer, returning the retagged version.
|
||||
fn tb_retag_reference(
|
||||
&mut self,
|
||||
val: &ImmTy<'tcx, Provenance>,
|
||||
val: &ImmTy<'tcx>,
|
||||
new_perm: NewPermission,
|
||||
) -> InterpResult<'tcx, ImmTy<'tcx, Provenance>> {
|
||||
) -> InterpResult<'tcx, ImmTy<'tcx>> {
|
||||
let this = self.eval_context_mut();
|
||||
let place = this.ref_to_mplace(val)?;
|
||||
let new_place = this.tb_retag_place(&place, new_perm)?;
|
||||
@ -383,8 +383,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
fn tb_retag_ptr_value(
|
||||
&mut self,
|
||||
kind: RetagKind,
|
||||
val: &ImmTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, ImmTy<'tcx, Provenance>> {
|
||||
val: &ImmTy<'tcx>,
|
||||
) -> InterpResult<'tcx, ImmTy<'tcx>> {
|
||||
let this = self.eval_context_mut();
|
||||
let new_perm = match val.layout.ty.kind() {
|
||||
&ty::Ref(_, pointee, mutability) =>
|
||||
@ -402,7 +402,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
fn tb_retag_place_contents(
|
||||
&mut self,
|
||||
kind: RetagKind,
|
||||
place: &PlaceTy<'tcx, Provenance>,
|
||||
place: &PlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
let options = this.machine.borrow_tracker.as_mut().unwrap().get_mut();
|
||||
@ -423,7 +423,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
#[inline(always)] // yes this helps in our benchmarks
|
||||
fn retag_ptr_inplace(
|
||||
&mut self,
|
||||
place: &PlaceTy<'tcx, Provenance>,
|
||||
place: &PlaceTy<'tcx>,
|
||||
new_perm: Option<NewPermission>,
|
||||
) -> InterpResult<'tcx> {
|
||||
if let Some(new_perm) = new_perm {
|
||||
@ -435,7 +435,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
}
|
||||
}
|
||||
impl<'ecx, 'tcx> ValueVisitor<'tcx, MiriMachine<'tcx>> for RetagVisitor<'ecx, 'tcx> {
|
||||
type V = PlaceTy<'tcx, Provenance>;
|
||||
type V = PlaceTy<'tcx>;
|
||||
|
||||
#[inline(always)]
|
||||
fn ecx(&self) -> &MiriInterpCx<'tcx> {
|
||||
@ -445,11 +445,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
/// Regardless of how `Unique` is handled, Boxes are always reborrowed.
|
||||
/// When `Unique` is also reborrowed, then it behaves exactly like `Box`
|
||||
/// except for the fact that `Box` has a non-zero-sized reborrow.
|
||||
fn visit_box(
|
||||
&mut self,
|
||||
box_ty: Ty<'tcx>,
|
||||
place: &PlaceTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx> {
|
||||
fn visit_box(&mut self, box_ty: Ty<'tcx>, place: &PlaceTy<'tcx>) -> InterpResult<'tcx> {
|
||||
// Only boxes for the global allocator get any special treatment.
|
||||
if box_ty.is_box_global(*self.ecx.tcx) {
|
||||
let new_perm = NewPermission::from_unique_ty(
|
||||
@ -463,7 +459,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn visit_value(&mut self, place: &PlaceTy<'tcx, Provenance>) -> InterpResult<'tcx> {
|
||||
fn visit_value(&mut self, place: &PlaceTy<'tcx>) -> InterpResult<'tcx> {
|
||||
// If this place is smaller than a pointer, we know that it can't contain any
|
||||
// pointers we need to retag, so we can stop recursion early.
|
||||
// This optimization is crucial for ZSTs, because they can contain way more fields
|
||||
@ -526,10 +522,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
/// call.
|
||||
///
|
||||
/// This is used to ensure soundness of in-place function argument/return passing.
|
||||
fn tb_protect_place(
|
||||
&mut self,
|
||||
place: &MPlaceTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, MPlaceTy<'tcx, Provenance>> {
|
||||
fn tb_protect_place(&mut self, place: &MPlaceTy<'tcx>) -> InterpResult<'tcx, MPlaceTy<'tcx>> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
// Retag it. With protection! That is the entire point.
|
||||
@ -581,7 +574,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
/// of `ptr` (with 0 representing `ptr` itself)
|
||||
fn tb_give_pointer_debug_name(
|
||||
&mut self,
|
||||
ptr: Pointer<Option<Provenance>>,
|
||||
ptr: Pointer,
|
||||
nth_parent: u8,
|
||||
name: &str,
|
||||
) -> InterpResult<'tcx> {
|
||||
@ -604,8 +597,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
/// and output can be used by `retag_ptr_inplace`.
|
||||
fn inner_ptr_of_unique<'tcx>(
|
||||
ecx: &MiriInterpCx<'tcx>,
|
||||
place: &PlaceTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, PlaceTy<'tcx, Provenance>> {
|
||||
place: &PlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx, PlaceTy<'tcx>> {
|
||||
// Follows the same layout as `interpret/visitor.rs:walk_value` for `Box` in
|
||||
// `rustc_const_eval`, just with one fewer layer.
|
||||
// Here we have a `Unique(NonNull(*mut), PhantomData)`
|
||||
|
@ -606,9 +606,9 @@ pub trait EvalContextExt<'tcx>: MiriInterpCxExt<'tcx> {
|
||||
/// Perform an atomic read operation at the memory location.
|
||||
fn read_scalar_atomic(
|
||||
&self,
|
||||
place: &MPlaceTy<'tcx, Provenance>,
|
||||
place: &MPlaceTy<'tcx>,
|
||||
atomic: AtomicReadOrd,
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_ref();
|
||||
this.atomic_access_check(place, AtomicAccessType::Load(atomic))?;
|
||||
// This will read from the last store in the modification order of this location. In case
|
||||
@ -625,8 +625,8 @@ pub trait EvalContextExt<'tcx>: MiriInterpCxExt<'tcx> {
|
||||
/// Perform an atomic write operation at the memory location.
|
||||
fn write_scalar_atomic(
|
||||
&mut self,
|
||||
val: Scalar<Provenance>,
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
val: Scalar,
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
atomic: AtomicWriteOrd,
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
@ -645,12 +645,12 @@ pub trait EvalContextExt<'tcx>: MiriInterpCxExt<'tcx> {
|
||||
/// Perform an atomic RMW operation on a memory location.
|
||||
fn atomic_rmw_op_immediate(
|
||||
&mut self,
|
||||
place: &MPlaceTy<'tcx, Provenance>,
|
||||
rhs: &ImmTy<'tcx, Provenance>,
|
||||
place: &MPlaceTy<'tcx>,
|
||||
rhs: &ImmTy<'tcx>,
|
||||
op: mir::BinOp,
|
||||
not: bool,
|
||||
atomic: AtomicRwOrd,
|
||||
) -> InterpResult<'tcx, ImmTy<'tcx, Provenance>> {
|
||||
) -> InterpResult<'tcx, ImmTy<'tcx>> {
|
||||
let this = self.eval_context_mut();
|
||||
this.atomic_access_check(place, AtomicAccessType::Rmw)?;
|
||||
|
||||
@ -670,10 +670,10 @@ pub trait EvalContextExt<'tcx>: MiriInterpCxExt<'tcx> {
|
||||
/// scalar value, the old value is returned.
|
||||
fn atomic_exchange_scalar(
|
||||
&mut self,
|
||||
place: &MPlaceTy<'tcx, Provenance>,
|
||||
new: Scalar<Provenance>,
|
||||
place: &MPlaceTy<'tcx>,
|
||||
new: Scalar,
|
||||
atomic: AtomicRwOrd,
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_mut();
|
||||
this.atomic_access_check(place, AtomicAccessType::Rmw)?;
|
||||
|
||||
@ -690,11 +690,11 @@ pub trait EvalContextExt<'tcx>: MiriInterpCxExt<'tcx> {
|
||||
/// scalar value, the old value is returned.
|
||||
fn atomic_min_max_scalar(
|
||||
&mut self,
|
||||
place: &MPlaceTy<'tcx, Provenance>,
|
||||
rhs: ImmTy<'tcx, Provenance>,
|
||||
place: &MPlaceTy<'tcx>,
|
||||
rhs: ImmTy<'tcx>,
|
||||
min: bool,
|
||||
atomic: AtomicRwOrd,
|
||||
) -> InterpResult<'tcx, ImmTy<'tcx, Provenance>> {
|
||||
) -> InterpResult<'tcx, ImmTy<'tcx>> {
|
||||
let this = self.eval_context_mut();
|
||||
this.atomic_access_check(place, AtomicAccessType::Rmw)?;
|
||||
|
||||
@ -726,9 +726,9 @@ pub trait EvalContextExt<'tcx>: MiriInterpCxExt<'tcx> {
|
||||
/// identical.
|
||||
fn atomic_compare_exchange_scalar(
|
||||
&mut self,
|
||||
place: &MPlaceTy<'tcx, Provenance>,
|
||||
expect_old: &ImmTy<'tcx, Provenance>,
|
||||
new: Scalar<Provenance>,
|
||||
place: &MPlaceTy<'tcx>,
|
||||
expect_old: &ImmTy<'tcx>,
|
||||
new: Scalar,
|
||||
success: AtomicRwOrd,
|
||||
fail: AtomicReadOrd,
|
||||
can_fail_spuriously: bool,
|
||||
@ -948,7 +948,7 @@ impl VClockAlloc {
|
||||
mem_clocks: &MemoryCellClocks,
|
||||
access: AccessType,
|
||||
access_size: Size,
|
||||
ptr_dbg: Pointer<AllocId>,
|
||||
ptr_dbg: interpret::Pointer<AllocId>,
|
||||
ty: Option<Ty<'_>>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let (active_index, active_clocks) = global.active_thread_state(thread_mgr);
|
||||
@ -1063,7 +1063,7 @@ impl VClockAlloc {
|
||||
mem_clocks,
|
||||
AccessType::NaRead(read_type),
|
||||
access_range.size,
|
||||
Pointer::new(alloc_id, Size::from_bytes(mem_clocks_range.start)),
|
||||
interpret::Pointer::new(alloc_id, Size::from_bytes(mem_clocks_range.start)),
|
||||
ty,
|
||||
);
|
||||
}
|
||||
@ -1108,7 +1108,7 @@ impl VClockAlloc {
|
||||
mem_clocks,
|
||||
AccessType::NaWrite(write_type),
|
||||
access_range.size,
|
||||
Pointer::new(alloc_id, Size::from_bytes(mem_clocks_range.start)),
|
||||
interpret::Pointer::new(alloc_id, Size::from_bytes(mem_clocks_range.start)),
|
||||
ty,
|
||||
);
|
||||
}
|
||||
@ -1163,7 +1163,7 @@ trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> {
|
||||
/// Checks that an atomic access is legal at the given place.
|
||||
fn atomic_access_check(
|
||||
&self,
|
||||
place: &MPlaceTy<'tcx, Provenance>,
|
||||
place: &MPlaceTy<'tcx>,
|
||||
access_type: AtomicAccessType,
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_ref();
|
||||
@ -1219,7 +1219,7 @@ trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> {
|
||||
/// associated memory-place and on the current thread.
|
||||
fn validate_atomic_load(
|
||||
&self,
|
||||
place: &MPlaceTy<'tcx, Provenance>,
|
||||
place: &MPlaceTy<'tcx>,
|
||||
atomic: AtomicReadOrd,
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_ref();
|
||||
@ -1241,7 +1241,7 @@ trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> {
|
||||
/// associated memory-place and on the current thread.
|
||||
fn validate_atomic_store(
|
||||
&mut self,
|
||||
place: &MPlaceTy<'tcx, Provenance>,
|
||||
place: &MPlaceTy<'tcx>,
|
||||
atomic: AtomicWriteOrd,
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
@ -1263,7 +1263,7 @@ trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> {
|
||||
/// at the associated memory place and on the current thread.
|
||||
fn validate_atomic_rmw(
|
||||
&mut self,
|
||||
place: &MPlaceTy<'tcx, Provenance>,
|
||||
place: &MPlaceTy<'tcx>,
|
||||
atomic: AtomicRwOrd,
|
||||
) -> InterpResult<'tcx> {
|
||||
use AtomicRwOrd::*;
|
||||
@ -1292,7 +1292,7 @@ trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> {
|
||||
/// Generic atomic operation implementation
|
||||
fn validate_atomic_op<A: Debug + Copy>(
|
||||
&self,
|
||||
place: &MPlaceTy<'tcx, Provenance>,
|
||||
place: &MPlaceTy<'tcx>,
|
||||
atomic: A,
|
||||
access: AccessType,
|
||||
mut op: impl FnMut(
|
||||
@ -1337,7 +1337,7 @@ trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> {
|
||||
mem_clocks,
|
||||
access,
|
||||
place.layout.size,
|
||||
Pointer::new(
|
||||
interpret::Pointer::new(
|
||||
alloc_id,
|
||||
Size::from_bytes(mem_clocks_range.start),
|
||||
),
|
||||
|
@ -51,7 +51,7 @@ impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
|
||||
pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
fn init_once_get_or_create_id(
|
||||
&mut self,
|
||||
lock_op: &OpTy<'tcx, Provenance>,
|
||||
lock_op: &OpTy<'tcx>,
|
||||
lock_layout: TyAndLayout<'tcx>,
|
||||
offset: u64,
|
||||
) -> InterpResult<'tcx, InitOnceId> {
|
||||
|
@ -55,7 +55,7 @@ macro_rules! declare_id {
|
||||
}
|
||||
|
||||
impl $name {
|
||||
pub fn to_u32_scalar(&self) -> Scalar<Provenance> {
|
||||
pub fn to_u32_scalar(&self) -> Scalar {
|
||||
Scalar::from_u32(self.0.get())
|
||||
}
|
||||
}
|
||||
@ -168,7 +168,7 @@ pub(super) trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
fn get_or_create_id<Id: SyncId>(
|
||||
&mut self,
|
||||
next_id: Id,
|
||||
lock_op: &OpTy<'tcx, Provenance>,
|
||||
lock_op: &OpTy<'tcx>,
|
||||
lock_layout: TyAndLayout<'tcx>,
|
||||
offset: u64,
|
||||
) -> InterpResult<'tcx, Option<Id>> {
|
||||
@ -262,8 +262,8 @@ pub(super) trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
fn condvar_reacquire_mutex(
|
||||
&mut self,
|
||||
mutex: MutexId,
|
||||
retval: Scalar<Provenance>,
|
||||
dest: MPlaceTy<'tcx, Provenance>,
|
||||
retval: Scalar,
|
||||
dest: MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
if this.mutex_is_locked(mutex) {
|
||||
@ -287,7 +287,7 @@ impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
|
||||
pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
fn mutex_get_or_create_id(
|
||||
&mut self,
|
||||
lock_op: &OpTy<'tcx, Provenance>,
|
||||
lock_op: &OpTy<'tcx>,
|
||||
lock_layout: TyAndLayout<'tcx>,
|
||||
offset: u64,
|
||||
) -> InterpResult<'tcx, MutexId> {
|
||||
@ -299,7 +299,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
|
||||
fn rwlock_get_or_create_id(
|
||||
&mut self,
|
||||
lock_op: &OpTy<'tcx, Provenance>,
|
||||
lock_op: &OpTy<'tcx>,
|
||||
lock_layout: TyAndLayout<'tcx>,
|
||||
offset: u64,
|
||||
) -> InterpResult<'tcx, RwLockId> {
|
||||
@ -311,7 +311,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
|
||||
fn condvar_get_or_create_id(
|
||||
&mut self,
|
||||
lock_op: &OpTy<'tcx, Provenance>,
|
||||
lock_op: &OpTy<'tcx>,
|
||||
lock_layout: TyAndLayout<'tcx>,
|
||||
offset: u64,
|
||||
) -> InterpResult<'tcx, CondvarId> {
|
||||
@ -393,12 +393,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
/// Put the thread into the queue waiting for the mutex.
|
||||
/// Once the Mutex becomes available, `retval` will be written to `dest`.
|
||||
#[inline]
|
||||
fn mutex_enqueue_and_block(
|
||||
&mut self,
|
||||
id: MutexId,
|
||||
retval: Scalar<Provenance>,
|
||||
dest: MPlaceTy<'tcx, Provenance>,
|
||||
) {
|
||||
fn mutex_enqueue_and_block(&mut self, id: MutexId, retval: Scalar, dest: MPlaceTy<'tcx>) {
|
||||
let this = self.eval_context_mut();
|
||||
assert!(this.mutex_is_locked(id), "queing on unlocked mutex");
|
||||
let thread = this.active_thread();
|
||||
@ -409,8 +404,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
callback!(
|
||||
@capture<'tcx> {
|
||||
id: MutexId,
|
||||
retval: Scalar<Provenance>,
|
||||
dest: MPlaceTy<'tcx, Provenance>,
|
||||
retval: Scalar,
|
||||
dest: MPlaceTy<'tcx>,
|
||||
}
|
||||
@unblock = |this| {
|
||||
assert!(!this.mutex_is_locked(id));
|
||||
@ -506,8 +501,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
fn rwlock_enqueue_and_block_reader(
|
||||
&mut self,
|
||||
id: RwLockId,
|
||||
retval: Scalar<Provenance>,
|
||||
dest: MPlaceTy<'tcx, Provenance>,
|
||||
retval: Scalar,
|
||||
dest: MPlaceTy<'tcx>,
|
||||
) {
|
||||
let this = self.eval_context_mut();
|
||||
let thread = this.active_thread();
|
||||
@ -519,8 +514,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
callback!(
|
||||
@capture<'tcx> {
|
||||
id: RwLockId,
|
||||
retval: Scalar<Provenance>,
|
||||
dest: MPlaceTy<'tcx, Provenance>,
|
||||
retval: Scalar,
|
||||
dest: MPlaceTy<'tcx>,
|
||||
}
|
||||
@unblock = |this| {
|
||||
this.rwlock_reader_lock(id);
|
||||
@ -589,8 +584,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
fn rwlock_enqueue_and_block_writer(
|
||||
&mut self,
|
||||
id: RwLockId,
|
||||
retval: Scalar<Provenance>,
|
||||
dest: MPlaceTy<'tcx, Provenance>,
|
||||
retval: Scalar,
|
||||
dest: MPlaceTy<'tcx>,
|
||||
) {
|
||||
let this = self.eval_context_mut();
|
||||
assert!(this.rwlock_is_locked(id), "write-queueing on unlocked rwlock");
|
||||
@ -602,8 +597,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
callback!(
|
||||
@capture<'tcx> {
|
||||
id: RwLockId,
|
||||
retval: Scalar<Provenance>,
|
||||
dest: MPlaceTy<'tcx, Provenance>,
|
||||
retval: Scalar,
|
||||
dest: MPlaceTy<'tcx>,
|
||||
}
|
||||
@unblock = |this| {
|
||||
this.rwlock_writer_lock(id);
|
||||
@ -629,9 +624,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
condvar: CondvarId,
|
||||
mutex: MutexId,
|
||||
timeout: Option<Timeout>,
|
||||
retval_succ: Scalar<Provenance>,
|
||||
retval_timeout: Scalar<Provenance>,
|
||||
dest: MPlaceTy<'tcx, Provenance>,
|
||||
retval_succ: Scalar,
|
||||
retval_timeout: Scalar,
|
||||
dest: MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
if let Some(old_locked_count) = this.mutex_unlock(mutex)? {
|
||||
@ -655,9 +650,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
@capture<'tcx> {
|
||||
condvar: CondvarId,
|
||||
mutex: MutexId,
|
||||
retval_succ: Scalar<Provenance>,
|
||||
retval_timeout: Scalar<Provenance>,
|
||||
dest: MPlaceTy<'tcx, Provenance>,
|
||||
retval_succ: Scalar,
|
||||
retval_timeout: Scalar,
|
||||
dest: MPlaceTy<'tcx>,
|
||||
}
|
||||
@unblock = |this| {
|
||||
// The condvar was signaled. Make sure we get the clock for that.
|
||||
@ -710,10 +705,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
addr: u64,
|
||||
bitset: u32,
|
||||
timeout: Option<Timeout>,
|
||||
retval_succ: Scalar<Provenance>,
|
||||
retval_timeout: Scalar<Provenance>,
|
||||
dest: MPlaceTy<'tcx, Provenance>,
|
||||
errno_timeout: Scalar<Provenance>,
|
||||
retval_succ: Scalar,
|
||||
retval_timeout: Scalar,
|
||||
dest: MPlaceTy<'tcx>,
|
||||
errno_timeout: Scalar,
|
||||
) {
|
||||
let this = self.eval_context_mut();
|
||||
let thread = this.active_thread();
|
||||
@ -727,10 +722,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
callback!(
|
||||
@capture<'tcx> {
|
||||
addr: u64,
|
||||
retval_succ: Scalar<Provenance>,
|
||||
retval_timeout: Scalar<Provenance>,
|
||||
dest: MPlaceTy<'tcx, Provenance>,
|
||||
errno_timeout: Scalar<Provenance>,
|
||||
retval_succ: Scalar,
|
||||
retval_timeout: Scalar,
|
||||
dest: MPlaceTy<'tcx>,
|
||||
errno_timeout: Scalar,
|
||||
}
|
||||
@unblock = |this| {
|
||||
let futex = this.machine.sync.futexes.get(&addr).unwrap();
|
||||
|
@ -256,10 +256,10 @@ pub struct Thread<'tcx> {
|
||||
/// which then forwards it to 'Resume'. However this argument is implicit in MIR,
|
||||
/// so we have to store it out-of-band. When there are multiple active unwinds,
|
||||
/// the innermost one is always caught first, so we can store them as a stack.
|
||||
pub(crate) panic_payloads: Vec<Scalar<Provenance>>,
|
||||
pub(crate) panic_payloads: Vec<Scalar>,
|
||||
|
||||
/// Last OS error location in memory. It is a 32-bit integer.
|
||||
pub(crate) last_error: Option<MPlaceTy<'tcx, Provenance>>,
|
||||
pub(crate) last_error: Option<MPlaceTy<'tcx>>,
|
||||
}
|
||||
|
||||
pub type StackEmptyCallback<'tcx> =
|
||||
@ -432,9 +432,8 @@ pub struct ThreadManager<'tcx> {
|
||||
///
|
||||
/// Note that this vector also contains terminated threads.
|
||||
threads: IndexVec<ThreadId, Thread<'tcx>>,
|
||||
/// A mapping from a thread-local static to an allocation id of a thread
|
||||
/// specific allocation.
|
||||
thread_local_alloc_ids: FxHashMap<(DefId, ThreadId), Pointer<Provenance>>,
|
||||
/// A mapping from a thread-local static to the thread specific allocation.
|
||||
thread_local_allocs: FxHashMap<(DefId, ThreadId), StrictPointer>,
|
||||
/// A flag that indicates that we should change the active thread.
|
||||
yield_active_thread: bool,
|
||||
}
|
||||
@ -443,7 +442,7 @@ impl VisitProvenance for ThreadManager<'_> {
|
||||
fn visit_provenance(&self, visit: &mut VisitWith<'_>) {
|
||||
let ThreadManager {
|
||||
threads,
|
||||
thread_local_alloc_ids,
|
||||
thread_local_allocs,
|
||||
active_thread: _,
|
||||
yield_active_thread: _,
|
||||
} = self;
|
||||
@ -451,7 +450,7 @@ impl VisitProvenance for ThreadManager<'_> {
|
||||
for thread in threads {
|
||||
thread.visit_provenance(visit);
|
||||
}
|
||||
for ptr in thread_local_alloc_ids.values() {
|
||||
for ptr in thread_local_allocs.values() {
|
||||
ptr.visit_provenance(visit);
|
||||
}
|
||||
}
|
||||
@ -465,7 +464,7 @@ impl<'tcx> Default for ThreadManager<'tcx> {
|
||||
Self {
|
||||
active_thread: ThreadId::MAIN_THREAD,
|
||||
threads,
|
||||
thread_local_alloc_ids: Default::default(),
|
||||
thread_local_allocs: Default::default(),
|
||||
yield_active_thread: false,
|
||||
}
|
||||
}
|
||||
@ -487,16 +486,16 @@ impl<'tcx> ThreadManager<'tcx> {
|
||||
|
||||
/// Check if we have an allocation for the given thread local static for the
|
||||
/// active thread.
|
||||
fn get_thread_local_alloc_id(&self, def_id: DefId) -> Option<Pointer<Provenance>> {
|
||||
self.thread_local_alloc_ids.get(&(def_id, self.active_thread)).cloned()
|
||||
fn get_thread_local_alloc_id(&self, def_id: DefId) -> Option<StrictPointer> {
|
||||
self.thread_local_allocs.get(&(def_id, self.active_thread)).cloned()
|
||||
}
|
||||
|
||||
/// Set the pointer for the allocation of the given thread local
|
||||
/// static for the active thread.
|
||||
///
|
||||
/// Panics if a thread local is initialized twice for the same thread.
|
||||
fn set_thread_local_alloc(&mut self, def_id: DefId, ptr: Pointer<Provenance>) {
|
||||
self.thread_local_alloc_ids.try_insert((def_id, self.active_thread), ptr).unwrap();
|
||||
fn set_thread_local_alloc(&mut self, def_id: DefId, ptr: StrictPointer) {
|
||||
self.thread_local_allocs.try_insert((def_id, self.active_thread), ptr).unwrap();
|
||||
}
|
||||
|
||||
/// Borrow the stack of the active thread.
|
||||
@ -848,7 +847,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
fn get_or_create_thread_local_alloc(
|
||||
&mut self,
|
||||
def_id: DefId,
|
||||
) -> InterpResult<'tcx, Pointer<Provenance>> {
|
||||
) -> InterpResult<'tcx, StrictPointer> {
|
||||
let this = self.eval_context_mut();
|
||||
let tcx = this.tcx;
|
||||
if let Some(old_alloc) = this.machine.threads.get_thread_local_alloc_id(def_id) {
|
||||
@ -877,10 +876,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
#[inline]
|
||||
fn start_regular_thread(
|
||||
&mut self,
|
||||
thread: Option<MPlaceTy<'tcx, Provenance>>,
|
||||
start_routine: Pointer<Option<Provenance>>,
|
||||
thread: Option<MPlaceTy<'tcx>>,
|
||||
start_routine: Pointer,
|
||||
start_abi: Abi,
|
||||
func_arg: ImmTy<'tcx, Provenance>,
|
||||
func_arg: ImmTy<'tcx>,
|
||||
ret_layout: TyAndLayout<'tcx>,
|
||||
) -> InterpResult<'tcx, ThreadId> {
|
||||
let this = self.eval_context_mut();
|
||||
@ -947,18 +946,16 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
let gone_thread = this.active_thread();
|
||||
{
|
||||
let mut free_tls_statics = Vec::new();
|
||||
this.machine.threads.thread_local_alloc_ids.retain(
|
||||
|&(_def_id, thread), &mut alloc_id| {
|
||||
if thread != gone_thread {
|
||||
// A different thread, keep this static around.
|
||||
return true;
|
||||
}
|
||||
// Delete this static from the map and from memory.
|
||||
// We cannot free directly here as we cannot use `?` in this context.
|
||||
free_tls_statics.push(alloc_id);
|
||||
false
|
||||
},
|
||||
);
|
||||
this.machine.threads.thread_local_allocs.retain(|&(_def_id, thread), &mut alloc_id| {
|
||||
if thread != gone_thread {
|
||||
// A different thread, keep this static around.
|
||||
return true;
|
||||
}
|
||||
// Delete this static from the map and from memory.
|
||||
// We cannot free directly here as we cannot use `?` in this context.
|
||||
free_tls_statics.push(alloc_id);
|
||||
false
|
||||
});
|
||||
// Now free the TLS statics.
|
||||
for ptr in free_tls_statics {
|
||||
match tls_alloc_action {
|
||||
|
@ -148,7 +148,7 @@ struct StoreElement {
|
||||
// FIXME: this means the store must be fully initialized;
|
||||
// we will have to change this if we want to support atomics on
|
||||
// (partially) uninitialized data.
|
||||
val: Scalar<Provenance>,
|
||||
val: Scalar,
|
||||
|
||||
/// Metadata about loads from this store element,
|
||||
/// behind a RefCell to keep load op take &self
|
||||
@ -197,7 +197,7 @@ impl StoreBufferAlloc {
|
||||
fn get_or_create_store_buffer<'tcx>(
|
||||
&self,
|
||||
range: AllocRange,
|
||||
init: Scalar<Provenance>,
|
||||
init: Scalar,
|
||||
) -> InterpResult<'tcx, Ref<'_, StoreBuffer>> {
|
||||
let access_type = self.store_buffers.borrow().access_type(range);
|
||||
let pos = match access_type {
|
||||
@ -222,7 +222,7 @@ impl StoreBufferAlloc {
|
||||
fn get_or_create_store_buffer_mut<'tcx>(
|
||||
&mut self,
|
||||
range: AllocRange,
|
||||
init: Scalar<Provenance>,
|
||||
init: Scalar,
|
||||
) -> InterpResult<'tcx, &mut StoreBuffer> {
|
||||
let buffers = self.store_buffers.get_mut();
|
||||
let access_type = buffers.access_type(range);
|
||||
@ -244,7 +244,7 @@ impl StoreBufferAlloc {
|
||||
}
|
||||
|
||||
impl<'tcx> StoreBuffer {
|
||||
fn new(init: Scalar<Provenance>) -> Self {
|
||||
fn new(init: Scalar) -> Self {
|
||||
let mut buffer = VecDeque::new();
|
||||
buffer.reserve(STORE_BUFFER_LIMIT);
|
||||
let mut ret = Self { buffer };
|
||||
@ -282,7 +282,7 @@ impl<'tcx> StoreBuffer {
|
||||
is_seqcst: bool,
|
||||
rng: &mut (impl rand::Rng + ?Sized),
|
||||
validate: impl FnOnce() -> InterpResult<'tcx>,
|
||||
) -> InterpResult<'tcx, (Scalar<Provenance>, LoadRecency)> {
|
||||
) -> InterpResult<'tcx, (Scalar, LoadRecency)> {
|
||||
// Having a live borrow to store_buffer while calling validate_atomic_load is fine
|
||||
// because the race detector doesn't touch store_buffer
|
||||
|
||||
@ -307,7 +307,7 @@ impl<'tcx> StoreBuffer {
|
||||
|
||||
fn buffered_write(
|
||||
&mut self,
|
||||
val: Scalar<Provenance>,
|
||||
val: Scalar,
|
||||
global: &DataRaceState,
|
||||
thread_mgr: &ThreadManager<'_>,
|
||||
is_seqcst: bool,
|
||||
@ -408,7 +408,7 @@ impl<'tcx> StoreBuffer {
|
||||
/// ATOMIC STORE IMPL in the paper (except we don't need the location's vector clock)
|
||||
fn store_impl(
|
||||
&mut self,
|
||||
val: Scalar<Provenance>,
|
||||
val: Scalar,
|
||||
index: VectorIdx,
|
||||
thread_clock: &VClock,
|
||||
is_seqcst: bool,
|
||||
@ -450,12 +450,7 @@ impl StoreElement {
|
||||
/// buffer regardless of subsequent loads by the same thread; if the earliest load of another
|
||||
/// thread doesn't happen before the current one, then no subsequent load by the other thread
|
||||
/// can happen before the current one.
|
||||
fn load_impl(
|
||||
&self,
|
||||
index: VectorIdx,
|
||||
clocks: &ThreadClockSet,
|
||||
is_seqcst: bool,
|
||||
) -> Scalar<Provenance> {
|
||||
fn load_impl(&self, index: VectorIdx, clocks: &ThreadClockSet, is_seqcst: bool) -> Scalar {
|
||||
let mut load_info = self.load_info.borrow_mut();
|
||||
load_info.sc_loaded |= is_seqcst;
|
||||
let _ = load_info.timestamps.try_insert(index, clocks.clock[index]);
|
||||
@ -467,10 +462,10 @@ impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
|
||||
pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
fn buffered_atomic_rmw(
|
||||
&mut self,
|
||||
new_val: Scalar<Provenance>,
|
||||
place: &MPlaceTy<'tcx, Provenance>,
|
||||
new_val: Scalar,
|
||||
place: &MPlaceTy<'tcx>,
|
||||
atomic: AtomicRwOrd,
|
||||
init: Scalar<Provenance>,
|
||||
init: Scalar,
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
let (alloc_id, base_offset, ..) = this.ptr_get_alloc_id(place.ptr())?;
|
||||
@ -493,11 +488,11 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
|
||||
fn buffered_atomic_read(
|
||||
&self,
|
||||
place: &MPlaceTy<'tcx, Provenance>,
|
||||
place: &MPlaceTy<'tcx>,
|
||||
atomic: AtomicReadOrd,
|
||||
latest_in_mo: Scalar<Provenance>,
|
||||
latest_in_mo: Scalar,
|
||||
validate: impl FnOnce() -> InterpResult<'tcx>,
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_ref();
|
||||
if let Some(global) = &this.machine.data_race {
|
||||
let (alloc_id, base_offset, ..) = this.ptr_get_alloc_id(place.ptr())?;
|
||||
@ -534,10 +529,10 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
|
||||
fn buffered_atomic_write(
|
||||
&mut self,
|
||||
val: Scalar<Provenance>,
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
val: Scalar,
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
atomic: AtomicWriteOrd,
|
||||
init: Scalar<Provenance>,
|
||||
init: Scalar,
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
let (alloc_id, base_offset, ..) = this.ptr_get_alloc_id(dest.ptr())?;
|
||||
@ -579,9 +574,9 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
/// to perform load_impl on the latest store element
|
||||
fn perform_read_on_buffered_latest(
|
||||
&self,
|
||||
place: &MPlaceTy<'tcx, Provenance>,
|
||||
place: &MPlaceTy<'tcx>,
|
||||
atomic: AtomicReadOrd,
|
||||
init: Scalar<Provenance>,
|
||||
init: Scalar,
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_ref();
|
||||
|
||||
|
@ -42,7 +42,7 @@ pub enum TerminationInfo {
|
||||
},
|
||||
DataRace {
|
||||
involves_non_atomic: bool,
|
||||
ptr: Pointer<AllocId>,
|
||||
ptr: interpret::Pointer<AllocId>,
|
||||
op1: RacingOp,
|
||||
op2: RacingOp,
|
||||
extra: Option<&'static str>,
|
||||
@ -128,7 +128,7 @@ pub enum NonHaltingDiagnostic {
|
||||
details: bool,
|
||||
},
|
||||
WeakMemoryOutdatedLoad {
|
||||
ptr: Pointer<Option<Provenance>>,
|
||||
ptr: Pointer,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -255,7 +255,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
}
|
||||
|
||||
/// Evaluates the scalar at the specified path.
|
||||
fn eval_path(&self, path: &[&str]) -> OpTy<'tcx, Provenance> {
|
||||
fn eval_path(&self, path: &[&str]) -> OpTy<'tcx> {
|
||||
let this = self.eval_context_ref();
|
||||
let instance = this.resolve_path(path, Namespace::ValueNS);
|
||||
// We don't give a span -- this isn't actually used directly by the program anyway.
|
||||
@ -264,7 +264,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
});
|
||||
const_val.into()
|
||||
}
|
||||
fn eval_path_scalar(&self, path: &[&str]) -> Scalar<Provenance> {
|
||||
fn eval_path_scalar(&self, path: &[&str]) -> Scalar {
|
||||
let this = self.eval_context_ref();
|
||||
let val = this.eval_path(path);
|
||||
this.read_scalar(&val)
|
||||
@ -272,7 +272,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
}
|
||||
|
||||
/// Helper function to get a `libc` constant as a `Scalar`.
|
||||
fn eval_libc(&self, name: &str) -> Scalar<Provenance> {
|
||||
fn eval_libc(&self, name: &str) -> Scalar {
|
||||
self.eval_path_scalar(&["libc", name])
|
||||
}
|
||||
|
||||
@ -293,7 +293,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
}
|
||||
|
||||
/// Helper function to get a `windows` constant as a `Scalar`.
|
||||
fn eval_windows(&self, module: &str, name: &str) -> Scalar<Provenance> {
|
||||
fn eval_windows(&self, module: &str, name: &str) -> Scalar {
|
||||
self.eval_context_ref().eval_path_scalar(&["std", "sys", "pal", "windows", module, name])
|
||||
}
|
||||
|
||||
@ -413,12 +413,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
}
|
||||
|
||||
/// Test if this pointer equals 0.
|
||||
fn ptr_is_null(&self, ptr: Pointer<Option<Provenance>>) -> InterpResult<'tcx, bool> {
|
||||
fn ptr_is_null(&self, ptr: Pointer) -> InterpResult<'tcx, bool> {
|
||||
Ok(ptr.addr().bytes() == 0)
|
||||
}
|
||||
|
||||
/// Generate some random bytes, and write them to `dest`.
|
||||
fn gen_random(&mut self, ptr: Pointer<Option<Provenance>>, len: u64) -> InterpResult<'tcx> {
|
||||
fn gen_random(&mut self, ptr: Pointer, len: u64) -> InterpResult<'tcx> {
|
||||
// Some programs pass in a null pointer and a length of 0
|
||||
// to their platform's random-generation function (e.g. getrandom())
|
||||
// on Linux. For compatibility with these programs, we don't perform
|
||||
@ -453,7 +453,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
f: ty::Instance<'tcx>,
|
||||
caller_abi: Abi,
|
||||
args: &[Immediate<Provenance>],
|
||||
dest: Option<&MPlaceTy<'tcx, Provenance>>,
|
||||
dest: Option<&MPlaceTy<'tcx>>,
|
||||
stack_pop: StackPopCleanup,
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
@ -501,7 +501,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
/// The range is relative to `place`.
|
||||
fn visit_freeze_sensitive(
|
||||
&self,
|
||||
place: &MPlaceTy<'tcx, Provenance>,
|
||||
place: &MPlaceTy<'tcx>,
|
||||
size: Size,
|
||||
mut action: impl FnMut(AllocRange, bool) -> InterpResult<'tcx>,
|
||||
) -> InterpResult<'tcx> {
|
||||
@ -520,8 +520,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
let mut cur_addr = start_addr;
|
||||
// Called when we detected an `UnsafeCell` at the given offset and size.
|
||||
// Calls `action` and advances `cur_ptr`.
|
||||
let mut unsafe_cell_action = |unsafe_cell_ptr: &Pointer<Option<Provenance>>,
|
||||
unsafe_cell_size: Size| {
|
||||
let mut unsafe_cell_action = |unsafe_cell_ptr: &Pointer, unsafe_cell_size: Size| {
|
||||
// We assume that we are given the fields in increasing offset order,
|
||||
// and nothing else changes.
|
||||
let unsafe_cell_addr = unsafe_cell_ptr.addr();
|
||||
@ -575,7 +574,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
/// whether we are inside an `UnsafeCell` or not.
|
||||
struct UnsafeCellVisitor<'ecx, 'tcx, F>
|
||||
where
|
||||
F: FnMut(&MPlaceTy<'tcx, Provenance>) -> InterpResult<'tcx>,
|
||||
F: FnMut(&MPlaceTy<'tcx>) -> InterpResult<'tcx>,
|
||||
{
|
||||
ecx: &'ecx MiriInterpCx<'tcx>,
|
||||
unsafe_cell_action: F,
|
||||
@ -583,9 +582,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
|
||||
impl<'ecx, 'tcx, F> ValueVisitor<'tcx, MiriMachine<'tcx>> for UnsafeCellVisitor<'ecx, 'tcx, F>
|
||||
where
|
||||
F: FnMut(&MPlaceTy<'tcx, Provenance>) -> InterpResult<'tcx>,
|
||||
F: FnMut(&MPlaceTy<'tcx>) -> InterpResult<'tcx>,
|
||||
{
|
||||
type V = MPlaceTy<'tcx, Provenance>;
|
||||
type V = MPlaceTy<'tcx>;
|
||||
|
||||
#[inline(always)]
|
||||
fn ecx(&self) -> &MiriInterpCx<'tcx> {
|
||||
@ -603,7 +602,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
}
|
||||
|
||||
// Hook to detect `UnsafeCell`.
|
||||
fn visit_value(&mut self, v: &MPlaceTy<'tcx, Provenance>) -> InterpResult<'tcx> {
|
||||
fn visit_value(&mut self, v: &MPlaceTy<'tcx>) -> InterpResult<'tcx> {
|
||||
trace!("UnsafeCellVisitor: {:?} {:?}", *v, v.layout.ty);
|
||||
let is_unsafe_cell = match v.layout.ty.kind() {
|
||||
ty::Adt(adt, _) =>
|
||||
@ -649,7 +648,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
|
||||
fn visit_union(
|
||||
&mut self,
|
||||
_v: &MPlaceTy<'tcx, Provenance>,
|
||||
_v: &MPlaceTy<'tcx>,
|
||||
_fields: NonZero<usize>,
|
||||
) -> InterpResult<'tcx> {
|
||||
bug!("we should have already handled unions in `visit_value`")
|
||||
@ -720,7 +719,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
|
||||
/// Get last error variable as a place, lazily allocating thread-local storage for it if
|
||||
/// necessary.
|
||||
fn last_error_place(&mut self) -> InterpResult<'tcx, MPlaceTy<'tcx, Provenance>> {
|
||||
fn last_error_place(&mut self) -> InterpResult<'tcx, MPlaceTy<'tcx>> {
|
||||
let this = self.eval_context_mut();
|
||||
if let Some(errno_place) = this.active_thread_ref().last_error.as_ref() {
|
||||
Ok(errno_place.clone())
|
||||
@ -735,14 +734,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
}
|
||||
|
||||
/// Sets the last error variable.
|
||||
fn set_last_error(&mut self, scalar: Scalar<Provenance>) -> InterpResult<'tcx> {
|
||||
fn set_last_error(&mut self, scalar: Scalar) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
let errno_place = this.last_error_place()?;
|
||||
this.write_scalar(scalar, &errno_place)
|
||||
}
|
||||
|
||||
/// Gets the last error variable.
|
||||
fn get_last_error(&mut self) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
fn get_last_error(&mut self) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_mut();
|
||||
let errno_place = this.last_error_place()?;
|
||||
this.read_scalar(&errno_place)
|
||||
@ -750,7 +749,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
|
||||
/// This function tries to produce the most similar OS error from the `std::io::ErrorKind`
|
||||
/// as a platform-specific errnum.
|
||||
fn io_error_to_errnum(&self, err: std::io::Error) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
fn io_error_to_errnum(&self, err: std::io::Error) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_ref();
|
||||
let target = &this.tcx.sess.target;
|
||||
if target.families.iter().any(|f| f == "unix") {
|
||||
@ -779,7 +778,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
#[allow(clippy::needless_return)]
|
||||
fn try_errnum_to_io_error(
|
||||
&self,
|
||||
errnum: Scalar<Provenance>,
|
||||
errnum: Scalar,
|
||||
) -> InterpResult<'tcx, Option<std::io::ErrorKind>> {
|
||||
let this = self.eval_context_ref();
|
||||
let target = &this.tcx.sess.target;
|
||||
@ -836,7 +835,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
&self,
|
||||
op: &impl Readable<'tcx, Provenance>,
|
||||
layout: TyAndLayout<'tcx>,
|
||||
) -> InterpResult<'tcx, MPlaceTy<'tcx, Provenance>> {
|
||||
) -> InterpResult<'tcx, MPlaceTy<'tcx>> {
|
||||
let this = self.eval_context_ref();
|
||||
let ptr = this.read_pointer(op)?;
|
||||
Ok(this.ptr_to_mplace(ptr, layout))
|
||||
@ -849,7 +848,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
offset: u64,
|
||||
base_layout: TyAndLayout<'tcx>,
|
||||
value_layout: TyAndLayout<'tcx>,
|
||||
) -> InterpResult<'tcx, MPlaceTy<'tcx, Provenance>> {
|
||||
) -> InterpResult<'tcx, MPlaceTy<'tcx>> {
|
||||
let this = self.eval_context_ref();
|
||||
let op_place = this.deref_pointer_as(op, base_layout)?;
|
||||
let offset = Size::from_bytes(offset);
|
||||
@ -866,7 +865,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
offset: u64,
|
||||
base_layout: TyAndLayout<'tcx>,
|
||||
value_layout: TyAndLayout<'tcx>,
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_ref();
|
||||
let value_place = this.deref_pointer_and_offset(op, offset, base_layout, value_layout)?;
|
||||
this.read_scalar(&value_place)
|
||||
@ -876,7 +875,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
&mut self,
|
||||
op: &impl Readable<'tcx, Provenance>,
|
||||
offset: u64,
|
||||
value: impl Into<Scalar<Provenance>>,
|
||||
value: impl Into<Scalar>,
|
||||
base_layout: TyAndLayout<'tcx>,
|
||||
value_layout: TyAndLayout<'tcx>,
|
||||
) -> InterpResult<'tcx, ()> {
|
||||
@ -888,10 +887,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
/// Parse a `timespec` struct and return it as a `std::time::Duration`. It returns `None`
|
||||
/// if the value in the `timespec` struct is invalid. Some libc functions will return
|
||||
/// `EINVAL` in this case.
|
||||
fn read_timespec(
|
||||
&mut self,
|
||||
tp: &MPlaceTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, Option<Duration>> {
|
||||
fn read_timespec(&mut self, tp: &MPlaceTy<'tcx>) -> InterpResult<'tcx, Option<Duration>> {
|
||||
let this = self.eval_context_mut();
|
||||
let seconds_place = this.project_field(tp, 0)?;
|
||||
let seconds_scalar = this.read_scalar(&seconds_place)?;
|
||||
@ -914,10 +910,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
}
|
||||
|
||||
/// Read bytes from a byte slice.
|
||||
fn read_byte_slice<'a>(
|
||||
&'a self,
|
||||
slice: &ImmTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, &'a [u8]>
|
||||
fn read_byte_slice<'a>(&'a self, slice: &ImmTy<'tcx>) -> InterpResult<'tcx, &'a [u8]>
|
||||
where
|
||||
'tcx: 'a,
|
||||
{
|
||||
@ -930,7 +923,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
}
|
||||
|
||||
/// Read a sequence of bytes until the first null terminator.
|
||||
fn read_c_str<'a>(&'a self, ptr: Pointer<Option<Provenance>>) -> InterpResult<'tcx, &'a [u8]>
|
||||
fn read_c_str<'a>(&'a self, ptr: Pointer) -> InterpResult<'tcx, &'a [u8]>
|
||||
where
|
||||
'tcx: 'a,
|
||||
{
|
||||
@ -963,7 +956,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
fn write_c_str(
|
||||
&mut self,
|
||||
c_str: &[u8],
|
||||
ptr: Pointer<Option<Provenance>>,
|
||||
ptr: Pointer,
|
||||
size: u64,
|
||||
) -> InterpResult<'tcx, (bool, u64)> {
|
||||
// If `size` is smaller or equal than `bytes.len()`, writing `bytes` plus the required null
|
||||
@ -982,7 +975,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
/// until the first null terminator.
|
||||
fn read_c_str_with_char_size<T>(
|
||||
&self,
|
||||
mut ptr: Pointer<Option<Provenance>>,
|
||||
mut ptr: Pointer,
|
||||
size: Size,
|
||||
align: Align,
|
||||
) -> InterpResult<'tcx, Vec<T>>
|
||||
@ -1014,7 +1007,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
}
|
||||
|
||||
/// Read a sequence of u16 until the first null terminator.
|
||||
fn read_wide_str(&self, ptr: Pointer<Option<Provenance>>) -> InterpResult<'tcx, Vec<u16>> {
|
||||
fn read_wide_str(&self, ptr: Pointer) -> InterpResult<'tcx, Vec<u16>> {
|
||||
self.read_c_str_with_char_size(ptr, Size::from_bytes(2), Align::from_bytes(2).unwrap())
|
||||
}
|
||||
|
||||
@ -1027,7 +1020,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
fn write_wide_str(
|
||||
&mut self,
|
||||
wide_str: &[u16],
|
||||
ptr: Pointer<Option<Provenance>>,
|
||||
ptr: Pointer,
|
||||
size: u64,
|
||||
) -> InterpResult<'tcx, (bool, u64)> {
|
||||
// If `size` is smaller or equal than `bytes.len()`, writing `bytes` plus the required
|
||||
@ -1052,7 +1045,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
|
||||
/// Read a sequence of wchar_t until the first null terminator.
|
||||
/// Always returns a `Vec<u32>` no matter the size of `wchar_t`.
|
||||
fn read_wchar_t_str(&self, ptr: Pointer<Option<Provenance>>) -> InterpResult<'tcx, Vec<u32>> {
|
||||
fn read_wchar_t_str(&self, ptr: Pointer) -> InterpResult<'tcx, Vec<u32>> {
|
||||
let this = self.eval_context_ref();
|
||||
let wchar_t = this.libc_ty_layout("wchar_t");
|
||||
self.read_c_str_with_char_size(ptr, wchar_t.size, wchar_t.align.abi)
|
||||
@ -1138,17 +1131,17 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
abi: Abi,
|
||||
exp_abi: Abi,
|
||||
link_name: Symbol,
|
||||
args: &'a [OpTy<'tcx, Provenance>],
|
||||
) -> InterpResult<'tcx, &'a [OpTy<'tcx, Provenance>; N]>
|
||||
args: &'a [OpTy<'tcx>],
|
||||
) -> InterpResult<'tcx, &'a [OpTy<'tcx>; N]>
|
||||
where
|
||||
&'a [OpTy<'tcx, Provenance>; N]: TryFrom<&'a [OpTy<'tcx, Provenance>]>,
|
||||
&'a [OpTy<'tcx>; N]: TryFrom<&'a [OpTy<'tcx>]>,
|
||||
{
|
||||
self.check_abi_and_shim_symbol_clash(abi, exp_abi, link_name)?;
|
||||
check_arg_count(args)
|
||||
}
|
||||
|
||||
/// Mark a machine allocation that was just created as immutable.
|
||||
fn mark_immutable(&mut self, mplace: &MPlaceTy<'tcx, Provenance>) {
|
||||
fn mark_immutable(&mut self, mplace: &MPlaceTy<'tcx>) {
|
||||
let this = self.eval_context_mut();
|
||||
// This got just allocated, so there definitely is a pointer here.
|
||||
let provenance = mplace.ptr().into_pointer_or_addr().unwrap().provenance;
|
||||
@ -1168,10 +1161,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
/// Returns `None` if `f` is NaN or out of range.
|
||||
fn float_to_int_checked(
|
||||
&self,
|
||||
src: &ImmTy<'tcx, Provenance>,
|
||||
src: &ImmTy<'tcx>,
|
||||
cast_to: TyAndLayout<'tcx>,
|
||||
round: rustc_apfloat::Round,
|
||||
) -> InterpResult<'tcx, Option<ImmTy<'tcx, Provenance>>> {
|
||||
) -> InterpResult<'tcx, Option<ImmTy<'tcx>>> {
|
||||
let this = self.eval_context_ref();
|
||||
|
||||
fn float_to_int_inner<'tcx, F: rustc_apfloat::Float>(
|
||||
@ -1179,7 +1172,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
src: F,
|
||||
cast_to: TyAndLayout<'tcx>,
|
||||
round: rustc_apfloat::Round,
|
||||
) -> (Scalar<Provenance>, rustc_apfloat::Status) {
|
||||
) -> (Scalar, rustc_apfloat::Status) {
|
||||
let int_size = cast_to.layout.size;
|
||||
match cast_to.ty.kind() {
|
||||
// Unsigned
|
||||
@ -1267,10 +1260,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
}
|
||||
|
||||
/// Lookup an array of immediates stored as a linker section of name `name`.
|
||||
fn lookup_link_section(
|
||||
&mut self,
|
||||
name: &str,
|
||||
) -> InterpResult<'tcx, Vec<ImmTy<'tcx, Provenance>>> {
|
||||
fn lookup_link_section(&mut self, name: &str) -> InterpResult<'tcx, Vec<ImmTy<'tcx>>> {
|
||||
let this = self.eval_context_mut();
|
||||
let tcx = this.tcx.tcx;
|
||||
|
||||
@ -1338,10 +1328,10 @@ impl<'tcx> MiriMachine<'tcx> {
|
||||
|
||||
/// Check that the number of args is what we expect.
|
||||
pub fn check_arg_count<'a, 'tcx, const N: usize>(
|
||||
args: &'a [OpTy<'tcx, Provenance>],
|
||||
) -> InterpResult<'tcx, &'a [OpTy<'tcx, Provenance>; N]>
|
||||
args: &'a [OpTy<'tcx>],
|
||||
) -> InterpResult<'tcx, &'a [OpTy<'tcx>; N]>
|
||||
where
|
||||
&'a [OpTy<'tcx, Provenance>; N]: TryFrom<&'a [OpTy<'tcx, Provenance>]>,
|
||||
&'a [OpTy<'tcx>; N]: TryFrom<&'a [OpTy<'tcx>]>,
|
||||
{
|
||||
if let Ok(ops) = args.try_into() {
|
||||
return Ok(ops);
|
||||
@ -1374,7 +1364,7 @@ pub fn get_local_crates(tcx: TyCtxt<'_>) -> Vec<CrateNum> {
|
||||
local_crates
|
||||
}
|
||||
|
||||
pub(crate) fn bool_to_simd_element(b: bool, size: Size) -> Scalar<Provenance> {
|
||||
pub(crate) fn bool_to_simd_element(b: bool, size: Size) -> Scalar {
|
||||
// SIMD uses all-1 as pattern for "true". In two's complement,
|
||||
// -1 has all its bits set to one and `from_int` will truncate or
|
||||
// sign-extend it to `size` as required.
|
||||
@ -1382,7 +1372,7 @@ pub(crate) fn bool_to_simd_element(b: bool, size: Size) -> Scalar<Provenance> {
|
||||
Scalar::from_int(val, size)
|
||||
}
|
||||
|
||||
pub(crate) fn simd_element_to_bool(elem: ImmTy<'_, Provenance>) -> InterpResult<'_, bool> {
|
||||
pub(crate) fn simd_element_to_bool(elem: ImmTy<'_>) -> InterpResult<'_, bool> {
|
||||
let val = elem.to_scalar().to_int(elem.layout.size)?;
|
||||
Ok(match val {
|
||||
0 => false,
|
||||
|
@ -18,8 +18,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
fn emulate_atomic_intrinsic(
|
||||
&mut self,
|
||||
intrinsic_name: &str,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
args: &[OpTy<'tcx>],
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx, EmulateItemResult> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
@ -124,8 +124,8 @@ impl<'tcx> EvalContextPrivExt<'tcx> for MiriInterpCx<'tcx> {}
|
||||
trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> {
|
||||
fn atomic_load(
|
||||
&mut self,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
args: &[OpTy<'tcx>],
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
atomic: AtomicReadOrd,
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
@ -140,11 +140,7 @@ trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn atomic_store(
|
||||
&mut self,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
atomic: AtomicWriteOrd,
|
||||
) -> InterpResult<'tcx> {
|
||||
fn atomic_store(&mut self, args: &[OpTy<'tcx>], atomic: AtomicWriteOrd) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let [place, val] = check_arg_count(args)?;
|
||||
@ -159,7 +155,7 @@ trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> {
|
||||
|
||||
fn compiler_fence_intrinsic(
|
||||
&mut self,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
args: &[OpTy<'tcx>],
|
||||
atomic: AtomicFenceOrd,
|
||||
) -> InterpResult<'tcx> {
|
||||
let [] = check_arg_count(args)?;
|
||||
@ -170,7 +166,7 @@ trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> {
|
||||
|
||||
fn atomic_fence_intrinsic(
|
||||
&mut self,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
args: &[OpTy<'tcx>],
|
||||
atomic: AtomicFenceOrd,
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
@ -181,8 +177,8 @@ trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> {
|
||||
|
||||
fn atomic_rmw_op(
|
||||
&mut self,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
args: &[OpTy<'tcx>],
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
atomic_op: AtomicOp,
|
||||
atomic: AtomicRwOrd,
|
||||
) -> InterpResult<'tcx> {
|
||||
@ -223,8 +219,8 @@ trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> {
|
||||
|
||||
fn atomic_exchange(
|
||||
&mut self,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
args: &[OpTy<'tcx>],
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
atomic: AtomicRwOrd,
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
@ -240,8 +236,8 @@ trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> {
|
||||
|
||||
fn atomic_compare_exchange_impl(
|
||||
&mut self,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
args: &[OpTy<'tcx>],
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
success: AtomicRwOrd,
|
||||
fail: AtomicReadOrd,
|
||||
can_fail_spuriously: bool,
|
||||
@ -269,8 +265,8 @@ trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> {
|
||||
|
||||
fn atomic_compare_exchange(
|
||||
&mut self,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
args: &[OpTy<'tcx>],
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
success: AtomicRwOrd,
|
||||
fail: AtomicReadOrd,
|
||||
) -> InterpResult<'tcx> {
|
||||
@ -279,8 +275,8 @@ trait EvalContextPrivExt<'tcx>: MiriInterpCxExt<'tcx> {
|
||||
|
||||
fn atomic_compare_exchange_weak(
|
||||
&mut self,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
args: &[OpTy<'tcx>],
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
success: AtomicRwOrd,
|
||||
fail: AtomicReadOrd,
|
||||
) -> InterpResult<'tcx> {
|
||||
|
@ -23,8 +23,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
fn call_intrinsic(
|
||||
&mut self,
|
||||
instance: ty::Instance<'tcx>,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
args: &[OpTy<'tcx>],
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
ret: Option<mir::BasicBlock>,
|
||||
unwind: mir::UnwindAction,
|
||||
) -> InterpResult<'tcx, Option<ty::Instance<'tcx>>> {
|
||||
@ -79,8 +79,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
&mut self,
|
||||
intrinsic_name: &str,
|
||||
generic_args: ty::GenericArgsRef<'tcx>,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
args: &[OpTy<'tcx>],
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
ret: Option<mir::BasicBlock>,
|
||||
) -> InterpResult<'tcx, EmulateItemResult> {
|
||||
let this = self.eval_context_mut();
|
||||
@ -385,7 +385,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
"frem_fast" => mir::BinOp::Rem,
|
||||
_ => bug!(),
|
||||
};
|
||||
let float_finite = |x: &ImmTy<'tcx, _>| -> InterpResult<'tcx, bool> {
|
||||
let float_finite = |x: &ImmTy<'tcx>| -> InterpResult<'tcx, bool> {
|
||||
let ty::Float(fty) = x.layout.ty.kind() else {
|
||||
bug!("float_finite: non-float input type {}", x.layout.ty)
|
||||
};
|
||||
|
@ -23,8 +23,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
&mut self,
|
||||
intrinsic_name: &str,
|
||||
generic_args: ty::GenericArgsRef<'tcx>,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
args: &[OpTy<'tcx>],
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx, EmulateItemResult> {
|
||||
let this = self.eval_context_mut();
|
||||
match intrinsic_name {
|
||||
@ -760,9 +760,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
fn fminmax_op(
|
||||
&self,
|
||||
op: MinMax,
|
||||
left: &ImmTy<'tcx, Provenance>,
|
||||
right: &ImmTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
left: &ImmTy<'tcx>,
|
||||
right: &ImmTy<'tcx>,
|
||||
) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_ref();
|
||||
assert_eq!(left.layout.ty, right.layout.ty);
|
||||
let ty::Float(float_ty) = left.layout.ty.kind() else {
|
||||
|
@ -97,7 +97,16 @@ use tracing::{info, trace};
|
||||
pub use rustc_const_eval::interpret::*;
|
||||
// Resolve ambiguity.
|
||||
#[doc(no_inline)]
|
||||
pub use rustc_const_eval::interpret::{self, AllocMap, PlaceTy, Provenance as _};
|
||||
pub use rustc_const_eval::interpret::{self, AllocMap, Provenance as _};
|
||||
|
||||
// Type aliases that set the provenance parameter.
|
||||
pub type Pointer = interpret::Pointer<Option<machine::Provenance>>;
|
||||
pub type StrictPointer = interpret::Pointer<machine::Provenance>;
|
||||
pub type Scalar = interpret::Scalar<machine::Provenance>;
|
||||
pub type ImmTy<'tcx> = interpret::ImmTy<'tcx, machine::Provenance>;
|
||||
pub type OpTy<'tcx> = interpret::OpTy<'tcx, machine::Provenance>;
|
||||
pub type PlaceTy<'tcx> = interpret::PlaceTy<'tcx, machine::Provenance>;
|
||||
pub type MPlaceTy<'tcx> = interpret::MPlaceTy<'tcx, machine::Provenance>;
|
||||
|
||||
pub use crate::intrinsics::EvalContextExt as _;
|
||||
pub use crate::shims::env::{EnvVars, EvalContextExt as _};
|
||||
|
@ -241,12 +241,12 @@ pub enum ProvenanceExtra {
|
||||
}
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
static_assert_size!(Pointer<Provenance>, 24);
|
||||
static_assert_size!(StrictPointer, 24);
|
||||
// FIXME: this would with in 24bytes but layout optimizations are not smart enough
|
||||
// #[cfg(target_pointer_width = "64")]
|
||||
//static_assert_size!(Pointer<Option<Provenance>>, 24);
|
||||
//static_assert_size!(Pointer, 24);
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
static_assert_size!(Scalar<Provenance>, 32);
|
||||
static_assert_size!(Scalar, 32);
|
||||
|
||||
impl fmt::Debug for Provenance {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
@ -270,7 +270,7 @@ impl fmt::Debug for Provenance {
|
||||
}
|
||||
|
||||
impl interpret::Provenance for Provenance {
|
||||
/// We use absolute addresses in the `offset` of a `Pointer<Provenance>`.
|
||||
/// We use absolute addresses in the `offset` of a `StrictPointer`.
|
||||
const OFFSET_IS_ADDR: bool = true;
|
||||
|
||||
fn get_alloc_id(self) -> Option<AllocId> {
|
||||
@ -280,7 +280,7 @@ impl interpret::Provenance for Provenance {
|
||||
}
|
||||
}
|
||||
|
||||
fn fmt(ptr: &Pointer<Self>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
fn fmt(ptr: &interpret::Pointer<Self>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let (prov, addr) = ptr.into_parts(); // address is absolute
|
||||
write!(f, "{:#x}", addr.bytes())?;
|
||||
if f.alternate() {
|
||||
@ -442,14 +442,14 @@ pub struct MiriMachine<'tcx> {
|
||||
pub(crate) env_vars: EnvVars<'tcx>,
|
||||
|
||||
/// Return place of the main function.
|
||||
pub(crate) main_fn_ret_place: Option<MPlaceTy<'tcx, Provenance>>,
|
||||
pub(crate) main_fn_ret_place: Option<MPlaceTy<'tcx>>,
|
||||
|
||||
/// Program arguments (`Option` because we can only initialize them after creating the ecx).
|
||||
/// These are *pointers* to argc/argv because macOS.
|
||||
/// We also need the full command line as one string because of Windows.
|
||||
pub(crate) argc: Option<Pointer<Option<Provenance>>>,
|
||||
pub(crate) argv: Option<Pointer<Option<Provenance>>>,
|
||||
pub(crate) cmd_line: Option<Pointer<Option<Provenance>>>,
|
||||
pub(crate) argc: Option<Pointer>,
|
||||
pub(crate) argv: Option<Pointer>,
|
||||
pub(crate) cmd_line: Option<Pointer>,
|
||||
|
||||
/// TLS state.
|
||||
pub(crate) tls: TlsData<'tcx>,
|
||||
@ -504,7 +504,7 @@ pub struct MiriMachine<'tcx> {
|
||||
pub(crate) local_crates: Vec<CrateNum>,
|
||||
|
||||
/// Mapping extern static names to their pointer.
|
||||
extern_statics: FxHashMap<Symbol, Pointer<Provenance>>,
|
||||
extern_statics: FxHashMap<Symbol, StrictPointer>,
|
||||
|
||||
/// The random number generator used for resolving non-determinism.
|
||||
/// Needs to be queried by ptr_to_int, hence needs interior mutability.
|
||||
@ -565,7 +565,7 @@ pub struct MiriMachine<'tcx> {
|
||||
/// Maps MIR consts to their evaluated result. We combine the const with a "salt" (`usize`)
|
||||
/// that is fixed per stack frame; this lets us have sometimes different results for the
|
||||
/// same const while ensuring consistent results within a single call.
|
||||
const_cache: RefCell<FxHashMap<(mir::Const<'tcx>, usize), OpTy<'tcx, Provenance>>>,
|
||||
const_cache: RefCell<FxHashMap<(mir::Const<'tcx>, usize), OpTy<'tcx>>>,
|
||||
|
||||
/// For each allocation, an offset inside that allocation that was deemed aligned even for
|
||||
/// symbolic alignment checks. This cannot be stored in `AllocExtra` since it needs to be
|
||||
@ -716,11 +716,7 @@ impl<'tcx> MiriMachine<'tcx> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn add_extern_static(
|
||||
this: &mut MiriInterpCx<'tcx>,
|
||||
name: &str,
|
||||
ptr: Pointer<Option<Provenance>>,
|
||||
) {
|
||||
pub(crate) fn add_extern_static(this: &mut MiriInterpCx<'tcx>, name: &str, ptr: Pointer) {
|
||||
// This got just allocated, so there definitely is a pointer here.
|
||||
let ptr = ptr.into_pointer_or_addr().unwrap();
|
||||
this.machine.extern_statics.try_insert(Symbol::intern(name), ptr).unwrap();
|
||||
@ -946,7 +942,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
|
||||
instance: ty::Instance<'tcx>,
|
||||
abi: Abi,
|
||||
args: &[FnArg<'tcx, Provenance>],
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
ret: Option<mir::BasicBlock>,
|
||||
unwind: mir::UnwindAction,
|
||||
) -> InterpResult<'tcx, Option<(&'tcx mir::Body<'tcx>, ty::Instance<'tcx>)>> {
|
||||
@ -973,7 +969,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
|
||||
fn_val: DynSym,
|
||||
abi: Abi,
|
||||
args: &[FnArg<'tcx, Provenance>],
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
ret: Option<mir::BasicBlock>,
|
||||
unwind: mir::UnwindAction,
|
||||
) -> InterpResult<'tcx> {
|
||||
@ -985,8 +981,8 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
|
||||
fn call_intrinsic(
|
||||
ecx: &mut MiriInterpCx<'tcx>,
|
||||
instance: ty::Instance<'tcx>,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
args: &[OpTy<'tcx>],
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
ret: Option<mir::BasicBlock>,
|
||||
unwind: mir::UnwindAction,
|
||||
) -> InterpResult<'tcx, Option<ty::Instance<'tcx>>> {
|
||||
@ -1027,9 +1023,9 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
|
||||
fn binary_ptr_op(
|
||||
ecx: &MiriInterpCx<'tcx>,
|
||||
bin_op: mir::BinOp,
|
||||
left: &ImmTy<'tcx, Provenance>,
|
||||
right: &ImmTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, ImmTy<'tcx, Provenance>> {
|
||||
left: &ImmTy<'tcx>,
|
||||
right: &ImmTy<'tcx>,
|
||||
) -> InterpResult<'tcx, ImmTy<'tcx>> {
|
||||
ecx.binary_ptr_op(bin_op, left, right)
|
||||
}
|
||||
|
||||
@ -1047,14 +1043,14 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
|
||||
fn thread_local_static_pointer(
|
||||
ecx: &mut MiriInterpCx<'tcx>,
|
||||
def_id: DefId,
|
||||
) -> InterpResult<'tcx, Pointer<Provenance>> {
|
||||
) -> InterpResult<'tcx, StrictPointer> {
|
||||
ecx.get_or_create_thread_local_alloc(def_id)
|
||||
}
|
||||
|
||||
fn extern_static_pointer(
|
||||
ecx: &MiriInterpCx<'tcx>,
|
||||
def_id: DefId,
|
||||
) -> InterpResult<'tcx, Pointer<Provenance>> {
|
||||
) -> InterpResult<'tcx, StrictPointer> {
|
||||
let link_name = ecx.item_link_name(def_id);
|
||||
if let Some(&ptr) = ecx.machine.extern_statics.get(&link_name) {
|
||||
// Various parts of the engine rely on `get_alloc_info` for size and alignment
|
||||
@ -1153,9 +1149,9 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
|
||||
|
||||
fn adjust_alloc_root_pointer(
|
||||
ecx: &MiriInterpCx<'tcx>,
|
||||
ptr: Pointer<CtfeProvenance>,
|
||||
ptr: interpret::Pointer<CtfeProvenance>,
|
||||
kind: Option<MemoryKind>,
|
||||
) -> InterpResult<'tcx, Pointer<Provenance>> {
|
||||
) -> InterpResult<'tcx, interpret::Pointer<Provenance>> {
|
||||
let kind = kind.expect("we set our GLOBAL_KIND so this cannot be None");
|
||||
let alloc_id = ptr.provenance.alloc_id();
|
||||
if cfg!(debug_assertions) {
|
||||
@ -1182,20 +1178,14 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
|
||||
|
||||
/// Called on `usize as ptr` casts.
|
||||
#[inline(always)]
|
||||
fn ptr_from_addr_cast(
|
||||
ecx: &MiriInterpCx<'tcx>,
|
||||
addr: u64,
|
||||
) -> InterpResult<'tcx, Pointer<Option<Self::Provenance>>> {
|
||||
fn ptr_from_addr_cast(ecx: &MiriInterpCx<'tcx>, addr: u64) -> InterpResult<'tcx, Pointer> {
|
||||
ecx.ptr_from_addr_cast(addr)
|
||||
}
|
||||
|
||||
/// Called on `ptr as usize` casts.
|
||||
/// (Actually computing the resulting `usize` doesn't need machine help,
|
||||
/// that's just `Scalar::try_to_int`.)
|
||||
fn expose_ptr(
|
||||
ecx: &mut InterpCx<'tcx, Self>,
|
||||
ptr: Pointer<Self::Provenance>,
|
||||
) -> InterpResult<'tcx> {
|
||||
fn expose_ptr(ecx: &mut InterpCx<'tcx, Self>, ptr: StrictPointer) -> InterpResult<'tcx> {
|
||||
match ptr.provenance {
|
||||
Provenance::Concrete { alloc_id, tag } => ecx.expose_ptr(alloc_id, tag),
|
||||
Provenance::Wildcard => {
|
||||
@ -1216,7 +1206,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
|
||||
/// stored in machine state).
|
||||
fn ptr_get_alloc(
|
||||
ecx: &MiriInterpCx<'tcx>,
|
||||
ptr: Pointer<Self::Provenance>,
|
||||
ptr: StrictPointer,
|
||||
) -> Option<(AllocId, Size, Self::ProvenanceExtra)> {
|
||||
let rel = ecx.ptr_get_alloc(ptr);
|
||||
|
||||
@ -1314,8 +1304,8 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
|
||||
fn retag_ptr_value(
|
||||
ecx: &mut InterpCx<'tcx, Self>,
|
||||
kind: mir::RetagKind,
|
||||
val: &ImmTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, ImmTy<'tcx, Provenance>> {
|
||||
val: &ImmTy<'tcx>,
|
||||
) -> InterpResult<'tcx, ImmTy<'tcx>> {
|
||||
if ecx.machine.borrow_tracker.is_some() {
|
||||
ecx.retag_ptr_value(kind, val)
|
||||
} else {
|
||||
@ -1327,7 +1317,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
|
||||
fn retag_place_contents(
|
||||
ecx: &mut InterpCx<'tcx, Self>,
|
||||
kind: mir::RetagKind,
|
||||
place: &PlaceTy<'tcx, Provenance>,
|
||||
place: &PlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx> {
|
||||
if ecx.machine.borrow_tracker.is_some() {
|
||||
ecx.retag_place_contents(kind, place)?;
|
||||
@ -1337,7 +1327,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
|
||||
|
||||
fn protect_in_place_function_argument(
|
||||
ecx: &mut InterpCx<'tcx, Self>,
|
||||
place: &MPlaceTy<'tcx, Provenance>,
|
||||
place: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx> {
|
||||
// If we have a borrow tracker, we also have it set up protection so that all reads *and
|
||||
// writes* during this call are insta-UB.
|
||||
@ -1492,7 +1482,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
|
||||
fn after_local_allocated(
|
||||
ecx: &mut InterpCx<'tcx, Self>,
|
||||
local: mir::Local,
|
||||
mplace: &MPlaceTy<'tcx, Provenance>,
|
||||
mplace: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let Some(Provenance::Concrete { alloc_id, .. }) = mplace.ptr().provenance else {
|
||||
panic!("after_local_allocated should only be called on fresh allocations");
|
||||
@ -1509,14 +1499,14 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
|
||||
span: Span,
|
||||
layout: Option<TyAndLayout<'tcx>>,
|
||||
eval: F,
|
||||
) -> InterpResult<'tcx, OpTy<'tcx, Self::Provenance>>
|
||||
) -> InterpResult<'tcx, OpTy<'tcx>>
|
||||
where
|
||||
F: Fn(
|
||||
&InterpCx<'tcx, Self>,
|
||||
mir::Const<'tcx>,
|
||||
Span,
|
||||
Option<TyAndLayout<'tcx>>,
|
||||
) -> InterpResult<'tcx, OpTy<'tcx, Self::Provenance>>,
|
||||
) -> InterpResult<'tcx, OpTy<'tcx>>,
|
||||
{
|
||||
let frame = ecx.active_thread_stack().last().unwrap();
|
||||
let mut cache = ecx.machine.const_cache.borrow_mut();
|
||||
|
@ -12,9 +12,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
fn binary_ptr_op(
|
||||
&self,
|
||||
bin_op: mir::BinOp,
|
||||
left: &ImmTy<'tcx, Provenance>,
|
||||
right: &ImmTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, ImmTy<'tcx, Provenance>> {
|
||||
left: &ImmTy<'tcx>,
|
||||
right: &ImmTy<'tcx>,
|
||||
) -> InterpResult<'tcx, ImmTy<'tcx>> {
|
||||
use rustc_middle::mir::BinOp::*;
|
||||
|
||||
let this = self.eval_context_ref();
|
||||
|
@ -56,21 +56,21 @@ impl VisitProvenance for Provenance {
|
||||
}
|
||||
}
|
||||
|
||||
impl VisitProvenance for Pointer<Provenance> {
|
||||
impl VisitProvenance for StrictPointer {
|
||||
fn visit_provenance(&self, visit: &mut VisitWith<'_>) {
|
||||
let (prov, _offset) = self.into_parts();
|
||||
prov.visit_provenance(visit);
|
||||
}
|
||||
}
|
||||
|
||||
impl VisitProvenance for Pointer<Option<Provenance>> {
|
||||
impl VisitProvenance for Pointer {
|
||||
fn visit_provenance(&self, visit: &mut VisitWith<'_>) {
|
||||
let (prov, _offset) = self.into_parts();
|
||||
prov.visit_provenance(visit);
|
||||
}
|
||||
}
|
||||
|
||||
impl VisitProvenance for Scalar<Provenance> {
|
||||
impl VisitProvenance for Scalar {
|
||||
fn visit_provenance(&self, visit: &mut VisitWith<'_>) {
|
||||
match self {
|
||||
Scalar::Ptr(ptr, _) => ptr.visit_provenance(visit),
|
||||
@ -103,20 +103,20 @@ impl VisitProvenance for MemPlaceMeta<Provenance> {
|
||||
}
|
||||
}
|
||||
|
||||
impl VisitProvenance for ImmTy<'_, Provenance> {
|
||||
impl VisitProvenance for ImmTy<'_> {
|
||||
fn visit_provenance(&self, visit: &mut VisitWith<'_>) {
|
||||
(**self).visit_provenance(visit)
|
||||
}
|
||||
}
|
||||
|
||||
impl VisitProvenance for MPlaceTy<'_, Provenance> {
|
||||
impl VisitProvenance for MPlaceTy<'_> {
|
||||
fn visit_provenance(&self, visit: &mut VisitWith<'_>) {
|
||||
self.ptr().visit_provenance(visit);
|
||||
self.meta().visit_provenance(visit);
|
||||
}
|
||||
}
|
||||
|
||||
impl VisitProvenance for PlaceTy<'_, Provenance> {
|
||||
impl VisitProvenance for PlaceTy<'_> {
|
||||
fn visit_provenance(&self, visit: &mut VisitWith<'_>) {
|
||||
match self.as_mplace_or_local() {
|
||||
Either::Left(mplace) => mplace.visit_provenance(visit),
|
||||
@ -125,7 +125,7 @@ impl VisitProvenance for PlaceTy<'_, Provenance> {
|
||||
}
|
||||
}
|
||||
|
||||
impl VisitProvenance for OpTy<'_, Provenance> {
|
||||
impl VisitProvenance for OpTy<'_> {
|
||||
fn visit_provenance(&self, visit: &mut VisitWith<'_>) {
|
||||
match self.as_mplace_or_imm() {
|
||||
Either::Left(mplace) => mplace.visit_provenance(visit),
|
||||
|
@ -92,11 +92,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn malloc(
|
||||
&mut self,
|
||||
size: u64,
|
||||
zero_init: bool,
|
||||
) -> InterpResult<'tcx, Pointer<Option<Provenance>>> {
|
||||
fn malloc(&mut self, size: u64, zero_init: bool) -> InterpResult<'tcx, Pointer> {
|
||||
let this = self.eval_context_mut();
|
||||
let align = this.malloc_align(size);
|
||||
let ptr = this.allocate_ptr(Size::from_bytes(size), align, MiriMemoryKind::C.into())?;
|
||||
@ -113,10 +109,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
|
||||
fn posix_memalign(
|
||||
&mut self,
|
||||
memptr: &OpTy<'tcx, Provenance>,
|
||||
align: &OpTy<'tcx, Provenance>,
|
||||
size: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
memptr: &OpTy<'tcx>,
|
||||
align: &OpTy<'tcx>,
|
||||
size: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_mut();
|
||||
let memptr = this.deref_pointer(memptr)?;
|
||||
let align = this.read_target_usize(align)?;
|
||||
@ -137,7 +133,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn free(&mut self, ptr: Pointer<Option<Provenance>>) -> InterpResult<'tcx> {
|
||||
fn free(&mut self, ptr: Pointer) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
if !this.ptr_is_null(ptr)? {
|
||||
this.deallocate_ptr(ptr, None, MiriMemoryKind::C.into())?;
|
||||
@ -145,11 +141,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn realloc(
|
||||
&mut self,
|
||||
old_ptr: Pointer<Option<Provenance>>,
|
||||
new_size: u64,
|
||||
) -> InterpResult<'tcx, Pointer<Option<Provenance>>> {
|
||||
fn realloc(&mut self, old_ptr: Pointer, new_size: u64) -> InterpResult<'tcx, Pointer> {
|
||||
let this = self.eval_context_mut();
|
||||
let new_align = this.malloc_align(new_size);
|
||||
if this.ptr_is_null(old_ptr)? {
|
||||
@ -175,9 +167,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
|
||||
fn aligned_alloc(
|
||||
&mut self,
|
||||
align: &OpTy<'tcx, Provenance>,
|
||||
size: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, Pointer<Option<Provenance>>> {
|
||||
align: &OpTy<'tcx>,
|
||||
size: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, Pointer> {
|
||||
let this = self.eval_context_mut();
|
||||
let align = this.read_target_usize(align)?;
|
||||
let size = this.read_target_usize(size)?;
|
||||
|
@ -11,8 +11,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
&mut self,
|
||||
abi: Abi,
|
||||
link_name: Symbol,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
args: &[OpTy<'tcx>],
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
let [flags] = this.check_shim(abi, Abi::Rust, link_name, args)?;
|
||||
@ -31,8 +31,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
&mut self,
|
||||
abi: Abi,
|
||||
link_name: Symbol,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
args: &[OpTy<'tcx>],
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
let tcx = this.tcx;
|
||||
@ -110,7 +110,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
|
||||
fn resolve_frame_pointer(
|
||||
&mut self,
|
||||
ptr: &OpTy<'tcx, Provenance>,
|
||||
ptr: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, (Instance<'tcx>, Loc, String, String)> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
@ -140,8 +140,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
&mut self,
|
||||
abi: Abi,
|
||||
link_name: Symbol,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
args: &[OpTy<'tcx>],
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
let [ptr, flags] = this.check_shim(abi, Abi::Rust, link_name, args)?;
|
||||
@ -218,7 +218,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
&mut self,
|
||||
abi: Abi,
|
||||
link_name: Symbol,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
args: &[OpTy<'tcx>],
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
|
@ -6,7 +6,7 @@ impl<'tcx> MiriMachine<'tcx> {
|
||||
fn alloc_extern_static(
|
||||
this: &mut MiriInterpCx<'tcx>,
|
||||
name: &str,
|
||||
val: ImmTy<'tcx, Provenance>,
|
||||
val: ImmTy<'tcx>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let place = this.allocate(val.layout, MiriMemoryKind::ExternStatic.into())?;
|
||||
this.write_immediate(*val, &place)?;
|
||||
|
@ -40,8 +40,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
&mut self,
|
||||
link_name: Symbol,
|
||||
abi: Abi,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
args: &[OpTy<'tcx>],
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
ret: Option<mir::BasicBlock>,
|
||||
unwind: mir::UnwindAction,
|
||||
) -> InterpResult<'tcx, Option<(&'tcx mir::Body<'tcx>, ty::Instance<'tcx>)>> {
|
||||
@ -123,8 +123,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
&mut self,
|
||||
sym: DynSym,
|
||||
abi: Abi,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
args: &[OpTy<'tcx>],
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
ret: Option<mir::BasicBlock>,
|
||||
unwind: mir::UnwindAction,
|
||||
) -> InterpResult<'tcx> {
|
||||
@ -208,8 +208,8 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
&mut self,
|
||||
link_name: Symbol,
|
||||
abi: Abi,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
args: &[OpTy<'tcx>],
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx, EmulateItemResult> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
@ -238,11 +238,11 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
// ```
|
||||
// fn shim_name(
|
||||
// &mut self,
|
||||
// arg1: &OpTy<'tcx, Provenance>,
|
||||
// arg2: &OpTy<'tcx, Provenance>,
|
||||
// arg3: &OpTy<'tcx, Provenance>,
|
||||
// arg4: &OpTy<'tcx, Provenance>)
|
||||
// -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
// arg1: &OpTy<'tcx>,
|
||||
// arg2: &OpTy<'tcx>,
|
||||
// arg3: &OpTy<'tcx>,
|
||||
// arg4: &OpTy<'tcx>)
|
||||
// -> InterpResult<'tcx, Scalar> {
|
||||
// let this = self.eval_context_mut();
|
||||
//
|
||||
// // First thing: load all the arguments. Details depend on the shim.
|
||||
|
@ -14,10 +14,10 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
fn call_native_with_args<'a>(
|
||||
&mut self,
|
||||
link_name: Symbol,
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
ptr: CodePtr,
|
||||
libffi_args: Vec<libffi::high::Arg<'a>>,
|
||||
) -> InterpResult<'tcx, ImmTy<'tcx, Provenance>> {
|
||||
) -> InterpResult<'tcx, ImmTy<'tcx>> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
// Call the function (`ptr`) with arguments `libffi_args`, and obtain the return value
|
||||
@ -132,8 +132,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
fn call_native_fn(
|
||||
&mut self,
|
||||
link_name: Symbol,
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
args: &[OpTy<'tcx>],
|
||||
) -> InterpResult<'tcx, bool> {
|
||||
let this = self.eval_context_mut();
|
||||
// Get the pointer to the function in the shared object file if it exists.
|
||||
@ -216,10 +216,7 @@ impl<'a> CArg {
|
||||
|
||||
/// Extract the scalar value from the result of reading a scalar from the machine,
|
||||
/// and convert it to a `CArg`.
|
||||
fn imm_to_carg<'tcx>(
|
||||
v: ImmTy<'tcx, Provenance>,
|
||||
cx: &impl HasDataLayout,
|
||||
) -> InterpResult<'tcx, CArg> {
|
||||
fn imm_to_carg<'tcx>(v: ImmTy<'tcx>, cx: &impl HasDataLayout) -> InterpResult<'tcx, CArg> {
|
||||
Ok(match v.layout.ty.kind() {
|
||||
// If the primitive provided can be converted to a type matching the type pattern
|
||||
// then create a `CArg` of this primitive value with the corresponding `CArg` constructor.
|
||||
|
@ -34,10 +34,7 @@ impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
|
||||
pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
/// Helper function to read an OsString from a null-terminated sequence of bytes, which is what
|
||||
/// the Unix APIs usually handle.
|
||||
fn read_os_str_from_c_str<'a>(
|
||||
&'a self,
|
||||
ptr: Pointer<Option<Provenance>>,
|
||||
) -> InterpResult<'tcx, &'a OsStr>
|
||||
fn read_os_str_from_c_str<'a>(&'a self, ptr: Pointer) -> InterpResult<'tcx, &'a OsStr>
|
||||
where
|
||||
'tcx: 'a,
|
||||
{
|
||||
@ -48,10 +45,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
|
||||
/// Helper function to read an OsString from a 0x0000-terminated sequence of u16,
|
||||
/// which is what the Windows APIs usually handle.
|
||||
fn read_os_str_from_wide_str<'a>(
|
||||
&'a self,
|
||||
ptr: Pointer<Option<Provenance>>,
|
||||
) -> InterpResult<'tcx, OsString>
|
||||
fn read_os_str_from_wide_str<'a>(&'a self, ptr: Pointer) -> InterpResult<'tcx, OsString>
|
||||
where
|
||||
'tcx: 'a,
|
||||
{
|
||||
@ -76,7 +70,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
fn write_os_str_to_c_str(
|
||||
&mut self,
|
||||
os_str: &OsStr,
|
||||
ptr: Pointer<Option<Provenance>>,
|
||||
ptr: Pointer,
|
||||
size: u64,
|
||||
) -> InterpResult<'tcx, (bool, u64)> {
|
||||
let bytes = os_str.as_encoded_bytes();
|
||||
@ -88,7 +82,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
fn write_os_str_to_wide_str_helper(
|
||||
&mut self,
|
||||
os_str: &OsStr,
|
||||
ptr: Pointer<Option<Provenance>>,
|
||||
ptr: Pointer,
|
||||
size: u64,
|
||||
truncate: bool,
|
||||
) -> InterpResult<'tcx, (bool, u64)> {
|
||||
@ -125,7 +119,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
fn write_os_str_to_wide_str(
|
||||
&mut self,
|
||||
os_str: &OsStr,
|
||||
ptr: Pointer<Option<Provenance>>,
|
||||
ptr: Pointer,
|
||||
size: u64,
|
||||
) -> InterpResult<'tcx, (bool, u64)> {
|
||||
self.write_os_str_to_wide_str_helper(os_str, ptr, size, /*truncate*/ false)
|
||||
@ -136,7 +130,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
fn write_os_str_to_wide_str_truncated(
|
||||
&mut self,
|
||||
os_str: &OsStr,
|
||||
ptr: Pointer<Option<Provenance>>,
|
||||
ptr: Pointer,
|
||||
size: u64,
|
||||
) -> InterpResult<'tcx, (bool, u64)> {
|
||||
self.write_os_str_to_wide_str_helper(os_str, ptr, size, /*truncate*/ true)
|
||||
@ -147,7 +141,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
&mut self,
|
||||
os_str: &OsStr,
|
||||
memkind: MemoryKind,
|
||||
) -> InterpResult<'tcx, Pointer<Option<Provenance>>> {
|
||||
) -> InterpResult<'tcx, Pointer> {
|
||||
let size = u64::try_from(os_str.len()).unwrap().checked_add(1).unwrap(); // Make space for `0` terminator.
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
@ -163,7 +157,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
&mut self,
|
||||
os_str: &OsStr,
|
||||
memkind: MemoryKind,
|
||||
) -> InterpResult<'tcx, Pointer<Option<Provenance>>> {
|
||||
) -> InterpResult<'tcx, Pointer> {
|
||||
let size = u64::try_from(os_str.len()).unwrap().checked_add(1).unwrap(); // Make space for `0x0000` terminator.
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
@ -175,10 +169,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
}
|
||||
|
||||
/// Read a null-terminated sequence of bytes, and perform path separator conversion if needed.
|
||||
fn read_path_from_c_str<'a>(
|
||||
&'a self,
|
||||
ptr: Pointer<Option<Provenance>>,
|
||||
) -> InterpResult<'tcx, Cow<'a, Path>>
|
||||
fn read_path_from_c_str<'a>(&'a self, ptr: Pointer) -> InterpResult<'tcx, Cow<'a, Path>>
|
||||
where
|
||||
'tcx: 'a,
|
||||
{
|
||||
@ -192,10 +183,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
}
|
||||
|
||||
/// Read a null-terminated sequence of `u16`s, and perform path separator conversion if needed.
|
||||
fn read_path_from_wide_str(
|
||||
&self,
|
||||
ptr: Pointer<Option<Provenance>>,
|
||||
) -> InterpResult<'tcx, PathBuf> {
|
||||
fn read_path_from_wide_str(&self, ptr: Pointer) -> InterpResult<'tcx, PathBuf> {
|
||||
let this = self.eval_context_ref();
|
||||
let os_str = this.read_os_str_from_wide_str(ptr)?;
|
||||
|
||||
@ -207,7 +195,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
fn write_path_to_c_str(
|
||||
&mut self,
|
||||
path: &Path,
|
||||
ptr: Pointer<Option<Provenance>>,
|
||||
ptr: Pointer,
|
||||
size: u64,
|
||||
) -> InterpResult<'tcx, (bool, u64)> {
|
||||
let this = self.eval_context_mut();
|
||||
@ -221,7 +209,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
fn write_path_to_wide_str(
|
||||
&mut self,
|
||||
path: &Path,
|
||||
ptr: Pointer<Option<Provenance>>,
|
||||
ptr: Pointer,
|
||||
size: u64,
|
||||
) -> InterpResult<'tcx, (bool, u64)> {
|
||||
let this = self.eval_context_mut();
|
||||
@ -235,7 +223,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
fn write_path_to_wide_str_truncated(
|
||||
&mut self,
|
||||
path: &Path,
|
||||
ptr: Pointer<Option<Provenance>>,
|
||||
ptr: Pointer,
|
||||
size: u64,
|
||||
) -> InterpResult<'tcx, (bool, u64)> {
|
||||
let this = self.eval_context_mut();
|
||||
@ -250,7 +238,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
&mut self,
|
||||
path: &Path,
|
||||
memkind: MemoryKind,
|
||||
) -> InterpResult<'tcx, Pointer<Option<Provenance>>> {
|
||||
) -> InterpResult<'tcx, Pointer> {
|
||||
let this = self.eval_context_mut();
|
||||
let os_str =
|
||||
this.convert_path(Cow::Borrowed(path.as_os_str()), PathConversion::HostToTarget);
|
||||
@ -263,7 +251,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
&mut self,
|
||||
path: &Path,
|
||||
memkind: MemoryKind,
|
||||
) -> InterpResult<'tcx, Pointer<Option<Provenance>>> {
|
||||
) -> InterpResult<'tcx, Pointer> {
|
||||
let this = self.eval_context_mut();
|
||||
let os_str =
|
||||
this.convert_path(Cow::Borrowed(path.as_os_str()), PathConversion::HostToTarget);
|
||||
|
@ -23,11 +23,11 @@ use helpers::check_arg_count;
|
||||
#[derive(Debug)]
|
||||
pub struct CatchUnwindData<'tcx> {
|
||||
/// The `catch_fn` callback to call in case of a panic.
|
||||
catch_fn: Pointer<Option<Provenance>>,
|
||||
catch_fn: Pointer,
|
||||
/// The `data` argument for that callback.
|
||||
data: Scalar<Provenance>,
|
||||
data: Scalar,
|
||||
/// The return place from the original call to `try`.
|
||||
dest: MPlaceTy<'tcx, Provenance>,
|
||||
dest: MPlaceTy<'tcx>,
|
||||
/// The return block from the original call to `try`.
|
||||
ret: Option<mir::BasicBlock>,
|
||||
}
|
||||
@ -45,7 +45,7 @@ impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
|
||||
pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
/// Handles the special `miri_start_unwind` intrinsic, which is called
|
||||
/// by libpanic_unwind to delegate the actual unwinding process to Miri.
|
||||
fn handle_miri_start_unwind(&mut self, payload: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx> {
|
||||
fn handle_miri_start_unwind(&mut self, payload: &OpTy<'tcx>) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
trace!("miri_start_unwind: {:?}", this.frame().instance);
|
||||
@ -60,8 +60,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
/// Handles the `try` intrinsic, the underlying implementation of `std::panicking::try`.
|
||||
fn handle_catch_unwind(
|
||||
&mut self,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
args: &[OpTy<'tcx>],
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
ret: Option<mir::BasicBlock>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
|
@ -18,9 +18,9 @@ impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
|
||||
pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
fn clock_gettime(
|
||||
&mut self,
|
||||
clk_id_op: &OpTy<'tcx, Provenance>,
|
||||
tp_op: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
clk_id_op: &OpTy<'tcx>,
|
||||
tp_op: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, Scalar> {
|
||||
// This clock support is deliberately minimal because a lot of clock types have fiddly
|
||||
// properties (is it possible for Miri to be suspended independently of the host?). If you
|
||||
// have a use for another clock type, please open an issue.
|
||||
@ -93,11 +93,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
Ok(Scalar::from_i32(0))
|
||||
}
|
||||
|
||||
fn gettimeofday(
|
||||
&mut self,
|
||||
tv_op: &OpTy<'tcx, Provenance>,
|
||||
tz_op: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, i32> {
|
||||
fn gettimeofday(&mut self, tv_op: &OpTy<'tcx>, tz_op: &OpTy<'tcx>) -> InterpResult<'tcx, i32> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
this.assert_target_os_is_unix("gettimeofday");
|
||||
@ -127,9 +123,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
// https://linux.die.net/man/3/localtime_r
|
||||
fn localtime_r(
|
||||
&mut self,
|
||||
timep: &OpTy<'tcx, Provenance>,
|
||||
result_op: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, Pointer<Option<Provenance>>> {
|
||||
timep: &OpTy<'tcx>,
|
||||
result_op: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, Pointer> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
this.assert_target_os_is_unix("localtime_r");
|
||||
@ -212,7 +208,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
fn GetSystemTimeAsFileTime(
|
||||
&mut self,
|
||||
shim_name: &str,
|
||||
LPFILETIME_op: &OpTy<'tcx, Provenance>,
|
||||
LPFILETIME_op: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
@ -242,8 +238,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
#[allow(non_snake_case)]
|
||||
fn QueryPerformanceCounter(
|
||||
&mut self,
|
||||
lpPerformanceCount_op: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
lpPerformanceCount_op: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
this.assert_target_os("windows", "QueryPerformanceCounter");
|
||||
@ -261,8 +257,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
#[allow(non_snake_case)]
|
||||
fn QueryPerformanceFrequency(
|
||||
&mut self,
|
||||
lpFrequency_op: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
lpFrequency_op: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
this.assert_target_os("windows", "QueryPerformanceFrequency");
|
||||
@ -279,7 +275,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
Ok(Scalar::from_i32(-1)) // Return non-zero on success
|
||||
}
|
||||
|
||||
fn mach_absolute_time(&self) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
fn mach_absolute_time(&self) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_ref();
|
||||
|
||||
this.assert_target_os("macos", "mach_absolute_time");
|
||||
@ -293,10 +289,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
Ok(Scalar::from_u64(res))
|
||||
}
|
||||
|
||||
fn mach_timebase_info(
|
||||
&mut self,
|
||||
info_op: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
fn mach_timebase_info(&mut self, info_op: &OpTy<'tcx>) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
this.assert_target_os("macos", "mach_timebase_info");
|
||||
@ -313,8 +306,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
|
||||
fn nanosleep(
|
||||
&mut self,
|
||||
req_op: &OpTy<'tcx, Provenance>,
|
||||
_rem: &OpTy<'tcx, Provenance>, // Signal handlers are not supported, so rem will never be written to.
|
||||
req_op: &OpTy<'tcx>,
|
||||
_rem: &OpTy<'tcx>, // Signal handlers are not supported, so rem will never be written to.
|
||||
) -> InterpResult<'tcx, i32> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
@ -350,7 +343,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
fn Sleep(&mut self, timeout: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx> {
|
||||
fn Sleep(&mut self, timeout: &OpTy<'tcx>) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
this.assert_target_os("windows", "Sleep");
|
||||
|
@ -16,7 +16,7 @@ pub type TlsKey = u128;
|
||||
pub struct TlsEntry<'tcx> {
|
||||
/// The data for this key. None is used to represent NULL.
|
||||
/// (We normalize this early to avoid having to do a NULL-ptr-test each time we access the data.)
|
||||
data: BTreeMap<ThreadId, Scalar<Provenance>>,
|
||||
data: BTreeMap<ThreadId, Scalar>,
|
||||
dtor: Option<ty::Instance<'tcx>>,
|
||||
}
|
||||
|
||||
@ -38,7 +38,7 @@ pub struct TlsData<'tcx> {
|
||||
|
||||
/// A single per thread destructor of the thread local storage (that's how
|
||||
/// things work on macOS) with a data argument.
|
||||
macos_thread_dtors: BTreeMap<ThreadId, (ty::Instance<'tcx>, Scalar<Provenance>)>,
|
||||
macos_thread_dtors: BTreeMap<ThreadId, (ty::Instance<'tcx>, Scalar)>,
|
||||
}
|
||||
|
||||
impl<'tcx> Default for TlsData<'tcx> {
|
||||
@ -86,7 +86,7 @@ impl<'tcx> TlsData<'tcx> {
|
||||
key: TlsKey,
|
||||
thread_id: ThreadId,
|
||||
cx: &impl HasDataLayout,
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
) -> InterpResult<'tcx, Scalar> {
|
||||
match self.keys.get(&key) {
|
||||
Some(TlsEntry { data, .. }) => {
|
||||
let value = data.get(&thread_id).copied();
|
||||
@ -101,7 +101,7 @@ impl<'tcx> TlsData<'tcx> {
|
||||
&mut self,
|
||||
key: TlsKey,
|
||||
thread_id: ThreadId,
|
||||
new_data: Scalar<Provenance>,
|
||||
new_data: Scalar,
|
||||
cx: &impl HasDataLayout,
|
||||
) -> InterpResult<'tcx> {
|
||||
match self.keys.get_mut(&key) {
|
||||
@ -132,7 +132,7 @@ impl<'tcx> TlsData<'tcx> {
|
||||
&mut self,
|
||||
thread: ThreadId,
|
||||
dtor: ty::Instance<'tcx>,
|
||||
data: Scalar<Provenance>,
|
||||
data: Scalar,
|
||||
) -> InterpResult<'tcx> {
|
||||
if self.macos_thread_dtors.insert(thread, (dtor, data)).is_some() {
|
||||
throw_unsup_format!(
|
||||
@ -165,7 +165,7 @@ impl<'tcx> TlsData<'tcx> {
|
||||
&mut self,
|
||||
key: Option<TlsKey>,
|
||||
thread_id: ThreadId,
|
||||
) -> Option<(ty::Instance<'tcx>, Scalar<Provenance>, TlsKey)> {
|
||||
) -> Option<(ty::Instance<'tcx>, Scalar, TlsKey)> {
|
||||
use std::ops::Bound::*;
|
||||
|
||||
let thread_local = &mut self.keys;
|
||||
@ -228,7 +228,7 @@ enum TlsDtorsStatePriv<'tcx> {
|
||||
PthreadDtors(RunningDtorState),
|
||||
/// For Windows Dtors, we store the list of functions that we still have to call.
|
||||
/// These are functions from the magic `.CRT$XLB` linker section.
|
||||
WindowsDtors(Vec<ImmTy<'tcx, Provenance>>),
|
||||
WindowsDtors(Vec<ImmTy<'tcx>>),
|
||||
Done,
|
||||
}
|
||||
|
||||
@ -297,7 +297,7 @@ impl<'tcx> EvalContextPrivExt<'tcx> for crate::MiriInterpCx<'tcx> {}
|
||||
trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
/// Schedule TLS destructors for Windows.
|
||||
/// On windows, TLS destructors are managed by std.
|
||||
fn lookup_windows_tls_dtors(&mut self) -> InterpResult<'tcx, Vec<ImmTy<'tcx, Provenance>>> {
|
||||
fn lookup_windows_tls_dtors(&mut self) -> InterpResult<'tcx, Vec<ImmTy<'tcx>>> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
// Windows has a special magic linker section that is run on certain events.
|
||||
@ -305,7 +305,7 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
Ok(this.lookup_link_section(".CRT$XLB")?)
|
||||
}
|
||||
|
||||
fn schedule_windows_tls_dtor(&mut self, dtor: ImmTy<'tcx, Provenance>) -> InterpResult<'tcx> {
|
||||
fn schedule_windows_tls_dtor(&mut self, dtor: ImmTy<'tcx>) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let dtor = dtor.to_scalar().to_pointer(this)?;
|
||||
|
@ -13,8 +13,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
&mut self,
|
||||
link_name: Symbol,
|
||||
abi: Abi,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
args: &[OpTy<'tcx>],
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx, EmulateItemResult> {
|
||||
let this = self.eval_context_mut();
|
||||
match link_name.as_str() {
|
||||
|
@ -13,10 +13,10 @@ use crate::*;
|
||||
pub struct UnixEnvVars<'tcx> {
|
||||
/// Stores pointers to the environment variables. These variables must be stored as
|
||||
/// null-terminated target strings (c_str or wide_str) with the `"{name}={value}"` format.
|
||||
map: FxHashMap<OsString, Pointer<Option<Provenance>>>,
|
||||
map: FxHashMap<OsString, Pointer>,
|
||||
|
||||
/// Place where the `environ` static is stored. Lazily initialized, but then never changes.
|
||||
environ: MPlaceTy<'tcx, Provenance>,
|
||||
environ: MPlaceTy<'tcx>,
|
||||
}
|
||||
|
||||
impl VisitProvenance for UnixEnvVars<'_> {
|
||||
@ -65,7 +65,7 @@ impl<'tcx> UnixEnvVars<'tcx> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn environ(&self) -> Pointer<Option<Provenance>> {
|
||||
pub(crate) fn environ(&self) -> Pointer {
|
||||
self.environ.ptr()
|
||||
}
|
||||
|
||||
@ -73,7 +73,7 @@ impl<'tcx> UnixEnvVars<'tcx> {
|
||||
&self,
|
||||
ecx: &InterpCx<'tcx, MiriMachine<'tcx>>,
|
||||
name: &OsStr,
|
||||
) -> InterpResult<'tcx, Option<Pointer<Option<Provenance>>>> {
|
||||
) -> InterpResult<'tcx, Option<Pointer>> {
|
||||
// We don't care about the value as we have the `map` to keep track of everything,
|
||||
// but we do want to do this read so it shows up as a data race.
|
||||
let _vars_ptr = ecx.read_pointer(&self.environ)?;
|
||||
@ -109,7 +109,7 @@ fn alloc_env_var<'tcx>(
|
||||
ecx: &mut InterpCx<'tcx, MiriMachine<'tcx>>,
|
||||
name: &OsStr,
|
||||
value: &OsStr,
|
||||
) -> InterpResult<'tcx, Pointer<Option<Provenance>>> {
|
||||
) -> InterpResult<'tcx, Pointer> {
|
||||
let mut name_osstring = name.to_os_string();
|
||||
name_osstring.push("=");
|
||||
name_osstring.push(value);
|
||||
@ -119,8 +119,8 @@ fn alloc_env_var<'tcx>(
|
||||
/// Allocates an `environ` block with the given list of pointers.
|
||||
fn alloc_environ_block<'tcx>(
|
||||
ecx: &mut InterpCx<'tcx, MiriMachine<'tcx>>,
|
||||
mut vars: Vec<Pointer<Option<Provenance>>>,
|
||||
) -> InterpResult<'tcx, Pointer<Option<Provenance>>> {
|
||||
mut vars: Vec<Pointer>,
|
||||
) -> InterpResult<'tcx, Pointer> {
|
||||
// Add trailing null.
|
||||
vars.push(Pointer::null());
|
||||
// Make an array with all these pointers inside Miri.
|
||||
@ -139,10 +139,7 @@ fn alloc_environ_block<'tcx>(
|
||||
|
||||
impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
|
||||
pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
fn getenv(
|
||||
&mut self,
|
||||
name_op: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, Pointer<Option<Provenance>>> {
|
||||
fn getenv(&mut self, name_op: &OpTy<'tcx>) -> InterpResult<'tcx, Pointer> {
|
||||
let this = self.eval_context_mut();
|
||||
this.assert_target_os_is_unix("getenv");
|
||||
|
||||
@ -153,11 +150,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
Ok(var_ptr.unwrap_or_else(Pointer::null))
|
||||
}
|
||||
|
||||
fn setenv(
|
||||
&mut self,
|
||||
name_op: &OpTy<'tcx, Provenance>,
|
||||
value_op: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, i32> {
|
||||
fn setenv(&mut self, name_op: &OpTy<'tcx>, value_op: &OpTy<'tcx>) -> InterpResult<'tcx, i32> {
|
||||
let this = self.eval_context_mut();
|
||||
this.assert_target_os_is_unix("setenv");
|
||||
|
||||
@ -187,7 +180,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn unsetenv(&mut self, name_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx, i32> {
|
||||
fn unsetenv(&mut self, name_op: &OpTy<'tcx>) -> InterpResult<'tcx, i32> {
|
||||
let this = self.eval_context_mut();
|
||||
this.assert_target_os_is_unix("unsetenv");
|
||||
|
||||
@ -213,11 +206,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn getcwd(
|
||||
&mut self,
|
||||
buf_op: &OpTy<'tcx, Provenance>,
|
||||
size_op: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, Pointer<Option<Provenance>>> {
|
||||
fn getcwd(&mut self, buf_op: &OpTy<'tcx>, size_op: &OpTy<'tcx>) -> InterpResult<'tcx, Pointer> {
|
||||
let this = self.eval_context_mut();
|
||||
this.assert_target_os_is_unix("getcwd");
|
||||
|
||||
@ -245,7 +234,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
Ok(Pointer::null())
|
||||
}
|
||||
|
||||
fn chdir(&mut self, path_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx, i32> {
|
||||
fn chdir(&mut self, path_op: &OpTy<'tcx>) -> InterpResult<'tcx, i32> {
|
||||
let this = self.eval_context_mut();
|
||||
this.assert_target_os_is_unix("chdir");
|
||||
|
||||
|
@ -273,7 +273,7 @@ impl FdTable {
|
||||
|
||||
impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
|
||||
pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
fn fcntl(&mut self, args: &[OpTy<'tcx, Provenance>]) -> InterpResult<'tcx, i32> {
|
||||
fn fcntl(&mut self, args: &[OpTy<'tcx>]) -> InterpResult<'tcx, i32> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
if args.len() < 2 {
|
||||
@ -329,7 +329,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn close(&mut self, fd_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
fn close(&mut self, fd_op: &OpTy<'tcx>) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let fd = this.read_scalar(fd_op)?.to_i32()?;
|
||||
@ -355,12 +355,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
Ok((-1).into())
|
||||
}
|
||||
|
||||
fn read(
|
||||
&mut self,
|
||||
fd: i32,
|
||||
buf: Pointer<Option<Provenance>>,
|
||||
count: u64,
|
||||
) -> InterpResult<'tcx, i64> {
|
||||
fn read(&mut self, fd: i32, buf: Pointer, count: u64) -> InterpResult<'tcx, i64> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
// Isolation check is done via `FileDescriptor` trait.
|
||||
@ -409,12 +404,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn write(
|
||||
&mut self,
|
||||
fd: i32,
|
||||
buf: Pointer<Option<Provenance>>,
|
||||
count: u64,
|
||||
) -> InterpResult<'tcx, i64> {
|
||||
fn write(&mut self, fd: i32, buf: Pointer, count: u64) -> InterpResult<'tcx, i64> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
// Isolation check is done via `FileDescriptor` trait.
|
||||
|
@ -43,8 +43,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
&mut self,
|
||||
link_name: Symbol,
|
||||
abi: Abi,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
args: &[OpTy<'tcx>],
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx, EmulateItemResult> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
@ -326,7 +326,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
let name = this.read_scalar(name)?.to_i32()?;
|
||||
// FIXME: Which of these are POSIX, and which are GNU/Linux?
|
||||
// At least the names seem to all also exist on macOS.
|
||||
let sysconfs: &[(&str, fn(&MiriInterpCx<'_>) -> Scalar<Provenance>)] = &[
|
||||
let sysconfs: &[(&str, fn(&MiriInterpCx<'_>) -> Scalar)] = &[
|
||||
("_SC_PAGESIZE", |this| Scalar::from_int(this.machine.page_size, this.pointer_size())),
|
||||
("_SC_NPROCESSORS_CONF", |this| Scalar::from_int(this.machine.num_cpus, this.pointer_size())),
|
||||
("_SC_NPROCESSORS_ONLN", |this| Scalar::from_int(this.machine.num_cpus, this.pointer_size())),
|
||||
|
@ -14,8 +14,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
&mut self,
|
||||
link_name: Symbol,
|
||||
abi: Abi,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
args: &[OpTy<'tcx>],
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx, EmulateItemResult> {
|
||||
let this = self.eval_context_mut();
|
||||
match link_name.as_str() {
|
||||
|
@ -91,7 +91,7 @@ trait EvalContextExtPrivate<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
fn macos_stat_write_buf(
|
||||
&mut self,
|
||||
metadata: FileMetadata,
|
||||
buf_op: &OpTy<'tcx, Provenance>,
|
||||
buf_op: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, i32> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
@ -180,7 +180,7 @@ struct OpenDir {
|
||||
read_dir: ReadDir,
|
||||
/// The most recent entry returned by readdir().
|
||||
/// Will be freed by the next call.
|
||||
entry: Option<Pointer<Option<Provenance>>>,
|
||||
entry: Option<Pointer>,
|
||||
}
|
||||
|
||||
impl OpenDir {
|
||||
@ -256,7 +256,7 @@ fn maybe_sync_file(
|
||||
|
||||
impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
|
||||
pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
fn open(&mut self, args: &[OpTy<'tcx, Provenance>]) -> InterpResult<'tcx, i32> {
|
||||
fn open(&mut self, args: &[OpTy<'tcx>]) -> InterpResult<'tcx, i32> {
|
||||
if args.len() < 2 {
|
||||
throw_ub_format!(
|
||||
"incorrect number of arguments for `open`: got {}, expected at least 2",
|
||||
@ -389,12 +389,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
this.try_unwrap_io_result(fd)
|
||||
}
|
||||
|
||||
fn lseek64(
|
||||
&mut self,
|
||||
fd: i32,
|
||||
offset: i128,
|
||||
whence: i32,
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
fn lseek64(&mut self, fd: i32, offset: i128, whence: i32) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
// Isolation check is done via `FileDescriptor` trait.
|
||||
@ -425,7 +420,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
Ok(Scalar::from_i64(result))
|
||||
}
|
||||
|
||||
fn unlink(&mut self, path_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx, i32> {
|
||||
fn unlink(&mut self, path_op: &OpTy<'tcx>) -> InterpResult<'tcx, i32> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let path = this.read_path_from_c_str(this.read_pointer(path_op)?)?;
|
||||
@ -443,8 +438,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
|
||||
fn symlink(
|
||||
&mut self,
|
||||
target_op: &OpTy<'tcx, Provenance>,
|
||||
linkpath_op: &OpTy<'tcx, Provenance>,
|
||||
target_op: &OpTy<'tcx>,
|
||||
linkpath_op: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, i32> {
|
||||
#[cfg(unix)]
|
||||
fn create_link(src: &Path, dst: &Path) -> std::io::Result<()> {
|
||||
@ -474,9 +469,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
|
||||
fn macos_fbsd_stat(
|
||||
&mut self,
|
||||
path_op: &OpTy<'tcx, Provenance>,
|
||||
buf_op: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
path_op: &OpTy<'tcx>,
|
||||
buf_op: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
if !matches!(&*this.tcx.sess.target.os, "macos" | "freebsd") {
|
||||
@ -506,9 +501,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
// `lstat` is used to get symlink metadata.
|
||||
fn macos_fbsd_lstat(
|
||||
&mut self,
|
||||
path_op: &OpTy<'tcx, Provenance>,
|
||||
buf_op: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
path_op: &OpTy<'tcx>,
|
||||
buf_op: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
if !matches!(&*this.tcx.sess.target.os, "macos" | "freebsd") {
|
||||
@ -536,9 +531,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
|
||||
fn macos_fbsd_fstat(
|
||||
&mut self,
|
||||
fd_op: &OpTy<'tcx, Provenance>,
|
||||
buf_op: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
fd_op: &OpTy<'tcx>,
|
||||
buf_op: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
if !matches!(&*this.tcx.sess.target.os, "macos" | "freebsd") {
|
||||
@ -563,11 +558,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
|
||||
fn linux_statx(
|
||||
&mut self,
|
||||
dirfd_op: &OpTy<'tcx, Provenance>, // Should be an `int`
|
||||
pathname_op: &OpTy<'tcx, Provenance>, // Should be a `const char *`
|
||||
flags_op: &OpTy<'tcx, Provenance>, // Should be an `int`
|
||||
mask_op: &OpTy<'tcx, Provenance>, // Should be an `unsigned int`
|
||||
statxbuf_op: &OpTy<'tcx, Provenance>, // Should be a `struct statx *`
|
||||
dirfd_op: &OpTy<'tcx>, // Should be an `int`
|
||||
pathname_op: &OpTy<'tcx>, // Should be a `const char *`
|
||||
flags_op: &OpTy<'tcx>, // Should be an `int`
|
||||
mask_op: &OpTy<'tcx>, // Should be an `unsigned int`
|
||||
statxbuf_op: &OpTy<'tcx>, // Should be a `struct statx *`
|
||||
) -> InterpResult<'tcx, i32> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
@ -745,8 +740,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
|
||||
fn rename(
|
||||
&mut self,
|
||||
oldpath_op: &OpTy<'tcx, Provenance>,
|
||||
newpath_op: &OpTy<'tcx, Provenance>,
|
||||
oldpath_op: &OpTy<'tcx>,
|
||||
newpath_op: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, i32> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
@ -774,11 +769,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
this.try_unwrap_io_result(result)
|
||||
}
|
||||
|
||||
fn mkdir(
|
||||
&mut self,
|
||||
path_op: &OpTy<'tcx, Provenance>,
|
||||
mode_op: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, i32> {
|
||||
fn mkdir(&mut self, path_op: &OpTy<'tcx>, mode_op: &OpTy<'tcx>) -> InterpResult<'tcx, i32> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
#[cfg_attr(not(unix), allow(unused_variables))]
|
||||
@ -813,7 +804,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
this.try_unwrap_io_result(result)
|
||||
}
|
||||
|
||||
fn rmdir(&mut self, path_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx, i32> {
|
||||
fn rmdir(&mut self, path_op: &OpTy<'tcx>) -> InterpResult<'tcx, i32> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let path = this.read_path_from_c_str(this.read_pointer(path_op)?)?;
|
||||
@ -830,10 +821,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
this.try_unwrap_io_result(result)
|
||||
}
|
||||
|
||||
fn opendir(
|
||||
&mut self,
|
||||
name_op: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
fn opendir(&mut self, name_op: &OpTy<'tcx>) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let name = this.read_path_from_c_str(this.read_pointer(name_op)?)?;
|
||||
@ -864,10 +852,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn linux_readdir64(
|
||||
&mut self,
|
||||
dirp_op: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
fn linux_readdir64(&mut self, dirp_op: &OpTy<'tcx>) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
this.assert_target_os("linux", "readdir64");
|
||||
@ -915,7 +900,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
dirent64_layout.align.abi,
|
||||
MiriMemoryKind::Runtime.into(),
|
||||
)?;
|
||||
let entry: Pointer<Option<Provenance>> = entry.into();
|
||||
let entry: Pointer = entry.into();
|
||||
|
||||
// If the host is a Unix system, fill in the inode number with its real value.
|
||||
// If not, use 0 as a fallback value.
|
||||
@ -962,10 +947,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
|
||||
fn macos_fbsd_readdir_r(
|
||||
&mut self,
|
||||
dirp_op: &OpTy<'tcx, Provenance>,
|
||||
entry_op: &OpTy<'tcx, Provenance>,
|
||||
result_op: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
dirp_op: &OpTy<'tcx>,
|
||||
entry_op: &OpTy<'tcx>,
|
||||
result_op: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
if !matches!(&*this.tcx.sess.target.os, "macos" | "freebsd") {
|
||||
@ -1083,7 +1068,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
}))
|
||||
}
|
||||
|
||||
fn closedir(&mut self, dirp_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx, i32> {
|
||||
fn closedir(&mut self, dirp_op: &OpTy<'tcx>) -> InterpResult<'tcx, i32> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let dirp = this.read_target_usize(dirp_op)?;
|
||||
@ -1106,7 +1091,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn ftruncate64(&mut self, fd: i32, length: i128) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
fn ftruncate64(&mut self, fd: i32, length: i128) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
// Reject if isolation is enabled.
|
||||
@ -1147,7 +1132,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn fsync(&mut self, fd_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx, i32> {
|
||||
fn fsync(&mut self, fd_op: &OpTy<'tcx>) -> InterpResult<'tcx, i32> {
|
||||
// On macOS, `fsync` (unlike `fcntl(F_FULLFSYNC)`) does not wait for the
|
||||
// underlying disk to finish writing. In the interest of host compatibility,
|
||||
// we conservatively implement this with `sync_all`, which
|
||||
@ -1182,7 +1167,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
this.try_unwrap_io_result(io_result)
|
||||
}
|
||||
|
||||
fn fdatasync(&mut self, fd_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx, i32> {
|
||||
fn fdatasync(&mut self, fd_op: &OpTy<'tcx>) -> InterpResult<'tcx, i32> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let fd = this.read_scalar(fd_op)?.to_i32()?;
|
||||
@ -1209,11 +1194,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
|
||||
fn sync_file_range(
|
||||
&mut self,
|
||||
fd_op: &OpTy<'tcx, Provenance>,
|
||||
offset_op: &OpTy<'tcx, Provenance>,
|
||||
nbytes_op: &OpTy<'tcx, Provenance>,
|
||||
flags_op: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
fd_op: &OpTy<'tcx>,
|
||||
offset_op: &OpTy<'tcx>,
|
||||
nbytes_op: &OpTy<'tcx>,
|
||||
flags_op: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let fd = this.read_scalar(fd_op)?.to_i32()?;
|
||||
@ -1259,9 +1244,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
|
||||
fn readlink(
|
||||
&mut self,
|
||||
pathname_op: &OpTy<'tcx, Provenance>,
|
||||
buf_op: &OpTy<'tcx, Provenance>,
|
||||
bufsize_op: &OpTy<'tcx, Provenance>,
|
||||
pathname_op: &OpTy<'tcx>,
|
||||
buf_op: &OpTy<'tcx>,
|
||||
bufsize_op: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, i64> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
@ -1302,10 +1287,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn isatty(
|
||||
&mut self,
|
||||
miri_fd: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
fn isatty(&mut self, miri_fd: &OpTy<'tcx>) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_mut();
|
||||
// "returns 1 if fd is an open file descriptor referring to a terminal;
|
||||
// otherwise 0 is returned, and errno is set to indicate the error"
|
||||
@ -1326,9 +1308,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
|
||||
fn realpath(
|
||||
&mut self,
|
||||
path_op: &OpTy<'tcx, Provenance>,
|
||||
processed_path_op: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
path_op: &OpTy<'tcx>,
|
||||
processed_path_op: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_mut();
|
||||
this.assert_target_os_is_unix("realpath");
|
||||
|
||||
@ -1384,7 +1366,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
fn mkstemp(&mut self, template_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx, i32> {
|
||||
fn mkstemp(&mut self, template_op: &OpTy<'tcx>) -> InterpResult<'tcx, i32> {
|
||||
use rand::seq::SliceRandom;
|
||||
|
||||
// POSIX defines the template string.
|
||||
@ -1531,7 +1513,7 @@ fn extract_sec_and_nsec<'tcx>(
|
||||
/// Stores a file's metadata in order to avoid code duplication in the different metadata related
|
||||
/// shims.
|
||||
struct FileMetadata {
|
||||
mode: Scalar<Provenance>,
|
||||
mode: Scalar,
|
||||
size: u64,
|
||||
created: Option<(u64, u32)>,
|
||||
accessed: Option<(u64, u32)>,
|
||||
|
@ -25,10 +25,10 @@ struct Epoll {
|
||||
struct EpollEvent {
|
||||
#[allow(dead_code)]
|
||||
events: u32,
|
||||
/// `Scalar<Provenance>` is used to represent the
|
||||
/// `Scalar` is used to represent the
|
||||
/// `epoll_data` type union.
|
||||
#[allow(dead_code)]
|
||||
data: Scalar<Provenance>,
|
||||
data: Scalar,
|
||||
}
|
||||
|
||||
impl FileDescription for Epoll {
|
||||
@ -51,10 +51,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
/// is 0, then this function is the same as `epoll_create()`.
|
||||
///
|
||||
/// <https://linux.die.net/man/2/epoll_create1>
|
||||
fn epoll_create1(
|
||||
&mut self,
|
||||
flags: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
fn epoll_create1(&mut self, flags: &OpTy<'tcx>) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let flags = this.read_scalar(flags)?.to_i32()?;
|
||||
@ -85,11 +82,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
/// <https://linux.die.net/man/2/epoll_ctl>
|
||||
fn epoll_ctl(
|
||||
&mut self,
|
||||
epfd: &OpTy<'tcx, Provenance>,
|
||||
op: &OpTy<'tcx, Provenance>,
|
||||
fd: &OpTy<'tcx, Provenance>,
|
||||
event: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
epfd: &OpTy<'tcx>,
|
||||
op: &OpTy<'tcx>,
|
||||
fd: &OpTy<'tcx>,
|
||||
event: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let epfd = this.read_scalar(epfd)?.to_i32()?;
|
||||
@ -167,11 +164,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
/// <https://man7.org/linux/man-pages/man2/epoll_wait.2.html>
|
||||
fn epoll_wait(
|
||||
&mut self,
|
||||
epfd: &OpTy<'tcx, Provenance>,
|
||||
events: &OpTy<'tcx, Provenance>,
|
||||
maxevents: &OpTy<'tcx, Provenance>,
|
||||
timeout: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
epfd: &OpTy<'tcx>,
|
||||
events: &OpTy<'tcx>,
|
||||
maxevents: &OpTy<'tcx>,
|
||||
timeout: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let epfd = this.read_scalar(epfd)?.to_i32()?;
|
||||
|
@ -84,11 +84,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
/// `EFD_SEMAPHORE` - miri does not support semaphore-like semantics.
|
||||
///
|
||||
/// <https://linux.die.net/man/2/eventfd>
|
||||
fn eventfd(
|
||||
&mut self,
|
||||
val: &OpTy<'tcx, Provenance>,
|
||||
flags: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
fn eventfd(&mut self, val: &OpTy<'tcx>, flags: &OpTy<'tcx>) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let val = this.read_scalar(val)?.to_u32()?;
|
||||
|
@ -20,8 +20,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
&mut self,
|
||||
link_name: Symbol,
|
||||
abi: Abi,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
args: &[OpTy<'tcx>],
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx, EmulateItemResult> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
|
@ -8,11 +8,11 @@ impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
|
||||
pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
fn mremap(
|
||||
&mut self,
|
||||
old_address: &OpTy<'tcx, Provenance>,
|
||||
old_size: &OpTy<'tcx, Provenance>,
|
||||
new_size: &OpTy<'tcx, Provenance>,
|
||||
flags: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
old_address: &OpTy<'tcx>,
|
||||
old_size: &OpTy<'tcx>,
|
||||
new_size: &OpTy<'tcx>,
|
||||
flags: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let old_address = this.read_pointer(old_address)?;
|
||||
|
@ -6,8 +6,8 @@ use crate::*;
|
||||
/// `args` is the arguments *after* the syscall number.
|
||||
pub fn futex<'tcx>(
|
||||
this: &mut MiriInterpCx<'tcx>,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
args: &[OpTy<'tcx>],
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx> {
|
||||
// The amount of arguments used depends on the type of futex operation.
|
||||
// The full futex syscall takes six arguments (excluding the syscall
|
||||
|
@ -14,8 +14,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
&mut self,
|
||||
link_name: Symbol,
|
||||
abi: Abi,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
args: &[OpTy<'tcx>],
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx, EmulateItemResult> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
|
@ -21,13 +21,13 @@ impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
|
||||
pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
fn mmap(
|
||||
&mut self,
|
||||
addr: &OpTy<'tcx, Provenance>,
|
||||
length: &OpTy<'tcx, Provenance>,
|
||||
prot: &OpTy<'tcx, Provenance>,
|
||||
flags: &OpTy<'tcx, Provenance>,
|
||||
fd: &OpTy<'tcx, Provenance>,
|
||||
addr: &OpTy<'tcx>,
|
||||
length: &OpTy<'tcx>,
|
||||
prot: &OpTy<'tcx>,
|
||||
flags: &OpTy<'tcx>,
|
||||
fd: &OpTy<'tcx>,
|
||||
offset: i128,
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
// We do not support MAP_FIXED, so the addr argument is always ignored (except for the MacOS hack)
|
||||
@ -123,11 +123,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
Ok(Scalar::from_pointer(ptr, this))
|
||||
}
|
||||
|
||||
fn munmap(
|
||||
&mut self,
|
||||
addr: &OpTy<'tcx, Provenance>,
|
||||
length: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
fn munmap(&mut self, addr: &OpTy<'tcx>, length: &OpTy<'tcx>) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let addr = this.read_pointer(addr)?;
|
||||
|
@ -35,11 +35,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
/// <https://linux.die.net/man/2/socketpair>
|
||||
fn socketpair(
|
||||
&mut self,
|
||||
domain: &OpTy<'tcx, Provenance>,
|
||||
type_: &OpTy<'tcx, Provenance>,
|
||||
protocol: &OpTy<'tcx, Provenance>,
|
||||
sv: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
domain: &OpTy<'tcx>,
|
||||
type_: &OpTy<'tcx>,
|
||||
protocol: &OpTy<'tcx>,
|
||||
sv: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let _domain = this.read_scalar(domain)?.to_i32()?;
|
||||
|
@ -14,8 +14,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
&mut self,
|
||||
link_name: Symbol,
|
||||
abi: Abi,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
args: &[OpTy<'tcx>],
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx, EmulateItemResult> {
|
||||
let this = self.eval_context_mut();
|
||||
match link_name.as_str() {
|
||||
|
@ -19,7 +19,7 @@ fn mutexattr_kind_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, u
|
||||
|
||||
fn mutexattr_get_kind<'tcx>(
|
||||
ecx: &MiriInterpCx<'tcx>,
|
||||
attr_op: &OpTy<'tcx, Provenance>,
|
||||
attr_op: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, i32> {
|
||||
ecx.deref_pointer_and_read(
|
||||
attr_op,
|
||||
@ -32,7 +32,7 @@ fn mutexattr_get_kind<'tcx>(
|
||||
|
||||
fn mutexattr_set_kind<'tcx>(
|
||||
ecx: &mut MiriInterpCx<'tcx>,
|
||||
attr_op: &OpTy<'tcx, Provenance>,
|
||||
attr_op: &OpTy<'tcx>,
|
||||
kind: i32,
|
||||
) -> InterpResult<'tcx, ()> {
|
||||
ecx.deref_pointer_and_write(
|
||||
@ -117,7 +117,7 @@ fn mutex_kind_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> u64 {
|
||||
|
||||
fn mutex_get_id<'tcx>(
|
||||
ecx: &mut MiriInterpCx<'tcx>,
|
||||
mutex_op: &OpTy<'tcx, Provenance>,
|
||||
mutex_op: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, MutexId> {
|
||||
ecx.mutex_get_or_create_id(
|
||||
mutex_op,
|
||||
@ -128,7 +128,7 @@ fn mutex_get_id<'tcx>(
|
||||
|
||||
fn mutex_reset_id<'tcx>(
|
||||
ecx: &mut MiriInterpCx<'tcx>,
|
||||
mutex_op: &OpTy<'tcx, Provenance>,
|
||||
mutex_op: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, ()> {
|
||||
ecx.deref_pointer_and_write(
|
||||
mutex_op,
|
||||
@ -141,7 +141,7 @@ fn mutex_reset_id<'tcx>(
|
||||
|
||||
fn mutex_get_kind<'tcx>(
|
||||
ecx: &MiriInterpCx<'tcx>,
|
||||
mutex_op: &OpTy<'tcx, Provenance>,
|
||||
mutex_op: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, i32> {
|
||||
ecx.deref_pointer_and_read(
|
||||
mutex_op,
|
||||
@ -154,7 +154,7 @@ fn mutex_get_kind<'tcx>(
|
||||
|
||||
fn mutex_set_kind<'tcx>(
|
||||
ecx: &mut MiriInterpCx<'tcx>,
|
||||
mutex_op: &OpTy<'tcx, Provenance>,
|
||||
mutex_op: &OpTy<'tcx>,
|
||||
kind: i32,
|
||||
) -> InterpResult<'tcx, ()> {
|
||||
ecx.deref_pointer_and_write(
|
||||
@ -198,7 +198,7 @@ fn rwlock_id_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, u64> {
|
||||
|
||||
fn rwlock_get_id<'tcx>(
|
||||
ecx: &mut MiriInterpCx<'tcx>,
|
||||
rwlock_op: &OpTy<'tcx, Provenance>,
|
||||
rwlock_op: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, RwLockId> {
|
||||
ecx.rwlock_get_or_create_id(
|
||||
rwlock_op,
|
||||
@ -222,7 +222,7 @@ fn condattr_clock_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> InterpResult<'tcx, u
|
||||
|
||||
fn condattr_get_clock_id<'tcx>(
|
||||
ecx: &MiriInterpCx<'tcx>,
|
||||
attr_op: &OpTy<'tcx, Provenance>,
|
||||
attr_op: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, i32> {
|
||||
ecx.deref_pointer_and_read(
|
||||
attr_op,
|
||||
@ -235,7 +235,7 @@ fn condattr_get_clock_id<'tcx>(
|
||||
|
||||
fn condattr_set_clock_id<'tcx>(
|
||||
ecx: &mut MiriInterpCx<'tcx>,
|
||||
attr_op: &OpTy<'tcx, Provenance>,
|
||||
attr_op: &OpTy<'tcx>,
|
||||
clock_id: i32,
|
||||
) -> InterpResult<'tcx, ()> {
|
||||
ecx.deref_pointer_and_write(
|
||||
@ -313,7 +313,7 @@ fn cond_clock_offset<'tcx>(ecx: &MiriInterpCx<'tcx>) -> u64 {
|
||||
|
||||
fn cond_get_id<'tcx>(
|
||||
ecx: &mut MiriInterpCx<'tcx>,
|
||||
cond_op: &OpTy<'tcx, Provenance>,
|
||||
cond_op: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, CondvarId> {
|
||||
ecx.condvar_get_or_create_id(
|
||||
cond_op,
|
||||
@ -324,7 +324,7 @@ fn cond_get_id<'tcx>(
|
||||
|
||||
fn cond_reset_id<'tcx>(
|
||||
ecx: &mut MiriInterpCx<'tcx>,
|
||||
cond_op: &OpTy<'tcx, Provenance>,
|
||||
cond_op: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, ()> {
|
||||
ecx.deref_pointer_and_write(
|
||||
cond_op,
|
||||
@ -337,7 +337,7 @@ fn cond_reset_id<'tcx>(
|
||||
|
||||
fn cond_get_clock_id<'tcx>(
|
||||
ecx: &MiriInterpCx<'tcx>,
|
||||
cond_op: &OpTy<'tcx, Provenance>,
|
||||
cond_op: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, i32> {
|
||||
ecx.deref_pointer_and_read(
|
||||
cond_op,
|
||||
@ -350,7 +350,7 @@ fn cond_get_clock_id<'tcx>(
|
||||
|
||||
fn cond_set_clock_id<'tcx>(
|
||||
ecx: &mut MiriInterpCx<'tcx>,
|
||||
cond_op: &OpTy<'tcx, Provenance>,
|
||||
cond_op: &OpTy<'tcx>,
|
||||
clock_id: i32,
|
||||
) -> InterpResult<'tcx, ()> {
|
||||
ecx.deref_pointer_and_write(
|
||||
@ -364,10 +364,7 @@ fn cond_set_clock_id<'tcx>(
|
||||
|
||||
impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
|
||||
pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
fn pthread_mutexattr_init(
|
||||
&mut self,
|
||||
attr_op: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, i32> {
|
||||
fn pthread_mutexattr_init(&mut self, attr_op: &OpTy<'tcx>) -> InterpResult<'tcx, i32> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let default_kind = this.eval_libc_i32("PTHREAD_MUTEX_DEFAULT");
|
||||
@ -378,8 +375,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
|
||||
fn pthread_mutexattr_settype(
|
||||
&mut self,
|
||||
attr_op: &OpTy<'tcx, Provenance>,
|
||||
kind_op: &OpTy<'tcx, Provenance>,
|
||||
attr_op: &OpTy<'tcx>,
|
||||
kind_op: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, i32> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
@ -417,10 +414,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
fn pthread_mutexattr_destroy(
|
||||
&mut self,
|
||||
attr_op: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, i32> {
|
||||
fn pthread_mutexattr_destroy(&mut self, attr_op: &OpTy<'tcx>) -> InterpResult<'tcx, i32> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
// Destroying an uninit pthread_mutexattr is UB, so check to make sure it's not uninit.
|
||||
@ -447,8 +441,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
|
||||
fn pthread_mutex_init(
|
||||
&mut self,
|
||||
mutex_op: &OpTy<'tcx, Provenance>,
|
||||
attr_op: &OpTy<'tcx, Provenance>,
|
||||
mutex_op: &OpTy<'tcx>,
|
||||
attr_op: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, i32> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
@ -469,8 +463,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
|
||||
fn pthread_mutex_lock(
|
||||
&mut self,
|
||||
mutex_op: &OpTy<'tcx, Provenance>,
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
mutex_op: &OpTy<'tcx>,
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
@ -508,10 +502,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn pthread_mutex_trylock(
|
||||
&mut self,
|
||||
mutex_op: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, i32> {
|
||||
fn pthread_mutex_trylock(&mut self, mutex_op: &OpTy<'tcx>) -> InterpResult<'tcx, i32> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let kind = mutex_get_kind(this, mutex_op)?;
|
||||
@ -543,10 +534,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn pthread_mutex_unlock(
|
||||
&mut self,
|
||||
mutex_op: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, i32> {
|
||||
fn pthread_mutex_unlock(&mut self, mutex_op: &OpTy<'tcx>) -> InterpResult<'tcx, i32> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let kind = mutex_get_kind(this, mutex_op)?;
|
||||
@ -577,10 +565,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn pthread_mutex_destroy(
|
||||
&mut self,
|
||||
mutex_op: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, i32> {
|
||||
fn pthread_mutex_destroy(&mut self, mutex_op: &OpTy<'tcx>) -> InterpResult<'tcx, i32> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let id = mutex_get_id(this, mutex_op)?;
|
||||
@ -604,8 +589,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
|
||||
fn pthread_rwlock_rdlock(
|
||||
&mut self,
|
||||
rwlock_op: &OpTy<'tcx, Provenance>,
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
rwlock_op: &OpTy<'tcx>,
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
@ -621,10 +606,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn pthread_rwlock_tryrdlock(
|
||||
&mut self,
|
||||
rwlock_op: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, i32> {
|
||||
fn pthread_rwlock_tryrdlock(&mut self, rwlock_op: &OpTy<'tcx>) -> InterpResult<'tcx, i32> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let id = rwlock_get_id(this, rwlock_op)?;
|
||||
@ -639,8 +621,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
|
||||
fn pthread_rwlock_wrlock(
|
||||
&mut self,
|
||||
rwlock_op: &OpTy<'tcx, Provenance>,
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
rwlock_op: &OpTy<'tcx>,
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
@ -668,10 +650,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn pthread_rwlock_trywrlock(
|
||||
&mut self,
|
||||
rwlock_op: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, i32> {
|
||||
fn pthread_rwlock_trywrlock(&mut self, rwlock_op: &OpTy<'tcx>) -> InterpResult<'tcx, i32> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let id = rwlock_get_id(this, rwlock_op)?;
|
||||
@ -684,10 +663,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn pthread_rwlock_unlock(
|
||||
&mut self,
|
||||
rwlock_op: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, i32> {
|
||||
fn pthread_rwlock_unlock(&mut self, rwlock_op: &OpTy<'tcx>) -> InterpResult<'tcx, i32> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let id = rwlock_get_id(this, rwlock_op)?;
|
||||
@ -702,10 +678,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn pthread_rwlock_destroy(
|
||||
&mut self,
|
||||
rwlock_op: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, i32> {
|
||||
fn pthread_rwlock_destroy(&mut self, rwlock_op: &OpTy<'tcx>) -> InterpResult<'tcx, i32> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let id = rwlock_get_id(this, rwlock_op)?;
|
||||
@ -726,10 +699,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
fn pthread_condattr_init(
|
||||
&mut self,
|
||||
attr_op: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, i32> {
|
||||
fn pthread_condattr_init(&mut self, attr_op: &OpTy<'tcx>) -> InterpResult<'tcx, i32> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
// no clock attribute on macOS
|
||||
@ -746,9 +716,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
|
||||
fn pthread_condattr_setclock(
|
||||
&mut self,
|
||||
attr_op: &OpTy<'tcx, Provenance>,
|
||||
clock_id_op: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
attr_op: &OpTy<'tcx>,
|
||||
clock_id_op: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let clock_id = this.read_scalar(clock_id_op)?.to_i32()?;
|
||||
@ -766,9 +736,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
|
||||
fn pthread_condattr_getclock(
|
||||
&mut self,
|
||||
attr_op: &OpTy<'tcx, Provenance>,
|
||||
clk_id_op: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
attr_op: &OpTy<'tcx>,
|
||||
clk_id_op: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let clock_id = condattr_get_clock_id(this, attr_op)?;
|
||||
@ -777,10 +747,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
Ok(Scalar::from_i32(0))
|
||||
}
|
||||
|
||||
fn pthread_condattr_destroy(
|
||||
&mut self,
|
||||
attr_op: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, i32> {
|
||||
fn pthread_condattr_destroy(&mut self, attr_op: &OpTy<'tcx>) -> InterpResult<'tcx, i32> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
// Destroying an uninit pthread_condattr is UB, so check to make sure it's not uninit.
|
||||
@ -800,8 +767,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
|
||||
fn pthread_cond_init(
|
||||
&mut self,
|
||||
cond_op: &OpTy<'tcx, Provenance>,
|
||||
attr_op: &OpTy<'tcx, Provenance>,
|
||||
cond_op: &OpTy<'tcx>,
|
||||
attr_op: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, i32> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
@ -821,17 +788,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
fn pthread_cond_signal(&mut self, cond_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx, i32> {
|
||||
fn pthread_cond_signal(&mut self, cond_op: &OpTy<'tcx>) -> InterpResult<'tcx, i32> {
|
||||
let this = self.eval_context_mut();
|
||||
let id = cond_get_id(this, cond_op)?;
|
||||
this.condvar_signal(id)?;
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
fn pthread_cond_broadcast(
|
||||
&mut self,
|
||||
cond_op: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, i32> {
|
||||
fn pthread_cond_broadcast(&mut self, cond_op: &OpTy<'tcx>) -> InterpResult<'tcx, i32> {
|
||||
let this = self.eval_context_mut();
|
||||
let id = cond_get_id(this, cond_op)?;
|
||||
while this.condvar_signal(id)? {}
|
||||
@ -840,9 +804,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
|
||||
fn pthread_cond_wait(
|
||||
&mut self,
|
||||
cond_op: &OpTy<'tcx, Provenance>,
|
||||
mutex_op: &OpTy<'tcx, Provenance>,
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
cond_op: &OpTy<'tcx>,
|
||||
mutex_op: &OpTy<'tcx>,
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
@ -863,10 +827,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
|
||||
fn pthread_cond_timedwait(
|
||||
&mut self,
|
||||
cond_op: &OpTy<'tcx, Provenance>,
|
||||
mutex_op: &OpTy<'tcx, Provenance>,
|
||||
abstime_op: &OpTy<'tcx, Provenance>,
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
cond_op: &OpTy<'tcx>,
|
||||
mutex_op: &OpTy<'tcx>,
|
||||
abstime_op: &OpTy<'tcx>,
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
@ -906,10 +870,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn pthread_cond_destroy(
|
||||
&mut self,
|
||||
cond_op: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, i32> {
|
||||
fn pthread_cond_destroy(&mut self, cond_op: &OpTy<'tcx>) -> InterpResult<'tcx, i32> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let id = cond_get_id(this, cond_op)?;
|
||||
|
@ -6,10 +6,10 @@ impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
|
||||
pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
fn pthread_create(
|
||||
&mut self,
|
||||
thread: &OpTy<'tcx, Provenance>,
|
||||
_attr: &OpTy<'tcx, Provenance>,
|
||||
start_routine: &OpTy<'tcx, Provenance>,
|
||||
arg: &OpTy<'tcx, Provenance>,
|
||||
thread: &OpTy<'tcx>,
|
||||
_attr: &OpTy<'tcx>,
|
||||
start_routine: &OpTy<'tcx>,
|
||||
arg: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, i32> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
@ -32,8 +32,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
|
||||
fn pthread_join(
|
||||
&mut self,
|
||||
thread: &OpTy<'tcx, Provenance>,
|
||||
retval: &OpTy<'tcx, Provenance>,
|
||||
thread: &OpTy<'tcx>,
|
||||
retval: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, i32> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
@ -48,7 +48,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
fn pthread_detach(&mut self, thread: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx, i32> {
|
||||
fn pthread_detach(&mut self, thread: &OpTy<'tcx>) -> InterpResult<'tcx, i32> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let thread_id = this.read_scalar(thread)?.to_int(this.libc_ty_layout("pthread_t").size)?;
|
||||
@ -60,7 +60,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
fn pthread_self(&mut self) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
fn pthread_self(&mut self) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let thread_id = this.active_thread();
|
||||
@ -71,10 +71,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
/// including the null terminator.
|
||||
fn pthread_setname_np(
|
||||
&mut self,
|
||||
thread: Scalar<Provenance>,
|
||||
name: Scalar<Provenance>,
|
||||
thread: Scalar,
|
||||
name: Scalar,
|
||||
max_name_len: usize,
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let thread = thread.to_int(this.libc_ty_layout("pthread_t").size)?;
|
||||
@ -95,10 +95,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
|
||||
fn pthread_getname_np(
|
||||
&mut self,
|
||||
thread: Scalar<Provenance>,
|
||||
name_out: Scalar<Provenance>,
|
||||
len: Scalar<Provenance>,
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
thread: Scalar,
|
||||
name_out: Scalar,
|
||||
len: Scalar,
|
||||
) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let thread = thread.to_int(this.libc_ty_layout("pthread_t").size)?;
|
||||
|
@ -14,8 +14,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
&mut self,
|
||||
link_name: Symbol,
|
||||
abi: Abi,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
args: &[OpTy<'tcx>],
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx, EmulateItemResult> {
|
||||
let this = self.eval_context_mut();
|
||||
match link_name.as_str() {
|
||||
|
@ -38,10 +38,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
#[allow(non_snake_case)]
|
||||
fn GetEnvironmentVariableW(
|
||||
&mut self,
|
||||
name_op: &OpTy<'tcx, Provenance>, // LPCWSTR
|
||||
buf_op: &OpTy<'tcx, Provenance>, // LPWSTR
|
||||
size_op: &OpTy<'tcx, Provenance>, // DWORD
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
name_op: &OpTy<'tcx>, // LPCWSTR
|
||||
buf_op: &OpTy<'tcx>, // LPWSTR
|
||||
size_op: &OpTy<'tcx>, // DWORD
|
||||
) -> InterpResult<'tcx, Scalar> {
|
||||
// ^ Returns DWORD (u32 on Windows)
|
||||
|
||||
let this = self.eval_context_mut();
|
||||
@ -71,7 +71,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
fn GetEnvironmentStringsW(&mut self) -> InterpResult<'tcx, Pointer<Option<Provenance>>> {
|
||||
fn GetEnvironmentStringsW(&mut self) -> InterpResult<'tcx, Pointer> {
|
||||
let this = self.eval_context_mut();
|
||||
this.assert_target_os("windows", "GetEnvironmentStringsW");
|
||||
|
||||
@ -93,10 +93,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
fn FreeEnvironmentStringsW(
|
||||
&mut self,
|
||||
env_block_op: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
fn FreeEnvironmentStringsW(&mut self, env_block_op: &OpTy<'tcx>) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_mut();
|
||||
this.assert_target_os("windows", "FreeEnvironmentStringsW");
|
||||
|
||||
@ -109,9 +106,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
#[allow(non_snake_case)]
|
||||
fn SetEnvironmentVariableW(
|
||||
&mut self,
|
||||
name_op: &OpTy<'tcx, Provenance>, // LPCWSTR
|
||||
value_op: &OpTy<'tcx, Provenance>, // LPCWSTR
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
name_op: &OpTy<'tcx>, // LPCWSTR
|
||||
value_op: &OpTy<'tcx>, // LPCWSTR
|
||||
) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_mut();
|
||||
this.assert_target_os("windows", "SetEnvironmentVariableW");
|
||||
|
||||
@ -142,9 +139,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
#[allow(non_snake_case)]
|
||||
fn GetCurrentDirectoryW(
|
||||
&mut self,
|
||||
size_op: &OpTy<'tcx, Provenance>, // DWORD
|
||||
buf_op: &OpTy<'tcx, Provenance>, // LPTSTR
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
size_op: &OpTy<'tcx>, // DWORD
|
||||
buf_op: &OpTy<'tcx>, // LPTSTR
|
||||
) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_mut();
|
||||
this.assert_target_os("windows", "GetCurrentDirectoryW");
|
||||
|
||||
@ -174,8 +171,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
#[allow(non_snake_case)]
|
||||
fn SetCurrentDirectoryW(
|
||||
&mut self,
|
||||
path_op: &OpTy<'tcx, Provenance>, // LPCTSTR
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
path_op: &OpTy<'tcx>, // LPCTSTR
|
||||
) -> InterpResult<'tcx, Scalar> {
|
||||
// ^ Returns BOOL (i32 on Windows)
|
||||
|
||||
let this = self.eval_context_mut();
|
||||
@ -211,10 +208,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
#[allow(non_snake_case)]
|
||||
fn GetUserProfileDirectoryW(
|
||||
&mut self,
|
||||
token: &OpTy<'tcx, Provenance>, // HANDLE
|
||||
buf: &OpTy<'tcx, Provenance>, // LPWSTR
|
||||
size: &OpTy<'tcx, Provenance>, // LPDWORD
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> // returns BOOL
|
||||
token: &OpTy<'tcx>, // HANDLE
|
||||
buf: &OpTy<'tcx>, // LPWSTR
|
||||
size: &OpTy<'tcx>, // LPDWORD
|
||||
) -> InterpResult<'tcx, Scalar> // returns BOOL
|
||||
{
|
||||
let this = self.eval_context_mut();
|
||||
this.assert_target_os("windows", "GetUserProfileDirectoryW");
|
||||
|
@ -82,8 +82,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
&mut self,
|
||||
link_name: Symbol,
|
||||
abi: Abi,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
args: &[OpTy<'tcx>],
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx, EmulateItemResult> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
|
@ -119,7 +119,7 @@ impl Handle {
|
||||
Self::new(discriminant, data)
|
||||
}
|
||||
|
||||
pub fn to_scalar(self, cx: &impl HasDataLayout) -> Scalar<Provenance> {
|
||||
pub fn to_scalar(self, cx: &impl HasDataLayout) -> Scalar {
|
||||
// 64-bit handles are sign extended 32-bit handles
|
||||
// see https://docs.microsoft.com/en-us/windows/win32/winprog64/interprocess-communication
|
||||
#[allow(clippy::cast_possible_wrap)] // we want it to wrap
|
||||
@ -128,7 +128,7 @@ impl Handle {
|
||||
}
|
||||
|
||||
pub fn from_scalar<'tcx>(
|
||||
handle: Scalar<Provenance>,
|
||||
handle: Scalar,
|
||||
cx: &impl HasDataLayout,
|
||||
) -> InterpResult<'tcx, Option<Self>> {
|
||||
let sign_extended_handle = handle.to_target_isize(cx)?;
|
||||
@ -155,7 +155,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
)))
|
||||
}
|
||||
|
||||
fn CloseHandle(&mut self, handle_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx> {
|
||||
fn CloseHandle(&mut self, handle_op: &OpTy<'tcx>) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let handle = this.read_scalar(handle_op)?;
|
||||
|
@ -10,10 +10,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
// Windows sync primitives are pointer sized.
|
||||
// We only use the first 4 bytes for the id.
|
||||
|
||||
fn init_once_get_id(
|
||||
&mut self,
|
||||
init_once_op: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, InitOnceId> {
|
||||
fn init_once_get_id(&mut self, init_once_op: &OpTy<'tcx>) -> InterpResult<'tcx, InitOnceId> {
|
||||
let this = self.eval_context_mut();
|
||||
this.init_once_get_or_create_id(init_once_op, this.windows_ty_layout("INIT_ONCE"), 0)
|
||||
}
|
||||
@ -22,8 +19,8 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
fn init_once_try_begin(
|
||||
&mut self,
|
||||
id: InitOnceId,
|
||||
pending_place: &MPlaceTy<'tcx, Provenance>,
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
pending_place: &MPlaceTy<'tcx>,
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx, bool> {
|
||||
let this = self.eval_context_mut();
|
||||
Ok(match this.init_once_status(id) {
|
||||
@ -49,11 +46,11 @@ impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
|
||||
pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
fn InitOnceBeginInitialize(
|
||||
&mut self,
|
||||
init_once_op: &OpTy<'tcx, Provenance>,
|
||||
flags_op: &OpTy<'tcx, Provenance>,
|
||||
pending_op: &OpTy<'tcx, Provenance>,
|
||||
context_op: &OpTy<'tcx, Provenance>,
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
init_once_op: &OpTy<'tcx>,
|
||||
flags_op: &OpTy<'tcx>,
|
||||
pending_op: &OpTy<'tcx>,
|
||||
context_op: &OpTy<'tcx>,
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
@ -82,8 +79,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
callback!(
|
||||
@capture<'tcx> {
|
||||
id: InitOnceId,
|
||||
pending_place: MPlaceTy<'tcx, Provenance>,
|
||||
dest: MPlaceTy<'tcx, Provenance>,
|
||||
pending_place: MPlaceTy<'tcx>,
|
||||
dest: MPlaceTy<'tcx>,
|
||||
}
|
||||
@unblock = |this| {
|
||||
let ret = this.init_once_try_begin(id, &pending_place, &dest)?;
|
||||
@ -97,10 +94,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
|
||||
fn InitOnceComplete(
|
||||
&mut self,
|
||||
init_once_op: &OpTy<'tcx, Provenance>,
|
||||
flags_op: &OpTy<'tcx, Provenance>,
|
||||
context_op: &OpTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
init_once_op: &OpTy<'tcx>,
|
||||
flags_op: &OpTy<'tcx>,
|
||||
context_op: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, Scalar> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let id = this.init_once_get_id(init_once_op)?;
|
||||
@ -137,11 +134,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
|
||||
fn WaitOnAddress(
|
||||
&mut self,
|
||||
ptr_op: &OpTy<'tcx, Provenance>,
|
||||
compare_op: &OpTy<'tcx, Provenance>,
|
||||
size_op: &OpTy<'tcx, Provenance>,
|
||||
timeout_op: &OpTy<'tcx, Provenance>,
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
ptr_op: &OpTy<'tcx>,
|
||||
compare_op: &OpTy<'tcx>,
|
||||
size_op: &OpTy<'tcx>,
|
||||
timeout_op: &OpTy<'tcx>,
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
@ -193,7 +190,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn WakeByAddressSingle(&mut self, ptr_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx> {
|
||||
fn WakeByAddressSingle(&mut self, ptr_op: &OpTy<'tcx>) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let ptr = this.read_pointer(ptr_op)?;
|
||||
@ -206,7 +203,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
fn WakeByAddressAll(&mut self, ptr_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx> {
|
||||
fn WakeByAddressAll(&mut self, ptr_op: &OpTy<'tcx>) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let ptr = this.read_pointer(ptr_op)?;
|
||||
|
@ -10,12 +10,12 @@ impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
|
||||
pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
fn CreateThread(
|
||||
&mut self,
|
||||
security_op: &OpTy<'tcx, Provenance>,
|
||||
stacksize_op: &OpTy<'tcx, Provenance>,
|
||||
start_op: &OpTy<'tcx, Provenance>,
|
||||
arg_op: &OpTy<'tcx, Provenance>,
|
||||
flags_op: &OpTy<'tcx, Provenance>,
|
||||
thread_op: &OpTy<'tcx, Provenance>,
|
||||
security_op: &OpTy<'tcx>,
|
||||
stacksize_op: &OpTy<'tcx>,
|
||||
start_op: &OpTy<'tcx>,
|
||||
arg_op: &OpTy<'tcx>,
|
||||
flags_op: &OpTy<'tcx>,
|
||||
thread_op: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, ThreadId> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
@ -57,8 +57,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
|
||||
fn WaitForSingleObject(
|
||||
&mut self,
|
||||
handle_op: &OpTy<'tcx, Provenance>,
|
||||
timeout_op: &OpTy<'tcx, Provenance>,
|
||||
handle_op: &OpTy<'tcx>,
|
||||
timeout_op: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, u32> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
|
@ -11,8 +11,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
&mut self,
|
||||
link_name: Symbol,
|
||||
abi: Abi,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
args: &[OpTy<'tcx>],
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx, EmulateItemResult> {
|
||||
let this = self.eval_context_mut();
|
||||
this.expect_target_feature_for_intrinsic(link_name, "aes")?;
|
||||
@ -133,9 +133,9 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
// `state` with the corresponding 128-bit key of `key`.
|
||||
fn aes_round<'tcx>(
|
||||
this: &mut crate::MiriInterpCx<'tcx>,
|
||||
state: &OpTy<'tcx, Provenance>,
|
||||
key: &OpTy<'tcx, Provenance>,
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
state: &OpTy<'tcx>,
|
||||
key: &OpTy<'tcx>,
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
f: impl Fn(u128, u128) -> u128,
|
||||
) -> InterpResult<'tcx, ()> {
|
||||
assert_eq!(dest.layout.size, state.layout.size);
|
||||
|
@ -18,8 +18,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
&mut self,
|
||||
link_name: Symbol,
|
||||
abi: Abi,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
args: &[OpTy<'tcx>],
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx, EmulateItemResult> {
|
||||
let this = self.eval_context_mut();
|
||||
this.expect_target_feature_for_intrinsic(link_name, "avx")?;
|
||||
|
@ -16,8 +16,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
&mut self,
|
||||
link_name: Symbol,
|
||||
abi: Abi,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
args: &[OpTy<'tcx>],
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx, EmulateItemResult> {
|
||||
let this = self.eval_context_mut();
|
||||
this.expect_target_feature_for_intrinsic(link_name, "avx2")?;
|
||||
|
@ -26,8 +26,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
&mut self,
|
||||
link_name: Symbol,
|
||||
abi: Abi,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
args: &[OpTy<'tcx>],
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx, EmulateItemResult> {
|
||||
let this = self.eval_context_mut();
|
||||
// Prefix should have already been checked.
|
||||
@ -244,9 +244,9 @@ impl FloatBinOp {
|
||||
fn bin_op_float<'tcx, F: rustc_apfloat::Float>(
|
||||
this: &crate::MiriInterpCx<'tcx>,
|
||||
which: FloatBinOp,
|
||||
left: &ImmTy<'tcx, Provenance>,
|
||||
right: &ImmTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
left: &ImmTy<'tcx>,
|
||||
right: &ImmTy<'tcx>,
|
||||
) -> InterpResult<'tcx, Scalar> {
|
||||
match which {
|
||||
FloatBinOp::Arith(which) => {
|
||||
let res = this.binary_op(which, left, right)?;
|
||||
@ -306,9 +306,9 @@ fn bin_op_float<'tcx, F: rustc_apfloat::Float>(
|
||||
fn bin_op_simd_float_first<'tcx, F: rustc_apfloat::Float>(
|
||||
this: &mut crate::MiriInterpCx<'tcx>,
|
||||
which: FloatBinOp,
|
||||
left: &OpTy<'tcx, Provenance>,
|
||||
right: &OpTy<'tcx, Provenance>,
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
left: &OpTy<'tcx>,
|
||||
right: &OpTy<'tcx>,
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx, ()> {
|
||||
let (left, left_len) = this.operand_to_simd(left)?;
|
||||
let (right, right_len) = this.operand_to_simd(right)?;
|
||||
@ -337,9 +337,9 @@ fn bin_op_simd_float_first<'tcx, F: rustc_apfloat::Float>(
|
||||
fn bin_op_simd_float_all<'tcx, F: rustc_apfloat::Float>(
|
||||
this: &mut crate::MiriInterpCx<'tcx>,
|
||||
which: FloatBinOp,
|
||||
left: &OpTy<'tcx, Provenance>,
|
||||
right: &OpTy<'tcx, Provenance>,
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
left: &OpTy<'tcx>,
|
||||
right: &OpTy<'tcx>,
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx, ()> {
|
||||
let (left, left_len) = this.operand_to_simd(left)?;
|
||||
let (right, right_len) = this.operand_to_simd(right)?;
|
||||
@ -384,8 +384,8 @@ enum FloatUnaryOp {
|
||||
fn unary_op_f32<'tcx>(
|
||||
this: &mut crate::MiriInterpCx<'tcx>,
|
||||
which: FloatUnaryOp,
|
||||
op: &ImmTy<'tcx, Provenance>,
|
||||
) -> InterpResult<'tcx, Scalar<Provenance>> {
|
||||
op: &ImmTy<'tcx>,
|
||||
) -> InterpResult<'tcx, Scalar> {
|
||||
match which {
|
||||
FloatUnaryOp::Sqrt => {
|
||||
let op = op.to_scalar();
|
||||
@ -435,8 +435,8 @@ fn apply_random_float_error<F: rustc_apfloat::Float>(
|
||||
fn unary_op_ss<'tcx>(
|
||||
this: &mut crate::MiriInterpCx<'tcx>,
|
||||
which: FloatUnaryOp,
|
||||
op: &OpTy<'tcx, Provenance>,
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
op: &OpTy<'tcx>,
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx, ()> {
|
||||
let (op, op_len) = this.operand_to_simd(op)?;
|
||||
let (dest, dest_len) = this.mplace_to_simd(dest)?;
|
||||
@ -458,8 +458,8 @@ fn unary_op_ss<'tcx>(
|
||||
fn unary_op_ps<'tcx>(
|
||||
this: &mut crate::MiriInterpCx<'tcx>,
|
||||
which: FloatUnaryOp,
|
||||
op: &OpTy<'tcx, Provenance>,
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
op: &OpTy<'tcx>,
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx, ()> {
|
||||
let (op, op_len) = this.operand_to_simd(op)?;
|
||||
let (dest, dest_len) = this.mplace_to_simd(dest)?;
|
||||
@ -494,10 +494,10 @@ enum ShiftOp {
|
||||
/// bit is copied to all bits.
|
||||
fn shift_simd_by_scalar<'tcx>(
|
||||
this: &mut crate::MiriInterpCx<'tcx>,
|
||||
left: &OpTy<'tcx, Provenance>,
|
||||
right: &OpTy<'tcx, Provenance>,
|
||||
left: &OpTy<'tcx>,
|
||||
right: &OpTy<'tcx>,
|
||||
which: ShiftOp,
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx, ()> {
|
||||
let (left, left_len) = this.operand_to_simd(left)?;
|
||||
let (dest, dest_len) = this.mplace_to_simd(dest)?;
|
||||
@ -550,10 +550,10 @@ fn shift_simd_by_scalar<'tcx>(
|
||||
/// bit is copied to all bits.
|
||||
fn shift_simd_by_simd<'tcx>(
|
||||
this: &mut crate::MiriInterpCx<'tcx>,
|
||||
left: &OpTy<'tcx, Provenance>,
|
||||
right: &OpTy<'tcx, Provenance>,
|
||||
left: &OpTy<'tcx>,
|
||||
right: &OpTy<'tcx>,
|
||||
which: ShiftOp,
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx, ()> {
|
||||
let (left, left_len) = this.operand_to_simd(left)?;
|
||||
let (right, right_len) = this.operand_to_simd(right)?;
|
||||
@ -602,7 +602,7 @@ fn shift_simd_by_simd<'tcx>(
|
||||
/// the first value.
|
||||
fn extract_first_u64<'tcx>(
|
||||
this: &crate::MiriInterpCx<'tcx>,
|
||||
op: &OpTy<'tcx, Provenance>,
|
||||
op: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, u64> {
|
||||
// Transmute vector to `[u64; 2]`
|
||||
let array_layout = this.layout_of(Ty::new_array(this.tcx.tcx, this.tcx.types.u64, 2))?;
|
||||
@ -616,10 +616,10 @@ fn extract_first_u64<'tcx>(
|
||||
// and copies the remaining elements from `left`.
|
||||
fn round_first<'tcx, F: rustc_apfloat::Float>(
|
||||
this: &mut crate::MiriInterpCx<'tcx>,
|
||||
left: &OpTy<'tcx, Provenance>,
|
||||
right: &OpTy<'tcx, Provenance>,
|
||||
rounding: &OpTy<'tcx, Provenance>,
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
left: &OpTy<'tcx>,
|
||||
right: &OpTy<'tcx>,
|
||||
rounding: &OpTy<'tcx>,
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx, ()> {
|
||||
let (left, left_len) = this.operand_to_simd(left)?;
|
||||
let (right, right_len) = this.operand_to_simd(right)?;
|
||||
@ -647,9 +647,9 @@ fn round_first<'tcx, F: rustc_apfloat::Float>(
|
||||
// Rounds all elements of `op` according to `rounding`.
|
||||
fn round_all<'tcx, F: rustc_apfloat::Float>(
|
||||
this: &mut crate::MiriInterpCx<'tcx>,
|
||||
op: &OpTy<'tcx, Provenance>,
|
||||
rounding: &OpTy<'tcx, Provenance>,
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
op: &OpTy<'tcx>,
|
||||
rounding: &OpTy<'tcx>,
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx, ()> {
|
||||
let (op, op_len) = this.operand_to_simd(op)?;
|
||||
let (dest, dest_len) = this.mplace_to_simd(dest)?;
|
||||
@ -699,9 +699,9 @@ fn rounding_from_imm<'tcx>(rounding: i32) -> InterpResult<'tcx, rustc_apfloat::R
|
||||
/// has less elements than `dest`, the rest is filled with zeros.
|
||||
fn convert_float_to_int<'tcx>(
|
||||
this: &mut crate::MiriInterpCx<'tcx>,
|
||||
op: &OpTy<'tcx, Provenance>,
|
||||
op: &OpTy<'tcx>,
|
||||
rnd: rustc_apfloat::Round,
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx, ()> {
|
||||
let (op, op_len) = this.operand_to_simd(op)?;
|
||||
let (dest, dest_len) = this.mplace_to_simd(dest)?;
|
||||
@ -734,8 +734,8 @@ fn convert_float_to_int<'tcx>(
|
||||
/// will wrap around.
|
||||
fn int_abs<'tcx>(
|
||||
this: &mut crate::MiriInterpCx<'tcx>,
|
||||
op: &OpTy<'tcx, Provenance>,
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
op: &OpTy<'tcx>,
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx, ()> {
|
||||
let (op, op_len) = this.operand_to_simd(op)?;
|
||||
let (dest, dest_len) = this.mplace_to_simd(dest)?;
|
||||
@ -802,9 +802,9 @@ fn horizontal_bin_op<'tcx>(
|
||||
this: &mut crate::MiriInterpCx<'tcx>,
|
||||
which: mir::BinOp,
|
||||
saturating: bool,
|
||||
left: &OpTy<'tcx, Provenance>,
|
||||
right: &OpTy<'tcx, Provenance>,
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
left: &OpTy<'tcx>,
|
||||
right: &OpTy<'tcx>,
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx, ()> {
|
||||
assert_eq!(left.layout, dest.layout);
|
||||
assert_eq!(right.layout, dest.layout);
|
||||
@ -853,10 +853,10 @@ fn horizontal_bin_op<'tcx>(
|
||||
/// 128-bit blocks of `left` and `right`).
|
||||
fn conditional_dot_product<'tcx>(
|
||||
this: &mut crate::MiriInterpCx<'tcx>,
|
||||
left: &OpTy<'tcx, Provenance>,
|
||||
right: &OpTy<'tcx, Provenance>,
|
||||
imm: &OpTy<'tcx, Provenance>,
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
left: &OpTy<'tcx>,
|
||||
right: &OpTy<'tcx>,
|
||||
imm: &OpTy<'tcx>,
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx, ()> {
|
||||
assert_eq!(left.layout, dest.layout);
|
||||
assert_eq!(right.layout, dest.layout);
|
||||
@ -911,8 +911,8 @@ fn conditional_dot_product<'tcx>(
|
||||
/// The second is true when `(op & mask) == mask`
|
||||
fn test_bits_masked<'tcx>(
|
||||
this: &crate::MiriInterpCx<'tcx>,
|
||||
op: &OpTy<'tcx, Provenance>,
|
||||
mask: &OpTy<'tcx, Provenance>,
|
||||
op: &OpTy<'tcx>,
|
||||
mask: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, (bool, bool)> {
|
||||
assert_eq!(op.layout, mask.layout);
|
||||
|
||||
@ -942,8 +942,8 @@ fn test_bits_masked<'tcx>(
|
||||
/// The second is true when the highest bit of each element of `!op & mask` is zero.
|
||||
fn test_high_bits_masked<'tcx>(
|
||||
this: &crate::MiriInterpCx<'tcx>,
|
||||
op: &OpTy<'tcx, Provenance>,
|
||||
mask: &OpTy<'tcx, Provenance>,
|
||||
op: &OpTy<'tcx>,
|
||||
mask: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, (bool, bool)> {
|
||||
assert_eq!(op.layout, mask.layout);
|
||||
|
||||
@ -973,9 +973,9 @@ fn test_high_bits_masked<'tcx>(
|
||||
/// element of `mask`. `ptr` does not need to be aligned.
|
||||
fn mask_load<'tcx>(
|
||||
this: &mut crate::MiriInterpCx<'tcx>,
|
||||
ptr: &OpTy<'tcx, Provenance>,
|
||||
mask: &OpTy<'tcx, Provenance>,
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
ptr: &OpTy<'tcx>,
|
||||
mask: &OpTy<'tcx>,
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx, ()> {
|
||||
let (mask, mask_len) = this.operand_to_simd(mask)?;
|
||||
let (dest, dest_len) = this.mplace_to_simd(dest)?;
|
||||
@ -1006,9 +1006,9 @@ fn mask_load<'tcx>(
|
||||
/// element of `mask`. `ptr` does not need to be aligned.
|
||||
fn mask_store<'tcx>(
|
||||
this: &mut crate::MiriInterpCx<'tcx>,
|
||||
ptr: &OpTy<'tcx, Provenance>,
|
||||
mask: &OpTy<'tcx, Provenance>,
|
||||
value: &OpTy<'tcx, Provenance>,
|
||||
ptr: &OpTy<'tcx>,
|
||||
mask: &OpTy<'tcx>,
|
||||
value: &OpTy<'tcx>,
|
||||
) -> InterpResult<'tcx, ()> {
|
||||
let (mask, mask_len) = this.operand_to_simd(mask)?;
|
||||
let (value, value_len) = this.operand_to_simd(value)?;
|
||||
@ -1046,10 +1046,10 @@ fn mask_store<'tcx>(
|
||||
/// 128-bit chunks of `left` and `right`).
|
||||
fn mpsadbw<'tcx>(
|
||||
this: &mut crate::MiriInterpCx<'tcx>,
|
||||
left: &OpTy<'tcx, Provenance>,
|
||||
right: &OpTy<'tcx, Provenance>,
|
||||
imm: &OpTy<'tcx, Provenance>,
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
left: &OpTy<'tcx>,
|
||||
right: &OpTy<'tcx>,
|
||||
imm: &OpTy<'tcx>,
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx, ()> {
|
||||
assert_eq!(left.layout, right.layout);
|
||||
assert_eq!(left.layout.size, dest.layout.size);
|
||||
@ -1103,9 +1103,9 @@ fn mpsadbw<'tcx>(
|
||||
/// <https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_mulhrs_epi16>
|
||||
fn pmulhrsw<'tcx>(
|
||||
this: &mut crate::MiriInterpCx<'tcx>,
|
||||
left: &OpTy<'tcx, Provenance>,
|
||||
right: &OpTy<'tcx, Provenance>,
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
left: &OpTy<'tcx>,
|
||||
right: &OpTy<'tcx>,
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx, ()> {
|
||||
let (left, left_len) = this.operand_to_simd(left)?;
|
||||
let (right, right_len) = this.operand_to_simd(right)?;
|
||||
@ -1142,10 +1142,10 @@ fn pmulhrsw<'tcx>(
|
||||
/// 128-bit chunks of `left` and `right`).
|
||||
fn pack_generic<'tcx>(
|
||||
this: &mut crate::MiriInterpCx<'tcx>,
|
||||
left: &OpTy<'tcx, Provenance>,
|
||||
right: &OpTy<'tcx, Provenance>,
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
f: impl Fn(Scalar<Provenance>) -> InterpResult<'tcx, Scalar<Provenance>>,
|
||||
left: &OpTy<'tcx>,
|
||||
right: &OpTy<'tcx>,
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
f: impl Fn(Scalar) -> InterpResult<'tcx, Scalar>,
|
||||
) -> InterpResult<'tcx, ()> {
|
||||
assert_eq!(left.layout, right.layout);
|
||||
assert_eq!(left.layout.size, dest.layout.size);
|
||||
@ -1187,9 +1187,9 @@ fn pack_generic<'tcx>(
|
||||
/// 128-bit chunks of `left` and `right`).
|
||||
fn packsswb<'tcx>(
|
||||
this: &mut crate::MiriInterpCx<'tcx>,
|
||||
left: &OpTy<'tcx, Provenance>,
|
||||
right: &OpTy<'tcx, Provenance>,
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
left: &OpTy<'tcx>,
|
||||
right: &OpTy<'tcx>,
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx, ()> {
|
||||
pack_generic(this, left, right, dest, |op| {
|
||||
let op = op.to_i16()?;
|
||||
@ -1206,9 +1206,9 @@ fn packsswb<'tcx>(
|
||||
/// 128-bit chunks of `left` and `right`).
|
||||
fn packuswb<'tcx>(
|
||||
this: &mut crate::MiriInterpCx<'tcx>,
|
||||
left: &OpTy<'tcx, Provenance>,
|
||||
right: &OpTy<'tcx, Provenance>,
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
left: &OpTy<'tcx>,
|
||||
right: &OpTy<'tcx>,
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx, ()> {
|
||||
pack_generic(this, left, right, dest, |op| {
|
||||
let op = op.to_i16()?;
|
||||
@ -1225,9 +1225,9 @@ fn packuswb<'tcx>(
|
||||
/// 128-bit chunks of `left` and `right`).
|
||||
fn packssdw<'tcx>(
|
||||
this: &mut crate::MiriInterpCx<'tcx>,
|
||||
left: &OpTy<'tcx, Provenance>,
|
||||
right: &OpTy<'tcx, Provenance>,
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
left: &OpTy<'tcx>,
|
||||
right: &OpTy<'tcx>,
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx, ()> {
|
||||
pack_generic(this, left, right, dest, |op| {
|
||||
let op = op.to_i32()?;
|
||||
@ -1244,9 +1244,9 @@ fn packssdw<'tcx>(
|
||||
/// 128-bit chunks of `left` and `right`).
|
||||
fn packusdw<'tcx>(
|
||||
this: &mut crate::MiriInterpCx<'tcx>,
|
||||
left: &OpTy<'tcx, Provenance>,
|
||||
right: &OpTy<'tcx, Provenance>,
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
left: &OpTy<'tcx>,
|
||||
right: &OpTy<'tcx>,
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx, ()> {
|
||||
pack_generic(this, left, right, dest, |op| {
|
||||
let op = op.to_i32()?;
|
||||
@ -1261,9 +1261,9 @@ fn packusdw<'tcx>(
|
||||
/// In other words, multiplies `left` with `right.signum()`.
|
||||
fn psign<'tcx>(
|
||||
this: &mut crate::MiriInterpCx<'tcx>,
|
||||
left: &OpTy<'tcx, Provenance>,
|
||||
right: &OpTy<'tcx, Provenance>,
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
left: &OpTy<'tcx>,
|
||||
right: &OpTy<'tcx>,
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx, ()> {
|
||||
let (left, left_len) = this.operand_to_simd(left)?;
|
||||
let (right, right_len) = this.operand_to_simd(right)?;
|
||||
|
@ -15,8 +15,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
&mut self,
|
||||
link_name: Symbol,
|
||||
abi: Abi,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
args: &[OpTy<'tcx>],
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx, EmulateItemResult> {
|
||||
let this = self.eval_context_mut();
|
||||
this.expect_target_feature_for_intrinsic(link_name, "sse")?;
|
||||
|
@ -14,8 +14,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
&mut self,
|
||||
link_name: Symbol,
|
||||
abi: Abi,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
args: &[OpTy<'tcx>],
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx, EmulateItemResult> {
|
||||
let this = self.eval_context_mut();
|
||||
this.expect_target_feature_for_intrinsic(link_name, "sse2")?;
|
||||
|
@ -11,8 +11,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
&mut self,
|
||||
link_name: Symbol,
|
||||
abi: Abi,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
args: &[OpTy<'tcx>],
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx, EmulateItemResult> {
|
||||
let this = self.eval_context_mut();
|
||||
this.expect_target_feature_for_intrinsic(link_name, "sse3")?;
|
||||
|
@ -10,8 +10,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
&mut self,
|
||||
link_name: Symbol,
|
||||
abi: Abi,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
args: &[OpTy<'tcx>],
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx, EmulateItemResult> {
|
||||
let this = self.eval_context_mut();
|
||||
this.expect_target_feature_for_intrinsic(link_name, "sse4.1")?;
|
||||
|
@ -11,8 +11,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||
&mut self,
|
||||
link_name: Symbol,
|
||||
abi: Abi,
|
||||
args: &[OpTy<'tcx, Provenance>],
|
||||
dest: &MPlaceTy<'tcx, Provenance>,
|
||||
args: &[OpTy<'tcx>],
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx, EmulateItemResult> {
|
||||
let this = self.eval_context_mut();
|
||||
this.expect_target_feature_for_intrinsic(link_name, "ssse3")?;
|
||||
|
Loading…
Reference in New Issue
Block a user