Skip to content

Commit

Permalink
chapter17: fuzzer compiles again
Browse files Browse the repository at this point in the history
  • Loading branch information
RobertObkircher committed Feb 15, 2025
1 parent a775185 commit ec87cb1
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 18 deletions.
30 changes: 21 additions & 9 deletions fuzz/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
pub mod script_generator;

use simple_rust::datastructures::arena ::DroplessArena;
use simple_rust::sea_of_nodes::tests::evaluator;
use simple_rust::sea_of_nodes::tests::evaluator::EResult;
use simple_rust::datastructures::arena::DroplessArena;
use simple_rust::sea_of_nodes::parser::Parser;
use simple_rust::sea_of_nodes::tests::evaluator;
use simple_rust::sea_of_nodes::tests::evaluator::{EResult, HeapObject};
use simple_rust::sea_of_nodes::types::Types;

pub fn run_and_compare_eval(source: &str, definitely_valid: bool) {
Expand Down Expand Up @@ -32,11 +32,23 @@ pub fn run_and_compare_eval(source: &str, definitely_valid: bool) {

let timeout = 1000;
for arg in [0, 1, 10] {
let er1 = evaluator::evaluate_with_result(&parser1.nodes, stop1, arg, timeout);
let er2 = evaluator::evaluate_with_result(&parser2.nodes, stop2, arg, timeout);
if er1 == EResult::Timeout || er2 == EResult::Timeout {
let er1 = evaluator::evaluate_with_result(&parser1.nodes, stop1.to_node(), arg, timeout);
let er2 = evaluator::evaluate_with_result(&parser2.nodes, stop2.to_node(), arg, timeout);
let EResult::Value(o1) = er1.1 else {
continue;
}
assert_eq!(er1, er2);
};
let EResult::Value(o2) = er2.1 else {
continue;
};
assert_eq!(
HeapObject {
heap: &er1.0,
object: o1,
},
HeapObject {
heap: &er2.0,
object: o2,
}
);
}
}
}
4 changes: 2 additions & 2 deletions fuzz/src/script_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
//! It is guaranteed to terminate.
use arbitrary::{Arbitrary, Unstructured};
use simple_rust::sea_of_nodes::nodes::ScopeOp;
use simple_rust::sea_of_nodes::nodes::Scope;
use simple_rust::sea_of_nodes::parser::is_keyword;

#[derive(Debug)]
Expand Down Expand Up @@ -152,7 +152,7 @@ impl<'a, 'b> ScriptGenerator<'a, 'b> {
/// Generates a program and writes it into the string builder supplied in the constructor.
/// @return If the program is allowed to be invalid returns if something potentially invalid was generated.
fn gen_program(&mut self) -> arbitrary::Result<()> {
self.variables.push(ScopeOp::ARG0.to_string());
self.variables.push(Scope::ARG0.to_string());
self.curr_scope_start = self.variables.len();
if (self.gen_statements()? & FLAG_STOP) == 0 {
if self.generate_valid || self.random.int_in_range(0..=9)? > 7 {
Expand Down
2 changes: 1 addition & 1 deletion src/sea_of_nodes/ir_printer.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::datastructures::id_set::IdSet;
use crate::sea_of_nodes::nodes::{Cfg, Node, Nodes, Op};
use crate::sea_of_nodes::nodes::{Cfg, Node, Nodes};
use crate::sea_of_nodes::types::{Ty, Types};
use std::borrow::Cow;
use std::collections::HashMap;
Expand Down
4 changes: 2 additions & 2 deletions src/sea_of_nodes/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ pub mod ir_printer;
pub mod location;
pub mod nodes;
pub mod parser;
#[cfg(test)]
mod tests;
#[cfg(any(test, fuzzing))]
pub mod tests;
pub mod types;
43 changes: 39 additions & 4 deletions src/sea_of_nodes/tests/evaluator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,19 +61,54 @@ impl<'t> Obj<'t> {

impl<'t> Display for ResultObject<'t> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
PrintableObject {
HeapObject {
object: self.object,
heap: &self.heap,
}
.fmt(f)
}
}

pub struct PrintableObject<'o, 't> {
pub struct HeapObject<'o, 't> {
pub object: Object,
pub heap: &'o Heap<'t>,
}

impl fmt::Debug for HeapObject<'_, '_> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
Display::fmt(&self, f)
}
}

impl<'o, 't> PartialEq<Self> for HeapObject<'o, 't> {
fn eq(&self, other: &Self) -> bool {
match self.object {
Object::Long(_) | Object::Null | Object::Memory | Object::Double(_) => {
self.object == other.object
}
Object::Obj(o) => {
if let Object::Obj(o2) = other.object {
let obj = &self.heap.objs[o];
let obj2 = &other.heap.objs[o2];
obj.ty == obj2.ty
&& obj.fields.len() == obj2.fields.len()
&& obj.fields.iter().zip(obj2.fields.iter()).all(|(&a, &b)| {
HeapObject {
heap: self.heap,
object: a,
} == HeapObject {
heap: other.heap,
object: b,
}
})
} else {
false
}
}
}
}
}

fn init(this: ObjId, objs: &mut HashMap<ObjId, i32>, heap: &Heap) {
if let Some(&oid) = objs.get(&this) {
if oid != 0 {
Expand Down Expand Up @@ -102,7 +137,7 @@ fn p1(
if let Object::Obj(obj) = obj {
p2(sb, obj, objs, id, indentation, step, sep, heap)
} else {
write!(sb, "{}", PrintableObject { object: obj, heap })?;
write!(sb, "{}", HeapObject { object: obj, heap })?;
Ok(id)
}
}
Expand Down Expand Up @@ -226,7 +261,7 @@ fn obj_to_string(f: &mut Formatter, this: ObjId, heap: &Heap) -> fmt::Result {
p3(f, this, "", "", ",", heap)
}

impl<'a, 't> Display for PrintableObject<'a, 't> {
impl<'a, 't> Display for HeapObject<'a, 't> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self.object {
Object::Long(l) => l.fmt(f),
Expand Down

0 comments on commit ec87cb1

Please sign in to comment.