Skip to content

Commit 970d164

Browse files
committed
Fix and optimize init intrinsic
1 parent 16f4126 commit 970d164

File tree

3 files changed

+58
-9
lines changed

3 files changed

+58
-9
lines changed

example/mini_core.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,7 @@ pub mod intrinsics {
371371
pub fn copy<T>(src: *const T, dst: *mut T, count: usize);
372372
pub fn transmute<T, U>(e: T) -> U;
373373
pub fn uninit<T>() -> T;
374+
pub fn init<T>() -> T;
374375
pub fn ctlz_nonzero<T>(x: T) -> T;
375376
pub fn needs_drop<T>() -> bool;
376377
pub fn bitreverse<T>(x: T) -> T;

example/mini_core_hello_world.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,29 @@ fn main() {
165165
struct MyDst<T: ?Sized>(T);
166166

167167
intrinsics::size_of_val(&MyDst([0u8; 4]) as &MyDst<[u8]>);
168+
169+
struct Foo {
170+
x: u8,
171+
y: !,
172+
}
173+
174+
unsafe fn zeroed<T>() -> T {
175+
intrinsics::init::<T>()
176+
}
177+
178+
unsafe fn uninitialized<T>() -> T {
179+
intrinsics::uninit::<T>()
180+
}
181+
182+
#[allow(unreachable_code)]
183+
{
184+
if false {
185+
zeroed::<!>();
186+
zeroed::<Foo>();
187+
zeroed::<(u8, u8)>();
188+
uninitialized::<Foo>();
189+
}
190+
}
168191
}
169192

170193
let _ = box NoisyDrop {

src/intrinsics.rs

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -337,16 +337,36 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
337337
let dst_layout = fx.layout_of(dst_ty);
338338
ret.write_cvalue(fx, CValue::ByRef(addr, dst_layout))
339339
};
340-
init, <T> () {
341-
let layout = fx.layout_of(T);
342-
let inited_place = CPlace::new_stack_slot(fx, T);
343-
let addr = inited_place.to_addr(fx);
344-
let zero_val = fx.bcx.ins().iconst(types::I8, 0);
345-
let len_val = fx.bcx.ins().iconst(pointer_ty(fx.tcx), layout.size.bytes() as i64);
346-
fx.bcx.call_memset(fx.module.target_config(), addr, zero_val, len_val);
340+
init, () {
341+
if ret.layout().abi == Abi::Uninhabited {
342+
crate::trap::trap_panic(&mut fx.bcx);
343+
return;
344+
}
347345

348-
let inited_val = inited_place.to_cvalue(fx);
349-
ret.write_cvalue(fx, inited_val);
346+
match ret {
347+
CPlace::NoPlace(_layout) => {}
348+
CPlace::Var(var, layout) => {
349+
let clif_ty = fx.clif_type(layout.ty).unwrap();
350+
let val = match clif_ty {
351+
types::I8 | types::I16 | types::I32 | types::I64 => fx.bcx.ins().iconst(clif_ty, 0),
352+
types::F32 => {
353+
let zero = fx.bcx.ins().iconst(types::I32, 0);
354+
fx.bcx.ins().bitcast(types::F32, zero)
355+
}
356+
types::F64 => {
357+
let zero = fx.bcx.ins().iconst(types::I64, 0);
358+
fx.bcx.ins().bitcast(types::F64, zero)
359+
}
360+
_ => panic!("clif_type returned {}", clif_ty),
361+
};
362+
fx.bcx.def_var(mir_var(var), val);
363+
}
364+
_ => {
365+
let addr = ret.to_addr(fx);
366+
let layout = ret.layout();
367+
fx.bcx.emit_small_memset(fx.module.target_config(), addr, 0, layout.size.bytes(), 1);
368+
}
369+
}
350370
};
351371
write_bytes, (c dst, v val, v count) {
352372
let pointee_ty = dst.layout().ty.builtin_deref(true).unwrap().ty;
@@ -356,6 +376,11 @@ pub fn codegen_intrinsic_call<'a, 'tcx: 'a>(
356376
fx.bcx.call_memset(fx.module.target_config(), dst_ptr, val, count);
357377
};
358378
uninit, <T> () {
379+
if ret.layout().abi == Abi::Uninhabited {
380+
crate::trap::trap_panic(&mut fx.bcx);
381+
return;
382+
}
383+
359384
let uninit_place = CPlace::new_stack_slot(fx, T);
360385
let uninit_val = uninit_place.to_cvalue(fx);
361386
ret.write_cvalue(fx, uninit_val);

0 commit comments

Comments
 (0)