Pieces of a fuzzer, WIP
This commit is contained in:
parent
6d3513eaee
commit
e91f8b5db2
38
src/fuzzer/ast_match.rs
Normal file
38
src/fuzzer/ast_match.rs
Normal file
@ -0,0 +1,38 @@
|
||||
use std;
|
||||
import std::ivec;
|
||||
|
||||
fn ivec_equal[T](&T[] v, &T[] u, fn (&T, &T) -> bool element_equality_test) -> bool {
|
||||
auto Lv = ivec::len(v);
|
||||
if (Lv != ivec::len(u)) {
|
||||
ret false;
|
||||
}
|
||||
auto i = 0u;
|
||||
while (i < Lv) {
|
||||
if (!element_equality_test(v.(i), u.(i))) {
|
||||
ret false;
|
||||
}
|
||||
i += 1u;
|
||||
}
|
||||
ret true;
|
||||
}
|
||||
|
||||
fn builtin_equal[T](&T a, &T b) -> bool {
|
||||
ret a == b;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// These pass
|
||||
assert builtin_equal(5, 5);
|
||||
assert !builtin_equal(5, 4);
|
||||
|
||||
// This passes
|
||||
assert !ivec_equal(~[5, 5], ~[5], builtin_equal);
|
||||
|
||||
// These crash
|
||||
// https://github.com/graydon/rust/issues/633
|
||||
assert !ivec_equal(~[5, 5], ~[5, 4], builtin_equal);
|
||||
assert !ivec_equal(~[5, 5], ~[4, 5], builtin_equal);
|
||||
assert ivec_equal(~[5, 5], ~[5, 5], builtin_equal);
|
||||
|
||||
log_err "Pass";
|
||||
}
|
@ -1,3 +1,6 @@
|
||||
use std;
|
||||
use rustc;
|
||||
|
||||
import std::fs;
|
||||
import std::getopts;
|
||||
import std::getopts::optopt;
|
||||
@ -5,56 +8,57 @@
|
||||
import std::getopts::opt_str;
|
||||
import std::io;
|
||||
import std::vec;
|
||||
import std::ivec;
|
||||
import std::str;
|
||||
|
||||
type src_gen = iter() -> str;
|
||||
import rustc::back::link;
|
||||
import rustc::syntax::ast;
|
||||
import driver = rustc::driver::rustc; // see https://github.com/graydon/rust/issues/624
|
||||
import rustc::driver::session;
|
||||
|
||||
iter dir_src_gen(str dir) -> str {
|
||||
}
|
||||
|
||||
fn usage(str binary) {
|
||||
io::stdout().write_line("usage");
|
||||
}
|
||||
|
||||
type session = rec(str srcdir);
|
||||
|
||||
fn make_session(vec[str] args) -> session {
|
||||
// Directory of rust source files to use as input
|
||||
auto opt_src = "src";
|
||||
|
||||
auto binary = vec::shift[str](args);
|
||||
auto opts = [optopt(opt_src)];
|
||||
auto match;
|
||||
alt (getopts::getopts(args, opts)) {
|
||||
case (getopts::failure(?f)) {
|
||||
log_err #fmt("error: %s", getopts::fail_str(f));
|
||||
fail;
|
||||
fn find_rust_files(&mutable str[] files, str root) {
|
||||
for (str filename in fs::list_dir(root)) {
|
||||
if (str::ends_with(filename, ".rs")) {
|
||||
files += ~[filename];
|
||||
}
|
||||
case (getopts::success(?m)) {
|
||||
match = m;
|
||||
}
|
||||
};
|
||||
|
||||
if (!opt_present(match, opt_src)) {
|
||||
usage(binary);
|
||||
fail;
|
||||
}
|
||||
|
||||
auto srcdir = opt_str(match, opt_src);
|
||||
|
||||
ret rec(srcdir = srcdir);
|
||||
}
|
||||
|
||||
fn log_session(session sess) {
|
||||
log #fmt("srcdir: %s", sess.srcdir);
|
||||
}
|
||||
|
||||
fn run_session(session sess) {
|
||||
}
|
||||
|
||||
fn main(vec[str] args) {
|
||||
auto sess = make_session(args);
|
||||
log_session(sess);
|
||||
run_session(sess);
|
||||
auto files = ~[];
|
||||
auto root = "/Users/jruderman/code/rust/src/lib/"; // XXX
|
||||
find_rust_files(files, root); // not using driver::time here because that currently screws with passing-a-mutable-array
|
||||
|
||||
auto binary = vec::shift[str](args);
|
||||
auto binary_dir = fs::dirname(binary);
|
||||
|
||||
let @session::options sopts =
|
||||
@rec(library=false,
|
||||
static=false,
|
||||
optimize=0u,
|
||||
debuginfo=false,
|
||||
verify=true,
|
||||
run_typestate=true,
|
||||
save_temps=false,
|
||||
stats=false,
|
||||
time_passes=false,
|
||||
time_llvm_passes=false,
|
||||
output_type=link::output_type_bitcode,
|
||||
library_search_paths=[binary_dir + "/lib"],
|
||||
sysroot=driver::get_default_sysroot(binary),
|
||||
cfg=~[],
|
||||
test=false);
|
||||
|
||||
let session::session sess = driver::build_session(sopts);
|
||||
|
||||
log_err ivec::len(files);
|
||||
for (str file in files) {
|
||||
log_err file;
|
||||
// Can't use parse_input here because of https://github.com/graydon/rust/issues/632 :(
|
||||
//auto crate = driver::parse_input(sess, ~[], file);
|
||||
//let @ast::crate crate = driver::time(true, "parsing " + file, bind driver::parse_input(sess, ~[], file));
|
||||
}
|
||||
}
|
||||
|
||||
// Local Variables:
|
||||
|
98
src/fuzzer/ivec_fuzz.rs
Normal file
98
src/fuzzer/ivec_fuzz.rs
Normal file
@ -0,0 +1,98 @@
|
||||
/*
|
||||
|
||||
Idea: provide functions for 'exhaustive' and 'random' modification of vecs.
|
||||
|
||||
two functions, "return all edits" and "return a random edit" <-- leaning toward this model
|
||||
or
|
||||
two functions, "return the number of possible edits" and "return edit #n"
|
||||
|
||||
It would be nice if this could be data-driven, so the two functions could share information:
|
||||
type vec_modifier = rec(fn (&int[] v, uint i) -> int[] fun, uint lo, uint di);
|
||||
const vec_modifier[] vec_modifiers = ~[rec(fun=vec_omit, 0u, 1u), ...];
|
||||
But that gives me "error: internal compiler error unimplemented consts that's not a plain literal".
|
||||
https://github.com/graydon/rust/issues/570
|
||||
|
||||
vec_edits is not an iter because iters might go away and:
|
||||
https://github.com/graydon/rust/issues/639
|
||||
|
||||
vec_omit and friends are not type-parameterized because:
|
||||
https://github.com/graydon/rust/issues/640
|
||||
|
||||
*/
|
||||
|
||||
use std;
|
||||
import std::ivec;
|
||||
import std::ivec::slice;
|
||||
import std::ivec::len;
|
||||
import std::int;
|
||||
|
||||
//fn vec_reverse(&int[] v) -> int[] { ... }
|
||||
|
||||
fn vec_omit (&int[] v, uint i) -> int[] { slice(v, 0u, i) + slice(v, i+1u, len(v)) }
|
||||
fn vec_dup (&int[] v, uint i) -> int[] { slice(v, 0u, i) + ~[v.(i)] + slice(v, i, len(v)) }
|
||||
fn vec_swadj (&int[] v, uint i) -> int[] { slice(v, 0u, i) + ~[v.(i+1u), v.(i)] + slice(v, i+2u, len(v)) }
|
||||
fn vec_prefix (&int[] v, uint i) -> int[] { slice(v, 0u, i) }
|
||||
fn vec_suffix (&int[] v, uint i) -> int[] { slice(v, i, len(v)) }
|
||||
|
||||
fn vec_poke (&int[] v, uint i, int x) -> int[] { slice(v, 0u, i) + ~[x] + slice(v, i+1u, len(v)) }
|
||||
fn vec_insert (&int[] v, uint i, int x) -> int[] { slice(v, 0u, i) + ~[x] + slice(v, i, len(v)) }
|
||||
|
||||
// Iterates over 0...length, skipping the specified number on each side.
|
||||
iter ix(uint skip_low, uint skip_high, uint length) -> uint { let uint i = skip_low; while (i + skip_high <= length) { put i; i += 1u; } }
|
||||
|
||||
// Returns a bunch of modified versions of v, some of which introduce new elements (borrowed from xs).
|
||||
fn vec_edits(&int[] v, &int[] xs) -> int[][] {
|
||||
let int[][] edits = ~[];
|
||||
let uint Lv = len(v);
|
||||
|
||||
if (Lv != 1u) { edits += ~[~[]]; } // When Lv == 1u, this is redundant with omit
|
||||
//if (Lv >= 3u) { edits += ~[vec_reverse(v)]; }
|
||||
|
||||
for each (uint i in ix(0u, 1u, Lv)) { edits += ~[vec_omit (v, i)]; }
|
||||
for each (uint i in ix(0u, 1u, Lv)) { edits += ~[vec_dup (v, i)]; }
|
||||
for each (uint i in ix(0u, 2u, Lv)) { edits += ~[vec_swadj (v, i)]; }
|
||||
for each (uint i in ix(1u, 2u, Lv)) { edits += ~[vec_prefix(v, i)]; }
|
||||
for each (uint i in ix(2u, 1u, Lv)) { edits += ~[vec_suffix(v, i)]; }
|
||||
|
||||
for each (uint j in ix(0u, 1u, len(xs))) {
|
||||
for each (uint i in ix(0u, 1u, Lv)) { edits += ~[vec_poke (v, i, xs.(j))]; }
|
||||
for each (uint i in ix(0u, 0u, Lv)) { edits += ~[vec_insert(v, i, xs.(j))]; }
|
||||
}
|
||||
|
||||
edits
|
||||
}
|
||||
|
||||
// Would be nice if this were built in: https://github.com/graydon/rust/issues/424
|
||||
fn vec_to_str(&int[] v) -> str {
|
||||
auto i = 0u;
|
||||
auto s = "[";
|
||||
while (i < len(v)) {
|
||||
s += int::str(v.(i));
|
||||
if (i + 1u < len(v)) {
|
||||
s += ", "
|
||||
}
|
||||
i += 1u;
|
||||
}
|
||||
ret s + "]";
|
||||
}
|
||||
|
||||
fn show_edits(&int[] a, &int[] xs) {
|
||||
log_err "=== Edits of " + vec_to_str(a) + " ===";
|
||||
auto b = vec_edits(a, xs);
|
||||
for each (uint i in ix(0u, 1u, len(b))) {
|
||||
log_err vec_to_str(b.(i));
|
||||
}
|
||||
}
|
||||
|
||||
fn demo_edits() {
|
||||
auto xs = ~[7, 8];
|
||||
show_edits(~[], xs);
|
||||
show_edits(~[1], xs);
|
||||
show_edits(~[1,2], xs);
|
||||
show_edits(~[1,2,3], xs);
|
||||
show_edits(~[1,2,3,4], xs);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
demo_edits();
|
||||
}
|
Loading…
Reference in New Issue
Block a user