Skip to content

use the log crate + env_logger #16

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Jun 1, 2016
24 changes: 24 additions & 0 deletions src/bin/miri.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ extern crate getopts;
extern crate miri;
extern crate rustc;
extern crate rustc_driver;
extern crate env_logger;
extern crate log_settings;
extern crate log;

use miri::interpreter;
use rustc::session::Session;
Expand All @@ -31,6 +34,27 @@ impl<'a> CompilerCalls<'a> for MiriCompilerCalls {

#[miri_run]
fn main() {
init_logger();
let args: Vec<String> = std::env::args().collect();
rustc_driver::run_compiler(&args, &mut MiriCompilerCalls);
}

#[miri_run]
fn init_logger() {
let format = |record: &log::LogRecord| {
// prepend spaces to indent the final string
let indentation = log_settings::settings().indentation;
Copy link
Member

@solson solson Jun 1, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you rename this to indent_amount or something so the indentation later doesn't use the same name?

EDIT: Err, they're both indentation amounts... scratch that. I guess you could move % NSPACES into the format call and remove the shadowing variable.

let spaces = " ";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess you were going for a max indentation here? It'd be nice to handle that in numbers rather than having this string which I'm not sure how long it is.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be nice if the indentation wrapped around to 0 when it gets too long with an indicator that it's actually extra-deep.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

makes sense

let indentation = &spaces[..std::cmp::min(indentation, spaces.len())];
format!("{} -{} {}", record.level(), indentation, record.args())
};

let mut builder = env_logger::LogBuilder::new();
builder.format(format).filter(None, log::LogLevelFilter::Info);

if std::env::var("RUST_LOG").is_ok() {
builder.parse(&std::env::var("RUST_LOG").unwrap());
}

builder.init().unwrap();
}
40 changes: 15 additions & 25 deletions src/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ use error::{EvalError, EvalResult};
use memory::{Memory, Pointer};
use primval::{self, PrimVal};

const TRACE_EXECUTION: bool = true;

struct GlobalEvalContext<'a, 'tcx: 'a> {
/// The results of the type checker, from rustc.
tcx: TyCtxt<'a, 'tcx, 'tcx>,
Expand Down Expand Up @@ -168,32 +166,24 @@ impl<'a, 'b, 'mir, 'tcx> FnEvalContext<'a, 'b, 'mir, 'tcx> {
r
}

fn log<F>(&self, extra_indent: usize, f: F) where F: FnOnce() {
let indent = self.stack.len() + extra_indent;
if !TRACE_EXECUTION { return; }
for _ in 0..indent { print!(" "); }
f();
println!("");
}

fn run(&mut self) -> EvalResult<()> {
'outer: while !self.stack.is_empty() {
let mut current_block = self.frame().next_block;

loop {
self.log(0, || print!("// {:?}", current_block));
trace!("// {:?}", current_block);
let current_mir = self.mir().clone(); // Cloning a reference.
let block_data = current_mir.basic_block_data(current_block);

for stmt in &block_data.statements {
self.log(0, || print!("{:?}", stmt));
trace!("{:?}", stmt);
let mir::StatementKind::Assign(ref lvalue, ref rvalue) = stmt.kind;
let result = self.eval_assignment(lvalue, rvalue);
self.maybe_report(stmt.span, result)?;
}

let terminator = block_data.terminator();
self.log(0, || print!("{:?}", terminator.kind));
trace!("{:?}", terminator.kind);

let result = self.eval_terminator(terminator);
match self.maybe_report(terminator.span, result)? {
Expand Down Expand Up @@ -245,6 +235,8 @@ impl<'a, 'b, 'mir, 'tcx> FnEvalContext<'a, 'b, 'mir, 'tcx> {
let num_args = mir.arg_decls.len();
let num_vars = mir.var_decls.len();

::log_settings::settings().indentation += 1;

self.stack.push(Frame {
mir: mir.clone(),
next_block: mir::START_BLOCK,
Expand All @@ -256,6 +248,7 @@ impl<'a, 'b, 'mir, 'tcx> FnEvalContext<'a, 'b, 'mir, 'tcx> {
}

fn pop_stack_frame(&mut self) {
::log_settings::settings().indentation -= 1;
let _frame = self.stack.pop().expect("tried to pop a stack frame, but there were none");
// TODO(solson): Deallocate local variables.
self.substs_stack.pop();
Expand Down Expand Up @@ -419,10 +412,10 @@ impl<'a, 'b, 'mir, 'tcx> FnEvalContext<'a, 'b, 'mir, 'tcx> {

fn drop(&mut self, ptr: Pointer, ty: Ty<'tcx>) -> EvalResult<()> {
if !self.type_needs_drop(ty) {
self.log(1, || print!("no need to drop {:?}", ty));
debug!("no need to drop {:?}", ty);
return Ok(());
}
self.log(1, || print!("need to drop {:?}", ty));
trace!("-need to drop {:?}", ty);

// TODO(solson): Call user-defined Drop::drop impls.

Expand All @@ -431,7 +424,7 @@ impl<'a, 'b, 'mir, 'tcx> FnEvalContext<'a, 'b, 'mir, 'tcx> {
match self.memory.read_ptr(ptr) {
Ok(contents_ptr) => {
self.drop(contents_ptr, contents_ty)?;
self.log(1, || print!("deallocating box"));
trace!("-deallocating box");
self.memory.deallocate(contents_ptr)?;
}
Err(EvalError::ReadBytesAsPointer) => {
Expand Down Expand Up @@ -1421,32 +1414,29 @@ pub fn interpret_start_points<'a, 'tcx>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
mir_map: &MirMap<'tcx>,
) {
let initial_indentation = ::log_settings::settings().indentation;
for (&id, mir) in &mir_map.map {
for attr in tcx.map.attrs(id) {
use syntax::attr::AttrMetaMethods;
if attr.check_name("miri_run") {
let item = tcx.map.expect_item(id);

if TRACE_EXECUTION {
println!("Interpreting: {}", item.name);
}
::log_settings::settings().indentation = initial_indentation;

debug!("Interpreting: {}", item.name);

let mut gecx = GlobalEvalContext::new(tcx, mir_map);
let mut fecx = FnEvalContext::new(&mut gecx);
match fecx.call_nested(mir) {
Ok(Some(return_ptr)) => if TRACE_EXECUTION {
Ok(Some(return_ptr)) => if log_enabled!(::log::LogLevel::Debug) {
fecx.memory.dump(return_ptr.alloc_id);
},
Ok(None) => println!("(diverging function returned)"),
Ok(None) => warn!("diverging function returned"),
Err(_e) => {
// TODO(solson): Detect whether the error was already reported or not.
// tcx.sess.err(&e.to_string());
}
}

if TRACE_EXECUTION {
println!("");
}
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#[macro_use] extern crate rustc;
extern crate rustc_mir;
extern crate syntax;
#[macro_use] extern crate log;
extern crate log_settings;

// From crates.io.
extern crate byteorder;
Expand Down