Implement intrinsic min_align_of_val
This commit is contained in:
parent
6e87a4f16d
commit
1f1746e2d3
@ -222,6 +222,8 @@ pub mod intrinsics {
|
||||
pub fn abort() -> !;
|
||||
pub fn size_of<T>() -> usize;
|
||||
pub fn size_of_val<T: ?::Sized>(val: &T) -> usize;
|
||||
pub fn min_align_of<T>() -> usize;
|
||||
pub fn min_align_of_val<T: ?::Sized>(val: &T) -> usize;
|
||||
pub fn copy<T>(src: *const T, dst: *mut T, count: usize);
|
||||
pub fn transmute<T, U>(e: T) -> U;
|
||||
pub fn uninit<T>() -> T;
|
||||
|
@ -86,6 +86,22 @@ fn start<T: Termination + 'static>(
|
||||
static mut NUM: u8 = 6 * 7;
|
||||
static NUM_REF: &'static u8 = unsafe { &NUM };
|
||||
|
||||
macro_rules! assert {
|
||||
($e:expr) => {
|
||||
if !$e {
|
||||
panic(&(stringify!(! $e), file!(), line!(), 0));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! assert_eq {
|
||||
($l:expr, $r: expr) => {
|
||||
if $l != $r {
|
||||
panic(&(stringify!($l != $r), file!(), line!(), 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
let hello: &[u8] = b"Hello\0" as &[u8; 6];
|
||||
@ -99,34 +115,23 @@ fn main() {
|
||||
puts(*world as *const str as *const u8);
|
||||
}
|
||||
|
||||
if intrinsics::size_of_val(hello) as u8 != 6 {
|
||||
panic(&("", "", 0, 0));
|
||||
};
|
||||
assert_eq!(intrinsics::size_of_val(hello) as u8, 6);
|
||||
|
||||
let chars = &['C', 'h', 'a', 'r', 's'];
|
||||
let chars = chars as &[char];
|
||||
if intrinsics::size_of_val(chars) as u8 != 4 * 5 {
|
||||
panic(&("", "", 0, 0));
|
||||
}
|
||||
assert_eq!(intrinsics::size_of_val(chars) as u8, 4 * 5);
|
||||
|
||||
let a: &dyn SomeTrait = &"abc\0";
|
||||
a.object_safe();
|
||||
|
||||
if intrinsics::size_of_val(a) as u8 != 16 {
|
||||
panic(&("", "", 0, 0));
|
||||
}
|
||||
assert_eq!(intrinsics::size_of_val(a) as u8, 16);
|
||||
assert_eq!(intrinsics::size_of_val(&0u32) as u8, 4);
|
||||
|
||||
if intrinsics::size_of_val(&0u32) as u8 != 4 {
|
||||
panic(&("", "", 0, 0));
|
||||
}
|
||||
assert_eq!(intrinsics::min_align_of::<u16>() as u8, 2);
|
||||
assert_eq!(intrinsics::min_align_of_val(&a) as u8, intrinsics::min_align_of::<&str>() as u8);
|
||||
|
||||
if intrinsics::needs_drop::<u8>() {
|
||||
panic(&("", "", 0, 0));
|
||||
}
|
||||
|
||||
if !intrinsics::needs_drop::<NoisyDrop>() {
|
||||
panic(&("", "", 0, 0));
|
||||
}
|
||||
assert!(!intrinsics::needs_drop::<u8>());
|
||||
assert!(intrinsics::needs_drop::<NoisyDrop>());
|
||||
}
|
||||
|
||||
let _ = NoisyDrop {
|
||||
|
28
src/abi.rs
28
src/abi.rs
@ -675,18 +675,34 @@ fn codegen_intrinsic_call<'a, 'tcx: 'a>(
|
||||
};
|
||||
ret.write_cvalue(fx, CValue::ByVal(size, usize_layout));
|
||||
}
|
||||
"type_id" => {
|
||||
assert_eq!(args.len(), 0);
|
||||
let type_id = fx.tcx.type_id_hash(substs.type_at(0));
|
||||
let type_id = CValue::const_val(fx, u64_layout.ty, type_id as i64);
|
||||
ret.write_cvalue(fx, type_id);
|
||||
}
|
||||
"min_align_of" => {
|
||||
assert_eq!(args.len(), 0);
|
||||
let min_align = fx.layout_of(substs.type_at(0)).align.abi();
|
||||
let min_align = CValue::const_val(fx, usize_layout.ty, min_align as i64);
|
||||
ret.write_cvalue(fx, min_align);
|
||||
}
|
||||
"min_align_of_val" => {
|
||||
assert_eq!(args.len(), 1);
|
||||
let layout = fx.layout_of(substs.type_at(0));
|
||||
let align = match &layout.ty.sty {
|
||||
_ if !layout.is_unsized() => {
|
||||
fx.bcx.ins().iconst(fx.module.pointer_type(), layout.align.abi() as i64)
|
||||
}
|
||||
ty::Slice(elem) => {
|
||||
let align = fx.layout_of(elem).align.abi() as i64;
|
||||
fx.bcx.ins().iconst(fx.module.pointer_type(), align)
|
||||
}
|
||||
ty::Dynamic(..) => crate::vtable::min_align_of_obj(fx, args[0]),
|
||||
ty => unimplemented!("min_align_of_val for {:?}", ty),
|
||||
};
|
||||
ret.write_cvalue(fx, CValue::ByVal(align, usize_layout));
|
||||
}
|
||||
"type_id" => {
|
||||
assert_eq!(args.len(), 0);
|
||||
let type_id = fx.tcx.type_id_hash(substs.type_at(0));
|
||||
let type_id = CValue::const_val(fx, u64_layout.ty, type_id as i64);
|
||||
ret.write_cvalue(fx, type_id);
|
||||
}
|
||||
_ if intrinsic.starts_with("unchecked_") => {
|
||||
assert_eq!(args.len(), 2);
|
||||
let bin_op = match intrinsic {
|
||||
|
@ -20,6 +20,20 @@ pub fn size_of_obj<'a, 'tcx: 'a>(
|
||||
)
|
||||
}
|
||||
|
||||
pub fn min_align_of_obj<'a, 'tcx: 'a>(
|
||||
fx: &mut FunctionCx<'a, 'tcx, impl Backend>,
|
||||
val: CValue<'tcx>,
|
||||
) -> Value {
|
||||
let (_ptr, vtable) = val.load_value_pair(fx);
|
||||
let usize_size = fx.layout_of(fx.tcx.types.usize).size.bytes() as usize;
|
||||
fx.bcx.ins().load(
|
||||
pointer_ty(fx.tcx),
|
||||
MemFlags::new(),
|
||||
vtable,
|
||||
(ALIGN_INDEX * usize_size) as i32,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn get_ptr_and_method_ref<'a, 'tcx: 'a>(
|
||||
fx: &mut FunctionCx<'a, 'tcx, impl Backend>,
|
||||
arg: CValue<'tcx>,
|
||||
|
Loading…
x
Reference in New Issue
Block a user