Removed uninitialized_statics
field from Memory
struct in miri.
Refactored code accordingly.
This commit is contained in:
parent
c697a56d01
commit
ea806e7815
@ -1,3 +1,6 @@
|
||||
use std::fmt;
|
||||
use std::error::Error;
|
||||
|
||||
use rustc::hir;
|
||||
use rustc::mir::interpret::{ConstEvalErr};
|
||||
use rustc::mir;
|
||||
@ -15,9 +18,6 @@ use rustc::mir::interpret::{
|
||||
};
|
||||
use super::{Place, EvalContext, StackPopCleanup, ValTy, PlaceExtra, Memory, MemoryKind};
|
||||
|
||||
use std::fmt;
|
||||
use std::error::Error;
|
||||
|
||||
pub fn mk_borrowck_eval_cx<'a, 'mir, 'tcx>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
instance: Instance<'tcx>,
|
||||
@ -152,7 +152,7 @@ fn eval_body_using_ecx<'a, 'mir, 'tcx>(
|
||||
let ptr = ecx.memory.allocate(
|
||||
layout.size,
|
||||
layout.align,
|
||||
None,
|
||||
MemoryKind::Stack,
|
||||
)?;
|
||||
let internally_mutable = !layout.ty.is_freeze(tcx, param_env, mir.span);
|
||||
let is_static = tcx.is_static(cid.instance.def_id());
|
||||
@ -486,7 +486,7 @@ pub fn const_variant_index<'a, 'tcx>(
|
||||
let (ptr, align) = match value {
|
||||
Value::ScalarPair(..) | Value::Scalar(_) => {
|
||||
let layout = ecx.layout_of(val.ty)?;
|
||||
let ptr = ecx.memory.allocate(layout.size, layout.align, Some(MemoryKind::Stack))?.into();
|
||||
let ptr = ecx.memory.allocate(layout.size, layout.align, MemoryKind::Stack)?.into();
|
||||
ecx.write_value_to_ptr(value, ptr, layout.align, val.ty)?;
|
||||
(ptr, layout.align)
|
||||
},
|
||||
@ -515,7 +515,7 @@ pub fn const_value_to_allocation_provider<'a, 'tcx>(
|
||||
());
|
||||
let value = ecx.const_to_value(val.val)?;
|
||||
let layout = ecx.layout_of(val.ty)?;
|
||||
let ptr = ecx.memory.allocate(layout.size, layout.align, Some(MemoryKind::Stack))?;
|
||||
let ptr = ecx.memory.allocate(layout.size, layout.align, MemoryKind::Stack)?;
|
||||
ecx.write_value_to_ptr(value, ptr.into(), layout.align, val.ty)?;
|
||||
let alloc = ecx.memory.get(ptr.alloc_id)?;
|
||||
Ok(tcx.intern_const_alloc(alloc.clone()))
|
||||
|
@ -1,4 +1,5 @@
|
||||
use std::fmt::Write;
|
||||
use std::mem;
|
||||
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::hir::def::Def;
|
||||
@ -9,14 +10,13 @@ use rustc::ty::subst::{Subst, Substs};
|
||||
use rustc::ty::{self, Ty, TyCtxt, TypeAndMut};
|
||||
use rustc::ty::query::TyCtxtAt;
|
||||
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
|
||||
use rustc::mir::interpret::FrameInfo;
|
||||
use syntax::codemap::{self, Span};
|
||||
use syntax::ast::Mutability;
|
||||
use rustc::mir::interpret::{
|
||||
GlobalId, Value, Scalar,
|
||||
FrameInfo, GlobalId, Value, Scalar,
|
||||
EvalResult, EvalErrorKind, Pointer, ConstValue,
|
||||
};
|
||||
use std::mem;
|
||||
|
||||
use syntax::codemap::{self, Span};
|
||||
use syntax::ast::Mutability;
|
||||
|
||||
use super::{Place, PlaceExtra, Memory,
|
||||
HasMemory, MemoryKind,
|
||||
@ -206,7 +206,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
|
||||
let layout = self.layout_of(ty)?;
|
||||
assert!(!layout.is_unsized(), "cannot alloc memory for unsized type");
|
||||
|
||||
self.memory.allocate(layout.size, layout.align, Some(MemoryKind::Stack))
|
||||
self.memory.allocate(layout.size, layout.align, MemoryKind::Stack)
|
||||
}
|
||||
|
||||
pub fn memory(&self) -> &Memory<'a, 'mir, 'tcx, M> {
|
||||
@ -246,7 +246,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
|
||||
}
|
||||
ConstValue::ByRef(alloc, offset) => {
|
||||
// FIXME: Allocate new AllocId for all constants inside
|
||||
let id = self.memory.allocate_value(alloc.clone(), Some(MemoryKind::Stack))?;
|
||||
let id = self.memory.allocate_value(alloc.clone(), MemoryKind::Stack)?;
|
||||
Ok(Value::ByRef(Pointer::new(id, offset).into(), alloc.align))
|
||||
},
|
||||
ConstValue::ScalarPair(a, b) => Ok(Value::ScalarPair(a, b)),
|
||||
|
@ -6,12 +6,12 @@ use rustc::ty::Instance;
|
||||
use rustc::ty::ParamEnv;
|
||||
use rustc::ty::query::TyCtxtAt;
|
||||
use rustc::ty::layout::{self, Align, TargetDataLayout, Size};
|
||||
use syntax::ast::Mutability;
|
||||
|
||||
use rustc_data_structures::fx::{FxHashSet, FxHashMap};
|
||||
use rustc::mir::interpret::{Pointer, AllocId, Allocation, AccessKind, Value,
|
||||
EvalResult, Scalar, EvalErrorKind, GlobalId, AllocType};
|
||||
pub use rustc::mir::interpret::{write_target_uint, write_target_int, read_target_uint};
|
||||
use rustc_data_structures::fx::{FxHashSet, FxHashMap};
|
||||
|
||||
use syntax::ast::Mutability;
|
||||
|
||||
use super::{EvalContext, Machine};
|
||||
|
||||
@ -41,11 +41,6 @@ pub struct Memory<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'mir, 'tcx>> {
|
||||
/// Actual memory allocations (arbitrary bytes, may contain pointers into other allocations).
|
||||
alloc_map: FxHashMap<AllocId, Allocation>,
|
||||
|
||||
/// Actual memory allocations (arbitrary bytes, may contain pointers into other allocations).
|
||||
///
|
||||
/// Stores statics while they are being processed, before they are interned and thus frozen
|
||||
uninitialized_statics: FxHashMap<AllocId, Allocation>,
|
||||
|
||||
/// The current stack frame. Used to check accesses against locks.
|
||||
pub cur_frame: usize,
|
||||
|
||||
@ -58,7 +53,6 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
|
||||
data,
|
||||
alloc_kind: FxHashMap::default(),
|
||||
alloc_map: FxHashMap::default(),
|
||||
uninitialized_statics: FxHashMap::default(),
|
||||
tcx,
|
||||
cur_frame: usize::max_value(),
|
||||
}
|
||||
@ -82,20 +76,12 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
|
||||
pub fn allocate_value(
|
||||
&mut self,
|
||||
alloc: Allocation,
|
||||
kind: Option<MemoryKind<M::MemoryKinds>>,
|
||||
kind: MemoryKind<M::MemoryKinds>,
|
||||
) -> EvalResult<'tcx, AllocId> {
|
||||
let id = self.tcx.alloc_map.lock().reserve();
|
||||
M::add_lock(self, id);
|
||||
match kind {
|
||||
Some(kind @ MemoryKind::Stack) |
|
||||
Some(kind @ MemoryKind::Machine(_)) => {
|
||||
self.alloc_map.insert(id, alloc);
|
||||
self.alloc_kind.insert(id, kind);
|
||||
},
|
||||
None => {
|
||||
self.uninitialized_statics.insert(id, alloc);
|
||||
},
|
||||
}
|
||||
self.alloc_map.insert(id, alloc);
|
||||
self.alloc_kind.insert(id, kind);
|
||||
Ok(id)
|
||||
}
|
||||
|
||||
@ -104,7 +90,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
|
||||
&mut self,
|
||||
size: Size,
|
||||
align: Align,
|
||||
kind: Option<MemoryKind<M::MemoryKinds>>,
|
||||
kind: MemoryKind<M::MemoryKinds>,
|
||||
) -> EvalResult<'tcx, Pointer> {
|
||||
self.allocate_value(Allocation::undef(size, align), kind).map(Pointer::from)
|
||||
}
|
||||
@ -132,7 +118,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
|
||||
}
|
||||
|
||||
// For simplicities' sake, we implement reallocate as "alloc, copy, dealloc"
|
||||
let new_ptr = self.allocate(new_size, new_align, Some(kind))?;
|
||||
let new_ptr = self.allocate(new_size, new_align, kind)?;
|
||||
self.copy(
|
||||
ptr.into(),
|
||||
old_align,
|
||||
@ -168,12 +154,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
|
||||
|
||||
let alloc = match self.alloc_map.remove(&ptr.alloc_id) {
|
||||
Some(alloc) => alloc,
|
||||
None => if self.uninitialized_statics.contains_key(&ptr.alloc_id) {
|
||||
return err!(DeallocatedWrongMemoryKind(
|
||||
"uninitializedstatic".to_string(),
|
||||
format!("{:?}", kind),
|
||||
))
|
||||
} else {
|
||||
None => {
|
||||
return match self.tcx.alloc_map.lock().get(ptr.alloc_id) {
|
||||
Some(AllocType::Function(..)) => err!(DeallocatedWrongMemoryKind(
|
||||
"function".to_string(),
|
||||
@ -299,24 +280,21 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
|
||||
pub fn get(&self, id: AllocId) -> EvalResult<'tcx, &Allocation> {
|
||||
// normal alloc?
|
||||
match self.alloc_map.get(&id) {
|
||||
Some(alloc) => Ok(alloc),
|
||||
Some(alloc) => Ok(alloc),
|
||||
// uninitialized static alloc?
|
||||
None => match self.uninitialized_statics.get(&id) {
|
||||
Some(alloc) => Ok(alloc),
|
||||
None => {
|
||||
// static alloc?
|
||||
let alloc = self.tcx.alloc_map.lock().get(id);
|
||||
match alloc {
|
||||
Some(AllocType::Memory(mem)) => Ok(mem),
|
||||
Some(AllocType::Function(..)) => {
|
||||
Err(EvalErrorKind::DerefFunctionPointer.into())
|
||||
}
|
||||
Some(AllocType::Static(did)) => {
|
||||
self.const_eval_static(did)
|
||||
}
|
||||
None => Err(EvalErrorKind::DanglingPointerDeref.into()),
|
||||
None => {
|
||||
// static alloc?
|
||||
let alloc = self.tcx.alloc_map.lock().get(id);
|
||||
match alloc {
|
||||
Some(AllocType::Memory(mem)) => Ok(mem),
|
||||
Some(AllocType::Function(..)) => {
|
||||
Err(EvalErrorKind::DerefFunctionPointer.into())
|
||||
}
|
||||
},
|
||||
Some(AllocType::Static(did)) => {
|
||||
self.const_eval_static(did)
|
||||
}
|
||||
None => Err(EvalErrorKind::DanglingPointerDeref.into()),
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -329,17 +307,14 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
|
||||
match self.alloc_map.get_mut(&id) {
|
||||
Some(alloc) => Ok(alloc),
|
||||
// uninitialized static alloc?
|
||||
None => match self.uninitialized_statics.get_mut(&id) {
|
||||
Some(alloc) => Ok(alloc),
|
||||
None => {
|
||||
// no alloc or immutable alloc? produce an error
|
||||
match self.tcx.alloc_map.lock().get(id) {
|
||||
Some(AllocType::Memory(..)) |
|
||||
Some(AllocType::Static(..)) => err!(ModifiedConstantMemory),
|
||||
Some(AllocType::Function(..)) => err!(DerefFunctionPointer),
|
||||
None => err!(DanglingPointerDeref),
|
||||
}
|
||||
},
|
||||
None => {
|
||||
// no alloc or immutable alloc? produce an error
|
||||
match self.tcx.alloc_map.lock().get(id) {
|
||||
Some(AllocType::Memory(..)) |
|
||||
Some(AllocType::Static(..)) => err!(ModifiedConstantMemory),
|
||||
Some(AllocType::Function(..)) => err!(DerefFunctionPointer),
|
||||
None => err!(DanglingPointerDeref),
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -390,27 +365,23 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
|
||||
MemoryKind::Stack => " (stack)".to_owned(),
|
||||
MemoryKind::Machine(m) => format!(" ({:?})", m),
|
||||
}),
|
||||
// uninitialized static alloc?
|
||||
None => match self.uninitialized_statics.get(&id) {
|
||||
Some(a) => (a, " (static in the process of initialization)".to_owned()),
|
||||
None => {
|
||||
// static alloc?
|
||||
match self.tcx.alloc_map.lock().get(id) {
|
||||
Some(AllocType::Memory(a)) => (a, "(immutable)".to_owned()),
|
||||
Some(AllocType::Function(func)) => {
|
||||
trace!("{} {}", msg, func);
|
||||
continue;
|
||||
}
|
||||
Some(AllocType::Static(did)) => {
|
||||
trace!("{} {:?}", msg, did);
|
||||
continue;
|
||||
}
|
||||
None => {
|
||||
trace!("{} (deallocated)", msg);
|
||||
continue;
|
||||
}
|
||||
None => {
|
||||
// static alloc?
|
||||
match self.tcx.alloc_map.lock().get(id) {
|
||||
Some(AllocType::Memory(a)) => (a, "(immutable)".to_owned()),
|
||||
Some(AllocType::Function(func)) => {
|
||||
trace!("{} {}", msg, func);
|
||||
continue;
|
||||
}
|
||||
},
|
||||
Some(AllocType::Static(did)) => {
|
||||
trace!("{} {:?}", msg, did);
|
||||
continue;
|
||||
}
|
||||
None => {
|
||||
trace!("{} (deallocated)", msg);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
@ -569,8 +540,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
|
||||
Some(MemoryKind::Machine(_)) => bug!("machine didn't handle machine alloc"),
|
||||
Some(MemoryKind::Stack) => {},
|
||||
}
|
||||
let uninit = self.uninitialized_statics.remove(&alloc_id);
|
||||
if let Some(mut alloc) = alloc.or(uninit) {
|
||||
if let Some(mut alloc) = alloc {
|
||||
// ensure llvm knows not to put this into immutable memroy
|
||||
alloc.runtime_mutability = mutability;
|
||||
let alloc = self.tcx.intern_const_alloc(alloc);
|
||||
|
@ -1,9 +1,10 @@
|
||||
use rustc::ty::{self, Ty};
|
||||
use rustc::ty::layout::{Size, Align, LayoutOf};
|
||||
use rustc::mir::interpret::{Scalar, Value, Pointer, EvalResult};
|
||||
|
||||
use syntax::ast::Mutability;
|
||||
|
||||
use rustc::mir::interpret::{Scalar, Value, Pointer, EvalResult};
|
||||
use super::{EvalContext, Machine};
|
||||
use super::{EvalContext, Machine, MemoryKind};
|
||||
|
||||
impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
|
||||
/// Creates a dynamic vtable for the given type and vtable origin. This is used only for
|
||||
@ -30,7 +31,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
|
||||
let vtable = self.memory.allocate(
|
||||
ptr_size * (3 + methods.len() as u64),
|
||||
ptr_align,
|
||||
None,
|
||||
MemoryKind::Stack,
|
||||
)?;
|
||||
|
||||
let drop = ::monomorphize::resolve_drop_in_place(*self.tcx, ty);
|
||||
|
Loading…
Reference in New Issue
Block a user