Skip to content

Commit 240d56c

Browse files
committed
Support virtual calls with unsized self argument
1 parent c53297f commit 240d56c

File tree

5 files changed

+23
-26
lines changed

5 files changed

+23
-26
lines changed

src/abi/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ pub fn codegen_fn_prelude(fx: &mut FunctionCx<'_, '_, impl Backend>, start_block
355355
// not mutated by the current function, this is necessary to support unsized arguments.
356356
match arg_kind {
357357
ArgKind::Normal(Some(val)) => {
358-
if let Some((addr, meta)) = val.try_to_addr() {
358+
if let Some((addr, meta)) = val.try_to_ptr() {
359359
let local_decl = &fx.mir.local_decls[local];
360360
// v this ! is important
361361
let internally_mutable = !val.layout().ty.is_freeze(
@@ -368,9 +368,9 @@ pub fn codegen_fn_prelude(fx: &mut FunctionCx<'_, '_, impl Backend>, start_block
368368
// of this argument, to prevent a copy.
369369

370370
let place = if let Some(meta) = meta {
371-
CPlace::for_ptr_with_extra(Pointer::new(addr), meta, val.layout())
371+
CPlace::for_ptr_with_extra(addr, meta, val.layout())
372372
} else {
373-
CPlace::for_ptr(Pointer::new(addr), val.layout())
373+
CPlace::for_ptr(addr, val.layout())
374374
};
375375

376376
#[cfg(debug_assertions)]

src/common.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,9 @@ impl<'tcx, B: Backend + 'static> FunctionCx<'_, 'tcx, B> {
353353
}
354354

355355
pub fn get_local_place(&mut self, local: Local) -> CPlace<'tcx> {
356-
*self.local_map.get(&local).unwrap()
356+
*self.local_map.get(&local).unwrap_or_else(|| {
357+
panic!("Local {:?} doesn't exist", local);
358+
})
357359
}
358360

359361
pub fn set_debug_loc(&mut self, source_info: mir::SourceInfo) {

src/pointer.rs

-7
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,6 @@ impl Pointer {
5555
}
5656
}
5757

58-
pub fn try_get_addr_and_offset(self) -> Option<(Value, Offset32)> {
59-
match self.base {
60-
PointerBase::Addr(addr) => Some((addr, self.offset)),
61-
PointerBase::Stack(_) => None,
62-
}
63-
}
64-
6558
pub fn offset<'a, 'tcx>(
6659
self,
6760
fx: &mut FunctionCx<'a, 'tcx, impl Backend>,

src/value_and_place.rs

+7-14
Original file line numberDiff line numberDiff line change
@@ -105,19 +105,9 @@ impl<'tcx> CValue<'tcx> {
105105
}
106106
}
107107

108-
pub fn try_to_addr(self) -> Option<(Value, Option<Value>)> {
108+
pub fn try_to_ptr(self) -> Option<(Pointer, Option<Value>)> {
109109
match self.0 {
110-
CValueInner::ByRef(ptr, meta) => {
111-
if let Some((base_addr, offset)) = ptr.try_get_addr_and_offset() {
112-
if offset == Offset32::new(0) {
113-
Some((base_addr, meta))
114-
} else {
115-
None
116-
}
117-
} else {
118-
None
119-
}
120-
}
110+
CValueInner::ByRef(ptr, meta) => Some((ptr, meta)),
121111
CValueInner::ByVal(_) | CValueInner::ByValPair(_, _) => None,
122112
}
123113
}
@@ -345,8 +335,11 @@ impl<'tcx> CPlace<'tcx> {
345335
CValue::by_val(val, layout)
346336
}
347337
CPlaceInner::Addr(ptr, extra) => {
348-
assert!(extra.is_none(), "unsized values are not yet supported");
349-
CValue::by_ref(ptr, layout)
338+
if let Some(extra) = extra {
339+
CValue::by_ref_unsized(ptr, extra, layout)
340+
} else {
341+
CValue::by_ref(ptr, layout)
342+
}
350343
}
351344
CPlaceInner::NoPlace => CValue::by_ref(
352345
Pointer::const_addr(fx, i64::try_from(self.layout.align.pref.bytes()).unwrap()),

src/vtable.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,16 @@ pub fn get_ptr_and_method_ref<'tcx>(
4747
arg: CValue<'tcx>,
4848
idx: usize,
4949
) -> (Value, Value) {
50-
let (ptr, vtable) = arg.load_scalar_pair(fx);
50+
let (ptr, vtable) = if let Abi::ScalarPair(_, _) = arg.layout().abi {
51+
arg.load_scalar_pair(fx)
52+
} else {
53+
let (ptr, vtable) = arg.try_to_ptr().unwrap();
54+
(
55+
ptr.get_addr(fx),
56+
vtable.unwrap()
57+
)
58+
};
59+
5160
let usize_size = fx.layout_of(fx.tcx.types.usize).size.bytes();
5261
let func_ref = fx.bcx.ins().load(
5362
pointer_ty(fx.tcx),

0 commit comments

Comments
 (0)