Skip to content

Commit

Permalink
Merge branch 'master' into ab/lsp-alias-references
Browse files Browse the repository at this point in the history
  • Loading branch information
asterite committed Jul 8, 2024
2 parents ab3a9a9 + 7bf3b49 commit 5b34383
Show file tree
Hide file tree
Showing 50 changed files with 1,323 additions and 258 deletions.
2 changes: 1 addition & 1 deletion .aztec-sync-commit
Original file line number Diff line number Diff line change
@@ -1 +1 @@
10076d9663dcf40ac712df69e3a71a1bb54866e2
c7b1ae40593c24530723f344111459a51ad5f0e5
108 changes: 58 additions & 50 deletions acvm-repo/acvm/src/pwg/brillig.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,63 +162,27 @@ impl<'b, B: BlackBoxFunctionSolver<F>, F: AcirField> BrilligSolver<'b, F, B> {
VMStatus::Finished { .. } => Ok(BrilligSolverStatus::Finished),
VMStatus::InProgress => Ok(BrilligSolverStatus::InProgress),
VMStatus::Failure { reason, call_stack } => {
let call_stack = call_stack
.iter()
.map(|brillig_index| OpcodeLocation::Brillig {
acir_index: self.acir_index,
brillig_index: *brillig_index,
})
.collect();
let payload = match reason {
FailureReason::RuntimeError { message } => {
Some(ResolvedAssertionPayload::String(message))
}
FailureReason::Trap { revert_data_offset, revert_data_size } => {
// Since noir can only revert with strings currently, we can parse return data as a string
if revert_data_size == 0 {
None
} else {
let memory = self.vm.get_memory();
let mut revert_values_iter = memory
[revert_data_offset..(revert_data_offset + revert_data_size)]
.iter();
let error_selector = ErrorSelector::new(
revert_values_iter
.next()
.expect("Incorrect revert data size")
.try_into()
.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(),
}))
}
}
}
extract_failure_payload_from_memory(
self.vm.get_memory(),
revert_data_offset,
revert_data_size,
)
}
};
Err(OpcodeResolutionError::BrilligFunctionFailed {
payload,
call_stack: call_stack
.iter()
.map(|brillig_index| OpcodeLocation::Brillig {
acir_index: self.acir_index,
brillig_index: *brillig_index,
})
.collect(),
})

Err(OpcodeResolutionError::BrilligFunctionFailed { payload, call_stack })
}
VMStatus::ForeignCallWait { function, inputs } => {
Ok(BrilligSolverStatus::ForeignCallWait(ForeignCallWaitInfo { function, inputs }))
Expand Down Expand Up @@ -283,6 +247,50 @@ impl<'b, B: BlackBoxFunctionSolver<F>, F: AcirField> BrilligSolver<'b, F, B> {
}
}

/// Extracts a `ResolvedAssertionPayload` from a block of memory of a Brillig VM instance.
///
/// Returns `None` if the amount of memory requested is zero.
fn extract_failure_payload_from_memory<F: AcirField>(
memory: &[MemoryValue<F>],
revert_data_offset: usize,
revert_data_size: usize,
) -> Option<ResolvedAssertionPayload<F>> {
// Since noir can only revert with strings currently, we can parse return data as a string
if revert_data_size == 0 {
None
} else {
let mut revert_values_iter =
memory[revert_data_offset..(revert_data_offset + revert_data_size)].iter();
let error_selector = ErrorSelector::new(
revert_values_iter
.next()
.expect("Incorrect revert data size")
.try_into()
.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(),
}))
}
}
}
}

/// Encapsulates a request from a Brillig VM process that encounters a [foreign call opcode][acir::brillig_vm::Opcode::ForeignCall]
/// where the result of the foreign call has not yet been provided.
///
Expand Down
99 changes: 41 additions & 58 deletions aztec_macros/src/transforms/contract_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,15 @@ use crate::utils::{
// PublicCallInterface {
// target_contract: self.target_contract,
// selector: FunctionSelector::from_signature("SELECTOR_PLACEHOLDER"),
// args_hash
// args_hash,
// name: "a_function",
// args_hash,
// args: args_acc,
// original: | inputs: dep::aztec::context::inputs::PublicContextInputs | -> Field {
// a_function(inputs, first_arg, second_arg, third_arg)
// },
// is_static: false,
// gas_opts: dep::aztec::context::gas::GasOpts::default()
// }
// }
//
Expand Down Expand Up @@ -132,73 +140,48 @@ pub fn stub_function(aztec_visibility: &str, func: &NoirFunction, is_static_call
format!("{}, {}>", return_type_hint, arg_types)
};

let fn_body = if aztec_visibility != "Public" {
let args_hash = if !parameters.is_empty() {
format!(
"let mut args_acc: [Field] = &[];
{}
let args_hash = aztec::hash::hash_args(args_acc);
assert(args_hash == aztec::oracle::arguments::pack_arguments(args_acc));",
call_args
)
let args = format!(
"let mut args_acc: [Field] = &[];
{}
{}",
call_args,
if aztec_visibility == "Private" {
"let args_hash = aztec::hash::hash_args(args_acc);"
} else {
"
let mut args_acc: [Field] = &[];
let args_hash = 0;
"
.to_string()
};

format!(
"{}
let selector = {};
dep::aztec::context::{}{}{}CallInterface {{
target_contract: self.target_contract,
selector,
name: \"{}\",
args_hash,
args: args_acc,
original: {},
is_static: {}
}}",
args_hash,
fn_selector,
aztec_visibility,
is_static,
is_void,
fn_name,
original,
is_static_call
)
""
}
);

let gas_opts = if aztec_visibility == "Public" {
"gas_opts: dep::aztec::context::gas::GasOpts::default()"
} else {
let args = format!(
"let mut args_acc: [Field] = &[];
{}
",
call_args
);
format!(
"{}
""
};

let fn_body = format!(
"{}
let selector = {};
dep::aztec::context::{}{}{}CallInterface {{
target_contract: self.target_contract,
selector,
name: \"{}\",
{}
args: args_acc,
gas_opts: dep::aztec::context::gas::GasOpts::default(),
original: {},
is_static: {}
is_static: {},
{}
}}",
args,
fn_selector,
aztec_visibility,
is_static,
is_void,
fn_name,
original,
is_static_call
)
};
args,
fn_selector,
aztec_visibility,
is_static,
is_void,
fn_name,
if aztec_visibility == "Private" { "args_hash," } else { "" },
original,
is_static_call,
gas_opts
);

format!(
"pub fn {}(self, {}) -> dep::aztec::context::{}{}{}CallInterface<{},{} {{
Expand Down
37 changes: 12 additions & 25 deletions aztec_macros/src/utils/hir_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -269,28 +269,19 @@ pub fn fully_qualified_note_path(context: &HirContext, note_id: StructId) -> Opt
if &module_id.krate == context.root_crate_id() {
Some(module_path)
} else {
find_non_contract_dependencies_bfs(context, context.root_crate_id(), &module_id.krate)
find_dependencies_bfs(context, context.root_crate_id(), &module_id.krate)
.map(|crates| crates.join("::") + "::" + &module_path)
}
}

fn filter_contract_modules(context: &HirContext, crate_id: &CrateId) -> bool {
if let Some(def_map) = context.def_map(crate_id) {
!def_map.modules().iter().any(|(_, module)| module.is_contract)
} else {
true
}
}

fn find_non_contract_dependencies_bfs(
fn find_dependencies_bfs(
context: &HirContext,
crate_id: &CrateId,
target_crate_id: &CrateId,
) -> Option<Vec<String>> {
context.crate_graph[crate_id]
.dependencies
.iter()
.filter(|dep| filter_contract_modules(context, &dep.crate_id))
.find_map(|dep| {
if &dep.crate_id == target_crate_id {
Some(vec![dep.name.to_string()])
Expand All @@ -299,20 +290,16 @@ fn find_non_contract_dependencies_bfs(
}
})
.or_else(|| {
context.crate_graph[crate_id]
.dependencies
.iter()
.filter(|dep| filter_contract_modules(context, &dep.crate_id))
.find_map(|dep| {
if let Some(mut path) =
find_non_contract_dependencies_bfs(context, &dep.crate_id, target_crate_id)
{
path.insert(0, dep.name.to_string());
Some(path)
} else {
None
}
})
context.crate_graph[crate_id].dependencies.iter().find_map(|dep| {
if let Some(mut path) =
find_dependencies_bfs(context, &dep.crate_id, target_crate_id)
{
path.insert(0, dep.name.to_string());
Some(path)
} else {
None
}
})
})
}

Expand Down
26 changes: 24 additions & 2 deletions compiler/noirc_errors/src/reporter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub struct CustomDiagnostic {
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum DiagnosticKind {
Error,
Bug,
Warning,
}

Expand Down Expand Up @@ -62,6 +63,19 @@ impl CustomDiagnostic {
}
}

pub fn simple_bug(
primary_message: String,
secondary_message: String,
secondary_span: Span,
) -> CustomDiagnostic {
CustomDiagnostic {
message: primary_message,
secondaries: vec![CustomLabel::new(secondary_message, secondary_span)],
notes: Vec::new(),
kind: DiagnosticKind::Bug,
}
}

pub fn in_file(self, file_id: fm::FileId) -> FileDiagnostic {
FileDiagnostic::new(file_id, self)
}
Expand All @@ -81,6 +95,10 @@ impl CustomDiagnostic {
pub fn is_warning(&self) -> bool {
matches!(self.kind, DiagnosticKind::Warning)
}

pub fn is_bug(&self) -> bool {
matches!(self.kind, DiagnosticKind::Bug)
}
}

impl std::fmt::Display for CustomDiagnostic {
Expand Down Expand Up @@ -120,10 +138,13 @@ pub fn report_all<'files>(
silence_warnings: bool,
) -> ReportedErrors {
// Report warnings before any errors
let (warnings, mut errors): (Vec<_>, _) =
diagnostics.iter().partition(|item| item.diagnostic.is_warning());
let (warnings_and_bugs, mut errors): (Vec<_>, _) =
diagnostics.iter().partition(|item| !item.diagnostic.is_error());

let (warnings, mut bugs): (Vec<_>, _) =
warnings_and_bugs.iter().partition(|item| item.diagnostic.is_warning());
let mut diagnostics = if silence_warnings { Vec::new() } else { warnings };
diagnostics.append(&mut bugs);
diagnostics.append(&mut errors);

let error_count =
Expand Down Expand Up @@ -170,6 +191,7 @@ fn convert_diagnostic(
) -> Diagnostic<fm::FileId> {
let diagnostic = match (cd.kind, deny_warnings) {
(DiagnosticKind::Warning, false) => Diagnostic::warning(),
(DiagnosticKind::Bug, ..) => Diagnostic::bug(),
_ => Diagnostic::error(),
};

Expand Down
Loading

0 comments on commit 5b34383

Please sign in to comment.