Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions tooling/ast_fuzzer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@ pub struct Config {
pub max_array_size: usize,
/// Maximum size of for loop ranges, which affects unrolling in ACIR.
pub max_loop_size: usize,
/// Maximum call depth for recursive calls.
pub max_call_depth: usize,
/// Whether to choose the backstop for `loop` and `while` randomly.
pub vary_loop_size: bool,
/// Maximum number of recursive calls to make at runtime.
pub max_recursive_calls: usize,
/// Frequency of expressions, which produce a value.
pub expr_freqs: Freqs,
/// Frequency of statements in ACIR functions.
Expand Down Expand Up @@ -81,7 +83,8 @@ impl Default for Config {
max_tuple_size: 5,
max_array_size: 4,
max_loop_size: 10,
max_call_depth: 5,
vary_loop_size: true,
max_recursive_calls: 25,
expr_freqs,
stmt_freqs_acir,
stmt_freqs_brillig,
Expand Down
15 changes: 14 additions & 1 deletion tooling/ast_fuzzer/src/program/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -277,10 +277,18 @@ pub(crate) fn if_else(
}

/// Assign a value to an identifier.
pub(crate) fn assign(ident: Ident, expr: Expression) -> Expression {
pub(crate) fn assign_ident(ident: Ident, expr: Expression) -> Expression {
Expression::Assign(Assign { lvalue: LValue::Ident(ident), expression: Box::new(expr) })
}

/// Assign a value to a mutable reference.
pub(crate) fn assign_ref(ident: Ident, expr: Expression) -> Expression {
let typ = ident.typ.clone();
let lvalue = LValue::Ident(ident);
let lvalue = LValue::Dereference { reference: Box::new(lvalue), element_type: typ };
Expression::Assign(Assign { lvalue, expression: Box::new(expr) })
}

/// Cast an expression to a target type.
pub(crate) fn cast(lhs: Expression, tgt_type: Type) -> Expression {
Expression::Cast(Cast { lhs: Box::new(lhs), r#type: tgt_type, location: Location::dummy() })
Expand Down Expand Up @@ -312,6 +320,11 @@ pub(crate) fn deref(rhs: Expression, tgt_type: Type) -> Expression {
unary(UnaryOp::Dereference { implicitly_added: false }, rhs, tgt_type)
}

/// Reference an expression as a target type
pub(crate) fn ref_mut(rhs: Expression, tgt_type: Type) -> Expression {
unary(UnaryOp::Reference { mutable: true }, rhs, tgt_type)
}

/// Make a unary expression.
pub(crate) fn unary(op: UnaryOp, rhs: Expression, tgt_type: Type) -> Expression {
Expression::Unary(Unary {
Expand Down
32 changes: 18 additions & 14 deletions tooling/ast_fuzzer/src/program/func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -931,19 +931,16 @@
// Increment the index in the beginning of the body.
expr::prepend(
&mut loop_body,
expr::assign(
expr::assign_ident(
idx_ident,
expr::binary(idx_expr.clone(), BinaryOp::Add, expr::u32_literal(1)),
),
);

// Put everything into if/else
let max_loop_size = self.gen_loop_size(u)?;
let loop_body = expr::if_else(
expr::binary(
idx_expr,
BinaryOp::Equal,
expr::u32_literal(self.ctx.config.max_loop_size as u32),
),
expr::binary(idx_expr, BinaryOp::Equal, expr::u32_literal(max_loop_size as u32)),
Expression::Break,
loop_body,
Type::Unit,
Expand Down Expand Up @@ -985,19 +982,16 @@
// Increment the index in the beginning of the body.
expr::prepend(
&mut loop_body,
expr::assign(
expr::assign_ident(
idx_ident,
expr::binary(idx_expr.clone(), BinaryOp::Add, expr::u32_literal(1)),
),
);

// Put everything into if/else
let max_loop_size = self.gen_loop_size(u)?;
let inner_block = Expression::Block(vec![expr::if_else(
expr::binary(
idx_expr,
BinaryOp::Equal,
expr::u32_literal(self.ctx.config.max_loop_size as u32),
),
expr::binary(idx_expr, BinaryOp::Equal, expr::u32_literal(max_loop_size as u32)),
Expression::Break,
loop_body,
Type::Unit,
Expand All @@ -1013,17 +1007,26 @@

Ok(Expression::Block(stmts))
}

fn gen_loop_size(&self, u: &mut Unstructured) -> arbitrary::Result<usize> {
if self.ctx.config.vary_loop_size {
u.choose_index(self.ctx.config.max_loop_size)
} else {
Ok(self.ctx.config.max_loop_size)
}
}
}

#[test]
fn test_loop() {
let mut u = Unstructured::new(&[0u8; 1]);
let mut ctx = Context::default();
ctx.config.max_loop_size = 10;
ctx.add_main_decl(&mut u);
ctx.config.vary_loop_size = false;
ctx.gen_main_decl(&mut u);
let mut fctx = FunctionContext::new(&mut ctx, FuncId(0));

Check warning on line 1027 in tooling/ast_fuzzer/src/program/func.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (fctx)
fctx.budget = 2;

Check warning on line 1028 in tooling/ast_fuzzer/src/program/func.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (fctx)
let loop_code = format!("{}", fctx.gen_loop(&mut u).unwrap()).replace(" ", "");

Check warning on line 1029 in tooling/ast_fuzzer/src/program/func.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (fctx)

println!("{loop_code}");
assert!(
Expand All @@ -1045,9 +1048,10 @@
let mut u = Unstructured::new(&[0u8; 1]);
let mut ctx = Context::default();
ctx.config.max_loop_size = 10;
ctx.add_main_decl(&mut u);
ctx.config.vary_loop_size = false;
ctx.gen_main_decl(&mut u);
let mut fctx = FunctionContext::new(&mut ctx, FuncId(0));

Check warning on line 1053 in tooling/ast_fuzzer/src/program/func.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (fctx)
fctx.budget = 2;

Check warning on line 1054 in tooling/ast_fuzzer/src/program/func.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (fctx)
let while_code = format!("{}", fctx.gen_while(&mut u).unwrap()).replace(" ", "");

println!("{while_code}");
Expand Down
4 changes: 2 additions & 2 deletions tooling/ast_fuzzer/src/program/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ impl Context {

/// Generate and add main (for testing)
#[cfg(test)]
fn add_main_decl(&mut self, u: &mut Unstructured) {
fn gen_main_decl(&mut self, u: &mut Unstructured) {
let d = self.gen_function_decl(u, 0).unwrap();
self.function_declarations.insert(FuncId(0u32), d);
}
Expand Down Expand Up @@ -208,7 +208,7 @@ impl Context {

/// As a post-processing step, identify recursive functions and add a call depth parameter to them.
fn rewrite_functions(&mut self, u: &mut Unstructured) -> arbitrary::Result<()> {
rewrite::add_recursion_depth(self, u)
rewrite::add_recursion_limit(self, u)
}

/// Return the generated [Program].
Expand Down
Loading
Loading