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
4 changes: 4 additions & 0 deletions compiler/noirc_evaluator/src/ssa/interpreter/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ pub enum InternalError {
"Argument count {arguments} to `{intrinsic}` does not match the expected parameter count {parameters}"
)]
IntrinsicArgumentCountMismatch { intrinsic: Intrinsic, arguments: usize, parameters: usize },
#[error(
"Argument count {arguments} to `{intrinsic}` does not match the expected minimum parameter count {parameters}"
)]
IntrinsicMinArgumentCountMismatch { intrinsic: Intrinsic, arguments: usize, parameters: usize },
#[error("Block {block} is missing the terminator instruction")]
BlockMissingTerminator { block: BasicBlockId },
#[error("Cannot call non-function value {value_id} = {value}")]
Expand Down
46 changes: 38 additions & 8 deletions compiler/noirc_evaluator/src/ssa/interpreter/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,20 @@
Ok(Vec::new())
}
Intrinsic::StaticAssert => {
check_argument_count(args, 2, intrinsic)?;
check_argument_count_is_at_least(args, 2, intrinsic)?;

let condition = self.lookup_bool(args[0], "static_assert")?;
if condition {
Ok(Vec::new())
} else {
let message = self.lookup_string(args[1], "static_assert")?;
// Static assert can either have 2 arguments, in which case the second one is a string,
// or it can have more arguments in case fmtstring or some other non-string value is passed.

Check warning on line 59 in compiler/noirc_evaluator/src/ssa/interpreter/intrinsics.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (fmtstring)
// For simplicity, we won't build the dynamic message here.
let message = if args.len() == 2 {
self.lookup_string(args[1], "static_assert")?
} else {
"static_assert failed".to_string()
};
Err(InterpreterError::StaticAssertFailed { condition: args[0], message })
}
}
Expand All @@ -70,11 +77,16 @@
reason: "Intrinsic::ApplyRangeConstraint should have been converted to a RangeCheck instruction",
}))
}
// Both of these are no-ops
Intrinsic::StrAsBytes | Intrinsic::AsWitness => {
Intrinsic::StrAsBytes => {
// This one is a no-op
check_argument_count(args, 1, intrinsic)?;
Ok(vec![self.lookup(args[0])?])
}
Intrinsic::AsWitness => {
// This one is also a no-op, but it doesn't return anything
check_argument_count(args, 1, intrinsic)?;
Ok(vec![])
}
Intrinsic::ToBits(endian) => {
check_argument_count(args, 1, intrinsic)?;
let field = self.lookup_field(args[0], "call to to_bits")?;
Expand Down Expand Up @@ -330,12 +342,14 @@
}))
}
acvm::acir::BlackBoxFunc::Poseidon2Permutation => {
check_argument_count(args, 1, intrinsic)?;
let inputs =
self.lookup_vec_field(args[0], "call Poseidon2Permutation BlackBox")?;
check_argument_count(args, 2, intrinsic)?;
let inputs = self
.lookup_vec_field(args[0], "call Poseidon2Permutation BlackBox (inputs)")?;
let length =
self.lookup_u32(args[1], "call Poseidon2Permutation BlackBox (length)")?;
let solver = bn254_blackbox_solver::Bn254BlackBoxSolver(false);
let result = solver
.poseidon2_permutation(&inputs, inputs.len() as u32)
.poseidon2_permutation(&inputs, length)
.map_err(Self::convert_error)?;
let result = Value::array_from_iter(result, NumericType::NativeField)?;
Ok(vec![result])
Expand Down Expand Up @@ -600,6 +614,22 @@
}
}

fn check_argument_count_is_at_least(
args: &[ValueId],
expected_count: usize,
intrinsic: Intrinsic,
) -> IResult<()> {
if args.len() < expected_count {
Err(InterpreterError::Internal(InternalError::IntrinsicMinArgumentCountMismatch {
intrinsic,
arguments: args.len(),
parameters: expected_count,
}))
} else {
Ok(())
}
}

fn check_slice_can_pop_all_element_types(slice_id: ValueId, slice: &ArrayValue) -> IResult<()> {
let actual_length = slice.elements.borrow().len();
if actual_length >= slice.element_types.len() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ fn test_poseidon() {
let src = "
acir(inline) predicate_pure fn main f0 {
b0(v0: [Field; 4]):
v1 = call poseidon2_permutation(v0) -> [u64; 4]
v1 = call poseidon2_permutation(v0, u32 4) -> [u64; 4]
return v1
}
";
Expand Down
15 changes: 15 additions & 0 deletions compiler/noirc_evaluator/src/ssa/interpreter/tests/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,18 @@ fn to_le_radix() {
);
assert_eq!(value, Value::Numeric(NumericValue::U8(255)));
}

#[test]
fn as_witness() {
let value = expect_value(
"
acir(inline) fn main f0 {
b0():
v0 = add Field 0, Field 1
call as_witness(v0)
return v0
}
",
);
assert_eq!(value, Value::Numeric(NumericValue::Field(1_u128.into())));
}
13 changes: 12 additions & 1 deletion compiler/noirc_evaluator/src/ssa/interpreter/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
pub element_type: Arc<Type>,
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Clone)]
pub struct ArrayValue {
pub elements: Shared<Vec<Value>>,

Expand Down Expand Up @@ -177,7 +177,7 @@

/// Return an uninitialized value of the given type. This is usually a zeroed
/// value but we make no guarantee that it is. This is often used as the default
/// value to return for side-effectful functions like `call` or `array_get` when

Check warning on line 180 in compiler/noirc_evaluator/src/ssa/interpreter/value.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (effectful)
/// side-effects are disabled.
pub(crate) fn uninitialized(typ: &Type, id: ValueId) -> Value {
match typ {
Expand Down Expand Up @@ -430,3 +430,14 @@
write!(f, "rc{} {is_slice}[{elements}]", self.rc.borrow())
}
}

impl PartialEq for ArrayValue {
fn eq(&self, other: &Self) -> bool {
// Don't compare RC
self.elements == other.elements
&& self.element_types == other.element_types
&& self.is_slice == other.is_slice
}
}

impl Eq for ArrayValue {}
30 changes: 1 addition & 29 deletions tooling/nargo_cli/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,18 +118,12 @@
];

/// `nargo interpret` ignored tests, either because they don't currently work or
/// becuase they are too slow to run.

Check warning on line 121 in tooling/nargo_cli/build.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (becuase)
const IGNORED_INTERPRET_EXECUTION_TESTS: [&str; 35] = [
const IGNORED_INTERPRET_EXECUTION_TESTS: [&str; 21] = [
// slow
"regression_4709",
// panic: index out of bounds
"array_dynamic_nested_blackbox_input",
// gives a different result with `--force-brillig`
"array_oob_regression_7965",
// gives a different result with `--force-brillig`
"array_oob_regression_7975",
// panic: FunctionReturnedIncorrectArgCount
"as_witness",
// wrong result
"brillig_block_parameter_liveness",
// panic: BlockArgumentCountMismatch
Expand All @@ -142,30 +136,14 @@
"databus_two_calldata",
// wrong result
"databus_two_calldata_simple",
// panic: IntrinsicArgumentCountMismatch
"fold_numeric_generic_poseidon",
// gives a different result with `--force-brillig`
"global_array_rc_regression_8259",
// panic: IntrinsicArgumentCountMismatch
"hash_to_field",
// panic: Internal(TypeError)
"inline_decompose_hint_brillig_call",
// panic: Internal(TypeError)
"multi_scalar_mul",
// gives a different result with `--force-brillig`
"nested_if_then_block_same_cond",
// panic: IntrinsicArgumentCountMismatch
"no_predicates_numeric_generic_poseidon",
// panic: IntrinsicArgumentCountMismatch
"ram_blowup_regression",
// panic: index out of bounds
"regression_11294",
// panic: Internal(TypeError)
"regression_3889",
// panic: IntrinsicArgumentCountMismatch
"regression_5252",
// panic: IntrinsicArgumentCountMismatch
"regression_7128",
// panic: index out of bounds
"regression_7612",
// gives a wrong result
Expand All @@ -182,14 +160,8 @@
"struct_array_inputs",
// panic: BlockArgumentCountMismatch
"struct_inputs",
// panic: IntrinsicArgumentCountMismatch
"to_be_bytes",
// panic: IntrinsicArgumentCountMismatch
"to_le_bytes",
// panic: BlockArgumentCountMismatch
"tuple_inputs",
// panic: IntrinsicArgumentCountMismatch
"unrolling_regression_8333",
];

/// These tests are ignored because making them work involves a more complex test code that
Expand All @@ -205,7 +177,7 @@
// There's no "src/main.nr" here so it's trickier to make this work
"overlapping_dep_and_mod",
// bug
"poseidonsponge_x5_254",

Check warning on line 180 in tooling/nargo_cli/build.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (poseidonsponge)
// bug
"regression_5045",
// bug
Expand Down Expand Up @@ -812,7 +784,7 @@
writeln!(test_file, "}}").unwrap();
}

/// Here we check, for every program in `test_programs/exeuction_success`, that:

Check warning on line 787 in tooling/nargo_cli/build.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (exeuction)
/// 1. `nargo expand` works on it
/// 2. That the output of the original program is the same as the output of the expanded program
/// (that is, we run `nargo execute` on the original program and the expanded program and compare the output)
Expand Down
Loading