Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: make nargo crate and debug info generic #5184

Merged
merged 4 commits into from
Jun 10, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
58 changes: 28 additions & 30 deletions compiler/noirc_printable_type/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::{collections::BTreeMap, str};

use acvm::{acir::AcirField, brillig_vm::brillig::ForeignCallParam, FieldElement};
use acvm::{acir::AcirField, brillig_vm::brillig::ForeignCallParam};
use iter_extended::vecmap;
use regex::{Captures, Regex};
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -51,19 +51,19 @@
/// For example, a toml file will parse into TomlTypes
/// and those TomlTypes will be mapped to Value
#[derive(Debug, Clone, Serialize, PartialEq)]
pub enum PrintableValue {
Field(FieldElement),
pub enum PrintableValue<F> {
Field(F),
String(String),
Vec { array_elements: Vec<PrintableValue>, is_slice: bool },
Struct(BTreeMap<String, PrintableValue>),
Vec { array_elements: Vec<PrintableValue<F>>, is_slice: bool },
Struct(BTreeMap<String, PrintableValue<F>>),
Other,
}

/// In order to display a `PrintableValue` we need a `PrintableType` to accurately
/// convert the value into a human-readable format.
pub enum PrintableValueDisplay {
Plain(PrintableValue, PrintableType),
FmtString(String, Vec<(PrintableValue, PrintableType)>),
pub enum PrintableValueDisplay<F> {
Plain(PrintableValue<F>, PrintableType),
FmtString(String, Vec<(PrintableValue<F>, PrintableType)>),
}

#[derive(Debug, Error)]
Expand All @@ -77,16 +77,14 @@
#[error("Failed calling external resolver. {0}")]
ExternalResolverError(#[from] jsonrpc::Error),

#[error("Assert message resolved after an unsatisified constrain. {0}")]

Check warning on line 80 in compiler/noirc_printable_type/src/lib.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (unsatisified)
ResolvedAssertMessage(String),
}

impl TryFrom<&[ForeignCallParam<FieldElement>]> for PrintableValueDisplay {
impl<F: AcirField> TryFrom<&[ForeignCallParam<F>]> for PrintableValueDisplay<F> {
type Error = ForeignCallError;

fn try_from(
foreign_call_inputs: &[ForeignCallParam<FieldElement>],
) -> Result<Self, Self::Error> {
fn try_from(foreign_call_inputs: &[ForeignCallParam<F>]) -> Result<Self, Self::Error> {
let (is_fmt_str, foreign_call_inputs) =
foreign_call_inputs.split_last().ok_or(ForeignCallError::MissingForeignCallInputs)?;

Expand All @@ -98,9 +96,9 @@
}
}

fn convert_string_inputs(
foreign_call_inputs: &[ForeignCallParam<FieldElement>],
) -> Result<PrintableValueDisplay, ForeignCallError> {
fn convert_string_inputs<F: AcirField>(
foreign_call_inputs: &[ForeignCallParam<F>],
) -> Result<PrintableValueDisplay<F>, ForeignCallError> {
// Fetch the PrintableType from the foreign call input
// The remaining input values should hold what is to be printed
let (printable_type_as_values, input_values) =
Expand All @@ -115,9 +113,9 @@
Ok(PrintableValueDisplay::Plain(value, printable_type))
}

fn convert_fmt_string_inputs(
foreign_call_inputs: &[ForeignCallParam<FieldElement>],
) -> Result<PrintableValueDisplay, ForeignCallError> {
fn convert_fmt_string_inputs<F: AcirField>(
foreign_call_inputs: &[ForeignCallParam<F>],
) -> Result<PrintableValueDisplay<F>, ForeignCallError> {
let (message, input_and_printable_types) =
foreign_call_inputs.split_first().ok_or(ForeignCallError::MissingForeignCallInputs)?;

Expand All @@ -144,8 +142,8 @@
Ok(PrintableValueDisplay::FmtString(message_as_string, output))
}

fn fetch_printable_type(
printable_type: &ForeignCallParam<FieldElement>,
fn fetch_printable_type<F: AcirField>(
printable_type: &ForeignCallParam<F>,
) -> Result<PrintableType, ForeignCallError> {
let printable_type_as_fields = printable_type.fields();
let printable_type_as_string = decode_string_value(&printable_type_as_fields);
Expand All @@ -154,7 +152,7 @@
Ok(printable_type)
}

fn to_string(value: &PrintableValue, typ: &PrintableType) -> Option<String> {
fn to_string<F: AcirField>(value: &PrintableValue<F>, typ: &PrintableType) -> Option<String> {
let mut output = String::new();
match (value, typ) {
(PrintableValue::Field(f), PrintableType::Field) => {
Expand Down Expand Up @@ -231,12 +229,12 @@

(PrintableValue::Vec { array_elements, .. }, PrintableType::Tuple { types }) => {
output.push('(');
let mut elems = array_elements.iter().zip(types).peekable();

Check warning on line 232 in compiler/noirc_printable_type/src/lib.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (elems)
while let Some((value, typ)) = elems.next() {

Check warning on line 233 in compiler/noirc_printable_type/src/lib.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (elems)
output.push_str(
&PrintableValueDisplay::Plain(value.clone(), typ.clone()).to_string(),
);
if elems.peek().is_some() {

Check warning on line 237 in compiler/noirc_printable_type/src/lib.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (elems)
output.push_str(", ");
}
}
Expand Down Expand Up @@ -269,7 +267,7 @@
Ok(new)
}

impl std::fmt::Display for PrintableValueDisplay {
impl<F: AcirField> std::fmt::Display for PrintableValueDisplay<F> {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Plain(value, typ) => {
Expand All @@ -295,7 +293,7 @@
/// A singular '0' will be prepended as well if the trimmed string has an odd length.
/// A hex string's length needs to be even to decode into bytes, as two digits correspond to
/// one byte.
fn format_field_string(field: FieldElement) -> String {
fn format_field_string<F: AcirField>(field: F) -> String {
if field.is_zero() {
return "0x00".to_owned();
}
Expand All @@ -306,11 +304,11 @@
"0x".to_owned() + &trimmed_field
}

/// Assumes that `field_iterator` contains enough [FieldElement] in order to decode the [PrintableType]
pub fn decode_value(
field_iterator: &mut impl Iterator<Item = FieldElement>,
/// Assumes that `field_iterator` contains enough field elements in order to decode the [PrintableType]
pub fn decode_value<F: AcirField>(
field_iterator: &mut impl Iterator<Item = F>,
typ: &PrintableType,
) -> PrintableValue {
) -> PrintableValue<F> {
match typ {
PrintableType::Field
| PrintableType::SignedInteger { .. }
Expand Down Expand Up @@ -346,7 +344,7 @@
is_slice: false,
},
PrintableType::String { length } => {
let field_elements: Vec<FieldElement> = field_iterator.take(*length as usize).collect();
let field_elements: Vec<F> = field_iterator.take(*length as usize).collect();

PrintableValue::String(decode_string_value(&field_elements))
}
Expand All @@ -372,11 +370,11 @@
// we decode the reference, but it's not really used for printing
decode_value(field_iterator, typ)
}
PrintableType::Unit => PrintableValue::Field(FieldElement::zero()),
PrintableType::Unit => PrintableValue::Field(F::zero()),
}
}

pub fn decode_string_value(field_elements: &[FieldElement]) -> String {
pub fn decode_string_value<F: AcirField>(field_elements: &[F]) -> String {
// TODO: Replace with `into` when Char is supported
let string_as_slice = vecmap(field_elements, |e| {
let mut field_as_bytes = e.to_be_bytes();
Expand Down
3 changes: 2 additions & 1 deletion tooling/acvm_cli/src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use acir::FieldElement;
use nargo::NargoError;
use std::path::PathBuf;
use thiserror::Error;
Expand Down Expand Up @@ -34,7 +35,7 @@ pub(crate) enum CliError {

/// Error related to circuit execution
#[error(transparent)]
CircuitExecutionError(#[from] NargoError),
CircuitExecutionError(#[from] NargoError<FieldElement>),

/// Input Witness Value Error
#[error("Error: failed to parse witness value {0}")]
Expand Down
6 changes: 3 additions & 3 deletions tooling/debugger/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
Done,
Ok,
BreakpointReached(OpcodeLocation),
Error(NargoError),
Error(NargoError<FieldElement>),
}

pub(super) struct DebugContext<'a, B: BlackBoxFunctionSolver<FieldElement>> {
Expand Down Expand Up @@ -482,11 +482,11 @@
}
}

pub(super) fn get_variables(&self) -> Vec<StackFrame> {
pub(super) fn get_variables(&self) -> Vec<StackFrame<FieldElement>> {
return self.foreign_call_executor.get_variables();
}

pub(super) fn current_stack_frame(&self) -> Option<StackFrame> {
pub(super) fn current_stack_frame(&self) -> Option<StackFrame<FieldElement>> {
return self.foreign_call_executor.current_stack_frame();
}

Expand Down Expand Up @@ -673,7 +673,7 @@
outputs: vec![],
predicate: None,
}];
let brillig_funcs = &vec![brillig_bytecode];

Check warning on line 676 in tooling/debugger/src/context.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (funcs)
let current_witness_index = 2;
let circuit = &Circuit { current_witness_index, opcodes, ..Circuit::default() };

Expand All @@ -691,7 +691,7 @@
debug_artifact,
initial_witness,
foreign_call_executor,
brillig_funcs,

Check warning on line 694 in tooling/debugger/src/context.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (funcs)
);

assert_eq!(context.get_current_opcode_location(), Some(OpcodeLocation::Acir(0)));
Expand Down Expand Up @@ -794,14 +794,14 @@

let foreign_call_executor =
Box::new(DefaultDebugForeignCallExecutor::from_artifact(true, debug_artifact));
let brillig_funcs = &vec![brillig_bytecode];

Check warning on line 797 in tooling/debugger/src/context.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (funcs)
let mut context = DebugContext::new(
&StubbedBlackBoxSolver,
circuit,
debug_artifact,
initial_witness,
foreign_call_executor,
brillig_funcs,

Check warning on line 804 in tooling/debugger/src/context.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (funcs)
);

// set breakpoint
Expand Down Expand Up @@ -846,7 +846,7 @@
];
let circuit = Circuit { opcodes, ..Circuit::default() };
let debug_artifact = DebugArtifact { debug_symbols: vec![], file_map: BTreeMap::new() };
let brillig_funcs = &vec![brillig_bytecode];

Check warning on line 849 in tooling/debugger/src/context.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (funcs)
let context = DebugContext::new(
&StubbedBlackBoxSolver,
&circuit,
Expand Down
16 changes: 8 additions & 8 deletions tooling/debugger/src/foreign_calls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ impl DebugForeignCall {
}
}

pub trait DebugForeignCallExecutor: ForeignCallExecutor {
fn get_variables(&self) -> Vec<StackFrame>;
fn current_stack_frame(&self) -> Option<StackFrame>;
pub trait DebugForeignCallExecutor: ForeignCallExecutor<FieldElement> {
fn get_variables(&self) -> Vec<StackFrame<FieldElement>>;
fn current_stack_frame(&self) -> Option<StackFrame<FieldElement>>;
}

pub struct DefaultDebugForeignCallExecutor {
executor: DefaultForeignCallExecutor,
pub debug_vars: DebugVars,
executor: DefaultForeignCallExecutor<FieldElement>,
pub debug_vars: DebugVars<FieldElement>,
}

impl DefaultDebugForeignCallExecutor {
Expand Down Expand Up @@ -73,11 +73,11 @@ impl DefaultDebugForeignCallExecutor {
}

impl DebugForeignCallExecutor for DefaultDebugForeignCallExecutor {
fn get_variables(&self) -> Vec<StackFrame> {
fn get_variables(&self) -> Vec<StackFrame<FieldElement>> {
self.debug_vars.get_variables()
}

fn current_stack_frame(&self) -> Option<StackFrame> {
fn current_stack_frame(&self) -> Option<StackFrame<FieldElement>> {
self.debug_vars.current_stack_frame()
}
}
Expand All @@ -90,7 +90,7 @@ fn debug_fn_id(value: &FieldElement) -> DebugFnId {
DebugFnId(value.to_u128() as u32)
}

impl ForeignCallExecutor for DefaultDebugForeignCallExecutor {
impl ForeignCallExecutor<FieldElement> for DefaultDebugForeignCallExecutor {
fn execute(
&mut self,
foreign_call: &ForeignCallWaitInfo<FieldElement>,
Expand Down
2 changes: 1 addition & 1 deletion tooling/debugger/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub fn debug_circuit<B: BlackBoxFunctionSolver<FieldElement>>(
debug_artifact: DebugArtifact,
initial_witness: WitnessMap<FieldElement>,
unconstrained_functions: &[BrilligBytecode<FieldElement>],
) -> Result<Option<WitnessMap<FieldElement>>, NargoError> {
) -> Result<Option<WitnessMap<FieldElement>>, NargoError<FieldElement>> {
repl::run(blackbox_solver, circuit, &debug_artifact, initial_witness, unconstrained_functions)
}

Expand Down
2 changes: 1 addition & 1 deletion tooling/debugger/src/repl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ pub fn run<B: BlackBoxFunctionSolver<FieldElement>>(
debug_artifact: &DebugArtifact,
initial_witness: WitnessMap<FieldElement>,
unconstrained_functions: &[BrilligBytecode<FieldElement>],
) -> Result<Option<WitnessMap<FieldElement>>, NargoError> {
) -> Result<Option<WitnessMap<FieldElement>>, NargoError<FieldElement>> {
let context = RefCell::new(ReplDebugger::new(
blackbox_solver,
circuit,
Expand Down
30 changes: 15 additions & 15 deletions tooling/nargo/src/artifacts/debug_vars.rs
Original file line number Diff line number Diff line change
@@ -1,42 +1,42 @@
use acvm::FieldElement;
use acvm::AcirField;
use noirc_errors::debug_info::{
DebugFnId, DebugFunction, DebugInfo, DebugTypeId, DebugVarId, DebugVariable,
};
use noirc_printable_type::{decode_value, PrintableType, PrintableValue};
use std::collections::HashMap;

#[derive(Debug, Default, Clone)]
pub struct DebugVars {
pub struct DebugVars<F> {
variables: HashMap<DebugVarId, DebugVariable>,
functions: HashMap<DebugFnId, DebugFunction>,
types: HashMap<DebugTypeId, PrintableType>,
frames: Vec<(DebugFnId, HashMap<DebugVarId, PrintableValue>)>,
frames: Vec<(DebugFnId, HashMap<DebugVarId, PrintableValue<F>>)>,
}

pub struct StackFrame<'a> {
pub struct StackFrame<'a, F> {
pub function_name: &'a str,
pub function_params: Vec<&'a str>,
pub variables: Vec<(&'a str, &'a PrintableValue, &'a PrintableType)>,
pub variables: Vec<(&'a str, &'a PrintableValue<F>, &'a PrintableType)>,
}

impl DebugVars {
impl<F: AcirField> DebugVars<F> {
pub fn insert_debug_info(&mut self, info: &DebugInfo) {
self.variables.extend(info.variables.clone());
self.types.extend(info.types.clone());
self.functions.extend(info.functions.clone());
}

pub fn get_variables(&self) -> Vec<StackFrame> {
pub fn get_variables(&self) -> Vec<StackFrame<F>> {
self.frames.iter().map(|(fn_id, frame)| self.build_stack_frame(fn_id, frame)).collect()
}

pub fn current_stack_frame(&self) -> Option<StackFrame> {
pub fn current_stack_frame(&self) -> Option<StackFrame<F>> {
self.frames.last().map(|(fn_id, frame)| self.build_stack_frame(fn_id, frame))
}

fn lookup_var(&self, var_id: DebugVarId) -> Option<(&str, &PrintableType)> {
self.variables.get(&var_id).and_then(|debug_var| {
let ptype = self.types.get(&debug_var.debug_type_id)?;

Check warning on line 39 in tooling/nargo/src/artifacts/debug_vars.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (ptype)
Some((debug_var.name.as_str(), ptype))
})
}
Expand All @@ -44,13 +44,13 @@
fn build_stack_frame<'a>(
&'a self,
fn_id: &DebugFnId,
frame: &'a HashMap<DebugVarId, PrintableValue>,
) -> StackFrame {
frame: &'a HashMap<DebugVarId, PrintableValue<F>>,
) -> StackFrame<F> {
let debug_fn = &self.functions.get(fn_id).expect("failed to find function metadata");

let params: Vec<&str> =
debug_fn.arg_names.iter().map(|arg_name| arg_name.as_str()).collect();
let vars: Vec<(&str, &PrintableValue, &PrintableType)> = frame
let vars: Vec<(&str, &PrintableValue<F>, &PrintableType)> = frame
.iter()
.filter_map(|(var_id, var_value)| {
self.lookup_var(*var_id).map(|(name, typ)| (name, var_value, typ))
Expand All @@ -64,7 +64,7 @@
}
}

pub fn assign_var(&mut self, var_id: DebugVarId, values: &[FieldElement]) {
pub fn assign_var(&mut self, var_id: DebugVarId, values: &[F]) {
let type_id = &self.variables.get(&var_id).unwrap().debug_type_id;
let ptype = self.types.get(type_id).unwrap();

Expand All @@ -75,9 +75,9 @@
.insert(var_id, decode_value(&mut values.iter().copied(), ptype));
}

pub fn assign_field(&mut self, var_id: DebugVarId, indexes: Vec<u32>, values: &[FieldElement]) {
pub fn assign_field(&mut self, var_id: DebugVarId, indexes: Vec<u32>, values: &[F]) {
let current_frame = &mut self.frames.last_mut().expect("unexpected empty stack frames").1;
let mut cursor: &mut PrintableValue = current_frame
let mut cursor: &mut PrintableValue<F> = current_frame
.get_mut(&var_id)
.unwrap_or_else(|| panic!("value unavailable for var_id {var_id:?}"));
let cursor_type_id = &self
Expand Down Expand Up @@ -146,7 +146,7 @@
*cursor = decode_value(&mut values.iter().copied(), cursor_type);
}

pub fn assign_deref(&mut self, _var_id: DebugVarId, _values: &[FieldElement]) {
pub fn assign_deref(&mut self, _var_id: DebugVarId, _values: &[F]) {
unimplemented![]
}

Expand Down
Loading
Loading