make the memory limit configurable
This commit is contained in:
parent
756fbcce48
commit
1444cabc08
2 changed files with 36 additions and 5 deletions
|
@ -4,6 +4,7 @@ extern crate getopts;
|
|||
extern crate miri;
|
||||
extern crate rustc;
|
||||
extern crate rustc_driver;
|
||||
extern crate rustc_plugin;
|
||||
extern crate env_logger;
|
||||
extern crate log_settings;
|
||||
extern crate syntax;
|
||||
|
@ -13,6 +14,7 @@ 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;
|
||||
|
||||
struct MiriCompilerCalls;
|
||||
|
||||
|
@ -23,7 +25,9 @@ impl<'a> CompilerCalls<'a> for MiriCompilerCalls {
|
|||
_: &getopts::Matches
|
||||
) -> driver::CompileController<'a> {
|
||||
let mut control = driver::CompileController::basic();
|
||||
|
||||
control.after_hir_lowering.callback = Box::new(|state| {
|
||||
state.session.plugin_attributes.borrow_mut().push(("miri".to_owned(), syntax::feature_gate::AttributeType::Whitelisted));
|
||||
});
|
||||
control.after_analysis.stop = Compilation::Stop;
|
||||
control.after_analysis.callback = Box::new(|state| {
|
||||
state.session.abort_if_errors();
|
||||
|
@ -33,9 +37,35 @@ impl<'a> CompilerCalls<'a> for MiriCompilerCalls {
|
|||
let (node_id, _) = state.session.entry_fn.borrow()
|
||||
.expect("no main or start function found");
|
||||
|
||||
let krate = state.hir_crate.as_ref().unwrap();
|
||||
let mut memory_size = 100*1024*1024; // 100MB
|
||||
fn extract_str(lit: &syntax::ast::Lit) -> syntax::parse::token::InternedString {
|
||||
match lit.node {
|
||||
syntax::ast::LitKind::Str(ref s, _) => s.clone(),
|
||||
_ => panic!("attribute values need to be strings"),
|
||||
}
|
||||
}
|
||||
for attr in krate.attrs.iter() {
|
||||
match attr.node.value.node {
|
||||
MetaItemKind::List(ref name, _) if name != "miri" => {}
|
||||
MetaItemKind::List(_, ref items) => for item in items {
|
||||
match item.node {
|
||||
MetaItemKind::NameValue(ref name, ref value) => {
|
||||
match &**name {
|
||||
"memory_size" => memory_size = extract_str(value).parse::<u64>().expect("not a number"),
|
||||
_ => state.session.span_err(item.span, "unknown miri attribute"),
|
||||
}
|
||||
}
|
||||
_ => state.session.span_err(item.span, "miri attributes need to be of key = value kind"),
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
|
||||
let mut mir_map = MirMap { map: mir_map.map.clone() };
|
||||
run_mir_passes(tcx, &mut mir_map);
|
||||
eval_main(tcx, &mir_map, node_id);
|
||||
eval_main(tcx, &mir_map, node_id, memory_size);
|
||||
|
||||
state.session.abort_if_errors();
|
||||
});
|
||||
|
|
|
@ -133,12 +133,12 @@ enum ConstantKind {
|
|||
}
|
||||
|
||||
impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, mir_map: &'a MirMap<'tcx>) -> Self {
|
||||
pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, mir_map: &'a MirMap<'tcx>, memory_size: u64) -> Self {
|
||||
EvalContext {
|
||||
tcx: tcx,
|
||||
mir_map: mir_map,
|
||||
mir_cache: RefCell::new(DefIdMap()),
|
||||
memory: Memory::new(&tcx.data_layout, 100*1024*1024 /* 100MB */),
|
||||
memory: Memory::new(&tcx.data_layout, memory_size),
|
||||
statics: HashMap::new(),
|
||||
stack: Vec::new(),
|
||||
}
|
||||
|
@ -928,10 +928,11 @@ pub fn eval_main<'a, 'tcx: 'a>(
|
|||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
mir_map: &'a MirMap<'tcx>,
|
||||
node_id: ast::NodeId,
|
||||
memory_size: u64,
|
||||
) {
|
||||
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 mut ecx = EvalContext::new(tcx, mir_map, memory_size);
|
||||
let substs = tcx.mk_substs(subst::Substs::empty());
|
||||
let return_ptr = ecx.alloc_ret_ptr(mir.return_ty, substs)
|
||||
.expect("should at least be able to allocate space for the main function's return value")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue