Skip to content

Commit de342e9

Browse files
committed
Split write_c_ints into less specific helper functions
1 parent fe2b0cf commit de342e9

File tree

2 files changed

+51
-28
lines changed

2 files changed

+51
-28
lines changed

src/helpers.rs

Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use rustc::hir::def_id::{DefId, CRATE_DEF_INDEX};
44
use rustc::mir;
55
use rustc::ty::{
66
self,
7-
layout::{self, Align, LayoutOf, Size},
7+
layout::{self, Align, LayoutOf, Size, TyLayout},
88
};
99

1010
use rand::RngCore;
@@ -296,47 +296,38 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
296296
}
297297
}
298298

299-
fn write_c_ints(
299+
// Writes several `ImmTy`s contiguosly into memory. This is useful when you have to pack
300+
// different values into an struct.
301+
fn write_immediates(
300302
&mut self,
301303
ptr: &Pointer<Tag>,
302-
bits: &[i128],
303-
ty_names: &[&str],
304+
imms: &[ImmTy<'tcx, Tag>],
304305
) -> InterpResult<'tcx> {
305306
let this = self.eval_context_mut();
306307

307308
let tcx = &{ this.tcx.tcx };
308309

309-
let mut sizes = Vec::new();
310-
311-
for name in ty_names {
312-
let ty = this.resolve_path(&["libc", name])?.ty(*tcx);
313-
sizes.push(this.layout_of(ty)?.size);
314-
}
315-
316310
let allocation = this.memory_mut().get_mut(ptr.alloc_id)?;
317311
let mut offset = Size::from_bytes(0);
318312

319-
for (&value, size) in bits.iter().zip(sizes) {
320-
// If `value` does not fit in `size` bits, we error instead of letting
321-
// `Scalar::from_int` panic.
322-
let truncated = truncate(value as u128, size);
323-
if sign_extend(truncated, size) as i128 != value {
324-
throw_unsup_format!(
325-
"Signed value {:#x} does not fit in {} bits",
326-
value,
327-
size.bits()
328-
)
329-
}
330-
313+
for imm in imms {
314+
let size = imm.layout.size;
331315
allocation.write_scalar(
332316
tcx,
333317
ptr.offset(offset, tcx)?,
334-
Scalar::from_int(value, size).into(),
318+
imm.to_scalar()?.into(),
335319
size,
336320
)?;
337321
offset += size;
338322
}
339323

340324
Ok(())
341325
}
326+
327+
fn libc_ty_layout(&mut self, name: &str) -> InterpResult<'tcx, TyLayout<'tcx>> {
328+
let this = self.eval_context_mut();
329+
let tcx = &{ this.tcx.tcx };
330+
let ty = this.resolve_path(&["libc", name])?.ty(*tcx);
331+
this.layout_of(ty)
332+
}
342333
}

src/shims/time.rs

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1+
use std::time::{Duration, SystemTime};
2+
3+
use rustc::ty::layout::TyLayout;
4+
15
use crate::stacked_borrows::Tag;
26
use crate::*;
37

4-
use std::time::{Duration, SystemTime};
5-
8+
// Returns the time elapsed between now and the unix epoch as a `Duration` and the sign of the time
9+
// interval
610
fn get_time() -> (Duration, i128) {
711
let mut sign = 1;
812
let duration = SystemTime::now()
@@ -14,6 +18,24 @@ fn get_time() -> (Duration, i128) {
1418
(duration, sign)
1519
}
1620

21+
fn int_to_immty_checked<'tcx>(
22+
int: i128,
23+
layout: TyLayout<'tcx>,
24+
) -> InterpResult<'tcx, ImmTy<'tcx, Tag>> {
25+
// If `int` does not fit in `size` bits, we error instead of letting
26+
// `ImmTy::from_int` panic.
27+
let size = layout.size;
28+
let truncated = truncate(int as u128, size);
29+
if sign_extend(truncated, size) as i128 != int {
30+
throw_unsup_format!(
31+
"Signed value {:#x} does not fit in {} bits",
32+
int,
33+
size.bits()
34+
)
35+
}
36+
Ok(ImmTy::from_int(int, layout))
37+
}
38+
1739
impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
1840
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
1941
// Foreign function used by linux
@@ -45,7 +67,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
4567
tv_nsec *= sign;
4668
}
4769

48-
this.write_c_ints(&tp, &[tv_sec, tv_nsec], &["time_t", "c_long"])?;
70+
let imms = [
71+
int_to_immty_checked(tv_sec, this.libc_ty_layout("time_t")?)?,
72+
int_to_immty_checked(tv_nsec, this.libc_ty_layout("c_long")?)?,
73+
];
74+
75+
this.write_immediates(&tp, &imms)?;
4976

5077
Ok(0)
5178
}
@@ -78,7 +105,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
78105
tv_usec *= sign;
79106
}
80107

81-
this.write_c_ints(&tv, &[tv_sec, tv_usec], &["time_t", "suseconds_t"])?;
108+
let imms = [
109+
int_to_immty_checked(tv_sec, this.libc_ty_layout("time_t")?)?,
110+
int_to_immty_checked(tv_usec, this.libc_ty_layout("suseconds_t")?)?,
111+
];
112+
113+
this.write_immediates(&tv, &imms)?;
82114

83115
Ok(0)
84116
}

0 commit comments

Comments
 (0)