Skip to content

Commit f455dc1

Browse files
committed
Improve the cycle-collector fuzzer
1 parent c00a7b0 commit f455dc1

File tree

1 file changed

+59
-27
lines changed

1 file changed

+59
-27
lines changed

src/fuzzer/cycles.rs

Lines changed: 59 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,91 @@
11
use std;
2-
import vec;
32
import std::rand;
4-
import option;
3+
import uint::range;
54

65
// random uint less than n
76
fn under(r : rand::rng, n : uint) -> uint { assert n != 0u; r.next() as uint % n }
87

98
// random choice from a vec
10-
fn choice<T: copy>(r : rand::rng, v : [T]) -> T { assert vec::len(v) != 0u; v[under(r, vec::len(v))] }
9+
fn choice<T: copy>(r : rand::rng, v : [const T]) -> T { assert vec::len(v) != 0u; v[under(r, vec::len(v))] }
1110

12-
// 1 in n chance of being true
13-
fn unlikely(r : rand::rng, n : uint) -> bool { under(r, n) == 0u }
11+
// k in n chance of being true
12+
fn likelihood(r : rand::rng, k : uint, n : uint) -> bool { under(r, n) < k }
13+
14+
15+
const iters : uint = 1000u;
16+
const vlen : uint = 100u;
1417

1518
enum maybe_pointy {
16-
no_pointy,
17-
yes_pointy(@pointy),
19+
none,
20+
p(@pointy)
1821
}
1922

2023
type pointy = {
21-
mutable x : maybe_pointy,
22-
mutable y : maybe_pointy,
23-
mutable z : fn@()->()
24+
mut a : maybe_pointy,
25+
mut b : ~maybe_pointy,
26+
mut c : @maybe_pointy,
27+
28+
mut f : fn@()->(),
29+
mut g : fn~()->(),
30+
31+
mut m : [maybe_pointy],
32+
mut n : [mut maybe_pointy],
33+
mut o : {x : int, y : maybe_pointy}
2434
};
35+
// To add: objects; ifaces; anything type-parameterized?
36+
37+
fn empty_pointy() -> @pointy {
38+
ret @{
39+
mut a : none,
40+
mut b : ~none,
41+
mut c : @none,
2542

26-
fn allunder(n: uint, it: block(uint)) {
27-
let i: uint = 0u;
28-
while i < n { it(i); i += 1u; }
43+
mut f : fn@()->(){},
44+
mut g : fn~()->(){},
45+
46+
mut m : [],
47+
mut n : [mut],
48+
mut o : {x : 0, y : none}
49+
}
2950
}
3051

31-
fn nopT(_x : @pointy) { }
32-
fn nop() { }
52+
fn nopP(_x : @pointy) { }
53+
fn nop<T>(_x: T) { }
3354

34-
fn test_cycles(r : rand::rng)
55+
fn test_cycles(r : rand::rng, k: uint, n: uint)
3556
{
36-
const max : uint = 10u;
57+
let v : [mut @pointy] = [mut];
3758

38-
let v : [mutable @pointy] = [mutable];
39-
allunder(max) {|_i|
40-
v += [mutable @{ mutable x : no_pointy, mutable y : no_pointy, mutable z: bind nop() }];
59+
// Create a graph with no edges
60+
range(0u, vlen) {|_i|
61+
v += [mut empty_pointy()];
4162
}
4263

43-
allunder(max) {|i|
44-
v[i].x = yes_pointy(v[under(r, max)]);
45-
v[i].y = yes_pointy(v[under(r, max)]);
46-
v[i].z = bind nopT(v[under(r, max)]);
64+
// Fill in the graph with random edges, with density k/n
65+
range(0u, vlen) {|i|
66+
if (likelihood(r, k, n)) { v[i].a = p(choice(r, v)); }
67+
if (likelihood(r, k, n)) { v[i].b = ~p(choice(r, v)); }
68+
if (likelihood(r, k, n)) { v[i].c = @p(choice(r, v)); }
69+
70+
if (likelihood(r, k, n)) { v[i].f = bind nopP(choice(r, v)); }
71+
if (false) { v[i].g = bind (fn~(_x: @pointy) { })(choice(r, v)); }
72+
// https://github.com/mozilla/rust/issues/1899
73+
74+
if (likelihood(r, k, n)) { v[i].m = [p(choice(r, v))]; }
75+
if (likelihood(r, k, n)) { v[i].n += [mut p(choice(r, v))]; }
76+
if (likelihood(r, k, n)) { v[i].o = {x: 0, y: p(choice(r, v))}; }
4777
}
4878

4979
// Drop refs one at a time
50-
allunder(max) {|i|
51-
v[i] = @{ mutable x : no_pointy, mutable y : no_pointy, mutable z: bind nop() };
80+
range(0u, vlen) {|i|
81+
v[i] = empty_pointy()
5282
}
5383
}
5484

5585
fn main()
5686
{
5787
let r = rand::mk_rng();
58-
test_cycles(r);
88+
range(0u, iters) {|i|
89+
test_cycles(r, i, iters);
90+
}
5991
}

0 commit comments

Comments
 (0)