Skip to content

Commit 0339647

Browse files
committed
libstd: changes to in response to #5656
1 parent 61b9e0e commit 0339647

File tree

7 files changed

+390
-14
lines changed

7 files changed

+390
-14
lines changed

src/libstd/arena.rs

+62-6
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ unsafe fn un_bitpack_tydesc_ptr(p: uint) -> (*TypeDesc, bool) {
171171

172172
pub impl Arena {
173173
// Functions for the POD part of the arena
174-
fn alloc_pod_grow(&self, n_bytes: uint, align: uint) -> *u8 {
174+
priv fn alloc_pod_grow(&self, n_bytes: uint, align: uint) -> *u8 {
175175
// Allocate a new chunk.
176176
let chunk_size = at_vec::capacity(self.pod_head.data);
177177
let new_min_chunk_size = uint::max(n_bytes, chunk_size);
@@ -183,7 +183,7 @@ pub impl Arena {
183183
}
184184

185185
#[inline(always)]
186-
fn alloc_pod_inner(&self, n_bytes: uint, align: uint) -> *u8 {
186+
priv fn alloc_pod_inner(&self, n_bytes: uint, align: uint) -> *u8 {
187187
let head = &mut self.pod_head;
188188

189189
let start = round_up_to(head.fill, align);
@@ -202,7 +202,22 @@ pub impl Arena {
202202
}
203203

204204
#[inline(always)]
205-
fn alloc_pod<T>(&self, op: &fn() -> T) -> &'self T {
205+
#[cfg(stage0)]
206+
priv fn alloc_pod<T>(&self, op: &fn() -> T) -> &'self T {
207+
unsafe {
208+
let tydesc = sys::get_type_desc::<T>();
209+
let ptr = self.alloc_pod_inner((*tydesc).size, (*tydesc).align);
210+
let ptr: *mut T = reinterpret_cast(&ptr);
211+
rusti::move_val_init(&mut (*ptr), op());
212+
return reinterpret_cast(&ptr);
213+
}
214+
}
215+
216+
#[inline(always)]
217+
#[cfg(stage1)]
218+
#[cfg(stage2)]
219+
#[cfg(stage3)]
220+
priv fn alloc_pod<'a, T>(&'a self, op: &fn() -> T) -> &'a T {
206221
unsafe {
207222
let tydesc = sys::get_type_desc::<T>();
208223
let ptr = self.alloc_pod_inner((*tydesc).size, (*tydesc).align);
@@ -213,7 +228,7 @@ pub impl Arena {
213228
}
214229

215230
// Functions for the non-POD part of the arena
216-
fn alloc_nonpod_grow(&self, n_bytes: uint, align: uint) -> (*u8, *u8) {
231+
priv fn alloc_nonpod_grow(&self, n_bytes: uint, align: uint) -> (*u8, *u8) {
217232
// Allocate a new chunk.
218233
let chunk_size = at_vec::capacity(self.head.data);
219234
let new_min_chunk_size = uint::max(n_bytes, chunk_size);
@@ -225,7 +240,7 @@ pub impl Arena {
225240
}
226241

227242
#[inline(always)]
228-
fn alloc_nonpod_inner(&self, n_bytes: uint, align: uint) -> (*u8, *u8) {
243+
priv fn alloc_nonpod_inner(&self, n_bytes: uint, align: uint) -> (*u8, *u8) {
229244
let head = &mut self.head;
230245

231246
let tydesc_start = head.fill;
@@ -247,7 +262,32 @@ pub impl Arena {
247262
}
248263

249264
#[inline(always)]
250-
fn alloc_nonpod<T>(&self, op: &fn() -> T) -> &'self T {
265+
#[cfg(stage0)]
266+
priv fn alloc_nonpod<T>(&self, op: &fn() -> T) -> &'self T {
267+
unsafe {
268+
let tydesc = sys::get_type_desc::<T>();
269+
let (ty_ptr, ptr) =
270+
self.alloc_nonpod_inner((*tydesc).size, (*tydesc).align);
271+
let ty_ptr: *mut uint = reinterpret_cast(&ty_ptr);
272+
let ptr: *mut T = reinterpret_cast(&ptr);
273+
// Write in our tydesc along with a bit indicating that it
274+
// has *not* been initialized yet.
275+
*ty_ptr = reinterpret_cast(&tydesc);
276+
// Actually initialize it
277+
rusti::move_val_init(&mut(*ptr), op());
278+
// Now that we are done, update the tydesc to indicate that
279+
// the object is there.
280+
*ty_ptr = bitpack_tydesc_ptr(tydesc, true);
281+
282+
return reinterpret_cast(&ptr);
283+
}
284+
}
285+
286+
#[inline(always)]
287+
#[cfg(stage1)]
288+
#[cfg(stage2)]
289+
#[cfg(stage3)]
290+
priv fn alloc_nonpod<'a, T>(&'a self, op: &fn() -> T) -> &'a T {
251291
unsafe {
252292
let tydesc = sys::get_type_desc::<T>();
253293
let (ty_ptr, ptr) =
@@ -269,6 +309,7 @@ pub impl Arena {
269309

270310
// The external interface
271311
#[inline(always)]
312+
#[cfg(stage0)]
272313
fn alloc<T>(&self, op: &fn() -> T) -> &'self T {
273314
unsafe {
274315
if !rusti::needs_drop::<T>() {
@@ -278,6 +319,21 @@ pub impl Arena {
278319
}
279320
}
280321
}
322+
323+
// The external interface
324+
#[inline(always)]
325+
#[cfg(stage1)]
326+
#[cfg(stage2)]
327+
#[cfg(stage3)]
328+
fn alloc<'a, T>(&'a self, op: &fn() -> T) -> &'a T {
329+
unsafe {
330+
if !rusti::needs_drop::<T>() {
331+
self.alloc_pod(op)
332+
} else {
333+
self.alloc_nonpod(op)
334+
}
335+
}
336+
}
281337
}
282338

283339
#[test]

src/libstd/bitv.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -437,8 +437,7 @@ pub impl Bitv {
437437
if offset >= bitv.nbits {
438438
0
439439
} else {
440-
// NOTE cannot use bitv[offset] until snapshot
441-
bitv.index(&offset) as u8 << (7 - bit)
440+
bitv[offset] as u8 << (7 - bit)
442441
}
443442
}
444443
@@ -460,8 +459,7 @@ pub impl Bitv {
460459
* Transform self into a [bool] by turning each bit into a bool
461460
*/
462461
fn to_bools(&self) -> ~[bool] {
463-
// NOTE cannot use self[i] until snapshot
464-
vec::from_fn(self.nbits, |i| self.index(&i))
462+
vec::from_fn(self.nbits, |i| self[i])
465463
}
466464
467465
/**

src/libstd/deque.rs

+122
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ impl<T> Mutable for Deque<T> {
4141
}
4242
}
4343

44+
#[cfg(stage0)]
4445
pub impl<T> Deque<T> {
4546
/// Create an empty Deque
4647
fn new() -> Deque<T> {
@@ -51,21 +52,142 @@ pub impl<T> Deque<T> {
5152
/// Return a reference to the first element in the deque
5253
///
5354
/// Fails if the deque is empty
55+
#[cfg(stage0)]
5456
fn peek_front(&self) -> &'self T { get(self.elts, self.lo) }
5557

58+
/// Return a reference to the first element in the deque
59+
///
60+
/// Fails if the deque is empty
61+
#[cfg(stage1)]
62+
#[cfg(stage2)]
63+
#[cfg(stage3)]
64+
fn peek_front<'a>(&'a self) -> &'a T { get(self.elts, self.lo) }
65+
5666
/// Return a reference to the last element in the deque
5767
///
5868
/// Fails if the deque is empty
69+
#[cfg(stage0)]
5970
fn peek_back(&self) -> &'self T { get(self.elts, self.hi - 1u) }
6071

72+
/// Return a reference to the last element in the deque
73+
///
74+
/// Fails if the deque is empty
75+
#[cfg(stage1)]
76+
#[cfg(stage2)]
77+
#[cfg(stage3)]
78+
fn peek_back<'a>(&'a self) -> &'a T { get(self.elts, self.hi - 1u) }
79+
6180
/// Retrieve an element in the deque by index
6281
///
6382
/// Fails if there is no element with the given index
83+
#[cfg(stage0)]
6484
fn get(&self, i: int) -> &'self T {
6585
let idx = (self.lo + (i as uint)) % self.elts.len();
6686
get(self.elts, idx)
6787
}
6888

89+
/// Retrieve an element in the deque by index
90+
///
91+
/// Fails if there is no element with the given index
92+
#[cfg(stage1)]
93+
#[cfg(stage2)]
94+
#[cfg(stage3)]
95+
fn get<'a>(&'a self, i: int) -> &'a T {
96+
let idx = (self.lo + (i as uint)) % self.elts.len();
97+
get(self.elts, idx)
98+
}
99+
100+
/// Iterate over the elements in the deque
101+
fn each(&self, f: &fn(&T) -> bool) {
102+
self.eachi(|_i, e| f(e))
103+
}
104+
105+
/// Iterate over the elements in the deque by index
106+
fn eachi(&self, f: &fn(uint, &T) -> bool) {
107+
for uint::range(0, self.nelts) |i| {
108+
if !f(i, self.get(i as int)) { return; }
109+
}
110+
}
111+
112+
/// Remove and return the first element in the deque
113+
///
114+
/// Fails if the deque is empty
115+
fn pop_front(&mut self) -> T {
116+
let mut result = self.elts[self.lo].swap_unwrap();
117+
self.lo = (self.lo + 1u) % self.elts.len();
118+
self.nelts -= 1u;
119+
result
120+
}
121+
122+
/// Remove and return the last element in the deque
123+
///
124+
/// Fails if the deque is empty
125+
fn pop_back(&mut self) -> T {
126+
if self.hi == 0u {
127+
self.hi = self.elts.len() - 1u;
128+
} else { self.hi -= 1u; }
129+
let mut result = self.elts[self.hi].swap_unwrap();
130+
self.elts[self.hi] = None;
131+
self.nelts -= 1u;
132+
result
133+
}
134+
135+
/// Prepend an element to the deque
136+
fn add_front(&mut self, t: T) {
137+
let oldlo = self.lo;
138+
if self.lo == 0u {
139+
self.lo = self.elts.len() - 1u;
140+
} else { self.lo -= 1u; }
141+
if self.lo == self.hi {
142+
self.elts = grow(self.nelts, oldlo, self.elts);
143+
self.lo = self.elts.len() - 1u;
144+
self.hi = self.nelts;
145+
}
146+
self.elts[self.lo] = Some(t);
147+
self.nelts += 1u;
148+
}
149+
150+
/// Append an element to the deque
151+
fn add_back(&mut self, t: T) {
152+
if self.lo == self.hi && self.nelts != 0u {
153+
self.elts = grow(self.nelts, self.lo, self.elts);
154+
self.lo = 0u;
155+
self.hi = self.nelts;
156+
}
157+
self.elts[self.hi] = Some(t);
158+
self.hi = (self.hi + 1u) % self.elts.len();
159+
self.nelts += 1u;
160+
}
161+
}
162+
163+
#[cfg(stage1)]
164+
#[cfg(stage2)]
165+
#[cfg(stage3)]
166+
pub impl<T> Deque<T> {
167+
/// Create an empty Deque
168+
fn new() -> Deque<T> {
169+
Deque{nelts: 0, lo: 0, hi: 0,
170+
elts: vec::from_fn(initial_capacity, |_| None)}
171+
}
172+
173+
/// Return a reference to the first element in the deque
174+
///
175+
/// Fails if the deque is empty
176+
fn peek_front<'a>(&'a self) -> &'a T { get(self.elts, self.lo) }
177+
178+
/// Return a reference to the last element in the deque
179+
///
180+
/// Fails if the deque is empty
181+
fn peek_back<'a>(&'a self) -> &'a T { get(self.elts, self.hi - 1u) }
182+
183+
/// Retrieve an element in the deque by index
184+
///
185+
/// Fails if there is no element with the given index
186+
fn get<'a>(&'a self, i: int) -> &'a T {
187+
let idx = (self.lo + (i as uint)) % self.elts.len();
188+
get(self.elts, idx)
189+
}
190+
69191
/// Iterate over the elements in the deque
70192
fn each(&self, f: &fn(&T) -> bool) {
71193
self.eachi(|_i, e| f(e))

src/libstd/future.rs

+29-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ pub impl<A:Copy> Future<A> {
5555
}
5656

5757
pub impl<A> Future<A> {
58-
58+
#[cfg(stage0)]
5959
fn get_ref(&self) -> &'self A {
6060
/*!
6161
* Executes the future's closure and then returns a borrowed
@@ -80,6 +80,34 @@ pub impl<A> Future<A> {
8080
}
8181
}
8282
}
83+
84+
#[cfg(stage1)]
85+
#[cfg(stage2)]
86+
#[cfg(stage3)]
87+
fn get_ref<'a>(&'a self) -> &'a A {
88+
/*!
89+
* Executes the future's closure and then returns a borrowed
90+
* pointer to the result. The borrowed pointer lasts as long as
91+
* the future.
92+
*/
93+
unsafe {
94+
match self.state {
95+
Forced(ref mut v) => { return cast::transmute(v); }
96+
Evaluating => fail!(~"Recursive forcing of future!"),
97+
Pending(_) => {}
98+
}
99+
100+
let mut state = Evaluating;
101+
self.state <-> state;
102+
match state {
103+
Forced(_) | Evaluating => fail!(~"Logic error."),
104+
Pending(f) => {
105+
self.state = Forced(f());
106+
self.get_ref()
107+
}
108+
}
109+
}
110+
}
83111
}
84112
85113
pub fn from_value<A>(val: A) -> Future<A> {

src/libstd/priority_queue.rs

+16
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,29 @@ impl<T:Ord> Mutable for PriorityQueue<T> {
5050

5151
pub impl <T:Ord> PriorityQueue<T> {
5252
/// Returns the greatest item in the queue - fails if empty
53+
#[cfg(stage0)]
5354
fn top(&self) -> &'self T { &self.data[0] }
5455

56+
/// Returns the greatest item in the queue - fails if empty
57+
#[cfg(stage1)]
58+
#[cfg(stage2)]
59+
#[cfg(stage3)]
60+
fn top<'a>(&'a self) -> &'a T { &self.data[0] }
61+
5562
/// Returns the greatest item in the queue - None if empty
63+
#[cfg(stage0)]
5664
fn maybe_top(&self) -> Option<&'self T> {
5765
if self.is_empty() { None } else { Some(self.top()) }
5866
}
5967

68+
/// Returns the greatest item in the queue - None if empty
69+
#[cfg(stage1)]
70+
#[cfg(stage2)]
71+
#[cfg(stage3)]
72+
fn maybe_top<'a>(&'a self) -> Option<&'a T> {
73+
if self.is_empty() { None } else { Some(self.top()) }
74+
}
75+
6076
/// Returns the number of elements the queue can hold without reallocating
6177
fn capacity(&self) -> uint { vec::capacity(&self.data) }
6278

0 commit comments

Comments
 (0)