about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2013-04-22 16:22:36 -0700
committerPatrick Walton <pcwalton@mimiga.net>2013-04-29 14:30:53 -0700
commitb6277f8140a496bed371e97ea1e260858e77fb41 (patch)
treec85ae630368d3b5a1d0fb2b55ed585115b735c5a /src/libcore
parentb0522a497ccfcc7b124d77121d8f076af7f09b71 (diff)
downloadrust-b6277f8140a496bed371e97ea1e260858e77fb41.tar.gz
rust-b6277f8140a496bed371e97ea1e260858e77fb41.zip
librustc: Implement `reinterpret_cast` in terms of `transmute`.
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/cast.rs36
1 files changed, 36 insertions, 0 deletions
diff --git a/src/libcore/cast.rs b/src/libcore/cast.rs
index 1d214f402f5..620f716a63d 100644
--- a/src/libcore/cast.rs
+++ b/src/libcore/cast.rs
@@ -10,21 +10,48 @@
 
 //! Unsafe casting functions
 
+use sys;
+use unstable;
+
 pub mod rusti {
     #[abi = "rust-intrinsic"]
     #[link_name = "rusti"]
     pub extern "rust-intrinsic" {
         fn forget<T>(+x: T);
+
+        #[cfg(stage0)]
         fn reinterpret_cast<T, U>(&&e: T) -> U;
+
+        #[cfg(stage1)]
+        #[cfg(stage2)]
+        #[cfg(stage3)]
+        fn transmute<T,U>(e: T) -> U;
     }
 }
 
 /// Casts the value at `src` to U. The two types must have the same length.
 #[inline(always)]
+#[cfg(stage0)]
 pub unsafe fn reinterpret_cast<T, U>(src: &T) -> U {
     rusti::reinterpret_cast(*src)
 }
 
+#[inline(always)]
+#[cfg(stage1)]
+#[cfg(stage2)]
+#[cfg(stage3)]
+pub unsafe fn reinterpret_cast<T, U>(src: &T) -> U {
+    let mut dest: U = unstable::intrinsics::init();
+    {
+        let dest_ptr: *mut u8 = rusti::transmute(&mut dest);
+        let src_ptr: *u8 = rusti::transmute(src);
+        unstable::intrinsics::memmove64(dest_ptr,
+                                        src_ptr,
+                                        sys::size_of::<U>() as u64);
+    }
+    dest
+}
+
 /**
  * Move a thing into the void
  *
@@ -53,12 +80,21 @@ pub unsafe fn bump_box_refcount<T>(t: @T) { forget(t); }
  *     assert!(transmute("L") == ~[76u8, 0u8]);
  */
 #[inline(always)]
+#[cfg(stage0)]
 pub unsafe fn transmute<L, G>(thing: L) -> G {
     let newthing: G = reinterpret_cast(&thing);
     forget(thing);
     newthing
 }
 
+#[inline(always)]
+#[cfg(stage1)]
+#[cfg(stage2)]
+#[cfg(stage3)]
+pub unsafe fn transmute<L, G>(thing: L) -> G {
+    rusti::transmute(thing)
+}
+
 /// Coerce an immutable reference to be mutable.
 #[inline(always)]
 pub unsafe fn transmute_mut<'a,T>(ptr: &'a T) -> &'a mut T { transmute(ptr) }