diff --git a/avm-transpiler/src/transpile_contract.rs b/avm-transpiler/src/transpile_contract.rs index 10b9367a4abd..0c38dbe1e0b9 100644 --- a/avm-transpiler/src/transpile_contract.rs +++ b/avm-transpiler/src/transpile_contract.rs @@ -6,11 +6,8 @@ use serde::{Deserialize, Serialize}; use acvm::acir::circuit::Program; use noirc_errors::debug_info::ProgramDebugInfo; -use crate::transpile::{ - brillig_to_avm, map_brillig_pcs_to_avm_pcs, patch_assert_message_pcs, patch_debug_info_pcs, -}; -use crate::utils::{extract_brillig_from_acir_program, extract_static_assert_messages}; -use fxhash::FxHashMap as HashMap; +use crate::transpile::{brillig_to_avm, map_brillig_pcs_to_avm_pcs, patch_debug_info_pcs}; +use crate::utils::extract_brillig_from_acir_program; /// Representation of a contract with some transpiled functions #[derive(Debug, Serialize, Deserialize)] @@ -51,7 +48,6 @@ pub struct AvmContractFunctionArtifact { )] pub debug_symbols: ProgramDebugInfo, pub brillig_names: Vec, - pub assert_messages: HashMap, } /// Representation of an ACIR contract function but with @@ -96,16 +92,11 @@ impl From for TranspiledContractArtifact { // Extract Brillig Opcodes from acir let acir_program = function.bytecode; let brillig_bytecode = extract_brillig_from_acir_program(&acir_program); - let assert_messages = extract_static_assert_messages(&acir_program); info!("Extracted Brillig program has {} instructions", brillig_bytecode.len()); // Map Brillig pcs to AVM pcs (index is Brillig PC, value is AVM PC) let brillig_pcs_to_avm_pcs = map_brillig_pcs_to_avm_pcs(brillig_bytecode); - // Patch the assert messages with updated PCs - let assert_messages = - patch_assert_message_pcs(assert_messages, &brillig_pcs_to_avm_pcs); - // Transpile to AVM let avm_bytecode = brillig_to_avm(brillig_bytecode, &brillig_pcs_to_avm_pcs); @@ -132,7 +123,6 @@ impl From for TranspiledContractArtifact { bytecode: base64::prelude::BASE64_STANDARD.encode(avm_bytecode), debug_symbols: ProgramDebugInfo { debug_infos }, brillig_names: function.brillig_names, - assert_messages, }, )); } else { diff --git a/avm-transpiler/src/utils.rs b/avm-transpiler/src/utils.rs index 3f5269f5daa8..018276e4b6d9 100644 --- a/avm-transpiler/src/utils.rs +++ b/avm-transpiler/src/utils.rs @@ -1,11 +1,9 @@ -use fxhash::FxHashMap as HashMap; - use acvm::acir::circuit::brillig::BrilligFunctionId; use acvm::{AcirField, FieldElement}; use log::{debug, info, trace}; use acvm::acir::brillig::Opcode as BrilligOpcode; -use acvm::acir::circuit::{AssertionPayload, Opcode, Program}; +use acvm::acir::circuit::{Opcode, Program}; use crate::instructions::{AvmInstruction, AvmOperand}; use crate::opcodes::AvmOpcode; @@ -39,33 +37,6 @@ pub fn extract_brillig_from_acir_program( &program.unconstrained_functions[0].bytecode } -/// Assertion messages that are static strings are stored in the assert_messages map of the ACIR program. -pub fn extract_static_assert_messages(program: &Program) -> HashMap { - assert_eq!( - program.functions.len(), - 1, - "An AVM program should have only a single ACIR function with a 'BrilligCall'" - ); - let main_function = &program.functions[0]; - main_function - .assert_messages - .iter() - .filter_map(|(location, payload)| { - if let AssertionPayload::StaticString(static_string) = payload { - Some(( - location - .to_brillig_location() - .expect("Assert message is not for the brillig function") - .0, - static_string.clone(), - )) - } else { - None - } - }) - .collect() -} - /// Print inputs, outputs, and instructions in a Brillig program pub fn dbg_print_brillig_program(brillig_bytecode: &[BrilligOpcode]) { trace!("Printing Brillig program..."); diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp index d02312f3d212..a96a5531a0e1 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp @@ -1,6 +1,5 @@ #pragma once -#include "barretenberg/common/throw_or_abort.hpp" #include "bincode.hpp" #include "serde.hpp" @@ -1276,24 +1275,8 @@ struct ExpressionOrMemory { }; struct AssertionPayload { - - struct StaticString { - std::string value; - - friend bool operator==(const StaticString&, const StaticString&); - std::vector bincodeSerialize() const; - static StaticString bincodeDeserialize(std::vector); - }; - - struct Dynamic { - std::tuple> value; - - friend bool operator==(const Dynamic&, const Dynamic&); - std::vector bincodeSerialize() const; - static Dynamic bincodeDeserialize(std::vector); - }; - - std::variant value; + uint64_t error_selector; + std::vector payload; friend bool operator==(const AssertionPayload&, const AssertionPayload&); std::vector bincodeSerialize() const; @@ -1394,7 +1377,10 @@ namespace Program { inline bool operator==(const AssertionPayload& lhs, const AssertionPayload& rhs) { - if (!(lhs.value == rhs.value)) { + if (!(lhs.error_selector == rhs.error_selector)) { + return false; + } + if (!(lhs.payload == rhs.payload)) { return false; } return true; @@ -1425,7 +1411,8 @@ void serde::Serializable::serialize(const Program::As Serializer& serializer) { serializer.increase_container_depth(); - serde::Serializable::serialize(obj.value, serializer); + serde::Serializable::serialize(obj.error_selector, serializer); + serde::Serializable::serialize(obj.payload, serializer); serializer.decrease_container_depth(); } @@ -1435,107 +1422,14 @@ Program::AssertionPayload serde::Deserializable::dese { deserializer.increase_container_depth(); Program::AssertionPayload obj; - obj.value = serde::Deserializable::deserialize(deserializer); + obj.error_selector = serde::Deserializable::deserialize(deserializer); + obj.payload = serde::Deserializable::deserialize(deserializer); deserializer.decrease_container_depth(); return obj; } namespace Program { -inline bool operator==(const AssertionPayload::StaticString& lhs, const AssertionPayload::StaticString& rhs) -{ - if (!(lhs.value == rhs.value)) { - return false; - } - return true; -} - -inline std::vector AssertionPayload::StaticString::bincodeSerialize() const -{ - auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); - return std::move(serializer).bytes(); -} - -inline AssertionPayload::StaticString AssertionPayload::StaticString::bincodeDeserialize(std::vector input) -{ - auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); - if (deserializer.get_buffer_offset() < input.size()) { - throw_or_abort("Some input bytes were not read"); - } - return value; -} - -} // end of namespace Program - -template <> -template -void serde::Serializable::serialize( - const Program::AssertionPayload::StaticString& obj, Serializer& serializer) -{ - serde::Serializable::serialize(obj.value, serializer); -} - -template <> -template -Program::AssertionPayload::StaticString serde::Deserializable::deserialize( - Deserializer& deserializer) -{ - Program::AssertionPayload::StaticString obj; - obj.value = serde::Deserializable::deserialize(deserializer); - return obj; -} - -namespace Program { - -inline bool operator==(const AssertionPayload::Dynamic& lhs, const AssertionPayload::Dynamic& rhs) -{ - if (!(lhs.value == rhs.value)) { - return false; - } - return true; -} - -inline std::vector AssertionPayload::Dynamic::bincodeSerialize() const -{ - auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); - return std::move(serializer).bytes(); -} - -inline AssertionPayload::Dynamic AssertionPayload::Dynamic::bincodeDeserialize(std::vector input) -{ - auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); - if (deserializer.get_buffer_offset() < input.size()) { - throw_or_abort("Some input bytes were not read"); - } - return value; -} - -} // end of namespace Program - -template <> -template -void serde::Serializable::serialize(const Program::AssertionPayload::Dynamic& obj, - Serializer& serializer) -{ - serde::Serializable::serialize(obj.value, serializer); -} - -template <> -template -Program::AssertionPayload::Dynamic serde::Deserializable::deserialize( - Deserializer& deserializer) -{ - Program::AssertionPayload::Dynamic obj; - obj.value = serde::Deserializable::deserialize(deserializer); - return obj; -} - -namespace Program { - inline bool operator==(const BinaryFieldOp& lhs, const BinaryFieldOp& rhs) { if (!(lhs.value == rhs.value)) { diff --git a/noir/noir-repo/acvm-repo/acir/codegen/acir.cpp b/noir/noir-repo/acvm-repo/acir/codegen/acir.cpp index 96d029a8f41e..8fa471e57bac 100644 --- a/noir/noir-repo/acvm-repo/acir/codegen/acir.cpp +++ b/noir/noir-repo/acvm-repo/acir/codegen/acir.cpp @@ -1216,24 +1216,8 @@ namespace Program { }; struct AssertionPayload { - - struct StaticString { - std::string value; - - friend bool operator==(const StaticString&, const StaticString&); - std::vector bincodeSerialize() const; - static StaticString bincodeDeserialize(std::vector); - }; - - struct Dynamic { - std::tuple> value; - - friend bool operator==(const Dynamic&, const Dynamic&); - std::vector bincodeSerialize() const; - static Dynamic bincodeDeserialize(std::vector); - }; - - std::variant value; + uint64_t error_selector; + std::vector payload; friend bool operator==(const AssertionPayload&, const AssertionPayload&); std::vector bincodeSerialize() const; @@ -1334,7 +1318,8 @@ namespace Program { namespace Program { inline bool operator==(const AssertionPayload &lhs, const AssertionPayload &rhs) { - if (!(lhs.value == rhs.value)) { return false; } + if (!(lhs.error_selector == rhs.error_selector)) { return false; } + if (!(lhs.payload == rhs.payload)) { return false; } return true; } @@ -1359,7 +1344,8 @@ template <> template void serde::Serializable::serialize(const Program::AssertionPayload &obj, Serializer &serializer) { serializer.increase_container_depth(); - serde::Serializable::serialize(obj.value, serializer); + serde::Serializable::serialize(obj.error_selector, serializer); + serde::Serializable::serialize(obj.payload, serializer); serializer.decrease_container_depth(); } @@ -1368,87 +1354,12 @@ template Program::AssertionPayload serde::Deserializable::deserialize(Deserializer &deserializer) { deserializer.increase_container_depth(); Program::AssertionPayload obj; - obj.value = serde::Deserializable::deserialize(deserializer); + obj.error_selector = serde::Deserializable::deserialize(deserializer); + obj.payload = serde::Deserializable::deserialize(deserializer); deserializer.decrease_container_depth(); return obj; } -namespace Program { - - inline bool operator==(const AssertionPayload::StaticString &lhs, const AssertionPayload::StaticString &rhs) { - if (!(lhs.value == rhs.value)) { return false; } - return true; - } - - inline std::vector AssertionPayload::StaticString::bincodeSerialize() const { - auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); - return std::move(serializer).bytes(); - } - - inline AssertionPayload::StaticString AssertionPayload::StaticString::bincodeDeserialize(std::vector input) { - auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); - if (deserializer.get_buffer_offset() < input.size()) { - throw serde::deserialization_error("Some input bytes were not read"); - } - return value; - } - -} // end of namespace Program - -template <> -template -void serde::Serializable::serialize(const Program::AssertionPayload::StaticString &obj, Serializer &serializer) { - serde::Serializable::serialize(obj.value, serializer); -} - -template <> -template -Program::AssertionPayload::StaticString serde::Deserializable::deserialize(Deserializer &deserializer) { - Program::AssertionPayload::StaticString obj; - obj.value = serde::Deserializable::deserialize(deserializer); - return obj; -} - -namespace Program { - - inline bool operator==(const AssertionPayload::Dynamic &lhs, const AssertionPayload::Dynamic &rhs) { - if (!(lhs.value == rhs.value)) { return false; } - return true; - } - - inline std::vector AssertionPayload::Dynamic::bincodeSerialize() const { - auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); - return std::move(serializer).bytes(); - } - - inline AssertionPayload::Dynamic AssertionPayload::Dynamic::bincodeDeserialize(std::vector input) { - auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); - if (deserializer.get_buffer_offset() < input.size()) { - throw serde::deserialization_error("Some input bytes were not read"); - } - return value; - } - -} // end of namespace Program - -template <> -template -void serde::Serializable::serialize(const Program::AssertionPayload::Dynamic &obj, Serializer &serializer) { - serde::Serializable::serialize(obj.value, serializer); -} - -template <> -template -Program::AssertionPayload::Dynamic serde::Deserializable::deserialize(Deserializer &deserializer) { - Program::AssertionPayload::Dynamic obj; - obj.value = serde::Deserializable::deserialize(deserializer); - return obj; -} - namespace Program { inline bool operator==(const BinaryFieldOp &lhs, const BinaryFieldOp &rhs) { diff --git a/noir/noir-repo/acvm-repo/acir/src/circuit/mod.rs b/noir/noir-repo/acvm-repo/acir/src/circuit/mod.rs index eddf61be100d..12990f66175b 100644 --- a/noir/noir-repo/acvm-repo/acir/src/circuit/mod.rs +++ b/noir/noir-repo/acvm-repo/acir/src/circuit/mod.rs @@ -77,9 +77,9 @@ pub enum ExpressionOrMemory { } #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -pub enum AssertionPayload { - StaticString(String), - Dynamic(/* error_selector */ u64, Vec>), +pub struct AssertionPayload { + pub error_selector: u64, + pub payload: Vec>, } #[derive(Debug, Copy, PartialEq, Eq, Hash, Clone, PartialOrd, Ord)] @@ -115,12 +115,6 @@ impl<'de> Deserialize<'de> for ErrorSelector { } } -/// This selector indicates that the payload is a string. -/// This is used to parse any error with a string payload directly, -/// to avoid users having to parse the error externally to the ACVM. -/// Only non-string errors need to be parsed externally to the ACVM using the circuit ABI. -pub const STRING_ERROR_SELECTOR: ErrorSelector = ErrorSelector(0); - #[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)] pub struct RawAssertionPayload { pub selector: ErrorSelector, diff --git a/noir/noir-repo/acvm-repo/acvm/src/pwg/brillig.rs b/noir/noir-repo/acvm-repo/acvm/src/pwg/brillig.rs index dffa45dbd7a5..a5f5783478ed 100644 --- a/noir/noir-repo/acvm-repo/acvm/src/pwg/brillig.rs +++ b/noir/noir-repo/acvm-repo/acvm/src/pwg/brillig.rs @@ -6,7 +6,6 @@ use acir::{ brillig::{BrilligFunctionId, BrilligInputs, BrilligOutputs}, opcodes::BlockId, ErrorSelector, OpcodeLocation, RawAssertionPayload, ResolvedAssertionPayload, - STRING_ERROR_SELECTOR, }, native_types::WitnessMap, AcirField, @@ -307,25 +306,10 @@ fn extract_failure_payload_from_memory( .expect("Error selector is not u64"), ); - match error_selector { - STRING_ERROR_SELECTOR => { - // If the error selector is 0, it means the error is a string - let string = revert_values_iter - .map(|&memory_value| { - let as_u8: u8 = memory_value.try_into().expect("String item is not u8"); - as_u8 as char - }) - .collect(); - Some(ResolvedAssertionPayload::String(string)) - } - _ => { - // If the error selector is not 0, it means the error is a custom error - Some(ResolvedAssertionPayload::Raw(RawAssertionPayload { - selector: error_selector, - data: revert_values_iter.map(|value| value.to_field()).collect(), - })) - } - } + Some(ResolvedAssertionPayload::Raw(RawAssertionPayload { + selector: error_selector, + data: revert_values_iter.map(|value| value.to_field()).collect(), + })) } } diff --git a/noir/noir-repo/acvm-repo/acvm/src/pwg/mod.rs b/noir/noir-repo/acvm-repo/acvm/src/pwg/mod.rs index fa3498da6138..e2b9ef1defaf 100644 --- a/noir/noir-repo/acvm-repo/acvm/src/pwg/mod.rs +++ b/noir/noir-repo/acvm-repo/acvm/src/pwg/mod.rs @@ -10,7 +10,7 @@ use acir::{ AcirFunctionId, BlockId, ConstantOrWitnessEnum, FunctionInput, InvalidInputBitSize, }, AssertionPayload, ErrorSelector, ExpressionOrMemory, Opcode, OpcodeLocation, - RawAssertionPayload, ResolvedAssertionPayload, STRING_ERROR_SELECTOR, + RawAssertionPayload, ResolvedAssertionPayload, }, native_types::{Expression, Witness, WitnessMap}, AcirField, BlackBoxFunc, @@ -445,59 +445,32 @@ impl<'a, F: AcirField, B: BlackBoxFunctionSolver> ACVM<'a, F, B> { &self, location: OpcodeLocation, ) -> Option> { - let (_, found_assertion_payload) = + let (_, assertion_descriptor) = self.assertion_payloads.iter().find(|(loc, _)| location == *loc)?; - match found_assertion_payload { - AssertionPayload::StaticString(string) => { - Some(ResolvedAssertionPayload::String(string.clone())) - } - AssertionPayload::Dynamic(error_selector, expression) => { - let mut fields = vec![]; - for expr in expression { - match expr { - ExpressionOrMemory::Expression(expr) => { - let value = get_value(expr, &self.witness_map).ok()?; - fields.push(value); - } - ExpressionOrMemory::Memory(block_id) => { - let memory_block = self.block_solvers.get(block_id)?; - fields.extend((0..memory_block.block_len).map(|memory_index| { - *memory_block - .block_value - .get(&memory_index) - .expect("All memory is initialized on creation") - })); - } - } + let mut fields = Vec::new(); + for expr in assertion_descriptor.payload.iter() { + match expr { + ExpressionOrMemory::Expression(expr) => { + let value = get_value(expr, &self.witness_map).ok()?; + fields.push(value); + } + ExpressionOrMemory::Memory(block_id) => { + let memory_block = self.block_solvers.get(block_id)?; + fields.extend((0..memory_block.block_len).map(|memory_index| { + *memory_block + .block_value + .get(&memory_index) + .expect("All memory is initialized on creation") + })); } - let error_selector = ErrorSelector::new(*error_selector); - - Some(match error_selector { - STRING_ERROR_SELECTOR => { - // If the error selector is 0, it means the error is a string - let string = fields - .iter() - .map(|field| { - let as_u8: u8 = field - .try_to_u64() - .expect("String character doesn't fit in u64") - .try_into() - .expect("String character doesn't fit in u8"); - as_u8 as char - }) - .collect(); - ResolvedAssertionPayload::String(string) - } - _ => { - // If the error selector is not 0, it means the error is a custom error - ResolvedAssertionPayload::Raw(RawAssertionPayload { - selector: error_selector, - data: fields, - }) - } - }) } } + let error_selector = ErrorSelector::new(assertion_descriptor.error_selector); + + Some(ResolvedAssertionPayload::Raw(RawAssertionPayload { + selector: error_selector, + data: fields, + })) } fn solve_brillig_call_opcode( @@ -530,7 +503,7 @@ impl<'a, F: AcirField, B: BlackBoxFunctionSolver> ACVM<'a, F, B> { )?, }; - let result = solver.solve().map_err(|err| self.map_brillig_error(err))?; + let result = solver.solve()?; match result { BrilligSolverStatus::ForeignCallWait(foreign_call) => { @@ -570,31 +543,6 @@ impl<'a, F: AcirField, B: BlackBoxFunctionSolver> ACVM<'a, F, B> { } } - fn map_brillig_error(&self, mut err: OpcodeResolutionError) -> OpcodeResolutionError { - match &mut err { - OpcodeResolutionError::BrilligFunctionFailed { call_stack, payload, .. } => { - // Some brillig errors have static strings as payloads, we can resolve them here - let last_location = - call_stack.last().expect("Call stacks should have at least one item"); - let assertion_descriptor = - self.assertion_payloads.iter().find_map(|(loc, payload)| { - if loc == last_location { - Some(payload) - } else { - None - } - }); - - if let Some(AssertionPayload::StaticString(string)) = assertion_descriptor { - *payload = Some(ResolvedAssertionPayload::String(string.clone())); - } - - err - } - _ => err, - } - } - pub fn step_into_brillig(&mut self) -> StepResult<'a, F, B> { let Opcode::BrilligCall { id, inputs, outputs, predicate } = &self.opcodes[self.instruction_pointer] diff --git a/noir/noir-repo/compiler/noirc_driver/src/abi_gen.rs b/noir/noir-repo/compiler/noirc_driver/src/abi_gen.rs index ad54d0f7d6bb..bf64c9c920c7 100644 --- a/noir/noir-repo/compiler/noirc_driver/src/abi_gen.rs +++ b/noir/noir-repo/compiler/noirc_driver/src/abi_gen.rs @@ -6,6 +6,7 @@ use iter_extended::vecmap; use noirc_abi::{ Abi, AbiErrorType, AbiParameter, AbiReturnType, AbiType, AbiValue, AbiVisibility, Sign, }; +use noirc_evaluator::ErrorType; use noirc_frontend::ast::{Signedness, Visibility}; use noirc_frontend::TypeBinding; use noirc_frontend::{ @@ -25,7 +26,7 @@ pub(super) fn gen_abi( context: &Context, func_id: &FuncId, return_visibility: Visibility, - error_types: BTreeMap, + error_types: BTreeMap, ) -> Abi { let (parameters, return_type) = compute_function_abi(context, func_id); let return_type = return_type.map(|typ| AbiReturnType { @@ -34,23 +35,27 @@ pub(super) fn gen_abi( }); let error_types = error_types .into_iter() - .map(|(selector, typ)| (selector, build_abi_error_type(context, &typ))) + .map(|(selector, typ)| (selector, build_abi_error_type(context, typ))) .collect(); Abi { parameters, return_type, error_types } } -fn build_abi_error_type(context: &Context, typ: &Type) -> AbiErrorType { +fn build_abi_error_type(context: &Context, typ: ErrorType) -> AbiErrorType { match typ { - Type::FmtString(len, item_types) => { - let length = len.evaluate_to_u32().expect("Cannot evaluate fmt length"); - let Type::Tuple(item_types) = item_types.as_ref() else { - unreachable!("FmtString items must be a tuple") - }; - let item_types = - item_types.iter().map(|typ| abi_type_from_hir_type(context, typ)).collect(); - AbiErrorType::FmtString { length, item_types } + ErrorType::Dynamic(typ) => { + if let Type::FmtString(len, item_types) = typ { + let length = len.evaluate_to_u32().expect("Cannot evaluate fmt length"); + let Type::Tuple(item_types) = item_types.as_ref() else { + unreachable!("FmtString items must be a tuple") + }; + let item_types = + item_types.iter().map(|typ| abi_type_from_hir_type(context, typ)).collect(); + AbiErrorType::FmtString { length, item_types } + } else { + AbiErrorType::Custom(abi_type_from_hir_type(context, &typ)) + } } - _ => AbiErrorType::Custom(abi_type_from_hir_type(context, typ)), + ErrorType::String(string) => AbiErrorType::String { string }, } } diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs index 23c802e3a146..48914c6219de 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs @@ -259,7 +259,7 @@ impl<'block> BrilligBlock<'block> { }; match assert_message { - Some(ConstrainError::Dynamic(selector, values)) => { + Some(ConstrainError::Dynamic(selector, _, values)) => { let payload_values = vecmap(values, |value| self.convert_ssa_value(*value, dfg)); let payload_as_params = vecmap(values, |value| { @@ -270,7 +270,7 @@ impl<'block> BrilligBlock<'block> { condition, payload_values, payload_as_params, - selector.as_u64(), + *selector, ); } Some(ConstrainError::StaticString(message)) => { diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_directive.rs b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_directive.rs index f066d967e0d2..469f0b430d6d 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_directive.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_directive.rs @@ -67,7 +67,7 @@ pub(crate) fn directive_invert() -> GeneratedBrillig { }, BrilligOpcode::Stop { return_data_offset: 0, return_data_size: 1 }, ], - assert_messages: Default::default(), + error_types: Default::default(), locations: Default::default(), name: "directive_invert".to_string(), } @@ -132,7 +132,7 @@ pub(crate) fn directive_quotient() -> GeneratedBrillig { }, BrilligOpcode::Stop { return_data_offset: 0, return_data_size: 2 }, ], - assert_messages: Default::default(), + error_types: Default::default(), locations: Default::default(), name: "directive_integer_quotient".to_string(), } diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/artifact.rs b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/artifact.rs index d0bd91e185cb..fa98f960dc60 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/artifact.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/artifact.rs @@ -1,8 +1,10 @@ use acvm::acir::brillig::Opcode as BrilligOpcode; +use acvm::acir::circuit::ErrorSelector; use std::collections::{BTreeMap, HashMap}; use crate::brillig::brillig_ir::procedures::ProcedureId; use crate::ssa::ir::{basic_block::BasicBlockId, dfg::CallStack, function::FunctionId}; +use crate::ErrorType; /// Represents a parameter or a return value of an entry point function. #[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)] @@ -22,7 +24,7 @@ pub(crate) enum BrilligParameter { pub(crate) struct GeneratedBrillig { pub(crate) byte_code: Vec>, pub(crate) locations: BTreeMap, - pub(crate) assert_messages: BTreeMap, + pub(crate) error_types: BTreeMap, pub(crate) name: String, } @@ -31,10 +33,7 @@ pub(crate) struct GeneratedBrillig { /// It includes the bytecode of the function and all the metadata that allows linking with other functions. pub(crate) struct BrilligArtifact { pub(crate) byte_code: Vec>, - /// A map of bytecode positions to assertion messages. - /// Some error messages (compiler intrinsics) are not emitted via revert data, - /// instead, they are handled externally so they don't add size to user programs. - pub(crate) assert_messages: BTreeMap, + pub(crate) error_types: BTreeMap, /// The set of jumps that need to have their locations /// resolved. unresolved_jumps: Vec<(JumpInstructionPosition, UnresolvedJumpLocation)>, @@ -58,7 +57,7 @@ pub(crate) struct BrilligArtifact { /// A pointer to a location in the opcode. pub(crate) type OpcodeLocation = usize; -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] +#[derive(Debug, Clone, Eq, PartialEq, Hash)] pub(crate) enum LabelType { /// Labels for the entry point bytecode Entrypoint, @@ -88,7 +87,7 @@ impl std::fmt::Display for LabelType { /// /// It is assumed that an entity will keep a map /// of labels to Opcode locations. -#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] +#[derive(Debug, Clone, Eq, PartialEq, Hash)] pub(crate) struct Label { pub(crate) label_type: LabelType, pub(crate) section: Option, @@ -96,7 +95,7 @@ pub(crate) struct Label { impl Label { pub(crate) fn add_section(&self, section: usize) -> Self { - Label { label_type: self.label_type, section: Some(section) } + Label { label_type: self.label_type.clone(), section: Some(section) } } pub(crate) fn function(func_id: FunctionId) -> Self { @@ -147,14 +146,14 @@ impl BrilligArtifact { GeneratedBrillig { byte_code: self.byte_code, locations: self.locations, - assert_messages: self.assert_messages, + error_types: self.error_types, name: self.name, } } /// Gets the first unresolved function call of this artifact. pub(crate) fn first_unresolved_function_call(&self) -> Option