Skip to content

Commit 5750970

Browse files
author
James Miller
committed
Make staged versions of the functions that use uninit
1 parent f5ab112 commit 5750970

File tree

4 files changed

+184
-0
lines changed

4 files changed

+184
-0
lines changed

src/libcore/cast.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ pub mod rusti {
2424
}
2525

2626
/// Casts the value at `src` to U. The two types must have the same length.
27+
#[cfg(not(stage0))]
2728
pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
2829
let mut dest: U = unstable::intrinsics::uninit();
2930
{
@@ -36,6 +37,19 @@ pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
3637
dest
3738
}
3839

40+
#[cfg(stage0)]
41+
pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
42+
let mut dest: U = unstable::intrinsics::init();
43+
{
44+
let dest_ptr: *mut u8 = rusti::transmute(&mut dest);
45+
let src_ptr: *u8 = rusti::transmute(src);
46+
unstable::intrinsics::memmove64(dest_ptr,
47+
src_ptr,
48+
sys::size_of::<U>() as u64);
49+
}
50+
dest
51+
}
52+
3953
/**
4054
* Move a thing into the void
4155
*

src/libcore/vec.rs

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,7 @@ pub fn consume_reverse<T>(mut v: ~[T], f: &fn(uint, v: T)) {
584584
}
585585
586586
/// Remove the last element from a vector and return it
587+
#[cfg(not(stage0))]
587588
pub fn pop<T>(v: &mut ~[T]) -> T {
588589
let ln = v.len();
589590
if ln == 0 {
@@ -598,6 +599,21 @@ pub fn pop<T>(v: &mut ~[T]) -> T {
598599
}
599600
}
600601
602+
#[cfg(stage0)]
603+
pub fn pop<T>(v: &mut ~[T]) -> T {
604+
let ln = v.len();
605+
if ln == 0 {
606+
fail!(~"sorry, cannot vec::pop an empty vector")
607+
}
608+
let valptr = ptr::to_mut_unsafe_ptr(&mut v[ln - 1u]);
609+
unsafe {
610+
let mut val = intrinsics::init();
611+
val <-> *valptr;
612+
raw::set_len(v, ln - 1u);
613+
val
614+
}
615+
}
616+
601617
/**
602618
* Remove an element from anywhere in the vector and return it, replacing it
603619
* with the last element. This does not preserve ordering, but is O(1).
@@ -659,6 +675,7 @@ pub fn push_all<T:Copy>(v: &mut ~[T], rhs: &const [T]) {
659675
}
660676
661677
#[inline(always)]
678+
#[cfg(not(stage0))]
662679
pub fn push_all_move<T>(v: &mut ~[T], mut rhs: ~[T]) {
663680
let new_len = v.len() + rhs.len();
664681
reserve(&mut *v, new_len);
@@ -674,7 +691,25 @@ pub fn push_all_move<T>(v: &mut ~[T], mut rhs: ~[T]) {
674691
}
675692
}
676693
694+
#[inline(always)]
695+
#[cfg(stage0)]
696+
pub fn push_all_move<T>(v: &mut ~[T], mut rhs: ~[T]) {
697+
let new_len = v.len() + rhs.len();
698+
reserve(&mut *v, new_len);
699+
unsafe {
700+
do as_mut_buf(rhs) |p, len| {
701+
for uint::range(0, len) |i| {
702+
let mut x = intrinsics::init();
703+
x <-> *ptr::mut_offset(p, i);
704+
push(&mut *v, x);
705+
}
706+
}
707+
raw::set_len(&mut rhs, 0);
708+
}
709+
}
710+
677711
/// Shorten a vector, dropping excess elements.
712+
#[cfg(not(stage0))]
678713
pub fn truncate<T>(v: &mut ~[T], newlen: uint) {
679714
do as_mut_buf(*v) |p, oldlen| {
680715
assert!(newlen <= oldlen);
@@ -689,10 +724,27 @@ pub fn truncate<T>(v: &mut ~[T], newlen: uint) {
689724
unsafe { raw::set_len(&mut *v, newlen); }
690725
}
691726
727+
/// Shorten a vector, dropping excess elements.
728+
#[cfg(stage0)]
729+
pub fn truncate<T>(v: &mut ~[T], newlen: uint) {
730+
do as_mut_buf(*v) |p, oldlen| {
731+
assert!(newlen <= oldlen);
732+
unsafe {
733+
// This loop is optimized out for non-drop types.
734+
for uint::range(newlen, oldlen) |i| {
735+
let mut dropped = intrinsics::init();
736+
dropped <-> *ptr::mut_offset(p, i);
737+
}
738+
}
739+
}
740+
unsafe { raw::set_len(&mut *v, newlen); }
741+
}
742+
692743
/**
693744
* Remove consecutive repeated elements from a vector; if the vector is
694745
* sorted, this removes all duplicates.
695746
*/
747+
#[cfg(not(stage0))]
696748
pub fn dedup<T:Eq>(v: &mut ~[T]) {
697749
unsafe {
698750
if v.len() < 1 { return; }
@@ -726,6 +778,44 @@ pub fn dedup<T:Eq>(v: &mut ~[T]) {
726778
}
727779
}
728780
781+
/**
782+
* Remove consecutive repeated elements from a vector; if the vector is
783+
* sorted, this removes all duplicates.
784+
*/
785+
#[cfg(stage0)]
786+
pub fn dedup<T:Eq>(v: &mut ~[T]) {
787+
unsafe {
788+
if v.len() < 1 { return; }
789+
let mut last_written = 0, next_to_read = 1;
790+
do as_const_buf(*v) |p, ln| {
791+
// We have a mutable reference to v, so we can make arbitrary
792+
// changes. (cf. push and pop)
793+
let p = p as *mut T;
794+
// last_written < next_to_read <= ln
795+
while next_to_read < ln {
796+
// last_written < next_to_read < ln
797+
if *ptr::mut_offset(p, next_to_read) ==
798+
*ptr::mut_offset(p, last_written) {
799+
let mut dropped = intrinsics::init();
800+
dropped <-> *ptr::mut_offset(p, next_to_read);
801+
} else {
802+
last_written += 1;
803+
// last_written <= next_to_read < ln
804+
if next_to_read != last_written {
805+
*ptr::mut_offset(p, last_written) <->
806+
*ptr::mut_offset(p, next_to_read);
807+
}
808+
}
809+
// last_written <= next_to_read < ln
810+
next_to_read += 1;
811+
// last_written < next_to_read <= ln
812+
}
813+
}
814+
// last_written < next_to_read == ln
815+
raw::set_len(v, last_written + 1);
816+
}
817+
}
818+
729819
730820
// Appending
731821
#[inline(always)]

src/libstd/priority_queue.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ pub impl <T:Ord> PriorityQueue<T> {
132132
// vector over the junk element. This reduces the constant factor
133133
// compared to using swaps, which involves twice as many moves.
134134

135+
#[cfg(not(stage0))]
135136
priv fn siftup(&mut self, start: uint, mut pos: uint) {
136137
unsafe {
137138
let new = *ptr::to_unsafe_ptr(&self.data[pos]);
@@ -151,6 +152,28 @@ pub impl <T:Ord> PriorityQueue<T> {
151152
}
152153
}
153154

155+
#[cfg(stage0)]
156+
priv fn siftup(&mut self, start: uint, mut pos: uint) {
157+
unsafe {
158+
let new = *ptr::to_unsafe_ptr(&self.data[pos]);
159+
160+
while pos > start {
161+
let parent = (pos - 1) >> 1;
162+
if new > self.data[parent] {
163+
let mut x = rusti::init();
164+
x <-> self.data[parent];
165+
rusti::move_val_init(&mut self.data[pos], x);
166+
pos = parent;
167+
loop
168+
}
169+
break
170+
}
171+
rusti::move_val_init(&mut self.data[pos], new);
172+
}
173+
}
174+
175+
176+
#[cfg(not(stage0))]
154177
priv fn siftdown_range(&mut self, mut pos: uint, end: uint) {
155178
unsafe {
156179
let start = pos;
@@ -174,6 +197,30 @@ pub impl <T:Ord> PriorityQueue<T> {
174197
}
175198
}
176199

200+
#[cfg(stage0)]
201+
priv fn siftdown_range(&mut self, mut pos: uint, end: uint) {
202+
unsafe {
203+
let start = pos;
204+
let new = *ptr::to_unsafe_ptr(&self.data[pos]);
205+
206+
let mut child = 2 * pos + 1;
207+
while child < end {
208+
let right = child + 1;
209+
if right < end && !(self.data[child] > self.data[right]) {
210+
child = right;
211+
}
212+
let mut x = rusti::init();
213+
x <-> self.data[child];
214+
rusti::move_val_init(&mut self.data[pos], x);
215+
pos = child;
216+
child = 2 * pos + 1;
217+
}
218+
219+
rusti::move_val_init(&mut self.data[pos], new);
220+
self.siftup(start, pos);
221+
}
222+
}
223+
177224
priv fn siftdown(&mut self, pos: uint) {
178225
let len = self.len();
179226
self.siftdown_range(pos, len);

src/libstd/rc.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ pub impl<T: Owned> Rc<T> {
4646
}
4747

4848
#[unsafe_destructor]
49+
#[cfg(not(stage0))]
4950
impl<T: Owned> Drop for Rc<T> {
5051
fn finalize(&self) {
5152
unsafe {
@@ -59,6 +60,22 @@ impl<T: Owned> Drop for Rc<T> {
5960
}
6061
}
6162

63+
#[unsafe_destructor]
64+
#[cfg(stage0)]
65+
impl<T: Owned> Drop for Rc<T> {
66+
fn finalize(&self) {
67+
unsafe {
68+
(*self.ptr).count -= 1;
69+
if (*self.ptr).count == 0 {
70+
let mut x = intrinsics::init();
71+
x <-> *self.ptr;
72+
free(self.ptr as *c_void)
73+
}
74+
}
75+
}
76+
}
77+
78+
6279
impl<T: Owned> Clone for Rc<T> {
6380
#[inline]
6481
fn clone(&self) -> Rc<T> {
@@ -154,6 +171,7 @@ pub impl<T: Owned> RcMut<T> {
154171
}
155172

156173
#[unsafe_destructor]
174+
#[cfg(not(stage0))]
157175
impl<T: Owned> Drop for RcMut<T> {
158176
fn finalize(&self) {
159177
unsafe {
@@ -167,6 +185,21 @@ impl<T: Owned> Drop for RcMut<T> {
167185
}
168186
}
169187

188+
#[unsafe_destructor]
189+
#[cfg(stage0)]
190+
impl<T: Owned> Drop for RcMut<T> {
191+
fn finalize(&self) {
192+
unsafe {
193+
(*self.ptr).count -= 1;
194+
if (*self.ptr).count == 0 {
195+
let mut x = rusti::init();
196+
x <-> *self.ptr;
197+
free(self.ptr as *c_void)
198+
}
199+
}
200+
}
201+
}
202+
170203
impl<T: Owned> Clone for RcMut<T> {
171204
#[inline]
172205
fn clone(&self) -> RcMut<T> {

0 commit comments

Comments
 (0)