Skip to content

Commit 7f77092

Browse files
committed
---
yaml --- r: 22693 b: refs/heads/master c: ae094a7 h: refs/heads/master i: 22691: ebf07f5 v: v3
1 parent 3152c90 commit 7f77092

File tree

22 files changed

+208
-93
lines changed

22 files changed

+208
-93
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: c341eb90522294dda6dbce646d1c0a7170a48bfc
2+
refs/heads/master: ae094a7adc8e0f166ea2b137c2940afdb9396bcd
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: cd6f24f9d14ac90d167386a56e7a6ac1f0318195
55
refs/heads/try: ffbe0e0e00374358b789b0037bcb3a577cd218be

trunk/src/libcore/core.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,22 @@ import str::{extensions, str_slice, unique_str};
1010
import vec::extensions;
1111
import vec::{const_vector, copyable_vector, immutable_vector};
1212
import vec::{immutable_copyable_vector, iter_trait_extensions, vec_concat};
13-
import iter::{base_iter, extended_iter, copyable_iter, times};
13+
import iter::{base_iter, extended_iter, copyable_iter, times, timesi};
1414
import option::extensions;
1515
import option_iter::extensions;
1616
import ptr::{extensions, ptr};
1717
import rand::extensions;
1818
import result::extensions;
19-
import int::{num, times};
20-
import i8::{num, times};
21-
import i16::{num, times};
22-
import i32::{num, times};
23-
import i64::{num, times};
24-
import uint::{num, times};
25-
import u8::{num, times};
26-
import u16::{num, times};
27-
import u32::{num, times};
28-
import u64::{num, times};
19+
import int::{num, times, timesi};
20+
import i8::{num, times, timesi};
21+
import i16::{num, times, timesi};
22+
import i32::{num, times, timesi};
23+
import i64::{num, times, timesi};
24+
import uint::{num, times, timesi};
25+
import u8::{num, times, timesi};
26+
import u16::{num, times, timesi};
27+
import u32::{num, times, timesi};
28+
import u64::{num, times, timesi};
2929
import float::num;
3030
import f32::num;
3131
import f64::num;
@@ -34,7 +34,7 @@ import num::num;
3434
export path, option, some, none, unreachable;
3535
export extensions;
3636
// The following exports are the extension impls for numeric types
37-
export num, times;
37+
export num, times, timesi;
3838
// The following exports are the common traits
3939
export str_slice, unique_str;
4040
export const_vector, copyable_vector, immutable_vector;

trunk/src/libcore/int-template.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export range;
1111
export compl;
1212
export abs;
1313
export parse_buf, from_str, to_str, to_str_bytes, str;
14-
export num, ord, eq, times;
14+
export num, ord, eq, times, timesi;
1515

1616
const min_value: T = -1 as T << (inst::bits - 1 as T);
1717
const max_value: T = min_value - 1 as T;
@@ -155,6 +155,23 @@ impl times of iter::times for T {
155155
}
156156
}
157157

158+
impl timesi of iter::timesi for T {
159+
#[inline(always)]
160+
/// Like `times`, but provides an index
161+
fn timesi(it: fn(uint) -> bool) {
162+
let slf = self as uint;
163+
if slf < 0u {
164+
fail #fmt("The .timesi method expects a nonnegative number, \
165+
but found %?", self);
166+
}
167+
let mut i = 0u;
168+
while i < slf {
169+
if !it(i) { break }
170+
i += 1u;
171+
}
172+
}
173+
}
174+
158175
// FIXME: Has alignment issues on windows and 32-bit linux (#2609)
159176
#[test]
160177
#[ignore]

trunk/src/libcore/iter.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ trait extended_iter<A> {
1616
iface times {
1717
fn times(it: fn() -> bool);
1818
}
19+
iface timesi{
20+
fn timesi(it: fn(uint) -> bool);
21+
}
1922

2023
trait copyable_iter<A:copy> {
2124
fn filter_to_vec(pred: fn(A) -> bool) -> ~[A];

trunk/src/libcore/rt.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,6 @@ fn rt_exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char {
3737
ret rustrt::rust_upcall_exchange_malloc(td, size);
3838
}
3939

40-
// NB: Calls to free CANNOT be allowed to fail, as throwing an exception from
41-
// inside a landing pad may corrupt the state of the exception handler. If a
42-
// problem occurs, call exit instead.
4340
#[rt(exchange_free)]
4441
fn rt_exchange_free(ptr: *c_char) {
4542
rustrt::rust_upcall_exchange_free(ptr);
@@ -50,9 +47,6 @@ fn rt_malloc(td: *c_char, size: uintptr_t) -> *c_char {
5047
ret rustrt::rust_upcall_malloc(td, size);
5148
}
5249

53-
// NB: Calls to free CANNOT be allowed to fail, as throwing an exception from
54-
// inside a landing pad may corrupt the state of the exception handler. If a
55-
// problem occurs, call exit instead.
5650
#[rt(free)]
5751
fn rt_free(ptr: *c_char) {
5852
rustrt::rust_upcall_free(ptr);

trunk/src/libcore/sys.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ export refcount;
99
export log_str;
1010
export lock_and_signal, condition, methods;
1111

12+
import task::atomically;
13+
1214
enum type_desc = {
1315
size: uint,
1416
align: uint
@@ -105,13 +107,17 @@ impl methods for lock_and_signal {
105107
unsafe fn lock<T>(f: fn() -> T) -> T {
106108
rustrt::rust_lock_cond_lock(self.lock);
107109
let _r = unlock(self.lock);
108-
f()
110+
do atomically {
111+
f()
112+
}
109113
}
110114

111115
unsafe fn lock_cond<T>(f: fn(condition) -> T) -> T {
112116
rustrt::rust_lock_cond_lock(self.lock);
113117
let _r = unlock(self.lock);
114-
f(condition_(self.lock))
118+
do atomically {
119+
f(condition_(self.lock))
120+
}
115121
}
116122
}
117123

trunk/src/libcore/task.rs

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ export yield;
6060
export failing;
6161
export get_task;
6262
export unkillable;
63+
export atomically;
6364

6465
export local_data_key;
6566
export local_data_pop;
@@ -683,16 +684,36 @@ fn get_task() -> task {
683684
*/
684685
unsafe fn unkillable(f: fn()) {
685686
class allow_failure {
686-
let i: (); // since a class must have at least one field
687-
new(_i: ()) { self.i = (); }
688-
drop { rustrt::rust_task_allow_kill(); }
687+
let t: *rust_task;
688+
new(t: *rust_task) { self.t = t; }
689+
drop { rustrt::rust_task_allow_kill(self.t); }
689690
}
690691

691-
let _allow_failure = allow_failure(());
692-
rustrt::rust_task_inhibit_kill();
692+
let t = rustrt::rust_get_task();
693+
let _allow_failure = allow_failure(t);
694+
rustrt::rust_task_inhibit_kill(t);
693695
f();
694696
}
695697

698+
/**
699+
* A stronger version of unkillable that also inhibits scheduling operations.
700+
* For use with exclusive ARCs, which use pthread mutexes directly.
701+
*/
702+
unsafe fn atomically<U>(f: fn() -> U) -> U {
703+
class defer_interrupts {
704+
let t: *rust_task;
705+
new(t: *rust_task) { self.t = t; }
706+
drop {
707+
rustrt::rust_task_allow_yield(self.t);
708+
rustrt::rust_task_allow_kill(self.t);
709+
}
710+
}
711+
let t = rustrt::rust_get_task();
712+
let _interrupts = defer_interrupts(t);
713+
rustrt::rust_task_inhibit_kill(t);
714+
rustrt::rust_task_inhibit_yield(t);
715+
f()
716+
}
696717

697718
/****************************************************************************
698719
* Internal
@@ -1235,8 +1256,10 @@ extern mod rustrt {
12351256

12361257
fn rust_task_is_unwinding(task: *rust_task) -> bool;
12371258
fn rust_osmain_sched_id() -> sched_id;
1238-
fn rust_task_inhibit_kill();
1239-
fn rust_task_allow_kill();
1259+
fn rust_task_inhibit_kill(t: *rust_task);
1260+
fn rust_task_allow_kill(t: *rust_task);
1261+
fn rust_task_inhibit_yield(t: *rust_task);
1262+
fn rust_task_allow_yield(t: *rust_task);
12401263
fn rust_task_kill_other(task: *rust_task);
12411264
fn rust_task_kill_all(task: *rust_task);
12421265

@@ -1759,6 +1782,21 @@ fn test_unkillable_nested() {
17591782
po.recv();
17601783
}
17611784
1785+
#[test] #[should_fail] #[ignore(cfg(windows))]
1786+
fn test_atomically() {
1787+
unsafe { do atomically { yield(); } }
1788+
}
1789+
1790+
#[test]
1791+
fn test_atomically2() {
1792+
unsafe { do atomically { } } yield(); // shouldn't fail
1793+
}
1794+
1795+
#[test] #[should_fail] #[ignore(cfg(windows))]
1796+
fn test_atomically_nested() {
1797+
unsafe { do atomically { do atomically { } yield(); } }
1798+
}
1799+
17621800
#[test]
17631801
fn test_child_doesnt_ref_parent() {
17641802
// If the child refcounts the parent task, this will stack overflow when

trunk/src/libcore/uint-template.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export range;
1111
export compl;
1212
export to_str, to_str_bytes;
1313
export from_str, from_str_radix, str, parse_buf;
14-
export num, ord, eq, times;
14+
export num, ord, eq, times, timesi;
1515

1616
const min_value: T = 0 as T;
1717
const max_value: T = 0 as T - 1 as T;
@@ -120,6 +120,19 @@ impl times of iter::times for T {
120120
}
121121
}
122122

123+
impl timesi of iter::timesi for T {
124+
#[inline(always)]
125+
/// Like `times`, but with an index, `eachi`-style.
126+
fn timesi(it: fn(uint) -> bool) {
127+
let slf = self as uint;
128+
let mut i = 0u;
129+
while i < slf {
130+
if !it(i) { break }
131+
i += 1u;
132+
}
133+
}
134+
}
135+
123136
/// Parse a string to an int
124137
fn from_str(s: ~str) -> option<T> { parse_buf(str::bytes(s), 10u) }
125138

trunk/src/libsyntax/ast.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -378,8 +378,9 @@ type matcher = spanned<matcher_>;
378378
enum matcher_ {
379379
/* match one token */
380380
mtc_tok(token::token),
381-
/* match repetitions of a sequence: body, separator, zero ok? : */
382-
mtc_rep(~[matcher], option<token::token>, bool),
381+
/* match repetitions of a sequence: body, separator, zero ok?,
382+
lo, hi position-in-match-array used: */
383+
mtc_rep(~[matcher], option<token::token>, bool, uint, uint),
383384
/* parse a Rust NT: name to bind, name of NT, position in match array : */
384385
mtc_bb(ident, ident, uint)
385386
}

trunk/src/libsyntax/ext/tt/earley_parser.rs

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ type matcher_pos = ~{
4141
mut idx: uint,
4242
mut up: matcher_pos_up, // mutable for swapping only
4343
matches: ~[dvec<@arb_depth>],
44+
match_lo: uint, match_hi: uint,
4445
sp_lo: uint,
4546
};
4647

@@ -55,17 +56,25 @@ fn count_names(ms: &[matcher]) -> uint {
5556
vec::foldl(0u, ms, |ct, m| {
5657
ct + alt m.node {
5758
mtc_tok(_) { 0u }
58-
mtc_rep(more_ms, _, _) { count_names(more_ms) }
59+
mtc_rep(more_ms, _, _, _, _) { count_names(more_ms) }
5960
mtc_bb(_,_,_) { 1u }
6061
}})
6162
}
6263

6364
#[warn(no_non_implicitly_copyable_typarams)]
64-
fn new_matcher_pos(ms: ~[matcher], sep: option<token>, lo: uint)
65+
fn initial_matcher_pos(ms: ~[matcher], sep: option<token>, lo: uint)
6566
-> matcher_pos {
67+
let mut match_idx_hi = 0u;
68+
for ms.each() |elt| {
69+
alt elt.node {
70+
mtc_tok(_) {}
71+
mtc_rep(_,_,_,_,hi) { match_idx_hi = hi; } //it is monotonic...
72+
mtc_bb(_,_,pos) { match_idx_hi = pos+1u; } //...so latest is highest
73+
}
74+
}
6675
~{elts: ms, sep: sep, mut idx: 0u, mut up: matcher_pos_up(none),
6776
matches: copy vec::from_fn(count_names(ms), |_i| dvec::dvec()),
68-
sp_lo: lo}
77+
match_lo: 0u, match_hi: match_idx_hi, sp_lo: lo}
6978
}
7079

7180
/* logically, an arb_depth should contain only one kind of nonterminal */
@@ -79,7 +88,7 @@ fn nameize(p_s: parse_sess, ms: ~[matcher], res: ~[@arb_depth])
7988
ret_val: hashmap<ident, @arb_depth>) {
8089
alt m {
8190
{node: mtc_tok(_), span: _} { }
82-
{node: mtc_rep(more_ms, _, _), span: _} {
91+
{node: mtc_rep(more_ms, _, _, _, _), span: _} {
8392
for more_ms.each() |next_m| { n_rec(p_s, next_m, res, ret_val) };
8493
}
8594
{node: mtc_bb(bind_name, _, idx), span: sp} {
@@ -104,7 +113,7 @@ enum parse_result {
104113
fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher])
105114
-> parse_result {
106115
let mut cur_eis = ~[];
107-
vec::push(cur_eis, new_matcher_pos(ms, none, rdr.peek().sp.lo));
116+
vec::push(cur_eis, initial_matcher_pos(ms, none, rdr.peek().sp.lo));
108117
109118
loop {
110119
let mut bb_eis = ~[]; // black-box parsed by parser.rs
@@ -141,10 +150,10 @@ fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher])
141150
// I bet this is a perf problem: we're preemptively
142151
// doing a lot of array work that will get thrown away
143152
// most of the time.
144-
for ei.matches.eachi() |idx, elt| {
145-
let sub = elt.get();
146-
// Some subtrees don't contain the name at all
147-
if sub.len() == 0u { again; }
153+
154+
// Only touch the binders we have actually bound
155+
for uint::range(ei.match_lo, ei.match_hi) |idx| {
156+
let sub = ei.matches[idx].get();
148157
new_pos.matches[idx]
149158
.push(@seq(sub, mk_sp(ei.sp_lo,sp.hi)));
150159
}
@@ -176,10 +185,15 @@ fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher])
176185
} else {
177186
alt copy ei.elts[idx].node {
178187
/* need to descend into sequence */
179-
mtc_rep(matchers, sep, zero_ok) {
188+
mtc_rep(matchers, sep, zero_ok, match_idx_lo, match_idx_hi){
180189
if zero_ok {
181190
let new_ei = copy ei;
182191
new_ei.idx += 1u;
192+
//we specifically matched zero repeats.
193+
for uint::range(match_idx_lo, match_idx_hi) |idx| {
194+
new_ei.matches[idx].push(@seq(~[], sp));
195+
}
196+
183197
vec::push(cur_eis, new_ei);
184198
}
185199

@@ -189,7 +203,9 @@ fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher])
189203
vec::push(cur_eis, ~{
190204
elts: matchers, sep: sep, mut idx: 0u,
191205
mut up: matcher_pos_up(some(ei_t)),
192-
matches: matches, sp_lo: sp.lo
206+
matches: matches,
207+
match_lo: match_idx_lo, match_hi: match_idx_hi,
208+
sp_lo: sp.lo
193209
});
194210
}
195211
mtc_bb(_,_,_) { vec::push(bb_eis, ei) }
@@ -216,9 +232,11 @@ fn parse(sess: parse_sess, cfg: ast::crate_cfg, rdr: reader, ms: ~[matcher])
216232
if (bb_eis.len() > 0u && next_eis.len() > 0u)
217233
|| bb_eis.len() > 1u {
218234
let nts = str::connect(vec::map(bb_eis, |ei| {
219-
alt ei.elts[ei.idx].node
220-
{ mtc_bb(_,name,_) { *name } _ { fail; } }
221-
}), ~" or ");
235+
alt ei.elts[ei.idx].node {
236+
mtc_bb(bind,name,_) {
237+
#fmt["%s ('%s')", *name, *bind]
238+
}
239+
_ { fail; } } }), ~" or ");
222240
ret failure(sp, #fmt[
223241
"Local ambiguity: multiple parsing options: \
224242
built-in NTs %s or %u other options.",

trunk/src/libsyntax/ext/tt/macro_rules.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ fn add_new_extension(cx: ext_ctxt, sp: span, name: ident,
2121
ms(mtc_bb(@~"lhs",@~"mtcs", 0u)),
2222
ms(mtc_tok(FAT_ARROW)),
2323
ms(mtc_bb(@~"rhs",@~"tt", 1u)),
24-
], some(SEMI), false))];
24+
], some(SEMI), false, 0u, 2u))];
2525

2626
let arg_reader = new_tt_reader(cx.parse_sess().span_diagnostic,
2727
cx.parse_sess().interner, none, arg);

0 commit comments

Comments
 (0)