rustup to rustc 1.14.0-nightly (7c69b0d5a 2016-11-01)
This commit is contained in:
@@ -6,7 +6,6 @@ extern crate test;
|
|||||||
|
|
||||||
use self::miri::{eval_main, run_mir_passes};
|
use self::miri::{eval_main, run_mir_passes};
|
||||||
use self::rustc::session::Session;
|
use self::rustc::session::Session;
|
||||||
use self::rustc::mir::mir_map::MirMap;
|
|
||||||
use self::rustc_driver::{driver, CompilerCalls, Compilation};
|
use self::rustc_driver::{driver, CompilerCalls, Compilation};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ extern crate syntax;
|
|||||||
|
|
||||||
use miri::{eval_main, run_mir_passes};
|
use miri::{eval_main, run_mir_passes};
|
||||||
use rustc::session::Session;
|
use rustc::session::Session;
|
||||||
use rustc::mir::mir_map::MirMap;
|
|
||||||
use rustc_driver::{driver, CompilerCalls, Compilation};
|
use rustc_driver::{driver, CompilerCalls, Compilation};
|
||||||
use syntax::ast::{MetaItemKind, NestedMetaItemKind};
|
use syntax::ast::{MetaItemKind, NestedMetaItemKind};
|
||||||
|
|
||||||
@@ -32,7 +31,6 @@ impl<'a> CompilerCalls<'a> for MiriCompilerCalls {
|
|||||||
state.session.abort_if_errors();
|
state.session.abort_if_errors();
|
||||||
|
|
||||||
let tcx = state.tcx.unwrap();
|
let tcx = state.tcx.unwrap();
|
||||||
let mir_map = state.mir_map.unwrap();
|
|
||||||
let (entry_node_id, _) = state.session.entry_fn.borrow()
|
let (entry_node_id, _) = state.session.entry_fn.borrow()
|
||||||
.expect("no main or start function found");
|
.expect("no main or start function found");
|
||||||
let entry_def_id = tcx.map.local_def_id(entry_node_id);
|
let entry_def_id = tcx.map.local_def_id(entry_node_id);
|
||||||
@@ -70,12 +68,8 @@ impl<'a> CompilerCalls<'a> for MiriCompilerCalls {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut mir_map_copy = MirMap::new(tcx.dep_graph.clone());
|
run_mir_passes(tcx);
|
||||||
for def_id in mir_map.map.keys() {
|
eval_main(tcx, entry_def_id, memory_size, step_limit, stack_limit);
|
||||||
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);
|
|
||||||
|
|
||||||
state.session.abort_if_errors();
|
state.session.abort_if_errors();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use rustc::mir::repr as mir;
|
use rustc::mir;
|
||||||
use rustc::ty::BareFnTy;
|
use rustc::ty::BareFnTy;
|
||||||
use memory::Pointer;
|
use memory::Pointer;
|
||||||
use rustc_const_math::ConstMathErr;
|
use rustc_const_math::ConstMathErr;
|
||||||
|
|||||||
@@ -1,17 +1,12 @@
|
|||||||
use rustc::middle::const_val::ConstVal;
|
use rustc::middle::const_val::ConstVal;
|
||||||
use rustc::hir::def_id::DefId;
|
use rustc::hir::def_id::DefId;
|
||||||
use rustc::hir::map::definitions::DefPathData;
|
use rustc::hir::map::definitions::DefPathData;
|
||||||
use rustc::mir::mir_map::MirMap;
|
use rustc::mir;
|
||||||
use rustc::mir::repr as mir;
|
|
||||||
use rustc::traits::Reveal;
|
use rustc::traits::Reveal;
|
||||||
use rustc::ty::layout::{self, Layout, Size};
|
use rustc::ty::layout::{self, Layout, Size};
|
||||||
use rustc::ty::subst::{self, Subst, Substs};
|
use rustc::ty::subst::{self, Subst, Substs};
|
||||||
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
|
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
|
||||||
use rustc::util::nodemap::DefIdMap;
|
|
||||||
use rustc_data_structures::indexed_vec::Idx;
|
use rustc_data_structures::indexed_vec::Idx;
|
||||||
use std::cell::RefCell;
|
|
||||||
use std::ops::Deref;
|
|
||||||
use std::rc::Rc;
|
|
||||||
use syntax::codemap::{self, DUMMY_SP};
|
use syntax::codemap::{self, DUMMY_SP};
|
||||||
|
|
||||||
use error::{EvalError, EvalResult};
|
use error::{EvalError, EvalResult};
|
||||||
@@ -20,6 +15,7 @@ use primval::{self, PrimVal, PrimValKind};
|
|||||||
pub use self::value::Value;
|
pub use self::value::Value;
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::cell::Ref;
|
||||||
|
|
||||||
mod step;
|
mod step;
|
||||||
mod terminator;
|
mod terminator;
|
||||||
@@ -27,16 +23,12 @@ mod cast;
|
|||||||
mod vtable;
|
mod vtable;
|
||||||
mod value;
|
mod value;
|
||||||
|
|
||||||
|
pub type MirRef<'tcx> = ::std::cell::Ref<'tcx, mir::Mir<'tcx>>;
|
||||||
|
|
||||||
pub struct EvalContext<'a, 'tcx: 'a> {
|
pub struct EvalContext<'a, 'tcx: 'a> {
|
||||||
/// The results of the type checker, from rustc.
|
/// The results of the type checker, from rustc.
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
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.
|
/// The virtual memory system.
|
||||||
memory: Memory<'a, 'tcx>,
|
memory: Memory<'a, 'tcx>,
|
||||||
|
|
||||||
@@ -44,20 +36,20 @@ pub struct EvalContext<'a, 'tcx: 'a> {
|
|||||||
globals: HashMap<GlobalId<'tcx>, Global<'tcx>>,
|
globals: HashMap<GlobalId<'tcx>, Global<'tcx>>,
|
||||||
|
|
||||||
/// The virtual call stack.
|
/// The virtual call stack.
|
||||||
stack: Vec<Frame<'a, 'tcx>>,
|
stack: Vec<Frame<'tcx>>,
|
||||||
|
|
||||||
/// The maximum number of stack frames allowed
|
/// The maximum number of stack frames allowed
|
||||||
stack_limit: usize,
|
stack_limit: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A stack frame.
|
/// A stack frame.
|
||||||
pub struct Frame<'a, 'tcx: 'a> {
|
pub struct Frame<'tcx> {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Function and callsite information
|
// Function and callsite information
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/// The MIR for the function called on this frame.
|
/// The MIR for the function called on this frame.
|
||||||
pub mir: CachedMir<'a, 'tcx>,
|
pub mir: MirRef<'tcx>,
|
||||||
|
|
||||||
/// The def_id of the current function.
|
/// The def_id of the current function.
|
||||||
pub def_id: DefId,
|
pub def_id: DefId,
|
||||||
@@ -125,12 +117,6 @@ pub enum LvalueExtra {
|
|||||||
DowncastVariant(usize),
|
DowncastVariant(usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub enum CachedMir<'mir, 'tcx: 'mir> {
|
|
||||||
Ref(&'mir mir::Mir<'tcx>),
|
|
||||||
Owned(Rc<mir::Mir<'tcx>>)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||||
/// Uniquely identifies a specific constant or static
|
/// Uniquely identifies a specific constant or static
|
||||||
pub struct GlobalId<'tcx> {
|
pub struct GlobalId<'tcx> {
|
||||||
@@ -176,11 +162,9 @@ pub enum StackPopCleanup {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
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 {
|
EvalContext {
|
||||||
tcx: tcx,
|
tcx: tcx,
|
||||||
mir_map: mir_map,
|
|
||||||
mir_cache: RefCell::new(DefIdMap()),
|
|
||||||
memory: Memory::new(&tcx.data_layout, memory_size),
|
memory: Memory::new(&tcx.data_layout, memory_size),
|
||||||
globals: HashMap::new(),
|
globals: HashMap::new(),
|
||||||
stack: Vec::new(),
|
stack: Vec::new(),
|
||||||
@@ -211,7 +195,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||||||
&mut self.memory
|
&mut self.memory
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn stack(&self) -> &[Frame<'a, 'tcx>] {
|
pub fn stack(&self) -> &[Frame<'tcx>] {
|
||||||
&self.stack
|
&self.stack
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,25 +276,12 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||||||
ty.is_sized(self.tcx, &self.tcx.empty_parameter_environment(), DUMMY_SP)
|
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, MirRef<'tcx>> {
|
||||||
trace!("load mir {:?}", def_id);
|
trace!("load mir {:?}", def_id);
|
||||||
if def_id.is_local() {
|
if def_id.is_local() || self.tcx.sess.cstore.is_item_mir_available(def_id) {
|
||||||
Ok(CachedMir::Ref(self.mir_map.map.get(&def_id).unwrap()))
|
Ok(self.tcx.item_mir(def_id))
|
||||||
} else {
|
} else {
|
||||||
let mut mir_cache = self.mir_cache.borrow_mut();
|
Err(EvalError::NoMirFor(self.tcx.item_path_str(def_id)))
|
||||||
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))),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -358,7 +329,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
span: codemap::Span,
|
span: codemap::Span,
|
||||||
mir: CachedMir<'a, 'tcx>,
|
mir: MirRef<'tcx>,
|
||||||
substs: &'tcx Substs<'tcx>,
|
substs: &'tcx Substs<'tcx>,
|
||||||
return_lvalue: Lvalue<'tcx>,
|
return_lvalue: Lvalue<'tcx>,
|
||||||
return_to_block: StackPopCleanup,
|
return_to_block: StackPopCleanup,
|
||||||
@@ -371,7 +342,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||||||
let locals = vec![None; num_locals];
|
let locals = vec![None; num_locals];
|
||||||
|
|
||||||
self.stack.push(Frame {
|
self.stack.push(Frame {
|
||||||
mir: mir.clone(),
|
mir: mir,
|
||||||
block: mir::START_BLOCK,
|
block: mir::START_BLOCK,
|
||||||
return_to_block: return_to_block,
|
return_to_block: return_to_block,
|
||||||
return_lvalue: return_lvalue,
|
return_lvalue: return_lvalue,
|
||||||
@@ -483,7 +454,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||||||
let dest_ty = self.lvalue_ty(lvalue);
|
let dest_ty = self.lvalue_ty(lvalue);
|
||||||
let dest_layout = self.type_layout(dest_ty);
|
let dest_layout = self.type_layout(dest_ty);
|
||||||
|
|
||||||
use rustc::mir::repr::Rvalue::*;
|
use rustc::mir::Rvalue::*;
|
||||||
match *rvalue {
|
match *rvalue {
|
||||||
Use(ref operand) => {
|
Use(ref operand) => {
|
||||||
let value = self.eval_operand(operand)?;
|
let value = self.eval_operand(operand)?;
|
||||||
@@ -653,7 +624,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||||||
|
|
||||||
Cast(kind, ref operand, cast_ty) => {
|
Cast(kind, ref operand, cast_ty) => {
|
||||||
debug_assert_eq!(self.monomorphize(cast_ty, self.substs()), dest_ty);
|
debug_assert_eq!(self.monomorphize(cast_ty, self.substs()), dest_ty);
|
||||||
use rustc::mir::repr::CastKind::*;
|
use rustc::mir::CastKind::*;
|
||||||
match kind {
|
match kind {
|
||||||
Unsize => {
|
Unsize => {
|
||||||
let src = self.eval_operand(operand)?;
|
let src = self.eval_operand(operand)?;
|
||||||
@@ -812,12 +783,12 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn eval_operand(&mut self, op: &mir::Operand<'tcx>) -> EvalResult<'tcx, Value> {
|
fn eval_operand(&mut self, op: &mir::Operand<'tcx>) -> EvalResult<'tcx, Value> {
|
||||||
use rustc::mir::repr::Operand::*;
|
use rustc::mir::Operand::*;
|
||||||
match *op {
|
match *op {
|
||||||
Consume(ref lvalue) => self.eval_and_read_lvalue(lvalue),
|
Consume(ref lvalue) => self.eval_and_read_lvalue(lvalue),
|
||||||
|
|
||||||
Constant(mir::Constant { ref literal, ty, .. }) => {
|
Constant(mir::Constant { ref literal, ty, .. }) => {
|
||||||
use rustc::mir::repr::Literal;
|
use rustc::mir::Literal;
|
||||||
let value = match *literal {
|
let value = match *literal {
|
||||||
Literal::Value { ref value } => self.const_to_value(value)?,
|
Literal::Value { ref value } => self.const_to_value(value)?,
|
||||||
|
|
||||||
@@ -883,7 +854,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn eval_lvalue(&mut self, mir_lvalue: &mir::Lvalue<'tcx>) -> EvalResult<'tcx, Lvalue<'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 {
|
let lvalue = match *mir_lvalue {
|
||||||
Local(mir::RETURN_POINTER) => self.frame().return_lvalue,
|
Local(mir::RETURN_POINTER) => self.frame().return_lvalue,
|
||||||
|
|
||||||
@@ -922,7 +893,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||||||
let base_ty = self.lvalue_ty(&proj.base);
|
let base_ty = self.lvalue_ty(&proj.base);
|
||||||
let base_layout = self.type_layout(base_ty);
|
let base_layout = self.type_layout(base_ty);
|
||||||
|
|
||||||
use rustc::mir::repr::ProjectionElem::*;
|
use rustc::mir::ProjectionElem::*;
|
||||||
let (ptr, extra) = match proj.elem {
|
let (ptr, extra) = match proj.elem {
|
||||||
Field(field, field_ty) => {
|
Field(field, field_ty) => {
|
||||||
// FIXME(solson)
|
// FIXME(solson)
|
||||||
@@ -1462,16 +1433,16 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||||||
Ok(Value::ByVal(val))
|
Ok(Value::ByVal(val))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn frame(&self) -> &Frame<'a, 'tcx> {
|
fn frame(&self) -> &Frame<'tcx> {
|
||||||
self.stack.last().expect("no call frames exist")
|
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")
|
self.stack.last_mut().expect("no call frames exist")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mir(&self) -> CachedMir<'a, 'tcx> {
|
fn mir(&self) -> MirRef<'tcx> {
|
||||||
self.frame().mir.clone()
|
Ref::clone(&self.frame().mir)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn substs(&self) -> &'tcx Substs<'tcx> {
|
fn substs(&self) -> &'tcx Substs<'tcx> {
|
||||||
@@ -1583,7 +1554,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> {
|
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.
|
// Subtract 1 because we don't store a value for the ReturnPointer, the local with index 0.
|
||||||
self.locals[local.index() - 1]
|
self.locals[local.index() - 1]
|
||||||
@@ -1630,34 +1601,23 @@ 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>(
|
pub fn eval_main<'a, 'tcx: 'a>(
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
mir_map: &'a MirMap<'tcx>,
|
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
memory_size: usize,
|
memory_size: usize,
|
||||||
step_limit: u64,
|
step_limit: u64,
|
||||||
stack_limit: usize,
|
stack_limit: usize,
|
||||||
) {
|
) {
|
||||||
let mir = mir_map.map.get(&def_id).expect("no mir for main function");
|
let mut ecx = EvalContext::new(tcx, memory_size, stack_limit);
|
||||||
let mut ecx = EvalContext::new(tcx, mir_map, memory_size, stack_limit);
|
let mir = ecx.load_mir(def_id).expect("main function's MIR not found");
|
||||||
|
|
||||||
ecx.push_stack_frame(
|
ecx.push_stack_frame(
|
||||||
def_id,
|
def_id,
|
||||||
mir.span,
|
mir.span,
|
||||||
CachedMir::Ref(mir),
|
mir,
|
||||||
tcx.intern_substs(&[]),
|
tcx.intern_substs(&[]),
|
||||||
Lvalue::from_ptr(Pointer::zst_ptr()),
|
Lvalue::from_ptr(Pointer::zst_ptr()),
|
||||||
StackPopCleanup::None
|
StackPopCleanup::None,
|
||||||
).expect("could not allocate first stack frame");
|
).expect("could not allocate first stack frame");
|
||||||
|
|
||||||
for _ in 0..step_limit {
|
for _ in 0..step_limit {
|
||||||
@@ -1695,7 +1655,7 @@ fn report(tcx: TyCtxt, ecx: &EvalContext, e: EvalError) {
|
|||||||
impl<'tcx> ::std::panic::RefUnwindSafe for Instance<'tcx> {}
|
impl<'tcx> ::std::panic::RefUnwindSafe for Instance<'tcx> {}
|
||||||
impl<'tcx> fmt::Display for Instance<'tcx> {
|
impl<'tcx> fmt::Display for Instance<'tcx> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
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.span_note(span, &format!("inside call to {}", Instance(def_id, substs)));
|
||||||
@@ -1703,7 +1663,7 @@ fn report(tcx: TyCtxt, ecx: &EvalContext, e: EvalError) {
|
|||||||
err.emit();
|
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();
|
let mut passes = ::rustc::mir::transform::Passes::new();
|
||||||
passes.push_hook(Box::new(::rustc_mir::transform::dump_mir::DumpMir));
|
passes.push_hook(Box::new(::rustc_mir::transform::dump_mir::DumpMir));
|
||||||
passes.push_pass(Box::new(::rustc_mir::transform::no_landing_pads::NoLandingPads));
|
passes.push_pass(Box::new(::rustc_mir::transform::no_landing_pads::NoLandingPads));
|
||||||
@@ -1716,7 +1676,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::simplify_cfg::SimplifyCfg::new("elaborate-drops")));
|
||||||
passes.push_pass(Box::new(::rustc_mir::transform::dump_mir::Marker("PreMiri")));
|
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.
|
// TODO(solson): Upstream these methods into rustc::ty::layout.
|
||||||
|
|||||||
@@ -3,21 +3,21 @@
|
|||||||
//! The main entry point is the `step` method.
|
//! The main entry point is the `step` method.
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
CachedMir,
|
|
||||||
GlobalId,
|
GlobalId,
|
||||||
EvalContext,
|
EvalContext,
|
||||||
Lvalue,
|
Lvalue,
|
||||||
StackPopCleanup,
|
StackPopCleanup,
|
||||||
Global,
|
Global,
|
||||||
|
MirRef,
|
||||||
};
|
};
|
||||||
use error::EvalResult;
|
use error::EvalResult;
|
||||||
use rustc::mir::repr as mir;
|
use rustc::mir;
|
||||||
use rustc::ty::{subst, self};
|
use rustc::ty::{subst, self};
|
||||||
use rustc::hir::def_id::DefId;
|
use rustc::hir::def_id::DefId;
|
||||||
use rustc::hir;
|
use rustc::hir;
|
||||||
use rustc::mir::visit::{Visitor, LvalueContext};
|
use rustc::mir::visit::{Visitor, LvalueContext};
|
||||||
|
use std::cell::Ref;
|
||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
use std::rc::Rc;
|
|
||||||
|
|
||||||
impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||||
/// Returns true as long as there are more things to do.
|
/// Returns true as long as there are more things to do.
|
||||||
@@ -38,7 +38,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||||||
substs: self.substs(),
|
substs: self.substs(),
|
||||||
def_id: self.frame().def_id,
|
def_id: self.frame().def_id,
|
||||||
ecx: self,
|
ecx: self,
|
||||||
mir: &mir,
|
mir: Ref::clone(&mir),
|
||||||
new_constants: &mut new,
|
new_constants: &mut new,
|
||||||
}.visit_statement(block, stmt, mir::Location {
|
}.visit_statement(block, stmt, mir::Location {
|
||||||
block: block,
|
block: block,
|
||||||
@@ -59,7 +59,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||||||
substs: self.substs(),
|
substs: self.substs(),
|
||||||
def_id: self.frame().def_id,
|
def_id: self.frame().def_id,
|
||||||
ecx: self,
|
ecx: self,
|
||||||
mir: &mir,
|
mir: Ref::clone(&mir),
|
||||||
new_constants: &mut new,
|
new_constants: &mut new,
|
||||||
}.visit_terminator(block, terminator, mir::Location {
|
}.visit_terminator(block, terminator, mir::Location {
|
||||||
block: block,
|
block: block,
|
||||||
@@ -76,7 +76,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||||||
fn statement(&mut self, stmt: &mir::Statement<'tcx>) -> EvalResult<'tcx, ()> {
|
fn statement(&mut self, stmt: &mir::Statement<'tcx>) -> EvalResult<'tcx, ()> {
|
||||||
trace!("{:?}", stmt);
|
trace!("{:?}", stmt);
|
||||||
|
|
||||||
use rustc::mir::repr::StatementKind::*;
|
use rustc::mir::StatementKind::*;
|
||||||
match stmt.kind {
|
match stmt.kind {
|
||||||
Assign(ref lvalue, ref rvalue) => self.eval_rvalue_into_lvalue(rvalue, lvalue)?,
|
Assign(ref lvalue, ref rvalue) => self.eval_rvalue_into_lvalue(rvalue, lvalue)?,
|
||||||
SetDiscriminant { .. } => unimplemented!(),
|
SetDiscriminant { .. } => unimplemented!(),
|
||||||
@@ -110,7 +110,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||||||
struct ConstantExtractor<'a, 'b: 'a, 'tcx: 'b> {
|
struct ConstantExtractor<'a, 'b: 'a, 'tcx: 'b> {
|
||||||
span: Span,
|
span: Span,
|
||||||
ecx: &'a mut EvalContext<'b, 'tcx>,
|
ecx: &'a mut EvalContext<'b, 'tcx>,
|
||||||
mir: &'a mir::Mir<'tcx>,
|
mir: MirRef<'tcx>,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
substs: &'tcx subst::Substs<'tcx>,
|
substs: &'tcx subst::Substs<'tcx>,
|
||||||
new_constants: &'a mut EvalResult<'tcx, u64>,
|
new_constants: &'a mut EvalResult<'tcx, u64>,
|
||||||
@@ -165,7 +165,6 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for ConstantExtractor<'a, 'b, 'tcx> {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
mir::Literal::Promoted { index } => {
|
mir::Literal::Promoted { index } => {
|
||||||
let mir = self.mir.promoted[index].clone();
|
|
||||||
let cid = GlobalId {
|
let cid = GlobalId {
|
||||||
def_id: self.def_id,
|
def_id: self.def_id,
|
||||||
substs: self.substs,
|
substs: self.substs,
|
||||||
@@ -174,8 +173,9 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for ConstantExtractor<'a, 'b, 'tcx> {
|
|||||||
if self.ecx.globals.contains_key(&cid) {
|
if self.ecx.globals.contains_key(&cid) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
let mir = Ref::clone(&self.mir);
|
||||||
|
let mir = Ref::map(mir, |mir| &mir.promoted[index]);
|
||||||
self.try(|this| {
|
self.try(|this| {
|
||||||
let mir = CachedMir::Owned(Rc::new(mir));
|
|
||||||
let ty = this.ecx.monomorphize(mir.return_ty, this.substs);
|
let ty = this.ecx.monomorphize(mir.return_ty, this.substs);
|
||||||
this.ecx.globals.insert(cid, Global::uninitialized(ty));
|
this.ecx.globals.insert(cid, Global::uninitialized(ty));
|
||||||
this.ecx.push_stack_frame(this.def_id,
|
this.ecx.push_stack_frame(this.def_id,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use rustc::hir::def_id::DefId;
|
use rustc::hir::def_id::DefId;
|
||||||
use rustc::mir::repr as mir;
|
use rustc::mir;
|
||||||
use rustc::ty::layout::Layout;
|
use rustc::ty::layout::Layout;
|
||||||
use rustc::ty::subst::Substs;
|
use rustc::ty::subst::Substs;
|
||||||
use rustc::ty::{self, Ty};
|
use rustc::ty::{self, Ty};
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use rustc::hir::def_id::DefId;
|
use rustc::hir::def_id::DefId;
|
||||||
use rustc::mir::repr as mir;
|
use rustc::mir;
|
||||||
use rustc::traits::{self, Reveal};
|
use rustc::traits::{self, Reveal};
|
||||||
use rustc::ty::fold::TypeFoldable;
|
use rustc::ty::fold::TypeFoldable;
|
||||||
use rustc::ty::layout::Layout;
|
use rustc::ty::layout::Layout;
|
||||||
@@ -28,7 +28,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
terminator: &mir::Terminator<'tcx>,
|
terminator: &mir::Terminator<'tcx>,
|
||||||
) -> EvalResult<'tcx, ()> {
|
) -> EvalResult<'tcx, ()> {
|
||||||
use rustc::mir::repr::TerminatorKind::*;
|
use rustc::mir::TerminatorKind::*;
|
||||||
match terminator.kind {
|
match terminator.kind {
|
||||||
Return => self.pop_stack_frame()?,
|
Return => self.pop_stack_frame()?,
|
||||||
|
|
||||||
@@ -204,7 +204,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||||||
mir,
|
mir,
|
||||||
resolved_substs,
|
resolved_substs,
|
||||||
return_lvalue,
|
return_lvalue,
|
||||||
return_to_block
|
return_to_block,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let arg_locals = self.frame().mir.args_iter();
|
let arg_locals = self.frame().mir.args_iter();
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
collections_bound,
|
collections_bound,
|
||||||
rustc_private,
|
rustc_private,
|
||||||
pub_restricted,
|
pub_restricted,
|
||||||
|
cell_extras,
|
||||||
)]
|
)]
|
||||||
|
|
||||||
// From rustc.
|
// From rustc.
|
||||||
@@ -30,7 +31,6 @@ pub use error::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub use interpreter::{
|
pub use interpreter::{
|
||||||
CachedMir,
|
|
||||||
EvalContext,
|
EvalContext,
|
||||||
Frame,
|
Frame,
|
||||||
eval_main,
|
eval_main,
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
use std::mem::transmute;
|
use std::mem::transmute;
|
||||||
|
|
||||||
use rustc::mir::repr as mir;
|
use rustc::mir;
|
||||||
|
|
||||||
use error::{EvalError, EvalResult};
|
use error::{EvalError, EvalResult};
|
||||||
use memory::{AllocId, Pointer};
|
use memory::{AllocId, Pointer};
|
||||||
@@ -274,7 +274,7 @@ pub fn binary_op<'tcx>(
|
|||||||
left: PrimVal,
|
left: PrimVal,
|
||||||
right: PrimVal
|
right: PrimVal
|
||||||
) -> EvalResult<'tcx, (PrimVal, bool)> {
|
) -> EvalResult<'tcx, (PrimVal, bool)> {
|
||||||
use rustc::mir::repr::BinOp::*;
|
use rustc::mir::BinOp::*;
|
||||||
use self::PrimValKind::*;
|
use self::PrimValKind::*;
|
||||||
|
|
||||||
match (left.try_as_ptr(), right.try_as_ptr()) {
|
match (left.try_as_ptr(), right.try_as_ptr()) {
|
||||||
@@ -377,7 +377,7 @@ pub fn binary_op<'tcx>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn unrelated_ptr_ops<'tcx>(bin_op: mir::BinOp) -> EvalResult<'tcx, PrimVal> {
|
fn unrelated_ptr_ops<'tcx>(bin_op: mir::BinOp) -> EvalResult<'tcx, PrimVal> {
|
||||||
use rustc::mir::repr::BinOp::*;
|
use rustc::mir::BinOp::*;
|
||||||
match bin_op {
|
match bin_op {
|
||||||
Eq => Ok(PrimVal::from_bool(false)),
|
Eq => Ok(PrimVal::from_bool(false)),
|
||||||
Ne => Ok(PrimVal::from_bool(true)),
|
Ne => Ok(PrimVal::from_bool(true)),
|
||||||
@@ -387,7 +387,7 @@ fn unrelated_ptr_ops<'tcx>(bin_op: mir::BinOp) -> EvalResult<'tcx, PrimVal> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn unary_op<'tcx>(un_op: mir::UnOp, val: PrimVal) -> EvalResult<'tcx, PrimVal> {
|
pub fn unary_op<'tcx>(un_op: mir::UnOp, val: PrimVal) -> EvalResult<'tcx, PrimVal> {
|
||||||
use rustc::mir::repr::UnOp::*;
|
use rustc::mir::UnOp::*;
|
||||||
use self::PrimValKind::*;
|
use self::PrimValKind::*;
|
||||||
|
|
||||||
let bits = match (un_op, val.kind) {
|
let bits = match (un_op, val.kind) {
|
||||||
|
|||||||
Reference in New Issue
Block a user