Skip to content

Commit 1357c9b

Browse files
author
Alexander Regueiro
committed
Cleaned up code for writing MIR for vtable.
1 parent 34b47b0 commit 1357c9b

File tree

1 file changed

+22
-21
lines changed

1 file changed

+22
-21
lines changed

src/librustc_mir/interpret/traits.rs

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
use std::convert::TryFrom;
1+
use super::{FnVal, InterpCx, Machine, Memory, MemoryKind};
22

33
use rustc_middle::mir::interpret::{InterpResult, Pointer, PointerArithmetic, Scalar};
44
use rustc_middle::ty::{self, Instance, Ty, TypeFoldable};
55
use rustc_target::abi::{Align, HasDataLayout, LayoutOf, Size};
66

7-
use super::{FnVal, InterpCx, Machine, MemoryKind};
7+
use std::convert::TryFrom;
88

99
impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
1010
/// Creates a dynamic vtable for the given type and vtable origin. This is used only for
@@ -62,34 +62,35 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
6262
);
6363
let tcx = &*self.tcx;
6464

65+
// Keep track of current position within vtable and write to there, offsetting position by
66+
// one pointer size each time.
67+
let mut cur_ptr = vtable;
68+
let mut write_ptr = |memory: &mut Memory<'mir, 'tcx, M>, val| -> InterpResult<'_> {
69+
let res = memory
70+
.get_raw_mut(cur_ptr.alloc_id)?
71+
.write_ptr_sized(tcx, cur_ptr, val)?;
72+
cur_ptr = cur_ptr.offset(ptr_size, tcx)?;
73+
Ok(res)
74+
};
75+
6576
let drop = Instance::resolve_drop_in_place(*tcx, ty);
6677
let drop = self.memory.create_fn_alloc(FnVal::Instance(drop));
6778

6879
// No need to do any alignment checks on the memory accesses below, because we know the
69-
// allocation is correctly aligned as we created it above. Also we're only offsetting by
70-
// multiples of `ptr_align`, which means that it will stay aligned to `ptr_align`.
71-
let vtable_alloc = self.memory.get_raw_mut(vtable.alloc_id)?;
72-
vtable_alloc.write_ptr_sized(tcx, vtable, drop.into())?;
73-
74-
let size_ptr = vtable.offset(ptr_size, tcx)?;
75-
vtable_alloc.write_ptr_sized(tcx, size_ptr, Scalar::from_uint(size, ptr_size).into())?;
76-
let align_ptr = vtable.offset(ptr_size * 2, tcx)?;
77-
vtable_alloc.write_ptr_sized(tcx, align_ptr, Scalar::from_uint(align, ptr_size).into())?;
80+
// allocation is correctly aligned, as we created it above. Also. we're only offsetting
81+
// by multiples of `ptr_align`, which means that it will stay aligned to `ptr_align`.
82+
write_ptr(&mut self.memory, Scalar::Ptr(drop).into())?;
83+
write_ptr(&mut self.memory, Scalar::from_uint(size, ptr_size).into())?;
84+
write_ptr(&mut self.memory, Scalar::from_uint(align, ptr_size).into())?;
7885

79-
for (i, method) in methods.iter().enumerate() {
86+
for method in methods.iter() {
8087
if let Some((def_id, substs)) = *method {
81-
// resolve for vtable: insert shims where needed
88+
// Resolve for vtable; insert shims where needed.
8289
let instance =
8390
ty::Instance::resolve_for_vtable(*tcx, self.param_env, def_id, substs)
8491
.ok_or_else(|| err_inval!(TooGeneric))?;
8592
let fn_ptr = self.memory.create_fn_alloc(FnVal::Instance(instance));
86-
// We cannot use `vtable_allic` as we are creating fn ptrs in this loop.
87-
let method_ptr = vtable.offset(ptr_size * (3 + i as u64), tcx)?;
88-
self.memory.get_raw_mut(vtable.alloc_id)?.write_ptr_sized(
89-
tcx,
90-
method_ptr,
91-
fn_ptr.into(),
92-
)?;
93+
write_ptr(&mut self.memory, Scalar::Ptr(fn_ptr).into())?;
9394
}
9495
}
9596

@@ -179,7 +180,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
179180
if size >= self.tcx.data_layout().obj_size_bound() {
180181
throw_ub_format!(
181182
"invalid vtable: \
182-
size is bigger than largest supported object"
183+
size is bigger than largest supported object"
183184
);
184185
}
185186
Ok((Size::from_bytes(size), Align::from_bytes(align).unwrap()))

0 commit comments

Comments
 (0)