Skip to content

Commit 65bc1e5

Browse files
committed
Fix write_cvalue for ByValPair when the cvalue is not trivially a pair
`write_cvalue` didn't work for `Box<[u8]>`, because the inner fat ptr was wrapped inside a newtype, which meant `Box<[u8]>` itself only had one field. This also simplifies `CValue::force_stack` by reusing `write_cvalue` when it is not already on the stack.
1 parent 4d406cd commit 65bc1e5

File tree

1 file changed

+20
-27
lines changed

1 file changed

+20
-27
lines changed

src/value_and_place.rs

+20-27
Original file line numberDiff line numberDiff line change
@@ -53,28 +53,10 @@ impl<'tcx> CValue<'tcx> {
5353
let layout = self.1;
5454
match self.0 {
5555
CValueInner::ByRef(value) => value,
56-
CValueInner::ByVal(value) => {
57-
let stack_slot = fx.bcx.create_stack_slot(StackSlotData {
58-
kind: StackSlotKind::ExplicitSlot,
59-
size: layout.size.bytes() as u32,
60-
offset: None,
61-
});
62-
let addr = fx.bcx.ins().stack_addr(fx.pointer_type, stack_slot, 0);
63-
fx.bcx.ins().store(MemFlags::new(), value, addr, 0);
64-
addr
65-
}
66-
CValueInner::ByValPair(value, extra) => {
67-
let stack_slot = fx.bcx.create_stack_slot(StackSlotData {
68-
kind: StackSlotKind::ExplicitSlot,
69-
size: layout.size.bytes() as u32,
70-
offset: None,
71-
});
72-
let base = fx.bcx.ins().stack_addr(types::I64, stack_slot, 0);
73-
let a_addr = codegen_field(fx, base, layout, mir::Field::new(0)).0;
74-
let b_addr = codegen_field(fx, base, layout, mir::Field::new(1)).0;
75-
fx.bcx.ins().store(MemFlags::new(), value, a_addr, 0);
76-
fx.bcx.ins().store(MemFlags::new(), extra, b_addr, 0);
77-
base
56+
CValueInner::ByVal(_) | CValueInner::ByValPair(_, _) => {
57+
let cplace = CPlace::new_stack_slot(fx, layout.ty);
58+
cplace.write_cvalue(fx, self);
59+
cplace.to_addr(fx)
7860
}
7961
}
8062
}
@@ -356,11 +338,22 @@ impl<'a, 'tcx: 'a> CPlace<'tcx> {
356338
CValueInner::ByVal(val) => {
357339
fx.bcx.ins().store(MemFlags::new(), val, addr, 0);
358340
}
359-
CValueInner::ByValPair(val1, val2) => {
360-
let val1_offset = dst_layout.fields.offset(0).bytes() as i32;
361-
let val2_offset = dst_layout.fields.offset(1).bytes() as i32;
362-
fx.bcx.ins().store(MemFlags::new(), val1, addr, val1_offset);
363-
fx.bcx.ins().store(MemFlags::new(), val2, addr, val2_offset);
341+
CValueInner::ByValPair(value, extra) => {
342+
match dst_layout.abi {
343+
Abi::ScalarPair(ref a, _) => {
344+
fx.bcx.ins().store(MemFlags::new(), value, addr, 0);
345+
fx.bcx.ins().store(
346+
MemFlags::new(),
347+
extra,
348+
addr,
349+
a.value.size(&fx.tcx).bytes() as u32 as i32,
350+
);
351+
}
352+
_ => bug!(
353+
"Non ScalarPair abi {:?} for ByValPair CValue",
354+
dst_layout.abi
355+
),
356+
}
364357
}
365358
CValueInner::ByRef(from_addr) => {
366359
let src_layout = from.1;

0 commit comments

Comments
 (0)