about summary refs log tree commit diff
path: root/src/fuzzer/cycles.rs
blob: 792d3b776861933e688748e908c283080eca1b9c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
use std;
import vec;
import std::rand;
import option;

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

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

// 1 in n chance of being true
fn unlikely(r : rand::rng, n : uint) -> bool { under(r, n) == 0u }

tag maybe_pointy {
  no_pointy;
  yes_pointy(@pointy);
}

type pointy = {
  mutable x : maybe_pointy,
  mutable y : maybe_pointy,
  mutable z : fn()->()
};

fn allunder(n: uint, it: block(uint)) {
    let i: uint = 0u;
    while i < n { it(i); i += 1u; }
}

fn nopT(_x : @pointy) { }
fn nop() { }

fn test_cycles(r : rand::rng)
{
    const max : uint = 10u;

    let v : [mutable @pointy] = [mutable];
    allunder(max) {|i|
        v += [mutable @{ mutable x : no_pointy, mutable y : no_pointy, mutable z: nop }];
    }

    allunder(max) {|i|
        v[i].x = yes_pointy(v[under(r, max)]);
        v[i].y = yes_pointy(v[under(r, max)]);
        v[i].z = bind nopT(v[under(r, max)]);
    }

    // Drop refs one at a time
    allunder(max) {|i|
        v[i] = @{ mutable x : no_pointy, mutable y : no_pointy, mutable z: nop };
    }
}

fn main()
{
    let r = rand::mk_rng();
    test_cycles(r);
}