From ec87cb113b498e08e2f441565f038ffc6d3b48af Mon Sep 17 00:00:00 2001 From: Robert Obkircher Date: Sat, 15 Feb 2025 15:53:33 +0100 Subject: [PATCH] chapter17: fuzzer compiles again --- fuzz/src/lib.rs | 30 ++++++++++++++------ fuzz/src/script_generator.rs | 4 +-- src/sea_of_nodes/ir_printer.rs | 2 +- src/sea_of_nodes/mod.rs | 4 +-- src/sea_of_nodes/tests/evaluator.rs | 43 ++++++++++++++++++++++++++--- 5 files changed, 65 insertions(+), 18 deletions(-) diff --git a/fuzz/src/lib.rs b/fuzz/src/lib.rs index 4a4b55b..e205edf 100644 --- a/fuzz/src/lib.rs +++ b/fuzz/src/lib.rs @@ -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) { @@ -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, + } + ); } -} \ No newline at end of file +} diff --git a/fuzz/src/script_generator.rs b/fuzz/src/script_generator.rs index 29e98f0..a9a771d 100644 --- a/fuzz/src/script_generator.rs +++ b/fuzz/src/script_generator.rs @@ -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)] @@ -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 { diff --git a/src/sea_of_nodes/ir_printer.rs b/src/sea_of_nodes/ir_printer.rs index 4a3a572..94d1b84 100644 --- a/src/sea_of_nodes/ir_printer.rs +++ b/src/sea_of_nodes/ir_printer.rs @@ -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; diff --git a/src/sea_of_nodes/mod.rs b/src/sea_of_nodes/mod.rs index 153cca2..d5f843e 100644 --- a/src/sea_of_nodes/mod.rs +++ b/src/sea_of_nodes/mod.rs @@ -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; diff --git a/src/sea_of_nodes/tests/evaluator.rs b/src/sea_of_nodes/tests/evaluator.rs index aacb9cb..eace517 100644 --- a/src/sea_of_nodes/tests/evaluator.rs +++ b/src/sea_of_nodes/tests/evaluator.rs @@ -61,7 +61,7 @@ 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, } @@ -69,11 +69,46 @@ impl<'t> Display for ResultObject<'t> { } } -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 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, heap: &Heap) { if let Some(&oid) = objs.get(&this) { if oid != 0 { @@ -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) } } @@ -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),