Skip to content

Commit 2cbf4af

Browse files
committed
Split write_c_ints into less specific helper functions
1 parent 87b210d commit 2cbf4af

File tree

2 files changed

+51
-28
lines changed

2 files changed

+51
-28
lines changed

src/helpers.rs

+15-24
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;
@@ -308,47 +308,38 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
308308
self.eval_libc(name)?.to_i32()
309309
}
310310

311-
fn write_c_ints(
311+
// Writes several `ImmTy`s contiguosly into memory. This is useful when you have to pack
312+
// different values into an struct.
313+
fn write_immediates(
312314
&mut self,
313315
ptr: &Pointer<Tag>,
314-
bits: &[i128],
315-
ty_names: &[&str],
316+
imms: &[ImmTy<'tcx, Tag>],
316317
) -> InterpResult<'tcx> {
317318
let this = self.eval_context_mut();
318319

319320
let tcx = &{ this.tcx.tcx };
320321

321-
let mut sizes = Vec::new();
322-
323-
for name in ty_names {
324-
let ty = this.resolve_path(&["libc", name])?.ty(*tcx);
325-
sizes.push(this.layout_of(ty)?.size);
326-
}
327-
328322
let allocation = this.memory_mut().get_mut(ptr.alloc_id)?;
329323
let mut offset = Size::from_bytes(0);
330324

331-
for (&value, size) in bits.iter().zip(sizes) {
332-
// If `value` does not fit in `size` bits, we error instead of letting
333-
// `Scalar::from_int` panic.
334-
let truncated = truncate(value as u128, size);
335-
if sign_extend(truncated, size) as i128 != value {
336-
throw_unsup_format!(
337-
"Signed value {:#x} does not fit in {} bits",
338-
value,
339-
size.bits()
340-
)
341-
}
342-
325+
for imm in imms {
326+
let size = imm.layout.size;
343327
allocation.write_scalar(
344328
tcx,
345329
ptr.offset(offset, tcx)?,
346-
Scalar::from_int(value, size).into(),
330+
imm.to_scalar()?.into(),
347331
size,
348332
)?;
349333
offset += size;
350334
}
351335

352336
Ok(())
353337
}
338+
339+
fn libc_ty_layout(&mut self, name: &str) -> InterpResult<'tcx, TyLayout<'tcx>> {
340+
let this = self.eval_context_mut();
341+
let tcx = &{ this.tcx.tcx };
342+
let ty = this.resolve_path(&["libc", name])?.ty(*tcx);
343+
this.layout_of(ty)
344+
}
354345
}

src/shims/time.rs

+36-4
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)