1 use arbitrary::{Arbitrary, Unstructured};
2 use bigint_presentation_code_register_allocator::{
3 function::{FnFields, Function},
9 use serde_json::{Deserializer, Value};
11 io::{BufWriter, Read, Write},
15 #[derive(Parser, Debug)]
16 #[command(version, about, long_about)]
18 /// dump the input function before attempting register allocation
21 /// write JSON outputs in pretty format
24 /// generate an input function from the random bytes read from stdin using
25 /// the same functionality used for fuzzing
30 #[derive(Serialize, Debug)]
32 DumpInput(&'a Function),
35 #[derive(Serialize, Debug)]
44 fn write_to_stdout(&self, pretty: bool) -> Result<()> {
45 let mut stdout = BufWriter::new(std::io::stdout().lock());
47 serde_json::to_writer_pretty(&mut stdout, self)?;
49 serde_json::to_writer(&mut stdout, self)?;
55 fn from_err(e: impl Into<eyre::Report>) -> Self {
56 Self::Error(format!("{:?}", e.into()))
60 fn process_input(args: &Args, input: Value, exit_code: &mut ExitCode) -> Result<()> {
61 GlobalState::scope(|| -> Result<()> {
62 let function = match serde_json::from_value::<Function>(input) {
65 Output::from_err(e).write_to_stdout(args.pretty)?;
66 *exit_code = ExitCode::FAILURE;
71 Output::Info(Info::DumpInput(&function)).write_to_stdout(args.pretty)?;
77 fn arbitrary_input(input_bytes: &[u8]) -> arbitrary::Result<Value> {
78 GlobalState::scope(|| -> arbitrary::Result<Value> {
80 serde_json::to_value(FnFields::arbitrary_take_rest(Unstructured::new(
83 .expect("serialization shouldn't ever fail"),
88 fn main() -> Result<ExitCode> {
89 let args = Args::parse();
95 let stdin = std::io::stdin().lock();
96 let mut exit_code = ExitCode::SUCCESS;
98 let mut input_bytes = vec![];
99 stdin.take(0x10000).read_to_end(&mut input_bytes)?;
100 if let Ok(input) = arbitrary_input(&input_bytes) {
101 process_input(&args, input, &mut exit_code)?;
103 Output::NeedDifferentInput.write_to_stdout(pretty)?;
104 exit_code = ExitCode::FAILURE;
107 for input in Deserializer::from_reader(stdin).into_iter::<Value>() {
108 process_input(&args, input?, &mut exit_code)?;