rustup
This commit is contained in:
parent
d9680dbb10
commit
de38015e47
@ -138,5 +138,5 @@ fn main() {
|
||||
args.push(find_sysroot());
|
||||
}
|
||||
|
||||
rustc_driver::run_compiler(&args, &mut MiriCompilerCalls);
|
||||
rustc_driver::run_compiler(&args, &mut MiriCompilerCalls, None, None);
|
||||
}
|
||||
|
@ -73,23 +73,13 @@ pub struct Frame<'a, 'tcx: 'a> {
|
||||
// Return pointer and local allocations
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// A pointer for writing the return value of the current call if it's not a diverging call.
|
||||
pub return_ptr: Option<Pointer>,
|
||||
|
||||
/// The block to return to when returning from the current stack frame
|
||||
pub return_to_block: StackPopCleanup,
|
||||
|
||||
/// The list of locals for the current function, stored in order as
|
||||
/// `[arguments..., variables..., temporaries...]`. The variables begin at `self.var_offset`
|
||||
/// and the temporaries at `self.temp_offset`.
|
||||
/// `[return_ptr, arguments..., variables..., temporaries...]`.
|
||||
pub locals: Vec<Pointer>,
|
||||
|
||||
/// The offset of the first variable in `self.locals`.
|
||||
pub var_offset: usize,
|
||||
|
||||
/// The offset of the first temporary in `self.locals`.
|
||||
pub temp_offset: usize,
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Current position within the function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -336,32 +326,26 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
span: codemap::Span,
|
||||
mir: CachedMir<'a, 'tcx>,
|
||||
substs: &'tcx Substs<'tcx>,
|
||||
return_ptr: Option<Pointer>,
|
||||
return_ptr: Pointer,
|
||||
return_to_block: StackPopCleanup,
|
||||
) -> EvalResult<'tcx, ()> {
|
||||
let arg_tys = mir.arg_decls.iter().map(|a| a.ty);
|
||||
let var_tys = mir.var_decls.iter().map(|v| v.ty);
|
||||
let temp_tys = mir.temp_decls.iter().map(|t| t.ty);
|
||||
|
||||
let num_args = mir.arg_decls.len();
|
||||
let num_vars = mir.var_decls.len();
|
||||
let local_tys = mir.local_decls.iter().map(|a| a.ty);
|
||||
|
||||
::log_settings::settings().indentation += 1;
|
||||
|
||||
let locals: EvalResult<'tcx, Vec<Pointer>> = arg_tys.chain(var_tys).chain(temp_tys).map(|ty| {
|
||||
// directly change the first allocation (the return value) to *be* the allocation where the
|
||||
// caller stores the result
|
||||
let locals: EvalResult<'tcx, Vec<Pointer>> = iter::once(Ok(return_ptr)).chain(local_tys.skip(1).map(|ty| {
|
||||
let size = self.type_size_with_substs(ty, substs);
|
||||
let align = self.type_align_with_substs(ty, substs);
|
||||
self.memory.allocate(size, align)
|
||||
}).collect();
|
||||
})).collect();
|
||||
|
||||
self.stack.push(Frame {
|
||||
mir: mir.clone(),
|
||||
block: mir::START_BLOCK,
|
||||
return_ptr: return_ptr,
|
||||
return_to_block: return_to_block,
|
||||
locals: locals?,
|
||||
var_offset: num_args,
|
||||
temp_offset: num_args + num_vars,
|
||||
span: span,
|
||||
def_id: def_id,
|
||||
substs: substs,
|
||||
@ -793,11 +777,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
fn eval_lvalue(&mut self, lvalue: &mir::Lvalue<'tcx>) -> EvalResult<'tcx, Lvalue> {
|
||||
use rustc::mir::repr::Lvalue::*;
|
||||
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.index()],
|
||||
Var(i) => self.frame().locals[self.frame().var_offset + i.index()],
|
||||
Temp(i) => self.frame().locals[self.frame().temp_offset + i.index()],
|
||||
Local(i) => self.frame().locals[i.index()],
|
||||
|
||||
Static(def_id) => {
|
||||
let substs = subst::Substs::empty(self.tcx);
|
||||
@ -1219,18 +1199,17 @@ pub fn eval_main<'a, 'tcx: 'a>(
|
||||
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");
|
||||
|
||||
ecx.push_stack_frame(def_id, mir.span, CachedMir::Ref(mir), substs, Some(return_ptr), StackPopCleanup::None)
|
||||
ecx.push_stack_frame(def_id, mir.span, CachedMir::Ref(mir), substs, return_ptr, StackPopCleanup::None)
|
||||
.expect("could not allocate first stack frame");
|
||||
|
||||
if mir.arg_decls.len() == 2 {
|
||||
// FIXME: this is a horrible and wrong way to detect the start function, but overwriting the first two locals shouldn't do much
|
||||
if mir.local_decls.len() > 2 {
|
||||
// start function
|
||||
let ptr_size = ecx.memory().pointer_size();
|
||||
let nargs = ecx.memory_mut().allocate(ptr_size, ptr_size).expect("can't allocate memory for nargs");
|
||||
ecx.memory_mut().write_usize(nargs, 0).unwrap();
|
||||
let args = ecx.memory_mut().allocate(ptr_size, ptr_size).expect("can't allocate memory for arg pointer");
|
||||
ecx.memory_mut().write_usize(args, 0).unwrap();
|
||||
ecx.frame_mut().locals[0] = nargs;
|
||||
ecx.frame_mut().locals[1] = args;
|
||||
let nargs = ecx.frame_mut().locals[1];
|
||||
let args = ecx.frame_mut().locals[2];
|
||||
// ignore errors, if the locals are too small this is not the start function
|
||||
let _ = ecx.memory_mut().write_usize(nargs, 0);
|
||||
let _ = ecx.memory_mut().write_usize(args, 0);
|
||||
}
|
||||
|
||||
for _ in 0..step_limit {
|
||||
|
@ -134,7 +134,7 @@ impl<'a, 'b, 'tcx> ConstantExtractor<'a, 'b, 'tcx> {
|
||||
} else {
|
||||
StackPopCleanup::None
|
||||
};
|
||||
this.ecx.push_stack_frame(def_id, span, mir, substs, Some(ptr), cleanup)
|
||||
this.ecx.push_stack_frame(def_id, span, mir, substs, ptr, cleanup)
|
||||
});
|
||||
}
|
||||
fn try<F: FnOnce(&mut Self) -> EvalResult<'tcx, ()>>(&mut self, f: F) {
|
||||
@ -183,7 +183,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for ConstantExtractor<'a, 'b, 'tcx> {
|
||||
constant.span,
|
||||
mir,
|
||||
this.substs,
|
||||
Some(return_ptr),
|
||||
return_ptr,
|
||||
StackPopCleanup::Freeze(return_ptr.alloc_id))
|
||||
});
|
||||
}
|
||||
|
@ -186,13 +186,14 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
|
||||
let mir = self.load_mir(resolved_def_id)?;
|
||||
let (return_ptr, return_to_block) = match destination {
|
||||
Some((ptr, block)) => (Some(ptr), StackPopCleanup::Goto(block)),
|
||||
None => (None, StackPopCleanup::None),
|
||||
Some((ptr, block)) => (ptr, StackPopCleanup::Goto(block)),
|
||||
None => (Pointer::never_ptr(), StackPopCleanup::None),
|
||||
};
|
||||
self.push_stack_frame(resolved_def_id, span, mir, resolved_substs, return_ptr, return_to_block)?;
|
||||
|
||||
for (i, (arg_val, arg_ty)) in args.into_iter().enumerate() {
|
||||
let dest = self.frame().locals[i];
|
||||
// argument start at index 1, since index 0 is reserved for the return allocation
|
||||
let dest = self.frame().locals[i + 1];
|
||||
self.write_value(arg_val, dest, arg_ty)?;
|
||||
}
|
||||
|
||||
|
@ -56,10 +56,10 @@ impl Pointer {
|
||||
self.alloc_id == ZST_ALLOC_ID
|
||||
}
|
||||
pub fn to_int<'tcx>(&self) -> EvalResult<'tcx, usize> {
|
||||
if self.points_to_zst() {
|
||||
Ok(self.offset)
|
||||
} else {
|
||||
Err(EvalError::ReadPointerAsBytes)
|
||||
match self.alloc_id {
|
||||
NEVER_ALLOC_ID |
|
||||
ZST_ALLOC_ID => Ok(self.offset),
|
||||
_ => Err(EvalError::ReadPointerAsBytes),
|
||||
}
|
||||
}
|
||||
pub fn from_int(i: usize) -> Self {
|
||||
@ -74,6 +74,12 @@ impl Pointer {
|
||||
offset: 0,
|
||||
}
|
||||
}
|
||||
pub fn never_ptr() -> Self {
|
||||
Pointer {
|
||||
alloc_id: NEVER_ALLOC_ID,
|
||||
offset: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Hash, Eq, PartialEq)]
|
||||
@ -115,6 +121,7 @@ pub struct Memory<'a, 'tcx> {
|
||||
}
|
||||
|
||||
const ZST_ALLOC_ID: AllocId = AllocId(0);
|
||||
const NEVER_ALLOC_ID: AllocId = AllocId(1);
|
||||
|
||||
impl<'a, 'tcx> Memory<'a, 'tcx> {
|
||||
pub fn new(layout: &'a TargetDataLayout, max_memory: usize) -> Self {
|
||||
@ -122,7 +129,7 @@ impl<'a, 'tcx> Memory<'a, 'tcx> {
|
||||
alloc_map: HashMap::new(),
|
||||
functions: HashMap::new(),
|
||||
function_alloc_cache: HashMap::new(),
|
||||
next_id: AllocId(1),
|
||||
next_id: AllocId(2),
|
||||
layout: layout,
|
||||
memory_size: max_memory,
|
||||
memory_usage: 0,
|
||||
|
Loading…
x
Reference in New Issue
Block a user