//! Global machine state as well as implementation of the interpreter engine
//! `Machine` trait.
-use std::rc::Rc;
use std::borrow::Cow;
use std::cell::RefCell;
+use std::rc::Rc;
use rand::rngs::StdRng;
-use syntax::attr;
-use syntax::symbol::sym;
use rustc::hir::def_id::DefId;
-use rustc::ty::{self, Ty, TyCtxt, layout::{Size, LayoutOf}};
use rustc::mir;
+use rustc::ty::{
+ self,
+ layout::{LayoutOf, Size},
+ Ty, TyCtxt,
+};
+use syntax::attr;
+use syntax::symbol::sym;
use crate::*;
// Some global facts about the emulated machine.
-pub const PAGE_SIZE: u64 = 4*1024; // FIXME: adjust to target architecture
-pub const STACK_ADDR: u64 = 32*PAGE_SIZE; // not really about the "stack", but where we start assigning integer addresses to allocations
-pub const STACK_SIZE: u64 = 16*PAGE_SIZE; // whatever
+pub const PAGE_SIZE: u64 = 4 * 1024; // FIXME: adjust to target architecture
+pub const STACK_ADDR: u64 = 32 * PAGE_SIZE; // not really about the "stack", but where we start assigning integer addresses to allocations
+pub const STACK_SIZE: u64 = 16 * PAGE_SIZE; // whatever
pub const NUM_CPUS: u64 = 1;
/// Extra memory kinds
pub(crate) argv: Option<Pointer<Tag>>,
pub(crate) cmd_line: Option<Pointer<Tag>>,
- /// Last OS error.
- pub(crate) last_error: u32,
+ /// Last OS error location in memory. It is a 32-bit integer.
+ pub(crate) last_error: Option<MPlaceTy<'tcx, Tag>>,
/// TLS state.
pub(crate) tls: TlsData<'tcx>,
/// If enabled, the `env_vars` field is populated with the host env vars during initialization
/// and random number generation is delegated to the host.
pub(crate) communicate: bool,
+
+ pub(crate) file_handler: FileHandler,
}
impl<'tcx> Evaluator<'tcx> {
argc: None,
argv: None,
cmd_line: None,
- last_error: 0,
+ last_error: None,
tls: TlsData::default(),
communicate,
+ file_handler: Default::default(),
}
}
}
type PointerTag = Tag;
type ExtraFnVal = Dlsym;
- type MemoryMap = MonoHashMap<AllocId, (MemoryKind<MiriMemoryKind>, Allocation<Tag, Self::AllocExtra>)>;
+ type MemoryMap = MonoHashMap<
+ AllocId,
+ (
+ MemoryKind<MiriMemoryKind>,
+ Allocation<Tag, Self::AllocExtra>,
+ ),
+ >;
const STATIC_KIND: Option<MiriMemoryKind> = Some(MiriMemoryKind::Static);
#[inline(always)]
fn enforce_validity(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {
- ecx.memory().extra.validate
+ ecx.memory.extra.validate
}
#[inline(always)]
ecx.write_scalar(Scalar::from_uint(align, arg.layout.size), arg)?;
// No more arguments.
- assert!(
- args.next().is_none(),
- "`exchange_malloc` lang item has more arguments than expected"
- );
+ args.next().expect_none("`exchange_malloc` lang item has more arguments than expected");
Ok(())
}
}
#[inline(always)]
- fn before_terminator(_ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx>
- {
+ fn before_terminator(_ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> {
// We are not interested in detecting loops.
Ok(())
}
id: AllocId,
alloc: Cow<'b, Allocation>,
kind: Option<MemoryKind<Self::MemoryKinds>>,
- ) -> (Cow<'b, Allocation<Self::PointerTag, Self::AllocExtra>>, Self::PointerTag) {
+ ) -> (
+ Cow<'b, Allocation<Self::PointerTag, Self::AllocExtra>>,
+ Self::PointerTag,
+ ) {
let kind = kind.expect("we set our STATIC_KIND so this cannot be None");
let alloc = alloc.into_owned();
let (stacks, base_tag) = if !memory_extra.validate {
};
let mut stacked_borrows = memory_extra.stacked_borrows.borrow_mut();
let alloc: Allocation<Tag, Self::AllocExtra> = alloc.with_tags_and_extra(
- |alloc| if !memory_extra.validate {
- Tag::Untagged
- } else {
- // Only statics may already contain pointers at this point
- assert_eq!(kind, MiriMemoryKind::Static.into());
- stacked_borrows.static_base_ptr(alloc)
+ |alloc| {
+ if !memory_extra.validate {
+ Tag::Untagged
+ } else {
+ // Only statics may already contain pointers at this point
+ assert_eq!(kind, MiriMemoryKind::Static.into());
+ stacked_borrows.static_base_ptr(alloc)
+ }
},
AllocExtra {
stacked_borrows: stacks,
}
#[inline(always)]
- fn tag_static_base_pointer(
- memory_extra: &MemoryExtra,
- id: AllocId,
- ) -> Self::PointerTag {
+ fn tag_static_base_pointer(memory_extra: &MemoryExtra, id: AllocId) -> Self::PointerTag {
if !memory_extra.validate {
Tag::Untagged
} else {
- memory_extra.stacked_borrows.borrow_mut().static_base_ptr(id)
+ memory_extra
+ .stacked_borrows
+ .borrow_mut()
+ .static_base_ptr(id)
}
}
) -> InterpResult<'tcx> {
if !Self::enforce_validity(ecx) {
// No tracking.
- Ok(())
+ Ok(())
} else {
ecx.retag(kind, place)
}
fn stack_push(
ecx: &mut InterpCx<'mir, 'tcx, Self>,
) -> InterpResult<'tcx, stacked_borrows::CallId> {
- Ok(ecx.memory().extra.stacked_borrows.borrow_mut().new_call())
+ Ok(ecx.memory.extra.stacked_borrows.borrow_mut().new_call())
}
#[inline(always)]
ecx: &mut InterpCx<'mir, 'tcx, Self>,
extra: stacked_borrows::CallId,
) -> InterpResult<'tcx> {
- Ok(ecx.memory().extra.stacked_borrows.borrow_mut().end_call(extra))
+ Ok(ecx
+ .memory
+ .extra
+ .stacked_borrows
+ .borrow_mut()
+ .end_call(extra))
}
#[inline(always)]