]> git.lizzy.rs Git - rust.git/commitdiff
Implement intrinsic min_align_of_val
authorbjorn3 <bjorn3@users.noreply.github.com>
Sat, 15 Sep 2018 09:14:27 +0000 (11:14 +0200)
committerbjorn3 <bjorn3@users.noreply.github.com>
Sat, 15 Sep 2018 09:14:27 +0000 (11:14 +0200)
examples/mini_core.rs
examples/mini_core_hello_world.rs
src/abi.rs
src/vtable.rs

index 6e2e9dd37f63e9e63a77bde384a80108694c29b1..544f2eceac0fad459ad4233cc453cf49fdf56a31 100644 (file)
@@ -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;
index 5948415c92913aa3ea01c02cad2cf7b3421acdbd..ff7d7975e27674e1e82951d81dda7a3d9e7788be 100644 (file)
@@ -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 {
index bc61ba5a70897f2ba212253f91cdd2d30f1b566e..21886218962092344d220e13043250354a9964e8 100644 (file)
@@ -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 {
index 4d2382979c976debcc1354a08b96cd2ab389e998..da9c3765588c4230ff534bdaae878582f9ee9313 100644 (file)
@@ -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>,