pass MemoryExtra to find_foreign_static and adjust_static_allocation; they might have to create allocations

This commit is contained in:
Ralf Jung 2018-11-15 12:03:38 +01:00
parent 4c090fe310
commit 6cca7165ea
3 changed files with 20 additions and 14 deletions

View file

@ -433,16 +433,18 @@ impl<'a, 'mir, 'tcx> interpret::Machine<'a, 'mir, 'tcx>
}
fn find_foreign_static(
_tcx: TyCtxtAt<'a, 'tcx, 'tcx>,
_def_id: DefId,
_tcx: TyCtxtAt<'a, 'tcx, 'tcx>,
_memory_extra: &(),
) -> EvalResult<'tcx, Cow<'tcx, Allocation<Self::PointerTag>>> {
err!(ReadForeignStatic)
}
#[inline(always)]
fn adjust_static_allocation(
alloc: &'_ Allocation
) -> Cow<'_, Allocation<Self::PointerTag>> {
fn adjust_static_allocation<'b>(
alloc: &'b Allocation,
_memory_extra: &(),
) -> Cow<'b, Allocation<Self::PointerTag>> {
// We do not use a tag so we can just cheaply forward the reference
Cow::Borrowed(alloc)
}

View file

@ -140,8 +140,9 @@ pub trait Machine<'a, 'mir, 'tcx>: Sized {
/// the machine memory. (This relies on `AllocMap::get_or` being able to add the
/// owned allocation to the map even when the map is shared.)
fn find_foreign_static(
tcx: TyCtxtAt<'a, 'tcx, 'tcx>,
def_id: DefId,
tcx: TyCtxtAt<'a, 'tcx, 'tcx>,
memory_extra: &Self::MemoryExtra,
) -> EvalResult<'tcx, Cow<'tcx, Allocation<Self::PointerTag, Self::AllocExtra>>>;
/// Called to turn an allocation obtained from the `tcx` into one that has
@ -151,9 +152,10 @@ pub trait Machine<'a, 'mir, 'tcx>: Sized {
/// allocation (because a copy had to be done to add tags or metadata), machine memory will
/// cache the result. (This relies on `AllocMap::get_or` being able to add the
/// owned allocation to the map even when the map is shared.)
fn adjust_static_allocation(
alloc: &'_ Allocation
) -> Cow<'_, Allocation<Self::PointerTag, Self::AllocExtra>>;
fn adjust_static_allocation<'b>(
alloc: &'b Allocation,
memory_extra: &Self::MemoryExtra,
) -> Cow<'b, Allocation<Self::PointerTag, Self::AllocExtra>>;
/// Called for all binary operations on integer(-like) types when one operand is a pointer
/// value, and for the `Offset` operation that is inherently about pointers.

View file

@ -320,15 +320,16 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
/// this machine use the same pointer tag, so it is indirected through
/// `M::static_with_default_tag`.
fn get_static_alloc(
tcx: TyCtxtAt<'a, 'tcx, 'tcx>,
id: AllocId,
tcx: TyCtxtAt<'a, 'tcx, 'tcx>,
memory_extra: &M::MemoryExtra,
) -> EvalResult<'tcx, Cow<'tcx, Allocation<M::PointerTag, M::AllocExtra>>> {
let alloc = tcx.alloc_map.lock().get(id);
let def_id = match alloc {
Some(AllocType::Memory(mem)) => {
// We got tcx memory. Let the machine figure out whether and how to
// turn that into memory with the right pointer tag.
return Ok(M::adjust_static_allocation(mem))
return Ok(M::adjust_static_allocation(mem, memory_extra))
}
Some(AllocType::Function(..)) => {
return err!(DerefFunctionPointer)
@ -342,7 +343,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
// We got a "lazy" static that has not been computed yet, do some work
trace!("static_alloc: Need to compute {:?}", def_id);
if tcx.is_foreign_item(def_id) {
return M::find_foreign_static(tcx, def_id);
return M::find_foreign_static(def_id, tcx, memory_extra);
}
let instance = Instance::mono(tcx.tcx, def_id);
let gid = GlobalId {
@ -362,7 +363,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
let allocation = tcx.alloc_map.lock().unwrap_memory(raw_const.alloc_id);
// We got tcx memory. Let the machine figure out whether and how to
// turn that into memory with the right pointer tag.
M::adjust_static_allocation(allocation)
M::adjust_static_allocation(allocation, memory_extra)
})
}
@ -372,7 +373,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
// `get_static_alloc` that we can actually use directly without inserting anything anywhere.
// So the error type is `EvalResult<'tcx, &Allocation<M::PointerTag>>`.
let a = self.alloc_map.get_or(id, || {
let alloc = Self::get_static_alloc(self.tcx, id).map_err(Err)?;
let alloc = Self::get_static_alloc(id, self.tcx, &self.extra).map_err(Err)?;
match alloc {
Cow::Borrowed(alloc) => {
// We got a ref, cheaply return that as an "error" so that the
@ -401,10 +402,11 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
id: AllocId,
) -> EvalResult<'tcx, &mut Allocation<M::PointerTag, M::AllocExtra>> {
let tcx = self.tcx;
let memory_extra = &self.extra;
let a = self.alloc_map.get_mut_or(id, || {
// Need to make a copy, even if `get_static_alloc` is able
// to give us a cheap reference.
let alloc = Self::get_static_alloc(tcx, id)?;
let alloc = Self::get_static_alloc(id, tcx, memory_extra)?;
if alloc.mutability == Mutability::Immutable {
return err!(ModifiedConstantMemory);
}