Rename new fields and move rng to MemoryExtra

This commit is contained in:
Christian Poveda 2019-06-24 10:03:16 -05:00
parent dd732e5862
commit 2861ceb2fa
5 changed files with 37 additions and 41 deletions

View File

@ -979,7 +979,7 @@ fn gen_random<'mir, 'tcx>(
}
let ptr = dest.to_ptr()?;
let data = match &mut this.machine.rng {
let data = match &mut this.memory_mut().extra.rng {
Some(rng) => {
let mut data = vec![0; len];
rng.fill_bytes(&mut data);

View File

@ -6,15 +6,17 @@
#[derive(Clone, Debug)]
pub struct GlobalState {
pub vec: Vec<(u64, AllocId)>,
pub addr: u64,
/// This field is used as a map between the address of each allocation and its `AllocId`
pub int_to_ptr_map: Vec<(u64, AllocId)>,
pub next_base_addr: u64,
}
impl Default for GlobalState {
// FIXME: Query the page size in the future
fn default() -> Self {
GlobalState {
vec: Vec::default(),
addr: 2u64.pow(16)
int_to_ptr_map: Vec::default(),
next_base_addr: 2u64.pow(16)
}
}
}

View File

@ -25,7 +25,7 @@
use std::collections::HashMap;
use std::borrow::Cow;
use std::cell::RefCell;
use std::cell::Cell;
use std::rc::Rc;
use rand::rngs::StdRng;
@ -83,9 +83,11 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
let mut ecx = InterpretCx::new(
tcx.at(syntax::source_map::DUMMY_SP),
ty::ParamEnv::reveal_all(),
Evaluator::new(config.validate, config.seed),
Evaluator::new(config.validate),
);
ecx.memory_mut().extra.rng = config.seed.map(StdRng::seed_from_u64);
let main_instance = ty::Instance::mono(ecx.tcx.tcx, main_id);
let main_mir = ecx.load_mir(main_instance.def)?;
@ -209,9 +211,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
cur_ptr = cur_ptr.offset(char_size, tcx)?;
}
}
ecx.memory_mut().extra.seed = config.seed.clone();
assert!(args.next().is_none(), "start lang item has more arguments than expected");
Ok(ecx)
@ -347,14 +347,10 @@ pub struct Evaluator<'tcx> {
/// Whether to enforce the validity invariant.
pub(crate) validate: bool,
/// The random number generator to use if Miri
/// is running in non-deterministic mode
pub(crate) rng: Option<StdRng>
}
impl<'tcx> Evaluator<'tcx> {
fn new(validate: bool, seed: Option<u64>) -> Self {
fn new(validate: bool) -> Self {
Evaluator {
env_vars: HashMap::default(),
argc: None,
@ -363,7 +359,6 @@ fn new(validate: bool, seed: Option<u64>) -> Self {
last_error: 0,
tls: TlsData::default(),
validate,
rng: seed.map(|s| StdRng::seed_from_u64(s))
}
}
}
@ -543,7 +538,7 @@ fn tag_allocation<'b>(
mutability: alloc.mutability,
extra: AllocExtra {
stacks: extra,
base_addr: RefCell::new(None),
base_addr: Cell::new(None),
},
};
(Cow::Owned(alloc), base_tag)
@ -598,20 +593,20 @@ fn int_to_ptr(
return err!(InvalidNullPointerUsage);
}
if memory.extra.seed.is_none() {
if memory.extra.rng.is_none() {
return err!(ReadBytesAsPointer);
}
let extra = memory.extra.intptrcast.borrow();
match extra.vec.binary_search_by_key(&int, |(int, _)| *int) {
match extra.int_to_ptr_map.binary_search_by_key(&int, |(int, _)| *int) {
Ok(pos) => {
let (_, alloc_id) = extra.vec[pos];
let (_, alloc_id) = extra.int_to_ptr_map[pos];
Ok(Pointer::new_with_tag(alloc_id, Size::from_bytes(0), Tag::Untagged))
}
Err(pos) => {
if pos > 0 {
let (glb, alloc_id) = extra.vec[pos - 1];
let (glb, alloc_id) = extra.int_to_ptr_map[pos - 1];
let offset = int - glb;
if offset <= memory.get(alloc_id)?.bytes.len() as u64 {
Ok(Pointer::new_with_tag(alloc_id, Size::from_bytes(offset), Tag::Untagged))
@ -629,7 +624,7 @@ fn ptr_to_int(
ptr: Pointer<Self::PointerTag>,
memory: &Memory<'mir, 'tcx, Self>,
) -> InterpResult<'tcx, u64> {
if memory.extra.seed.is_none() {
if memory.extra.rng.is_none() {
return err!(ReadPointerAsBytes);
}
@ -637,28 +632,24 @@ fn ptr_to_int(
let alloc = memory.get(ptr.alloc_id)?;
let mut base_addr = alloc.extra.base_addr.borrow_mut();
let addr = match *base_addr {
Some(addr) => addr,
let base_addr = match alloc.extra.base_addr.get() {
Some(base_addr) => base_addr,
None => {
let addr = extra.addr;
extra.addr += alloc.bytes.len() as u64;
let base_addr = extra.next_base_addr;
extra.next_base_addr += alloc.bytes.len() as u64;
*base_addr = Some(addr);
alloc.extra.base_addr.set(Some(base_addr));
let elem = (addr, ptr.alloc_id);
let elem = (base_addr, ptr.alloc_id);
if let Err(pos) = extra.vec.binary_search(&elem) {
extra.vec.insert(pos, elem);
} else {
return err!(Unreachable);
}
// Given that `next_base_addr` increases in each allocation, pushing the
// corresponding tuple keeps `int_to_ptr_map` sorted
extra.int_to_ptr_map.push(elem);
addr
base_addr
}
};
Ok(addr + ptr.offset.bytes())
Ok(base_addr + ptr.offset.bytes())
}
}

View File

@ -1,4 +1,5 @@
use std::cell::RefCell;
use std::cell::Cell;
use rand::rngs::StdRng;
use rustc_mir::interpret::{Pointer, Allocation, AllocationExtra, InterpResult};
use rustc_target::abi::Size;
@ -10,13 +11,15 @@
pub struct MemoryState {
pub stacked: stacked_borrows::MemoryState,
pub intptrcast: intptrcast::MemoryState,
pub seed: Option<u64>,
/// The random number generator to use if Miri
/// is running in non-deterministic mode
pub(crate) rng: Option<StdRng>
}
#[derive(Debug, Clone,)]
pub struct AllocExtra {
pub stacks: stacked_borrows::Stacks,
pub base_addr: RefCell<Option<u64>>,
pub base_addr: Cell<Option<u64>>,
}
impl AllocationExtra<Tag> for AllocExtra {

View File

@ -44,7 +44,7 @@ fn ptr_op(
trace!("ptr_op: {:?} {:?} {:?}", *left, bin_op, *right);
if self.memory().extra.seed.is_some() && bin_op != Offset {
if self.memory().extra.rng.is_some() && bin_op != Offset {
let l_bits = self.force_bits(left.imm.to_scalar()?, left.layout.size)?;
let r_bits = self.force_bits(right.imm.to_scalar()?, right.layout.size)?;