Merge pull request #1 from solson/fixup-function_pointers2
Fixup function_pointers2
This commit is contained in:
commit
4ae77b765a
7 changed files with 70 additions and 88 deletions
10
Cargo.lock
generated
10
Cargo.lock
generated
|
|
@ -3,7 +3,7 @@ name = "miri"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"byteorder 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"compiletest_rs 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"compiletest_rs 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log_settings 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
@ -24,7 +24,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "compiletest_rs"
|
||||
version = "0.1.2"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
@ -55,7 +55,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.11"
|
||||
version = "0.2.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
|
|
@ -76,7 +76,7 @@ name = "memchr"
|
|||
version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -102,7 +102,7 @@ version = "2.0.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
#![feature(rustc_private, custom_attribute)]
|
||||
#![allow(unused_attributes)]
|
||||
#![feature(rustc_private)]
|
||||
|
||||
extern crate getopts;
|
||||
extern crate miri;
|
||||
|
|
@ -66,21 +65,22 @@ fn interpret_start_points<'a, 'tcx>(
|
|||
ecx.push_stack_frame(tcx.map.local_def_id(id), mir.span, CachedMir::Ref(mir), substs, return_ptr);
|
||||
|
||||
loop {
|
||||
match (step(&mut ecx), return_ptr) {
|
||||
(Ok(true), _) => {},
|
||||
(Ok(false), Some(ptr)) => if log_enabled!(::log::LogLevel::Debug) {
|
||||
ecx.memory().dump(ptr.alloc_id);
|
||||
match step(&mut ecx) {
|
||||
Ok(true) => {}
|
||||
Ok(false) => {
|
||||
match return_ptr {
|
||||
Some(ptr) => if log_enabled!(::log::LogLevel::Debug) {
|
||||
ecx.memory().dump(ptr.alloc_id);
|
||||
},
|
||||
None => warn!("diverging function returned"),
|
||||
}
|
||||
break;
|
||||
},
|
||||
(Ok(false), None) => {
|
||||
warn!("diverging function returned");
|
||||
break;
|
||||
},
|
||||
}
|
||||
// FIXME: diverging functions can end up here in some future miri
|
||||
(Err(e), _) => {
|
||||
Err(e) => {
|
||||
report(tcx, &ecx, e);
|
||||
break;
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -90,11 +90,11 @@ fn interpret_start_points<'a, 'tcx>(
|
|||
|
||||
fn report(tcx: TyCtxt, ecx: &EvalContext, e: EvalError) {
|
||||
let frame = ecx.stack().last().expect("stackframe was empty");
|
||||
let block = frame.mir.basic_block_data(frame.next_block);
|
||||
let block = &frame.mir.basic_blocks()[frame.next_block];
|
||||
let span = if frame.stmt < block.statements.len() {
|
||||
block.statements[frame.stmt].span
|
||||
block.statements[frame.stmt].source_info.span
|
||||
} else {
|
||||
block.terminator().span
|
||||
block.terminator().source_info.span
|
||||
};
|
||||
let mut err = tcx.sess.struct_span_err(span, &e.to_string());
|
||||
for &Frame { def_id, substs, span, .. } in ecx.stack().iter().rev() {
|
||||
|
|
@ -105,7 +105,7 @@ fn report(tcx: TyCtxt, ecx: &EvalContext, e: EvalError) {
|
|||
impl<'tcx> fmt::Display for Instance<'tcx> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
ppaux::parameterized(f, self.1, self.0, ppaux::Ns::Value, &[],
|
||||
|tcx| tcx.lookup_item_type(self.0).generics)
|
||||
|tcx| Some(tcx.lookup_item_type(self.0).generics))
|
||||
}
|
||||
}
|
||||
err.span_note(span, &format!("inside call to {}", Instance(def_id, substs)));
|
||||
|
|
@ -113,14 +113,12 @@ fn report(tcx: TyCtxt, ecx: &EvalContext, e: EvalError) {
|
|||
err.emit();
|
||||
}
|
||||
|
||||
#[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() {
|
||||
const NSPACES: usize = 40;
|
||||
let format = |record: &log::LogRecord| {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ use rustc::ty::layout::{self, Layout, Size};
|
|||
use rustc::ty::subst::{self, Subst, Substs};
|
||||
use rustc::ty::{self, Ty, TyCtxt, BareFnTy};
|
||||
use rustc::util::nodemap::DefIdMap;
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
use std::cell::RefCell;
|
||||
use std::ops::Deref;
|
||||
use std::rc::Rc;
|
||||
|
|
@ -118,7 +119,7 @@ struct ConstantId<'tcx> {
|
|||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
|
||||
enum ConstantKind {
|
||||
Promoted(usize),
|
||||
Promoted(mir::Promoted),
|
||||
/// Statics, constants and associated constants
|
||||
Global,
|
||||
}
|
||||
|
|
@ -426,24 +427,38 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||
assert_eq!(ptr.offset, 0);
|
||||
let fn_ptr = self.memory.read_ptr(ptr)?;
|
||||
let (def_id, substs) = self.memory.get_fn(fn_ptr.alloc_id)?;
|
||||
self.eval_fn_call(def_id, substs, bare_fn_ty, return_ptr, args, terminator.span)?
|
||||
self.eval_fn_call(def_id, substs, bare_fn_ty, return_ptr, args,
|
||||
terminator.source_info.span)?
|
||||
},
|
||||
ty::TyFnDef(def_id, substs, fn_ty) => {
|
||||
self.eval_fn_call(def_id, substs, fn_ty, return_ptr, args, terminator.span)?
|
||||
self.eval_fn_call(def_id, substs, fn_ty, return_ptr, args,
|
||||
terminator.source_info.span)?
|
||||
}
|
||||
|
||||
_ => return Err(EvalError::Unimplemented(format!("can't handle callee of type {:?}", func_ty))),
|
||||
}
|
||||
}
|
||||
|
||||
Drop { ref value, target, .. } => {
|
||||
let ptr = self.eval_lvalue(value)?.to_ptr();
|
||||
let ty = self.lvalue_ty(value);
|
||||
Drop { ref location, target, .. } => {
|
||||
let ptr = self.eval_lvalue(location)?.to_ptr();
|
||||
let ty = self.lvalue_ty(location);
|
||||
self.drop(ptr, ty)?;
|
||||
self.frame_mut().next_block = target;
|
||||
}
|
||||
|
||||
Assert { ref cond, expected, ref msg, target, cleanup } => {
|
||||
let actual_ptr = self.eval_operand(cond)?;
|
||||
let actual = self.memory.read_bool(actual_ptr)?;
|
||||
if actual == expected {
|
||||
self.frame_mut().next_block = target;
|
||||
} else {
|
||||
panic!("unimplemented: jump to {:?} and print {:?}", cleanup, msg);
|
||||
}
|
||||
}
|
||||
|
||||
DropAndReplace { .. } => unimplemented!(),
|
||||
Resume => unimplemented!(),
|
||||
Unreachable => unimplemented!(),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
@ -867,6 +882,25 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||
self.memory.write_primval(dest, val)?;
|
||||
}
|
||||
|
||||
// FIXME(solson): Factor this out with BinaryOp.
|
||||
CheckedBinaryOp(bin_op, ref left, ref right) => {
|
||||
let left_ptr = self.eval_operand(left)?;
|
||||
let left_ty = self.operand_ty(left);
|
||||
let left_val = self.read_primval(left_ptr, left_ty)?;
|
||||
|
||||
let right_ptr = self.eval_operand(right)?;
|
||||
let right_ty = self.operand_ty(right);
|
||||
let right_val = self.read_primval(right_ptr, right_ty)?;
|
||||
|
||||
let val = primval::binary_op(bin_op, left_val, right_val)?;
|
||||
self.memory.write_primval(dest, val)?;
|
||||
|
||||
// FIXME(solson): Find the result type size properly. Perhaps refactor out
|
||||
// Projection calculations so we can do the equivalent of `dest.1` here.
|
||||
let s = self.type_size(left_ty, self.substs());
|
||||
self.memory.write_bool(dest.offset(s as isize), false)?;
|
||||
}
|
||||
|
||||
UnaryOp(un_op, ref operand) => {
|
||||
let ptr = self.eval_operand(operand)?;
|
||||
let ty = self.operand_ty(operand);
|
||||
|
|
@ -1048,7 +1082,6 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
Slice { .. } => unimplemented!(),
|
||||
InlineAsm { .. } => unimplemented!(),
|
||||
}
|
||||
|
||||
|
|
@ -1161,9 +1194,9 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||
let ptr = match *lvalue {
|
||||
ReturnPointer => self.frame().return_ptr
|
||||
.expect("ReturnPointer used in a function with no return value"),
|
||||
Arg(i) => self.frame().locals[i as usize],
|
||||
Var(i) => self.frame().locals[self.frame().var_offset + i as usize],
|
||||
Temp(i) => self.frame().locals[self.frame().temp_offset + i as usize],
|
||||
Arg(i) => self.frame().locals[i.index()],
|
||||
Var(i) => self.frame().locals[self.frame().var_offset + i.index()],
|
||||
Temp(i) => self.frame().locals[self.frame().temp_offset + i.index()],
|
||||
|
||||
Static(def_id) => {
|
||||
let substs = self.tcx.mk_substs(subst::Substs::empty());
|
||||
|
|
@ -1248,6 +1281,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||
}
|
||||
|
||||
ConstantIndex { .. } => unimplemented!(),
|
||||
Subslice { .. } => unimplemented!(),
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -51,12 +51,12 @@ impl<'ecx, 'a, 'tcx> Stepper<'ecx, 'a, 'tcx> {
|
|||
let block = self.ecx.frame().next_block;
|
||||
let stmt = self.ecx.frame().stmt;
|
||||
let mir = self.ecx.mir();
|
||||
let basic_block = mir.basic_block_data(block);
|
||||
let basic_block = &mir.basic_blocks()[block];
|
||||
|
||||
if let Some(ref stmt) = basic_block.statements.get(stmt) {
|
||||
let current_stack = self.ecx.stack.len();
|
||||
ConstantExtractor {
|
||||
span: stmt.span,
|
||||
span: stmt.source_info.span,
|
||||
substs: self.ecx.substs(),
|
||||
def_id: self.ecx.frame().def_id,
|
||||
ecx: self.ecx,
|
||||
|
|
@ -75,7 +75,7 @@ impl<'ecx, 'a, 'tcx> Stepper<'ecx, 'a, 'tcx> {
|
|||
let terminator = basic_block.terminator();
|
||||
let current_stack = self.ecx.stack.len();
|
||||
ConstantExtractor {
|
||||
span: terminator.span,
|
||||
span: terminator.source_info.span,
|
||||
substs: self.ecx.substs(),
|
||||
def_id: self.ecx.frame().def_id,
|
||||
ecx: self.ecx,
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
// From rustc.
|
||||
#[macro_use] extern crate rustc;
|
||||
extern crate rustc_data_structures;
|
||||
extern crate rustc_mir;
|
||||
extern crate rustc_trans;
|
||||
extern crate syntax;
|
||||
|
|
|
|||
|
|
@ -27,5 +27,4 @@ fn run_mode(mode: &'static str) {
|
|||
fn compile_test() {
|
||||
run_mode("compile-fail");
|
||||
run_mode("run-pass");
|
||||
run_mode("run-fail");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,50 +0,0 @@
|
|||
// error-pattern:no mir for `env_logger/
|
||||
|
||||
use std::env;
|
||||
use std::process::{Command, Output};
|
||||
|
||||
fn run_miri(file: &str, sysroot: &str) -> Output {
|
||||
let path = env::current_dir().unwrap();
|
||||
let libpath = path.join("target").join("debug");
|
||||
let libpath = libpath.to_str().unwrap();
|
||||
let libpath2 = path.join("target").join("debug").join("deps");
|
||||
let libpath2 = libpath2.to_str().unwrap();
|
||||
let mut args = vec![
|
||||
"run".to_string(), "--".to_string(),
|
||||
"--sysroot".to_string(), sysroot.to_string(),
|
||||
"-L".to_string(), libpath.to_string(),
|
||||
"-L".to_string(), libpath2.to_string(),
|
||||
file.to_string()
|
||||
];
|
||||
for file in std::fs::read_dir("target/debug/deps").unwrap() {
|
||||
let file = file.unwrap();
|
||||
if file.file_type().unwrap().is_file() {
|
||||
let path = file.path();
|
||||
if let Some(ext) = path.extension() {
|
||||
if ext == "rlib" {
|
||||
let name = path.file_stem().unwrap().to_str().unwrap();
|
||||
if let Some(dash) = name.rfind('-') {
|
||||
if name.starts_with("lib") {
|
||||
args.push("--extern".to_string());
|
||||
args.push(format!("{}={}", &name[3..dash], path.to_str().unwrap()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Command::new("cargo")
|
||||
.args(&args)
|
||||
.output()
|
||||
.unwrap_or_else(|e| panic!("failed to execute process: {}", e))
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let sysroot = env::var("RUST_SYSROOT").expect("env variable `RUST_SYSROOT` not set");
|
||||
let test_run = run_miri("src/bin/miri.rs", &sysroot);
|
||||
|
||||
if test_run.status.code().unwrap_or(-1) != 0 {
|
||||
println!("{}", String::from_utf8(test_run.stdout).unwrap());
|
||||
panic!("{}", String::from_utf8(test_run.stderr).unwrap());
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue