Skip to content

Commit

Permalink
Fix build for latest nightly.
Browse files Browse the repository at this point in the history
The most significant change comes from rust-lang/rust#37400, which
removes the need to maintain our node cache of MIR nodes.
  • Loading branch information
plietar committed Nov 4, 2016
1 parent c148d88 commit f75d4fb
Show file tree
Hide file tree
Showing 8 changed files with 56 additions and 99 deletions.
10 changes: 2 additions & 8 deletions src/bin/miri.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ extern crate syntax;

use miri::{eval_main, run_mir_passes};
use rustc::session::Session;
use rustc::mir::mir_map::MirMap;
use rustc_driver::{driver, CompilerCalls, Compilation};
use syntax::ast::{MetaItemKind, NestedMetaItemKind};

Expand All @@ -32,7 +31,6 @@ impl<'a> CompilerCalls<'a> for MiriCompilerCalls {
state.session.abort_if_errors();

let tcx = state.tcx.unwrap();
let mir_map = state.mir_map.unwrap();
let (entry_node_id, _) = state.session.entry_fn.borrow()
.expect("no main or start function found");
let entry_def_id = tcx.map.local_def_id(entry_node_id);
Expand Down Expand Up @@ -70,12 +68,8 @@ impl<'a> CompilerCalls<'a> for MiriCompilerCalls {
}
}

let mut mir_map_copy = MirMap::new(tcx.dep_graph.clone());
for def_id in mir_map.map.keys() {
mir_map_copy.map.insert(def_id, mir_map.map.get(&def_id).unwrap().clone());
}
run_mir_passes(tcx, &mut mir_map_copy);
eval_main(tcx, &mir_map_copy, entry_def_id, memory_size, step_limit, stack_limit);
run_mir_passes(tcx);
eval_main(tcx, entry_def_id, memory_size, step_limit, stack_limit);

state.session.abort_if_errors();
});
Expand Down
2 changes: 1 addition & 1 deletion src/error.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::error::Error;
use std::fmt;
use rustc::mir::repr as mir;
use rustc::mir;
use rustc::ty::BareFnTy;
use memory::Pointer;
use rustc_const_math::ConstMathErr;
Expand Down
109 changes: 36 additions & 73 deletions src/interpreter/mod.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
use rustc::middle::const_val::ConstVal;
use rustc::hir::def_id::DefId;
use rustc::hir::map::definitions::DefPathData;
use rustc::mir::mir_map::MirMap;
use rustc::mir::repr as mir;
use rustc::mir as mir;
use rustc::traits::Reveal;
use rustc::ty::layout::{self, Layout, Size};
use rustc::ty::subst::{self, Subst, Substs};
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
use rustc::util::nodemap::DefIdMap;
use rustc_data_structures::indexed_vec::Idx;
use std::cell::RefCell;
use std::ops::Deref;
use std::rc::Rc;
use std::cell;
use syntax::codemap::{self, DUMMY_SP};

use error::{EvalError, EvalResult};
Expand All @@ -31,33 +27,27 @@ pub struct EvalContext<'a, 'tcx: 'a> {
/// The results of the type checker, from rustc.
tcx: TyCtxt<'a, 'tcx, 'tcx>,

/// A mapping from NodeIds to Mir, from rustc. Only contains MIR for crate-local items.
mir_map: &'a MirMap<'tcx>,

/// A local cache from DefIds to Mir for non-crate-local items.
mir_cache: RefCell<DefIdMap<Rc<mir::Mir<'tcx>>>>,

/// The virtual memory system.
memory: Memory<'a, 'tcx>,

/// Precomputed statics, constants and promoteds.
globals: HashMap<GlobalId<'tcx>, Global<'tcx>>,

/// The virtual call stack.
stack: Vec<Frame<'a, 'tcx>>,
stack: Vec<Frame<'tcx>>,

/// The maximum number of stack frames allowed
stack_limit: usize,
}

/// A stack frame.
pub struct Frame<'a, 'tcx: 'a> {
pub struct Frame<'tcx> {
////////////////////////////////////////////////////////////////////////////////
// Function and callsite information
////////////////////////////////////////////////////////////////////////////////

/// The MIR for the function called on this frame.
pub mir: CachedMir<'a, 'tcx>,
pub mir: CachedMir<'tcx>,

/// The def_id of the current function.
pub def_id: DefId,
Expand Down Expand Up @@ -125,11 +115,7 @@ pub enum LvalueExtra {
DowncastVariant(usize),
}

#[derive(Clone)]
pub enum CachedMir<'mir, 'tcx: 'mir> {
Ref(&'mir mir::Mir<'tcx>),
Owned(Rc<mir::Mir<'tcx>>)
}
pub type CachedMir<'tcx> = cell::Ref<'tcx, mir::Mir<'tcx>>;

#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
/// Uniquely identifies a specific constant or static
Expand Down Expand Up @@ -176,11 +162,9 @@ pub enum StackPopCleanup {
}

impl<'a, 'tcx> EvalContext<'a, 'tcx> {
pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, mir_map: &'a MirMap<'tcx>, memory_size: usize, stack_limit: usize) -> Self {
pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, memory_size: usize, stack_limit: usize) -> Self {
EvalContext {
tcx: tcx,
mir_map: mir_map,
mir_cache: RefCell::new(DefIdMap()),
memory: Memory::new(&tcx.data_layout, memory_size),
globals: HashMap::new(),
stack: Vec::new(),
Expand Down Expand Up @@ -211,7 +195,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
&mut self.memory
}

pub fn stack(&self) -> &[Frame<'a, 'tcx>] {
pub fn stack(&self) -> &[Frame<'tcx>] {
&self.stack
}

Expand Down Expand Up @@ -292,25 +276,15 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
ty.is_sized(self.tcx, &self.tcx.empty_parameter_environment(), DUMMY_SP)
}

pub fn load_mir(&self, def_id: DefId) -> EvalResult<'tcx, CachedMir<'a, 'tcx>> {
pub fn load_mir(&self, def_id: DefId) -> EvalResult<'tcx, CachedMir<'tcx>> {
trace!("load mir {:?}", def_id);
if def_id.is_local() {
Ok(CachedMir::Ref(self.mir_map.map.get(&def_id).unwrap()))
} else {
let mut mir_cache = self.mir_cache.borrow_mut();
if let Some(mir) = mir_cache.get(&def_id) {
return Ok(CachedMir::Owned(mir.clone()));
}

let cs = &self.tcx.sess.cstore;
match cs.maybe_get_item_mir(self.tcx, def_id) {
Some(mir) => {
let cached = Rc::new(mir);
mir_cache.insert(def_id, cached.clone());
Ok(CachedMir::Owned(cached))
},
None => Err(EvalError::NoMirFor(self.tcx.item_path_str(def_id))),
}
let cs = &self.tcx.sess.cstore;

if def_id.is_local() || cs.is_item_mir_available(def_id) {
Ok(self.tcx.item_mir(def_id))
} else {
Err(EvalError::NoMirFor(self.tcx.item_path_str(def_id)))
}
}

Expand Down Expand Up @@ -358,7 +332,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
&mut self,
def_id: DefId,
span: codemap::Span,
mir: CachedMir<'a, 'tcx>,
mir: CachedMir<'tcx>,
substs: &'tcx Substs<'tcx>,
return_lvalue: Lvalue<'tcx>,
return_to_block: StackPopCleanup,
Expand All @@ -371,7 +345,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
let locals = vec![None; num_locals];

self.stack.push(Frame {
mir: mir.clone(),
mir: CachedMir::clone(&mir),
block: mir::START_BLOCK,
return_to_block: return_to_block,
return_lvalue: return_lvalue,
Expand Down Expand Up @@ -483,7 +457,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
let dest_ty = self.lvalue_ty(lvalue);
let dest_layout = self.type_layout(dest_ty);

use rustc::mir::repr::Rvalue::*;
use rustc::mir::Rvalue::*;
match *rvalue {
Use(ref operand) => {
let value = self.eval_operand(operand)?;
Expand Down Expand Up @@ -653,7 +627,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {

Cast(kind, ref operand, cast_ty) => {
debug_assert_eq!(self.monomorphize(cast_ty, self.substs()), dest_ty);
use rustc::mir::repr::CastKind::*;
use rustc::mir::CastKind::*;
match kind {
Unsize => {
let src = self.eval_operand(operand)?;
Expand Down Expand Up @@ -812,12 +786,12 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
}

fn eval_operand(&mut self, op: &mir::Operand<'tcx>) -> EvalResult<'tcx, Value> {
use rustc::mir::repr::Operand::*;
use rustc::mir::Operand::*;
match *op {
Consume(ref lvalue) => self.eval_and_read_lvalue(lvalue),

Constant(mir::Constant { ref literal, ty, .. }) => {
use rustc::mir::repr::Literal;
use rustc::mir::Literal;
let value = match *literal {
Literal::Value { ref value } => self.const_to_value(value)?,

Expand Down Expand Up @@ -883,7 +857,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
}

fn eval_lvalue(&mut self, mir_lvalue: &mir::Lvalue<'tcx>) -> EvalResult<'tcx, Lvalue<'tcx>> {
use rustc::mir::repr::Lvalue::*;
use rustc::mir::Lvalue::*;
let lvalue = match *mir_lvalue {
Local(mir::RETURN_POINTER) => self.frame().return_lvalue,

Expand All @@ -895,7 +869,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
}

Static(def_id) => {
let substs = subst::Substs::empty(self.tcx);
let substs = subst::Substs::empty();
let cid = GlobalId {
def_id: def_id,
substs: substs,
Expand All @@ -922,7 +896,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
let base_ty = self.lvalue_ty(&proj.base);
let base_layout = self.type_layout(base_ty);

use rustc::mir::repr::ProjectionElem::*;
use rustc::mir::ProjectionElem::*;
let (ptr, extra) = match proj.elem {
Field(field, field_ty) => {
// FIXME(solson)
Expand Down Expand Up @@ -1462,16 +1436,16 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
Ok(Value::ByVal(val))
}

fn frame(&self) -> &Frame<'a, 'tcx> {
fn frame(&self) -> &Frame<'tcx> {
self.stack.last().expect("no call frames exist")
}

pub fn frame_mut(&mut self) -> &mut Frame<'a, 'tcx> {
pub fn frame_mut(&mut self) -> &mut Frame<'tcx> {
self.stack.last_mut().expect("no call frames exist")
}

fn mir(&self) -> CachedMir<'a, 'tcx> {
self.frame().mir.clone()
fn mir(&self) -> CachedMir<'tcx> {
CachedMir::clone(&self.frame().mir)
}

fn substs(&self) -> &'tcx Substs<'tcx> {
Expand Down Expand Up @@ -1583,7 +1557,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
}
}

impl<'a, 'tcx: 'a> Frame<'a, 'tcx> {
impl<'tcx> Frame<'tcx> {
pub fn get_local(&self, local: mir::Local) -> Option<Value> {
// Subtract 1 because we don't store a value for the ReturnPointer, the local with index 0.
self.locals[local.index() - 1]
Expand Down Expand Up @@ -1630,32 +1604,21 @@ impl<'tcx> Lvalue<'tcx> {
}
}

impl<'mir, 'tcx: 'mir> Deref for CachedMir<'mir, 'tcx> {
type Target = mir::Mir<'tcx>;
fn deref(&self) -> &mir::Mir<'tcx> {
match *self {
CachedMir::Ref(r) => r,
CachedMir::Owned(ref rc) => rc,
}
}
}

pub fn eval_main<'a, 'tcx: 'a>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
mir_map: &'a MirMap<'tcx>,
def_id: DefId,
memory_size: usize,
step_limit: u64,
stack_limit: usize,
) {
let mir = mir_map.map.get(&def_id).expect("no mir for main function");
let mut ecx = EvalContext::new(tcx, mir_map, memory_size, stack_limit);
let mir = tcx.item_mir(def_id);
let mut ecx = EvalContext::new(tcx, memory_size, stack_limit);

ecx.push_stack_frame(
def_id,
mir.span,
CachedMir::Ref(mir),
subst::Substs::empty(tcx),
mir,
subst::Substs::empty(),
Lvalue::from_ptr(Pointer::zst_ptr()),
StackPopCleanup::None
).expect("could not allocate first stack frame");
Expand Down Expand Up @@ -1695,15 +1658,15 @@ fn report(tcx: TyCtxt, ecx: &EvalContext, e: EvalError) {
impl<'tcx> ::std::panic::RefUnwindSafe for Instance<'tcx> {}
impl<'tcx> fmt::Display for Instance<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
ppaux::parameterized(f, self.1, self.0, ppaux::Ns::Value, &[])
ppaux::parameterized(f, self.1, self.0, &[])
}
}
err.span_note(span, &format!("inside call to {}", Instance(def_id, substs)));
}
err.emit();
}

pub fn run_mir_passes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, mir_map: &mut MirMap<'tcx>) {
pub fn run_mir_passes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
let mut passes = ::rustc::mir::transform::Passes::new();
passes.push_hook(Box::new(::rustc_mir::transform::dump_mir::DumpMir));
passes.push_pass(Box::new(::rustc_mir::transform::no_landing_pads::NoLandingPads));
Expand All @@ -1716,7 +1679,7 @@ pub fn run_mir_passes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, mir_map: &mut MirMa
passes.push_pass(Box::new(::rustc_mir::transform::simplify_cfg::SimplifyCfg::new("elaborate-drops")));
passes.push_pass(Box::new(::rustc_mir::transform::dump_mir::Marker("PreMiri")));

passes.run_passes(tcx, mir_map);
passes.run_passes(tcx);
}

// TODO(solson): Upstream these methods into rustc::ty::layout.
Expand Down
Loading

0 comments on commit f75d4fb

Please sign in to comment.