inclusive_range_methods,
)]
+ #![cfg_attr(feature = "cargo-clippy", allow(cast_lossless))]
+
#[macro_use]
extern crate log;
use rustc::ty::subst::Subst;
use rustc::hir::def_id::DefId;
use rustc::mir;
- use rustc::middle::const_val;
+use rustc_data_structures::fx::FxHasher;
+
use syntax::ast::Mutability;
use syntax::codemap::Span;
use std::collections::{HashMap, BTreeMap};
+use std::hash::{Hash, Hasher};
pub use rustc::mir::interpret::*;
pub use rustc_mir::interpret::*;
// Return value
let size = ecx.tcx.data_layout.pointer_size;
let align = ecx.tcx.data_layout.pointer_align;
- let ret_ptr = ecx.memory_mut().allocate(size, align, Some(MemoryKind::Stack))?;
+ let ret_ptr = ecx.memory_mut().allocate(size, align, MemoryKind::Stack)?;
cleanup_ptr = Some(ret_ptr);
// Push our stack frame
let foo = ecx.memory.allocate_bytes(b"foo\0");
let ptr_size = ecx.memory.pointer_size();
let ptr_align = ecx.tcx.data_layout.pointer_align;
- let foo_ptr = ecx.memory.allocate(ptr_size, ptr_align, None)?;
+ let foo_ptr = ecx.memory.allocate(ptr_size, ptr_align, MemoryKind::Stack)?;
ecx.memory.write_scalar(foo_ptr.into(), ptr_align, Scalar::Ptr(foo), ptr_size, false)?;
ecx.memory.mark_static_initialized(foo_ptr.alloc_id, Mutability::Immutable)?;
ecx.write_ptr(dest, foo_ptr.into(), ty)?;
block.terminator().source_info.span
};
- let mut err = const_val::struct_error(ecx.tcx.tcx.at(span), "constant evaluation error");
+ let mut err = struct_error(ecx.tcx.tcx.at(span), "constant evaluation error");
let (frames, span) = ecx.generate_stacktrace(None);
err.span_label(span, e.to_string());
- for const_val::FrameInfo { span, location, .. } in frames {
+ for FrameInfo { span, location, .. } in frames {
err.span_note(span, &format!("inside call to `{}`", location));
}
err.emit();
}
}
-#[derive(Default)]
+#[derive(Clone, Default, PartialEq, Eq)]
pub struct Evaluator<'tcx> {
/// Environment variables set by `setenv`
/// Miri does not expose env vars from the host to the emulated program
pub(crate) suspended: HashMap<DynamicLifetime, Vec<ValidationQuery<'tcx>>>,
}
+impl<'tcx> Hash for Evaluator<'tcx> {
+ fn hash<H: Hasher>(&self, state: &mut H) {
+ let Evaluator {
+ env_vars,
+ suspended: _,
+ } = self;
+
+ env_vars.iter()
+ .map(|(env, ptr)| {
+ let mut h = FxHasher::default();
+ env.hash(&mut h);
+ ptr.hash(&mut h);
+ h.finish()
+ })
+ .fold(0u64, |acc, hash| acc.wrapping_add(hash))
+ .hash(state);
+ }
+}
+
pub type TlsKey = u128;
-#[derive(Copy, Clone, Debug)]
+#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub struct TlsEntry<'tcx> {
data: Scalar, // Will eventually become a map from thread IDs to `Scalar`s, if we ever support more than one thread.
dtor: Option<ty::Instance<'tcx>>,
}
-#[derive(Default)]
+#[derive(Clone, Default, PartialEq, Eq)]
pub struct MemoryData<'tcx> {
/// The Key to use for the next thread-local allocation.
next_thread_local: TlsKey,
statics: HashMap<GlobalId<'tcx>, AllocId>,
}
+impl<'tcx> Hash for MemoryData<'tcx> {
+ fn hash<H: Hasher>(&self, state: &mut H) {
+ let MemoryData {
+ next_thread_local: _,
+ thread_local,
+ locks: _,
+ statics: _,
+ } = self;
+
+ thread_local.hash(state);
+ }
+}
+
impl<'mir, 'tcx: 'mir> Machine<'mir, 'tcx> for Evaluator<'tcx> {
type MemoryData = MemoryData<'tcx>;
type MemoryKinds = memory::MemoryKind;
let ptr = ecx.memory.allocate(
layout.size,
layout.align,
- None,
+ MemoryKind::Stack,
)?;
// Step 4: Cache allocation id for recursive statics
let frame = ecx.frame_mut();
let bb = &frame.mir.basic_blocks()[frame.block];
if bb.statements.len() == frame.stmt && !bb.is_cleanup {
- match bb.terminator().kind {
- ::rustc::mir::TerminatorKind::Return => {
- for (local, _local_decl) in mir.local_decls.iter_enumerated().skip(1) {
- // Don't deallocate locals, because the return value might reference them
- frame.storage_dead(local);
- }
+ if let ::rustc::mir::TerminatorKind::Return = bb.terminator().kind {
+ for (local, _local_decl) in mir.local_decls.iter_enumerated().skip(1) {
+ // Don't deallocate locals, because the return value might reference them
+ frame.storage_dead(local);
}
- _ => {}
}
}
}
value: Value::Scalar(Scalar::from_u128(match layout.size.bytes() {
0 => 1 as u128,
size => size as u128,
- }.into())),
+ })),
ty: usize,
},
dest,