Split write_c_ints into less specific helper functions
This commit is contained in:
parent
87b210df6c
commit
2cbf4afa99
2 changed files with 51 additions and 28 deletions
|
|
@ -4,7 +4,7 @@ use rustc::hir::def_id::{DefId, CRATE_DEF_INDEX};
|
|||
use rustc::mir;
|
||||
use rustc::ty::{
|
||||
self,
|
||||
layout::{self, Align, LayoutOf, Size},
|
||||
layout::{self, Align, LayoutOf, Size, TyLayout},
|
||||
};
|
||||
|
||||
use rand::RngCore;
|
||||
|
|
@ -308,42 +308,26 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
|||
self.eval_libc(name)?.to_i32()
|
||||
}
|
||||
|
||||
fn write_c_ints(
|
||||
// Writes several `ImmTy`s contiguosly into memory. This is useful when you have to pack
|
||||
// different values into an struct.
|
||||
fn write_immediates(
|
||||
&mut self,
|
||||
ptr: &Pointer<Tag>,
|
||||
bits: &[i128],
|
||||
ty_names: &[&str],
|
||||
imms: &[ImmTy<'tcx, Tag>],
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let tcx = &{ this.tcx.tcx };
|
||||
|
||||
let mut sizes = Vec::new();
|
||||
|
||||
for name in ty_names {
|
||||
let ty = this.resolve_path(&["libc", name])?.ty(*tcx);
|
||||
sizes.push(this.layout_of(ty)?.size);
|
||||
}
|
||||
|
||||
let allocation = this.memory_mut().get_mut(ptr.alloc_id)?;
|
||||
let mut offset = Size::from_bytes(0);
|
||||
|
||||
for (&value, size) in bits.iter().zip(sizes) {
|
||||
// If `value` does not fit in `size` bits, we error instead of letting
|
||||
// `Scalar::from_int` panic.
|
||||
let truncated = truncate(value as u128, size);
|
||||
if sign_extend(truncated, size) as i128 != value {
|
||||
throw_unsup_format!(
|
||||
"Signed value {:#x} does not fit in {} bits",
|
||||
value,
|
||||
size.bits()
|
||||
)
|
||||
}
|
||||
|
||||
for imm in imms {
|
||||
let size = imm.layout.size;
|
||||
allocation.write_scalar(
|
||||
tcx,
|
||||
ptr.offset(offset, tcx)?,
|
||||
Scalar::from_int(value, size).into(),
|
||||
imm.to_scalar()?.into(),
|
||||
size,
|
||||
)?;
|
||||
offset += size;
|
||||
|
|
@ -351,4 +335,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn libc_ty_layout(&mut self, name: &str) -> InterpResult<'tcx, TyLayout<'tcx>> {
|
||||
let this = self.eval_context_mut();
|
||||
let tcx = &{ this.tcx.tcx };
|
||||
let ty = this.resolve_path(&["libc", name])?.ty(*tcx);
|
||||
this.layout_of(ty)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,12 @@
|
|||
use std::time::{Duration, SystemTime};
|
||||
|
||||
use rustc::ty::layout::TyLayout;
|
||||
|
||||
use crate::stacked_borrows::Tag;
|
||||
use crate::*;
|
||||
|
||||
use std::time::{Duration, SystemTime};
|
||||
|
||||
// Returns the time elapsed between now and the unix epoch as a `Duration` and the sign of the time
|
||||
// interval
|
||||
fn get_time() -> (Duration, i128) {
|
||||
let mut sign = 1;
|
||||
let duration = SystemTime::now()
|
||||
|
|
@ -14,6 +18,24 @@ fn get_time() -> (Duration, i128) {
|
|||
(duration, sign)
|
||||
}
|
||||
|
||||
fn int_to_immty_checked<'tcx>(
|
||||
int: i128,
|
||||
layout: TyLayout<'tcx>,
|
||||
) -> InterpResult<'tcx, ImmTy<'tcx, Tag>> {
|
||||
// If `int` does not fit in `size` bits, we error instead of letting
|
||||
// `ImmTy::from_int` panic.
|
||||
let size = layout.size;
|
||||
let truncated = truncate(int as u128, size);
|
||||
if sign_extend(truncated, size) as i128 != int {
|
||||
throw_unsup_format!(
|
||||
"Signed value {:#x} does not fit in {} bits",
|
||||
int,
|
||||
size.bits()
|
||||
)
|
||||
}
|
||||
Ok(ImmTy::from_int(int, layout))
|
||||
}
|
||||
|
||||
impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
|
||||
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
|
||||
// Foreign function used by linux
|
||||
|
|
@ -45,7 +67,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
|||
tv_nsec *= sign;
|
||||
}
|
||||
|
||||
this.write_c_ints(&tp, &[tv_sec, tv_nsec], &["time_t", "c_long"])?;
|
||||
let imms = [
|
||||
int_to_immty_checked(tv_sec, this.libc_ty_layout("time_t")?)?,
|
||||
int_to_immty_checked(tv_nsec, this.libc_ty_layout("c_long")?)?,
|
||||
];
|
||||
|
||||
this.write_immediates(&tp, &imms)?;
|
||||
|
||||
Ok(0)
|
||||
}
|
||||
|
|
@ -78,7 +105,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
|||
tv_usec *= sign;
|
||||
}
|
||||
|
||||
this.write_c_ints(&tv, &[tv_sec, tv_usec], &["time_t", "suseconds_t"])?;
|
||||
let imms = [
|
||||
int_to_immty_checked(tv_sec, this.libc_ty_layout("time_t")?)?,
|
||||
int_to_immty_checked(tv_usec, this.libc_ty_layout("suseconds_t")?)?,
|
||||
];
|
||||
|
||||
this.write_immediates(&tv, &imms)?;
|
||||
|
||||
Ok(0)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue