Skip to content

Commit 1c1a60f

Browse files
committed
interpret: convert_tag_add_extra, init_allocation_extra: allow tagger to raise errors
1 parent 872503d commit 1c1a60f

File tree

3 files changed

+21
-17
lines changed

3 files changed

+21
-17
lines changed

compiler/rustc_const_eval/src/interpret/machine.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -334,12 +334,14 @@ pub trait Machine<'mir, 'tcx>: Sized {
334334
/// allocation (because a copy had to be done to add tags or metadata), machine memory will
335335
/// cache the result. (This relies on `AllocMap::get_or` being able to add the
336336
/// owned allocation to the map even when the map is shared.)
337+
///
338+
/// This must only fail if `alloc` contains relocations.
337339
fn init_allocation_extra<'b>(
338340
ecx: &InterpCx<'mir, 'tcx, Self>,
339341
id: AllocId,
340342
alloc: Cow<'b, Allocation>,
341343
kind: Option<MemoryKind<Self::MemoryKind>>,
342-
) -> Cow<'b, Allocation<Self::PointerTag, Self::AllocExtra>>;
344+
) -> InterpResult<'tcx, Cow<'b, Allocation<Self::PointerTag, Self::AllocExtra>>>;
343345

344346
/// Hook for performing extra checks on a memory read access.
345347
///
@@ -485,9 +487,9 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
485487
_id: AllocId,
486488
alloc: Cow<'b, Allocation>,
487489
_kind: Option<MemoryKind<Self::MemoryKind>>,
488-
) -> Cow<'b, Allocation<Self::PointerTag>> {
490+
) -> InterpResult<$tcx, Cow<'b, Allocation<Self::PointerTag>>> {
489491
// We do not use a tag so we can just cheaply forward the allocation
490-
alloc
492+
Ok(alloc)
491493
}
492494

493495
fn extern_static_base_pointer(

compiler/rustc_const_eval/src/interpret/memory.rs

+10-8
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
199199
kind: MemoryKind<M::MemoryKind>,
200200
) -> InterpResult<'tcx, Pointer<M::PointerTag>> {
201201
let alloc = Allocation::uninit(size, align, M::PANIC_ON_ALLOC_FAIL)?;
202-
Ok(self.allocate_raw_ptr(alloc, kind))
202+
// We can `unwrap` since `alloc` contains no pointers.
203+
Ok(self.allocate_raw_ptr(alloc, kind).unwrap())
203204
}
204205

205206
pub fn allocate_bytes_ptr(
@@ -210,23 +211,25 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
210211
mutability: Mutability,
211212
) -> Pointer<M::PointerTag> {
212213
let alloc = Allocation::from_bytes(bytes, align, mutability);
213-
self.allocate_raw_ptr(alloc, kind)
214+
// We can `unwrap` since `alloc` contains no pointers.
215+
self.allocate_raw_ptr(alloc, kind).unwrap()
214216
}
215217

218+
/// This can fail only of `alloc` contains relocations.
216219
pub fn allocate_raw_ptr(
217220
&mut self,
218221
alloc: Allocation,
219222
kind: MemoryKind<M::MemoryKind>,
220-
) -> Pointer<M::PointerTag> {
223+
) -> InterpResult<'tcx, Pointer<M::PointerTag>> {
221224
let id = self.tcx.reserve_alloc_id();
222225
debug_assert_ne!(
223226
Some(kind),
224227
M::GLOBAL_KIND.map(MemoryKind::Machine),
225228
"dynamically allocating global memory"
226229
);
227-
let alloc = M::init_allocation_extra(self, id, Cow::Owned(alloc), Some(kind));
230+
let alloc = M::init_allocation_extra(self, id, Cow::Owned(alloc), Some(kind))?;
228231
self.memory.alloc_map.insert(id, (kind, alloc.into_owned()));
229-
M::tag_alloc_base_pointer(self, Pointer::from(id))
232+
Ok(M::tag_alloc_base_pointer(self, Pointer::from(id)))
230233
}
231234

232235
pub fn reallocate_ptr(
@@ -510,13 +513,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
510513
};
511514
M::before_access_global(*self.tcx, &self.machine, id, alloc, def_id, is_write)?;
512515
// We got tcx memory. Let the machine initialize its "extra" stuff.
513-
let alloc = M::init_allocation_extra(
516+
M::init_allocation_extra(
514517
self,
515518
id, // always use the ID we got as input, not the "hidden" one.
516519
Cow::Borrowed(alloc.inner()),
517520
M::GLOBAL_KIND.map(MemoryKind::Machine),
518-
);
519-
Ok(alloc)
521+
)
520522
}
521523

522524
/// Gives raw access to the `Allocation`, without bounds or alignment checks.

compiler/rustc_middle/src/mir/interpret/allocation.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -201,12 +201,12 @@ impl<Tag> Allocation<Tag> {
201201

202202
impl Allocation {
203203
/// Convert Tag and add Extra fields
204-
pub fn convert_tag_add_extra<Tag, Extra>(
204+
pub fn convert_tag_add_extra<Tag, Extra, Err>(
205205
self,
206206
cx: &impl HasDataLayout,
207207
extra: Extra,
208-
mut tagger: impl FnMut(Pointer<AllocId>) -> Pointer<Tag>,
209-
) -> Allocation<Tag, Extra> {
208+
mut tagger: impl FnMut(Pointer<AllocId>) -> Result<Pointer<Tag>, Err>,
209+
) -> Result<Allocation<Tag, Extra>, Err> {
210210
// Compute new pointer tags, which also adjusts the bytes.
211211
let mut bytes = self.bytes;
212212
let mut new_relocations = Vec::with_capacity(self.relocations.0.len());
@@ -217,19 +217,19 @@ impl Allocation {
217217
let ptr_bytes = &mut bytes[idx..idx + ptr_size];
218218
let bits = read_target_uint(endian, ptr_bytes).unwrap();
219219
let (ptr_tag, ptr_offset) =
220-
tagger(Pointer::new(alloc_id, Size::from_bytes(bits))).into_parts();
220+
tagger(Pointer::new(alloc_id, Size::from_bytes(bits)))?.into_parts();
221221
write_target_uint(endian, ptr_bytes, ptr_offset.bytes().into()).unwrap();
222222
new_relocations.push((offset, ptr_tag));
223223
}
224224
// Create allocation.
225-
Allocation {
225+
Ok(Allocation {
226226
bytes,
227227
relocations: Relocations::from_presorted(new_relocations),
228228
init_mask: self.init_mask,
229229
align: self.align,
230230
mutability: self.mutability,
231231
extra,
232-
}
232+
})
233233
}
234234
}
235235

0 commit comments

Comments
 (0)