use rustc::session::Session;
use rustc_driver::{driver, CompilerCalls};
use rustc::ty::{TyCtxt, subst};
-use rustc::mir::mir_map::MirMap;
-use rustc::mir::repr::Mir;
use rustc::hir::def_id::DefId;
-use rustc::hir::{map, ItemFn, Item};
-use syntax::codemap::Span;
struct MiriCompilerCalls;
let tcx = state.tcx.unwrap();
let mir_map = state.mir_map.unwrap();
- let (span, mir, def_id) = get_main(tcx, mir_map);
- println!("found `main` function at: {:?}", span);
+ let (node_id, span) = state.session.entry_fn.borrow().expect("no main or start function found");
+ debug!("found `main` function at: {:?}", span);
+
+ let mir = mir_map.map.get(&node_id).expect("no mir for main function");
+ let def_id = tcx.map.local_def_id(node_id);
let mut ecx = EvalContext::new(tcx, mir_map);
let substs = tcx.mk_substs(subst::Substs::empty());
let return_ptr = ecx.alloc_ret_ptr(mir.return_ty, substs).expect("main function should not be diverging");
ecx.push_stack_frame(def_id, mir.span, CachedMir::Ref(mir), substs, Some(return_ptr));
+ if mir.arg_decls.len() == 2 {
+ // start function
+ let ptr_size = ecx.memory().pointer_size;
+ let nargs = ecx.memory_mut().allocate(ptr_size);
+ ecx.memory_mut().write_usize(nargs, 0).unwrap();
+ let args = ecx.memory_mut().allocate(ptr_size);
+ ecx.memory_mut().write_usize(args, 0).unwrap();
+ ecx.frame_mut().locals[0] = nargs;
+ ecx.frame_mut().locals[1] = args;
+ }
+
loop {
match step(&mut ecx) {
Ok(true) => {}
}
}
-fn get_main<'a, 'b, 'tcx: 'b>(tcx: TyCtxt<'a, 'tcx, 'tcx>, mir_map: &'b MirMap<'tcx>) -> (Span, &'b Mir<'tcx>, DefId) {
- for (&id, mir) in &mir_map.map {
- if let map::Node::NodeItem(&Item { name, span, ref node, .. }) = tcx.map.get(id) {
- if let ItemFn(..) = *node {
- if name.as_str() == "main" {
- return (span, mir, tcx.map.local_def_id(id));
- }
- }
- }
- }
- panic!("no main function found");
-}
-
fn report(tcx: TyCtxt, ecx: &EvalContext, e: EvalError) {
let frame = ecx.stack().last().expect("stackframe was empty");
let block = &frame.mir.basic_blocks()[frame.next_block];
.expect("need to specify RUST_SYSROOT env var or use rustup or multirust")
.to_owned(),
};
- let sysroot_flag = format!("--sysroot {} -Dwarnings", sysroot);
+ let flags = format!("--sysroot {} -Dwarnings", sysroot);
// FIXME: read directories in sysroot/lib/rustlib and generate the test targets from that
let targets = &["x86_64-unknown-linux-gnu", "i686-unknown-linux-gnu"];
for &target in targets {
+ use std::io::Write;
+ let stderr = std::io::stderr();
+ write!(stderr.lock(), "running tests for target {}", target).unwrap();
let mut config = compiletest::default_config();
- config.host_rustcflags = Some(sysroot_flag.clone());
+ config.host_rustcflags = Some(flags.clone());
config.mode = mode.parse().expect("Invalid mode");
config.run_lib_path = format!("{}/lib/rustlib/{}/lib", sysroot, target);
config.rustc_path = "target/debug/miri".into();
config.src_base = PathBuf::from(format!("tests/{}", mode));
config.target = target.to_owned();
- config.target_rustcflags = Some(sysroot_flag.clone());
+ config.target_rustcflags = Some(flags.clone());
compiletest::run_tests(&config);
}
}