Refactor passing of resource limits.

This commit is contained in:
Scott Olson 2016-11-26 17:54:19 -08:00
parent 3f764a5cfd
commit 020f0b782b
3 changed files with 42 additions and 25 deletions

View File

@ -9,7 +9,6 @@ extern crate log_settings;
extern crate syntax;
#[macro_use] extern crate log;
use miri::{eval_main, run_mir_passes};
use rustc::session::Session;
use rustc_driver::{CompilerCalls, Compilation};
use rustc_driver::driver::{CompileState, CompileController};
@ -39,17 +38,23 @@ fn after_analysis(state: &mut CompileState) {
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);
let limits = resource_limits_from_attributes(state);
miri::run_mir_passes(tcx);
miri::eval_main(tcx, entry_def_id, limits);
state.session.abort_if_errors();
}
fn resource_limits_from_attributes(state: &CompileState) -> miri::ResourceLimits {
let mut limits = miri::ResourceLimits::default();
let krate = state.hir_crate.as_ref().unwrap();
let mut memory_size = 100 * 1024 * 1024; // 100 MB
let mut step_limit = 1_000_000;
let mut stack_limit = 100;
let err_msg = "miri attributes need to be in the form `miri(key = value)`";
let extract_int = |lit: &syntax::ast::Lit| -> u64 {
match lit.node {
syntax::ast::LitKind::Int(i, _) => i,
_ => state.session.span_fatal(lit.span, "expected an integer literal"),
}
};
let err_msg = "miri attributes need to be in the form `miri(key = value)`";
for attr in krate.attrs.iter().filter(|a| a.name() == "miri") {
if let MetaItemKind::List(ref items) = attr.value.node {
@ -57,9 +62,9 @@ fn after_analysis(state: &mut CompileState) {
if let NestedMetaItemKind::MetaItem(ref inner) = item.node {
if let MetaItemKind::NameValue(ref value) = inner.node {
match &inner.name().as_str()[..] {
"memory_size" => memory_size = extract_int(value),
"step_limit" => step_limit = extract_int(value),
"stack_limit" => stack_limit = extract_int(value) as usize,
"memory_size" => limits.memory_size = extract_int(value),
"step_limit" => limits.step_limit = extract_int(value),
"stack_limit" => limits.stack_limit = extract_int(value) as usize,
_ => state.session.span_err(item.span, "unknown miri attribute"),
}
} else {
@ -73,11 +78,7 @@ fn after_analysis(state: &mut CompileState) {
state.session.span_err(attr.span, err_msg);
}
}
run_mir_passes(tcx);
eval_main(tcx, entry_def_id, memory_size, step_limit, stack_limit);
state.session.abort_if_errors();
limits
}
fn init_logger() {

View File

@ -166,15 +166,32 @@ pub enum StackPopCleanup {
None,
}
#[derive(Copy, Clone, Debug)]
pub struct ResourceLimits {
pub memory_size: u64,
pub step_limit: u64,
pub stack_limit: usize,
}
impl Default for ResourceLimits {
fn default() -> Self {
ResourceLimits {
memory_size: 100 * 1024 * 1024, // 100 MB
step_limit: 1_000_000,
stack_limit: 100,
}
}
}
impl<'a, 'tcx> EvalContext<'a, 'tcx> {
pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, memory_size: u64, stack_limit: usize, step_limit: u64) -> Self {
pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, limits: ResourceLimits) -> Self {
EvalContext {
tcx: tcx,
memory: Memory::new(&tcx.data_layout, memory_size),
memory: Memory::new(&tcx.data_layout, limits.memory_size),
globals: HashMap::new(),
stack: Vec::new(),
stack_limit: stack_limit,
steps_remaining: step_limit,
stack_limit: limits.stack_limit,
steps_remaining: limits.step_limit,
}
}
@ -1696,11 +1713,9 @@ impl<'tcx> Lvalue<'tcx> {
pub fn eval_main<'a, 'tcx: 'a>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
def_id: DefId,
memory_size: u64,
step_limit: u64,
stack_limit: usize,
limits: ResourceLimits,
) {
let mut ecx = EvalContext::new(tcx, memory_size, stack_limit, step_limit);
let mut ecx = EvalContext::new(tcx, limits);
let mir = ecx.load_mir(def_id).expect("main function's MIR not found");
ecx.push_stack_frame(

View File

@ -33,12 +33,13 @@ pub use error::{
pub use interpreter::{
EvalContext,
Frame,
eval_main,
run_mir_passes,
StackPopCleanup,
Value,
Lvalue,
LvalueExtra,
ResourceLimits,
StackPopCleanup,
Value,
eval_main,
run_mir_passes,
};
pub use memory::{