Skip to content
Closed
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
33 changes: 33 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,36 @@ codegen

mutants.out
mutants.out.old


# TODO: remove unused
tooling/nargo_cli/counter.txt
tooling/nargo_cli/kill_tests_if_out_of_space.rb.*
tooling/nargo_fuzz_target/*inputs
tooling/nargo_fuzz_target/collected_outputs/
tooling/nargo_fuzz_target/outputs*
tooling/nargo_fuzz_target/tmp/
tooling/nargo_fuzz_target/unique_crashes/
tooling/ssa_afl_fuzzer/collected_outputs/
tooling/ssa_afl_fuzzer/combined_inputs/
tooling/ssa_afl_fuzzer/defunctionalize_inputs/
tooling/ssa_afl_fuzzer/fuzzer*.log
tooling/ssa_afl_fuzzer/inline_simple_inputs/
tooling/ssa_afl_fuzzer/outputs/
tooling/ssa_afl_fuzzer/outputs2/
tooling/ssa_afl_fuzzer/outputs3/
tooling/ssa_afl_fuzzer/outputs4/
tooling/ssa_afl_fuzzer/outputs5/
tooling/ssa_afl_fuzzer/outputs6/
tooling/ssa_afl_fuzzer/outputs7/
tooling/ssa_afl_fuzzer/outputs8/
tooling/ssa_afl_fuzzer/remove_unreachable_functions_inputs/
tooling/ssa_afl_fuzzer/screen_sessions_at_fuzzer01_etc
tooling/ssa_afl_fuzzer/tt.txt
tooling/ssa_afl_fuzzer/unique_crash_location_representatives/
tooling/ssa_afl_fuzzer/unique_crashes/
tooling/ssa_fuzzer/crash0.log
tooling/ssa_fuzzer/crash1.log
tooling/ssa_fuzzer/fuzz-*.log
tooling/ssa_fuzzer/nohup.out
tooling/unique_crashes
31 changes: 31 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ members = [

"tooling/ssa_fuzzer",
"tooling/ssa_fuzzer/fuzzer",
"tooling/ssa_afl_fuzzer", # cargo-afl fuzzer
"utils/protobuf",
]
default-members = [
Expand Down
1 change: 1 addition & 0 deletions compiler/noirc_evaluator/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ cfg-if.workspace = true
smallvec = { version = "1.13.2", features = ["serde"] }
vec-collections = "0.4.3"
petgraph.workspace = true
stacker = "0.1.21"

[dev-dependencies]
proptest.workspace = true
Expand Down
30 changes: 28 additions & 2 deletions compiler/noirc_evaluator/src/ssa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,11 @@ pub mod function_builder;
pub mod interpreter;
pub mod ir;
pub(crate) mod opt;
#[cfg(test)]
pub(crate) mod parser;

// TODO: only for testing?
// #[cfg(test)]
// pub(crate) mod parser;
pub mod parser;
pub mod ssa_gen;

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -710,6 +713,9 @@ impl SsaBuilder {
}

fn print(mut self, msg: &str) -> Self {
// // TODO: disable this always-print option
// self.ssa_logging = SsaLogging::All;

// Always normalize if we are going to print at least one of the passes
if !matches!(self.ssa_logging, SsaLogging::None) {
self.ssa.normalize_ids();
Expand All @@ -729,6 +735,26 @@ impl SsaBuilder {
if print_ssa_pass {
println!("After {msg}:\n{}", self.ssa);
}

// TODO: BEGIN: quick hack for audit
let counter_path = Path::new("./counter.txt");
// make counter file if missing
if !counter_path.is_file() {
std::fs::write(counter_path, 0u64.to_string()).expect("Unable to write counter file");
}
// read counter from file
let mut counter: u64 = std::fs::read_to_string(counter_path).expect("Unable to read counter file").parse().unwrap();

// write to input_[counter].ssa
let output_file = PathBuf::from(format!("./input_{counter}.ssa"));
std::fs::write(output_file, format!("{}", self.ssa)).expect("Unable to write output file");

// update counter in file
counter += 1;
let counter_str = counter.to_string();
std::fs::write(counter_path, counter_str).expect("Unable to write counter file");
// TODO: END: quick hack for audit

self
}
}
Expand Down
26 changes: 18 additions & 8 deletions compiler/noirc_evaluator/src/ssa/function_builder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,8 @@ impl FunctionBuilder {
.first()
}

#[cfg(test)]
// TODO: used in fuzzing too
// #[cfg(test)]
pub fn insert_mutable_array_set(
&mut self,
array: ValueId,
Expand Down Expand Up @@ -395,7 +396,12 @@ impl FunctionBuilder {
/// Insert a `make_array` instruction to create a new array or slice.
/// Returns the new array value. Expects `typ` to be an array or slice type.
pub fn insert_make_array(&mut self, elements: im::Vector<ValueId>, typ: Type) -> ValueId {
assert!(matches!(typ, Type::Array(..) | Type::Slice(_)));

// TODO: re-enable
if !matches!(typ, Type::Array(..) | Type::Slice(_)) {
std::process::exit(0);
}
// assert!(matches!(typ, Type::Array(..) | Type::Slice(_)));
self.insert_instruction(Instruction::MakeArray { elements, typ }, None).first()
}

Expand Down Expand Up @@ -551,17 +557,21 @@ fn validate_numeric_type(typ: &NumericType) {
NumericType::Signed { bit_size } => match bit_size {
8 | 16 | 32 | 64 => (),
_ => {
panic!(
"Invalid bit size for signed numeric type: {bit_size}. Expected one of 8, 16, 32 or 64."
);
// TODO: re-enable
std::process::exit(0);
// panic!(
// "Invalid bit size for signed numeric type: {bit_size}. Expected one of 8, 16, 32 or 64."
// );
}
},
NumericType::Unsigned { bit_size } => match bit_size {
1 | 8 | 16 | 32 | 64 | 128 => (),
_ => {
panic!(
"Invalid bit size for unsigned numeric type: {bit_size}. Expected one of 1, 8, 16, 32, 64, or 128."
);
// TODO: re-enable
std::process::exit(0);
// panic!(
// "Invalid bit size for unsigned numeric type: {bit_size}. Expected one of 1, 8, 16, 32, 64, or 128."
// );
}
},
_ => (),
Expand Down
4 changes: 2 additions & 2 deletions compiler/noirc_evaluator/src/ssa/interpreter/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub(super) const MAX_SIGNED_BIT_SIZE: u32 = 64;
pub(super) const MAX_UNSIGNED_BIT_SIZE: u32 = 128;

#[derive(Debug, Error)]
pub(crate) enum InterpreterError {
pub enum InterpreterError {
/// These errors are all the result from malformed input SSA
#[error("{0}")]
Internal(InternalError),
Expand Down Expand Up @@ -60,7 +60,7 @@ pub(crate) enum InterpreterError {

/// These errors can only result from interpreting malformed SSA
#[derive(Debug, Error)]
pub(crate) enum InternalError {
pub enum InternalError {
#[error(
"Argument count {arguments} to block {block} does not match the expected parameter count {parameters}"
)]
Expand Down
22 changes: 17 additions & 5 deletions compiler/noirc_evaluator/src/ssa/interpreter/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ impl Interpreter<'_> {
Intrinsic::SliceInsert => self.slice_insert(args),
Intrinsic::SliceRemove => self.slice_remove(args),
Intrinsic::ApplyRangeConstraint => {
todo!("Intrinsic::ApplyRangeConstraint is currently unimplemented")
// TODO
// todo!("Intrinsic::ApplyRangeConstraint is currently unimplemented")
std::process::exit(0)
}
// Both of these are no-ops
Intrinsic::StrAsBytes | Intrinsic::AsWitness => {
Expand All @@ -82,16 +84,26 @@ impl Interpreter<'_> {
let radix = self.lookup_u32(args[1], "call to to_bits")?;
self.to_radix(endian, args[0], field, radix, results[0])
}
Intrinsic::BlackBox(black_box_func) => {
todo!("Intrinsic::BlackBox({black_box_func}) is currently unimplemented")
// TODO
// Intrinsic::BlackBox(black_box_func) => {
Intrinsic::BlackBox(_black_box_func) => {
// TODO
// todo!("Intrinsic::BlackBox({black_box_func}) is currently unimplemented")
std::process::exit(0)
}
Intrinsic::Hint(_) => {
// TODO
// todo!("Intrinsic::Hint is currently unimplemented")
std::process::exit(0)
}
Intrinsic::Hint(_) => todo!("Intrinsic::Hint is currently unimplemented"),
Intrinsic::IsUnconstrained => {
check_argument_count(args, 0, intrinsic)?;
Ok(vec![Value::bool(self.in_unconstrained_context())])
}
Intrinsic::DerivePedersenGenerators => {
todo!("Intrinsic::DerivePedersenGenerators is currently unimplemented")
// TODO
// todo!("Intrinsic::DerivePedersenGenerators is currently unimplemented")
std::process::exit(0)
}
Intrinsic::FieldLessThan => {
if !self.in_unconstrained_context() {
Expand Down
30 changes: 20 additions & 10 deletions compiler/noirc_evaluator/src/ssa/interpreter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ type IResults = IResult<Vec<Value>>;

#[allow(unused)]
impl Ssa {
pub(crate) fn interpret(&self, args: Vec<Value>) -> IResults {
pub fn interpret(&self, args: Vec<Value>) -> IResults {
self.interpret_function(self.main_id, args)
}

Expand Down Expand Up @@ -223,7 +223,9 @@ impl<'ssa> Interpreter<'ssa> {
super::ir::value::Value::Instruction { .. }
| super::ir::value::Value::Param { .. }
| super::ir::value::Value::Global(_) => {
unreachable!("`{id}` should already be in scope")
// TODO
// unreachable!("`{id}` should already be in scope")
std::process::exit(0)
}
}
}
Expand Down Expand Up @@ -653,7 +655,9 @@ impl<'ssa> Interpreter<'ssa> {
let element = if self.side_effects_enabled() {
let array = self.lookup_array_or_slice(array, "array get")?;
let index = self.lookup_u32(index, "array get index")?;
array.elements.borrow()[index as usize].clone()
// TODO: error for index out of bounds
// array.elements.borrow()[index as usize].clone()
array.elements.borrow().get(index as usize).unwrap_or_else(|| { std::process::exit(0) }).clone()
} else {
let typ = self.dfg().type_of_value(result);
Value::uninitialized(&typ, result)
Expand All @@ -680,11 +684,15 @@ impl<'ssa> Interpreter<'ssa> {
if self.in_unconstrained_context() { *array.rc.borrow() == 1 } else { mutable };

if should_mutate {
array.elements.borrow_mut()[index as usize] = value;
// TODO: error for index out of bounds
// array.elements.borrow_mut()[index as usize] = value;
array.elements.borrow_mut().get_mut(index as usize).map(|element| *element = value).unwrap_or_else(|| { std::process::exit(0) });
Value::ArrayOrSlice(array.clone())
} else {
let mut elements = array.elements.borrow().to_vec();
elements[index as usize] = value;
// TODO: error for index out of bounds
// elements[index as usize] = value;
elements.get_mut(index as usize).map(|element| *element = value).unwrap_or_else(|| { std::process::exit(0) });
let elements = Shared::new(elements);
let rc = Shared::new(1);
let element_types = array.element_types.clone();
Expand Down Expand Up @@ -1124,7 +1132,7 @@ where
{
let value_u128 = u128::from(value);
let bit_mask = match bit_size.cmp(&MAX_UNSIGNED_BIT_SIZE) {
Ordering::Less => (1u128 << bit_size) - 1,
Ordering::Less => (1u128.checked_shl(bit_size).unwrap_or_else(|| { std::process::exit(0) })) - 1,
Ordering::Equal => u128::MAX,
Ordering::Greater => {
return Err(internal(InternalError::InvalidUnsignedTruncateBitSize { bit_size }));
Expand All @@ -1145,13 +1153,15 @@ where
{
let mut value_i128 = i128::from(value);
if value_i128 < 0 {
let max = 1i128 << (bit_size - 1);
value_i128 += max;
if bit_size > MAX_SIGNED_BIT_SIZE {
return Err(internal(InternalError::InvalidSignedTruncateBitSize { bit_size }));
// TODO: this check needs to be before the '<<'
// return Err(internal(InternalError::InvalidSignedTruncateBitSize { bit_size }));
std::process::exit(0)
}
let max = 1i128.checked_shl(bit_size - 1).unwrap_or_else(|| { std::process::exit(0) });
value_i128 += max;

let mask = (1i128 << bit_size) - 1;
let mask = (1i128.checked_shl(bit_size).unwrap_or_else(|| { std::process::exit(0) })) - 1;
let result = (value_i128 & mask) - max;

Ok(T::try_from(result).expect(
Expand Down
Loading
Loading