diff --git a/circom/build.rs b/circom/build.rs index 7f7486fbf..503b9cde8 100644 --- a/circom/build.rs +++ b/circom/build.rs @@ -14,19 +14,27 @@ fn main() { let path = entry.unwrap(); create_dir_all(Path::new(&out_dir).join(path.parent().unwrap())).unwrap(); copy(path.clone(), Path::new(&out_dir).join(path.clone())).unwrap(); - let test_name = path.to_str().unwrap() + let test_name = path + .to_str() + .unwrap() .replace("/", "_") .replace(".circom", "") .replace("-", "_") .to_lowercase(); - test_code = format!(" + test_code = format!( + " {} #[test] fn {}() -> LitResult<()> {{ lit_test(include_str!(\"{}\"), \"{}\") - }}", test_code, test_name, path.to_str().unwrap(), test_name); + }}", + test_code, + test_name, + path.to_str().unwrap(), + test_name + ); } generate_file(&dest_path, test_code.as_bytes()); @@ -35,4 +43,4 @@ fn main() { fn generate_file>(path: P, text: &[u8]) { let mut f = File::create(path).unwrap(); f.write_all(text).unwrap() -} \ No newline at end of file +} diff --git a/circuit_passes/src/bucket_interpreter/mod.rs b/circuit_passes/src/bucket_interpreter/mod.rs index cb1c7d800..c5ff9627f 100644 --- a/circuit_passes/src/bucket_interpreter/mod.rs +++ b/circuit_passes/src/bucket_interpreter/mod.rs @@ -16,7 +16,6 @@ use crate::bucket_interpreter::operations::compute_offset; use crate::bucket_interpreter::value::{JoinSemiLattice, Value}; use crate::bucket_interpreter::value::Value::{KnownBigInt, KnownU32, Unknown}; - pub struct BucketInterpreter<'a> { _scope: &'a String, _prime: &'a String, @@ -26,7 +25,7 @@ pub struct BucketInterpreter<'a> { p: BigInt, signal_index_mapping: &'a IndexMapping, variables_index_mapping: &'a IndexMapping, - component_addr_index_mapping: &'a IndexMapping + component_addr_index_mapping: &'a IndexMapping, } pub type R<'a> = (Option, Env<'a>); @@ -36,7 +35,7 @@ impl JoinSemiLattice for Option { match (self, other) { (x, None) => x.clone(), (None, x) => x.clone(), - (Some(x), Some(y)) => Some(x.join(y)) + (Some(x), Some(y)) => Some(x.join(y)), } } } @@ -47,7 +46,6 @@ impl JoinSemiLattice for R<'_> { } } - impl<'a> BucketInterpreter<'a> { pub fn init( scope: &'a String, @@ -57,7 +55,7 @@ impl<'a> BucketInterpreter<'a> { io_map: &'a TemplateInstanceIOMap, signal_index_mapping: &'a IndexMapping, variables_index_mapping: &'a IndexMapping, - component_addr_index_mapping: &'a IndexMapping + component_addr_index_mapping: &'a IndexMapping, ) -> Self { BucketInterpreter { _scope: scope, @@ -68,7 +66,7 @@ impl<'a> BucketInterpreter<'a> { p: UsefulConstants::new(prime).get_p().clone(), signal_index_mapping, variables_index_mapping, - component_addr_index_mapping + component_addr_index_mapping, } } @@ -78,23 +76,33 @@ impl<'a> BucketInterpreter<'a> { let (idx, _) = self.execute_instruction(location, env.clone(), false); idx.expect("LocationRule must produce a value!").get_u32() } - LocationRule::Mapped { .. } => unreachable!() + LocationRule::Mapped { .. } => unreachable!(), } } - fn get_write_operations_in_store_bucket(&self, bucket: &StoreBucket, - vars: &mut Vec, - signals: &mut Vec, - subcmps: &mut Vec, - env: &Env) { + fn get_write_operations_in_store_bucket( + &self, + bucket: &StoreBucket, + vars: &mut Vec, + signals: &mut Vec, + subcmps: &mut Vec, + env: &Env, + ) { match bucket.dest_address_type { AddressType::Variable => { let idx = self.get_id_from_indexed_location(&bucket.dest, env); - let indices = self.variables_index_mapping.get(&idx).expect( - format!("Could not get idx {idx} from mapping. Min key {:?}. Max key {:?}", + let indices = self + .variables_index_mapping + .get(&idx) + .expect( + format!( + "Could not get idx {idx} from mapping. Min key {:?}. Max key {:?}", self.variables_index_mapping.keys().min(), - self.variables_index_mapping.keys().max()).as_str() - ).clone(); + self.variables_index_mapping.keys().max() + ) + .as_str(), + ) + .clone(); for index in indices { vars.push(index); } @@ -122,33 +130,49 @@ impl<'a> BucketInterpreter<'a> { vars: &mut Vec, signals: &mut Vec, subcmps: &mut Vec, - env: &Env + env: &Env, ) { match inst { Instruction::Value(_) => {} // Cannot write - Instruction::Load(_) => {} // Should not have a StoreBucket inside + Instruction::Load(_) => {} // Should not have a StoreBucket inside Instruction::Store(bucket) => { self.get_write_operations_in_store_bucket(bucket, vars, signals, subcmps, env) } Instruction::Compute(_) => {} // Should not have a StoreBucket inside - Instruction::Call(_) => {} // Should not have a StoreBucket as argument + Instruction::Call(_) => {} // Should not have a StoreBucket as argument Instruction::Branch(bucket) => { - self.get_write_operations_in_body_rec(&bucket.if_branch, vars, signals, subcmps, env); - self.get_write_operations_in_body_rec(&bucket.else_branch, vars, signals, subcmps, env); + self.get_write_operations_in_body_rec( + &bucket.if_branch, + vars, + signals, + subcmps, + env, + ); + self.get_write_operations_in_body_rec( + &bucket.else_branch, + vars, + signals, + subcmps, + env, + ); } Instruction::Return(_) => {} // Should not have a StoreBucket in the return expression Instruction::Assert(_) => {} // Should not have a StoreBucket inside - Instruction::Log(_) => {} // Should not have a StoreBucket inside + Instruction::Log(_) => {} // Should not have a StoreBucket inside Instruction::Loop(bucket) => { self.get_write_operations_in_body_rec(&bucket.body, vars, signals, subcmps, env) } Instruction::CreateCmp(_) => {} // Should not have a StoreBucket inside - Instruction::Constraint(bucket) => { - self.get_write_operations_in_inst_rec(match bucket { + Instruction::Constraint(bucket) => self.get_write_operations_in_inst_rec( + match bucket { ConstraintBucket::Substitution(i) => i, - ConstraintBucket::Equality(i) => i - }, vars, signals, subcmps, env) - } + ConstraintBucket::Equality(i) => i, + }, + vars, + signals, + subcmps, + env, + ), Instruction::Block(bucket) => { self.get_write_operations_in_body_rec(&bucket.body, vars, signals, subcmps, env) } @@ -162,7 +186,7 @@ impl<'a> BucketInterpreter<'a> { vars: &mut Vec, signals: &mut Vec, subcmps: &mut Vec, - env: &Env + env: &Env, ) { for inst in body { self.get_write_operations_in_inst_rec(inst, vars, signals, subcmps, env); @@ -173,7 +197,11 @@ impl<'a> BucketInterpreter<'a> { /// 0: Indices of variables /// 1: Indices of signals /// 2: Indices of subcmps - fn get_write_operations_in_body(&self, body: &InstructionList, env: &Env) -> (Vec, Vec, Vec) { + fn get_write_operations_in_body( + &self, + body: &InstructionList, + env: &Env, + ) -> (Vec, Vec, Vec) { let mut vars = vec![]; let mut signals = vec![]; let mut subcmps = vec![]; @@ -183,7 +211,12 @@ impl<'a> BucketInterpreter<'a> { return (vars, signals, subcmps); } - pub fn execute_value_bucket<'env>(&self, bucket: &ValueBucket, env: Env<'env>, _observe: bool) -> R<'env> { + pub fn execute_value_bucket<'env>( + &self, + bucket: &ValueBucket, + env: Env<'env>, + _observe: bool, + ) -> R<'env> { ( Some(match bucket.parse_as { ValueType::BigInt => { @@ -195,18 +228,25 @@ impl<'a> BucketInterpreter<'a> { } ValueType::U32 => KnownU32(bucket.value), }), - env + env, ) } - pub fn execute_load_bucket<'env>(&self, bucket: &'env LoadBucket, env: Env<'env>, observe: bool) -> R<'env> { + pub fn execute_load_bucket<'env>( + &self, + bucket: &'env LoadBucket, + env: Env<'env>, + observe: bool, + ) -> R<'env> { match &bucket.address_type { AddressType::Variable => { let continue_observing = if observe { self.observer.on_location_rule(&bucket.src, &env) } else { false }; let (idx, env) = match &bucket.src { - LocationRule::Indexed { location, .. } => self.execute_instruction(location, env, continue_observing), - LocationRule::Mapped { .. } => unreachable!() + LocationRule::Indexed { location, .. } => { + self.execute_instruction(location, env, continue_observing) + } + LocationRule::Mapped { .. } => unreachable!(), }; let idx = idx.expect("Indexed location must produce a value!"); if idx.is_unknown() { @@ -214,13 +254,15 @@ impl<'a> BucketInterpreter<'a> { } else { (Some(env.get_var(idx.get_u32())), env) } - }, + } AddressType::Signal => { let continue_observing = if observe { self.observer.on_location_rule(&bucket.src, &env) } else { false }; let (idx, env) = match &bucket.src { - LocationRule::Indexed { location, .. } => self.execute_instruction(location, env, continue_observing), - LocationRule::Mapped { .. } => unreachable!() + LocationRule::Indexed { location, .. } => { + self.execute_instruction(location, env, continue_observing) + } + LocationRule::Mapped { .. } => unreachable!(), }; let idx = idx.expect("Indexed location must produce a value!"); if idx.is_unknown() { @@ -228,7 +270,7 @@ impl<'a> BucketInterpreter<'a> { } else { (Some(env.get_signal(idx.get_u32())), env) } - }, + } AddressType::SubcmpSignal { cmp_address, .. } => { let (addr, env) = self.execute_instruction(cmp_address, env, observe); let addr = addr @@ -240,18 +282,23 @@ impl<'a> BucketInterpreter<'a> { if observe { self.observer.on_location_rule(&bucket.src, &env) } else { false }; let (idx, env) = match &bucket.src { LocationRule::Indexed { location, .. } => { - let (idx, env) = self.execute_instruction(location, env, continue_observing); + let (idx, env) = + self.execute_instruction(location, env, continue_observing); (idx.expect("Indexed location must produce a value!").get_u32(), env) - }, + } LocationRule::Mapped { signal_code, indexes } => { let mut acc_env = env; - let io_def = &self.io_map[&acc_env.get_subcmp_template_id(addr)][*signal_code]; + let io_def = + &self.io_map[&acc_env.get_subcmp_template_id(addr)][*signal_code]; let map_access = io_def.offset; if indexes.len() > 0 { let mut indexes_values = vec![]; for i in indexes { - let (val, new_env) = self.execute_instruction(i, acc_env, continue_observing); - indexes_values.push(val.expect("Mapped location must produce a value!").get_u32()); + let (val, new_env) = + self.execute_instruction(i, acc_env, continue_observing); + indexes_values.push( + val.expect("Mapped location must produce a value!").get_u32(), + ); acc_env = new_env; } let offset = compute_offset(&indexes_values, &io_def.lengths); @@ -266,14 +313,23 @@ impl<'a> BucketInterpreter<'a> { } } - pub fn store_value_in_address<'env>(&self, address: &'env AddressType, location: &'env LocationRule, value: Value, env: Env<'env>, observe: bool) -> Env<'env> { + pub fn store_value_in_address<'env>( + &self, + address: &'env AddressType, + location: &'env LocationRule, + value: Value, + env: Env<'env>, + observe: bool, + ) -> Env<'env> { match address { AddressType::Variable => { let continue_observing = if observe { self.observer.on_location_rule(location, &env) } else { false }; let (idx, env) = match location { - LocationRule::Indexed { location, .. } => self.execute_instruction(location, env, continue_observing), - LocationRule::Mapped { .. } => unreachable!() + LocationRule::Indexed { location, .. } => { + self.execute_instruction(location, env, continue_observing) + } + LocationRule::Mapped { .. } => unreachable!(), }; let idx_value = idx.expect("Indexed location must produce a value!"); @@ -283,13 +339,15 @@ impl<'a> BucketInterpreter<'a> { } else { env } - }, + } AddressType::Signal => { let continue_observing = if observe { self.observer.on_location_rule(location, &env) } else { false }; let (idx, env) = match location { - LocationRule::Indexed { location, .. } => self.execute_instruction(location, env, continue_observing), - LocationRule::Mapped { .. } => unreachable!() + LocationRule::Indexed { location, .. } => { + self.execute_instruction(location, env, continue_observing) + } + LocationRule::Mapped { .. } => unreachable!(), }; let idx_value = idx.expect("Indexed location must produce a value!"); @@ -299,7 +357,7 @@ impl<'a> BucketInterpreter<'a> { } else { env } - }, + } AddressType::SubcmpSignal { cmp_address, input_information, .. } => { let (addr, env) = self.execute_instruction(cmp_address, env, observe); let addr = addr @@ -311,19 +369,28 @@ impl<'a> BucketInterpreter<'a> { if observe { self.observer.on_location_rule(location, &env) } else { false }; let (idx, env, sub_cmp_name) = match location { LocationRule::Indexed { location, template_header } => { - let (idx, env) = self.execute_instruction(location, env, continue_observing); - (idx.expect("Indexed location must produce a value!").get_u32(), env, template_header.clone()) - }, + let (idx, env) = + self.execute_instruction(location, env, continue_observing); + ( + idx.expect("Indexed location must produce a value!").get_u32(), + env, + template_header.clone(), + ) + } LocationRule::Mapped { signal_code, indexes } => { let mut acc_env = env; let name = Some(acc_env.get_subcmp_name(addr).clone()); - let io_def = &self.io_map[&acc_env.get_subcmp_template_id(addr)][*signal_code]; + let io_def = + &self.io_map[&acc_env.get_subcmp_template_id(addr)][*signal_code]; let map_access = io_def.offset; if indexes.len() > 0 { let mut indexes_values = vec![]; for i in indexes { - let (val, new_env) = self.execute_instruction(i, acc_env, continue_observing); - indexes_values.push(val.expect("Mapped location must produce a value!").get_u32()); + let (val, new_env) = + self.execute_instruction(i, acc_env, continue_observing); + indexes_values.push( + val.expect("Mapped location must produce a value!").get_u32(), + ); acc_env = new_env; } let offset = compute_offset(&indexes_values, &io_def.lengths); @@ -334,22 +401,16 @@ impl<'a> BucketInterpreter<'a> { } }; - let env = env - .set_subcmp_signal(addr, idx, value) - .decrease_subcmp_counter(addr); + let env = env.set_subcmp_signal(addr, idx, value).decrease_subcmp_counter(addr); if let InputInformation::Input { status } = input_information { match status { StatusInput::Last => { - return - env.run_subcmp(addr, &sub_cmp_name.unwrap(), self, observe) - ; + return env.run_subcmp(addr, &sub_cmp_name.unwrap(), self, observe); } StatusInput::Unknown => { if env.subcmp_counter_is_zero(addr) { - return - env.run_subcmp(addr, &sub_cmp_name.unwrap(), self, observe) - ; + return env.run_subcmp(addr, &sub_cmp_name.unwrap(), self, observe); } } _ => {} @@ -360,14 +421,25 @@ impl<'a> BucketInterpreter<'a> { } } - pub fn execute_store_bucket<'env>(&self, bucket: &'env StoreBucket, env: Env<'env>, observe: bool) -> R<'env> { + pub fn execute_store_bucket<'env>( + &self, + bucket: &'env StoreBucket, + env: Env<'env>, + observe: bool, + ) -> R<'env> { let (src, env) = self.execute_instruction(&bucket.src, env, observe); let src = src.expect("src instruction in StoreBucket must produce a value!"); - let env = self.store_value_in_address(&bucket.dest_address_type, &bucket.dest, src, env, observe); + let env = + self.store_value_in_address(&bucket.dest_address_type, &bucket.dest, src, env, observe); (None, env) } - pub fn execute_compute_bucket<'env>(&self, bucket: &'env ComputeBucket, env: Env<'env>, observe: bool) -> R<'env> { + pub fn execute_compute_bucket<'env>( + &self, + bucket: &'env ComputeBucket, + env: Env<'env>, + observe: bool, + ) -> R<'env> { let mut stack = vec![]; let mut env = env; for i in &bucket.stack { @@ -384,8 +456,12 @@ impl<'a> BucketInterpreter<'a> { (computed_value, env) } - - pub fn execute_call_bucket<'env>(&self, bucket: &'env CallBucket, env: Env<'env>, observe: bool) -> R<'env> { + pub fn execute_call_bucket<'env>( + &self, + bucket: &'env CallBucket, + env: Env<'env>, + observe: bool, + ) -> R<'env> { let mut args = vec![]; let mut env = env; for i in &bucket.arguments { @@ -406,13 +482,25 @@ impl<'a> BucketInterpreter<'a> { // Write the result in the destination according to the address type match &bucket.return_info { ReturnType::Intermediate { .. } => (Some(result), env), - ReturnType::Final(final_data) => { - (None, self.store_value_in_address(&final_data.dest_address_type, &final_data.dest, result, env, observe)) - } + ReturnType::Final(final_data) => ( + None, + self.store_value_in_address( + &final_data.dest_address_type, + &final_data.dest, + result, + env, + observe, + ), + ), } } - pub fn execute_branch_bucket<'env>(&self, bucket: &'env BranchBucket, env: Env<'env>, observe: bool) -> R<'env> { + pub fn execute_branch_bucket<'env>( + &self, + bucket: &'env BranchBucket, + env: Env<'env>, + observe: bool, + ) -> R<'env> { let (value, cond, mut env) = self.execute_conditional_bucket( &bucket.cond, &bucket.if_branch, @@ -427,8 +515,15 @@ impl<'a> BucketInterpreter<'a> { // If cond is None means that the condition instruction evaluates to Unknown // Thus we don't know what branch to take // We take all writes in both branches and set all writes in them as Unknown - let (mut vars, mut signals, mut subcmps) = self.get_write_operations_in_body(&bucket.if_branch, &env); - self.get_write_operations_in_body_rec(&bucket.else_branch, &mut vars, &mut signals, &mut subcmps, &env); + let (mut vars, mut signals, mut subcmps) = + self.get_write_operations_in_body(&bucket.if_branch, &env); + self.get_write_operations_in_body_rec( + &bucket.else_branch, + &mut vars, + &mut signals, + &mut subcmps, + &env, + ); for var in vars { env = env.set_var(var, Unknown); @@ -442,11 +537,21 @@ impl<'a> BucketInterpreter<'a> { (value, env) } - pub fn execute_return_bucket<'env>(&self, bucket: &'env ReturnBucket, env: Env<'env>, observe: bool) -> R<'env> { + pub fn execute_return_bucket<'env>( + &self, + bucket: &'env ReturnBucket, + env: Env<'env>, + observe: bool, + ) -> R<'env> { self.execute_instruction(&bucket.value, env, observe) } - pub fn execute_assert_bucket<'env>(&self, bucket: &'env AssertBucket, env: Env<'env>, observe: bool) -> R<'env> { + pub fn execute_assert_bucket<'env>( + &self, + bucket: &'env AssertBucket, + env: Env<'env>, + observe: bool, + ) -> R<'env> { //self.observer.on_assert_bucket(bucket, &env); let (cond, env) = self.execute_instruction(&bucket.evaluate, env, observe); @@ -457,7 +562,12 @@ impl<'a> BucketInterpreter<'a> { (None, env) } - pub fn execute_log_bucket<'env>(&self, bucket: &'env LogBucket, env: Env<'env>, observe: bool) -> R<'env> { + pub fn execute_log_bucket<'env>( + &self, + bucket: &'env LogBucket, + env: Env<'env>, + observe: bool, + ) -> R<'env> { let mut env = env; for arg in &bucket.argsprint { if let LogBucketArg::LogExp(i) = arg { @@ -482,16 +592,18 @@ impl<'a> BucketInterpreter<'a> { let cond_bool_result = self.value_to_bool(&executed_cond); return match cond_bool_result { - None => { - (None, None, env) - } + None => (None, None, env), Some(true) => { - if cfg!(debug_assertions) { println!("Running then branch"); } + if cfg!(debug_assertions) { + println!("Running then branch"); + } let (ret, env) = self.execute_instructions(&true_branch, env, observe); (ret, Some(true), env) } Some(false) => { - if cfg!(debug_assertions) { println!("Running else branch"); } + if cfg!(debug_assertions) { + println!("Running else branch"); + } let (ret, env) = self.execute_instructions(&false_branch, env, observe); (ret, Some(false), env) } @@ -520,7 +632,12 @@ impl<'a> BucketInterpreter<'a> { /// In the case the condition evaluates to `Unknown` all the memory addresses /// potentially written into in the loop's body are set to `Unknown` to represent /// that we don't know the values after the execution of that loop. - pub fn execute_loop_bucket<'env>(&self, bucket: &'env LoopBucket, env: Env<'env>, observe: bool) -> R<'env> { + pub fn execute_loop_bucket<'env>( + &self, + bucket: &'env LoopBucket, + env: Env<'env>, + observe: bool, + ) -> R<'env> { //self.observer.on_loop_bucket(bucket, &env); let mut last_value = Some(Unknown); let mut loop_env = env; @@ -542,7 +659,8 @@ impl<'a> BucketInterpreter<'a> { loop_env = new_env; match cond { None => { - let (vars, signals, subcmps) = self.get_write_operations_in_body(&bucket.body, &loop_env); + let (vars, signals, subcmps) = + self.get_write_operations_in_body(&bucket.body, &loop_env); for var in vars { loop_env = loop_env.set_var(var, Unknown); @@ -575,7 +693,8 @@ impl<'a> BucketInterpreter<'a> { let (cmp_id, env) = self.execute_instruction(&bucket.sub_cmp_id, env, observe); let cmp_id = cmp_id.expect("sub_cmp_id subexpression must yield a value!").get_u32(); - let mut env = env.create_subcmp(&bucket.symbol, cmp_id, bucket.number_of_cmp, bucket.template_id); + let mut env = + env.create_subcmp(&bucket.symbol, cmp_id, bucket.number_of_cmp, bucket.template_id); // Run the subcomponents with 0 inputs directly for i in cmp_id..(cmp_id + bucket.number_of_cmp) { if env.subcmp_counter_is_zero(i) { @@ -625,11 +744,21 @@ impl<'a> BucketInterpreter<'a> { self.execute_instructions(&bucket.body, env, observe) } - pub fn execute_nop_bucket<'env>(&self, _bucket: &NopBucket, env: Env<'env>, _observe: bool) -> R<'env> { + pub fn execute_nop_bucket<'env>( + &self, + _bucket: &NopBucket, + env: Env<'env>, + _observe: bool, + ) -> R<'env> { (None, env) } - pub fn execute_instruction<'env>(&self, inst: &'env InstructionPointer, env: Env<'env>, observe: bool) -> R<'env> { + pub fn execute_instruction<'env>( + &self, + inst: &'env InstructionPointer, + env: Env<'env>, + observe: bool, + ) -> R<'env> { let continue_observing = if observe { self.observer.on_instruction(inst, &env) } else { observe }; match inst.as_ref() { diff --git a/circuit_passes/src/bucket_interpreter/operations.rs b/circuit_passes/src/bucket_interpreter/operations.rs index 9f5848823..4be7eb9d4 100644 --- a/circuit_passes/src/bucket_interpreter/operations.rs +++ b/circuit_passes/src/bucket_interpreter/operations.rs @@ -27,13 +27,9 @@ pub fn compute_operation(bucket: &ComputeBucket, stack: &Vec, p: &BigInt) OperatorType::BitOr => resolve_operation(value::bit_or_value, p, &stack), OperatorType::BitAnd => resolve_operation(value::bit_and_value, p, &stack), OperatorType::BitXor => resolve_operation(value::bit_xor_value, p, &stack), - OperatorType::PrefixSub => { - value::prefix_sub(&stack[0], p) - } + OperatorType::PrefixSub => value::prefix_sub(&stack[0], p), OperatorType::BoolNot => KnownU32((!stack[0].to_bool(p)).into()), - OperatorType::Complement => { - value::complement(&stack[0], p) - } + OperatorType::Complement => value::complement(&stack[0], p), OperatorType::ToAddress => value::to_address(&stack[0]), OperatorType::MulAddress => stack.iter().fold(KnownU32(1), value::mul_address), OperatorType::AddAddress => stack.iter().fold(KnownU32(0), value::add_address), @@ -50,7 +46,7 @@ pub fn compute_offset(indexes: &Vec, lengths: &Vec) -> usize { } let mut total_offset = indexes.last().copied().expect("must contain some indexes!"); let mut size_multiplier = lengths.last().copied().expect("must contain some array lengths!"); - for i in (0..lengths.len()-1).rev() { + for i in (0..lengths.len() - 1).rev() { total_offset += indexes[i] * size_multiplier; size_multiplier *= lengths[i]; } @@ -84,11 +80,11 @@ mod test { fn test_increments() { let lengths = vec![5, 7]; for i in 0..lengths[0] { - for j in 0..lengths[1]-1 { + for j in 0..lengths[1] - 1 { let offset = compute_offset(&vec![i, j], &lengths); let next_offset = compute_offset(&vec![i, j + 1], &lengths); assert_eq!(offset + 1, next_offset); } } } -} \ No newline at end of file +} diff --git a/circuit_passes/src/passes/deterministic_subcomponent_invocation.rs b/circuit_passes/src/passes/deterministic_subcomponent_invocation.rs index cb6448fcb..795c89b00 100644 --- a/circuit_passes/src/passes/deterministic_subcomponent_invocation.rs +++ b/circuit_passes/src/passes/deterministic_subcomponent_invocation.rs @@ -95,11 +95,11 @@ impl InterpreterObserver for DeterministicSubCmpInvokePass { fn on_call_bucket(&self, bucket: &CallBucket, env: &Env) -> bool { match &bucket.return_info { - ReturnType::Intermediate {..} => true, + ReturnType::Intermediate { .. } => true, ReturnType::Final(data) => { self.try_resolve_input_status(&data.dest_address_type, env); true - }, + } } } diff --git a/circuit_passes/src/passes/mapped_to_indexed.rs b/circuit_passes/src/passes/mapped_to_indexed.rs index 4a7df6b32..6e29072d0 100644 --- a/circuit_passes/src/passes/mapped_to_indexed.rs +++ b/circuit_passes/src/passes/mapped_to_indexed.rs @@ -19,16 +19,24 @@ pub struct MappedToIndexedPass { impl MappedToIndexedPass { pub fn new(prime: &String) -> Self { - MappedToIndexedPass { memory: PassMemory::new_cell(prime, "".to_string(), Default::default()), replacements: Default::default() } + MappedToIndexedPass { + memory: PassMemory::new_cell(prime, "".to_string(), Default::default()), + replacements: Default::default(), + } } - fn transform_mapped_loc_to_indexed_loc(&self, - cmp_address: &InstructionPointer, indexes: &Vec, signal_code: usize, env: &Env) -> LocationRule { - + fn transform_mapped_loc_to_indexed_loc( + &self, + cmp_address: &InstructionPointer, + indexes: &Vec, + signal_code: usize, + env: &Env, + ) -> LocationRule { let mem = self.memory.borrow(); let interpreter = mem.build_interpreter(self); - let (resolved_addr, acc_env) = interpreter.execute_instruction(cmp_address, env.clone(), false); + let (resolved_addr, acc_env) = + interpreter.execute_instruction(cmp_address, env.clone(), false); let resolved_addr = resolved_addr .expect("cmp_address instruction in SubcmpSignal must produce a value!") @@ -60,24 +68,30 @@ impl MappedToIndexedPass { } } - fn maybe_transform_location_rule(&self, address: &AddressType, location: &LocationRule, env: &Env) -> bool { + fn maybe_transform_location_rule( + &self, + address: &AddressType, + location: &LocationRule, + env: &Env, + ) -> bool { match address { - AddressType::Variable | AddressType::Signal => { - match location { - LocationRule::Indexed { .. } => true, - LocationRule::Mapped { .. } => unreachable!() - } + AddressType::Variable | AddressType::Signal => match location { + LocationRule::Indexed { .. } => true, + LocationRule::Mapped { .. } => unreachable!(), }, - AddressType::SubcmpSignal { cmp_address, .. } => { - match location { - LocationRule::Indexed { .. } => true, - LocationRule::Mapped { indexes, signal_code } => { - let indexed_rule = self.transform_mapped_loc_to_indexed_loc(cmp_address, indexes, *signal_code, env); - self.replacements.borrow_mut().insert(location.clone(), indexed_rule); - true - } + AddressType::SubcmpSignal { cmp_address, .. } => match location { + LocationRule::Indexed { .. } => true, + LocationRule::Mapped { indexes, signal_code } => { + let indexed_rule = self.transform_mapped_loc_to_indexed_loc( + cmp_address, + indexes, + *signal_code, + env, + ); + self.replacements.borrow_mut().insert(location.clone(), indexed_rule); + true } - } + }, } } } @@ -177,7 +191,7 @@ impl CircuitTransformationPass for MappedToIndexedPass { location: self.transform_instruction(location), template_header: template_header.clone(), }, - LocationRule::Mapped { .. } => unreachable!() + LocationRule::Mapped { .. } => unreachable!(), } } diff --git a/code_producers/src/llvm_elements/instructions.rs b/code_producers/src/llvm_elements/instructions.rs index 1496453be..afddc3bca 100644 --- a/code_producers/src/llvm_elements/instructions.rs +++ b/code_producers/src/llvm_elements/instructions.rs @@ -589,10 +589,7 @@ pub fn create_br<'a>(producer: &dyn LLVMIRProducer<'a>, bb: BasicBlock<'a>) -> A producer.llvm().builder.build_unconditional_branch(bb).as_any_value_enum() } -pub fn find_function<'a>( - producer: &dyn LLVMIRProducer<'a>, - name: &str, -) -> FunctionValue<'a> { +pub fn find_function<'a>(producer: &dyn LLVMIRProducer<'a>, name: &str) -> FunctionValue<'a> { producer .llvm() .module @@ -772,7 +769,7 @@ pub fn pointer_cast_with_name<'a>( producer: &dyn LLVMIRProducer<'a>, from: PointerValue<'a>, to: PointerType<'a>, - name: &str + name: &str, ) -> PointerValue<'a> { producer.builder().build_pointer_cast(from, to, name) } @@ -792,4 +789,4 @@ pub fn create_switch<'a>( cases: &[(IntValue<'a>, BasicBlock<'a>)], ) -> InstructionValue<'a> { producer.builder().build_switch(value, else_block, cases) -} \ No newline at end of file +} diff --git a/code_producers/src/llvm_elements/template.rs b/code_producers/src/llvm_elements/template.rs index 10b3946ba..3152d6493 100644 --- a/code_producers/src/llvm_elements/template.rs +++ b/code_producers/src/llvm_elements/template.rs @@ -49,7 +49,10 @@ impl<'a, 'b> LLVMIRProducer<'a> for TemplateLLVMIRProducer<'a, 'b> { } fn get_template_mem_arg(&self, run_fn: FunctionValue<'a>) -> ArrayValue<'a> { - run_fn.get_nth_param(self.template_ctx.signals_arg_offset as u32).unwrap().into_array_value() + run_fn + .get_nth_param(self.template_ctx.signals_arg_offset as u32) + .unwrap() + .into_array_value() } } @@ -125,7 +128,7 @@ impl<'a> TemplateCtx<'a> { pub fn load_subcmp( &self, producer: &dyn LLVMIRProducer<'a>, - id: AnyValueEnum<'a> + id: AnyValueEnum<'a>, ) -> PointerValue<'a> { create_gep(producer, self.subcmps, &[zero(producer), id.into_int_value()]) .into_pointer_value() @@ -137,8 +140,12 @@ impl<'a> TemplateCtx<'a> { producer: &dyn LLVMIRProducer<'a>, id: AnyValueEnum<'a>, ) -> PointerValue<'a> { - let signals = create_gep(producer, self.subcmps, &[zero(producer), id.into_int_value(), zero(producer)]) - .into_pointer_value(); + let signals = create_gep( + producer, + self.subcmps, + &[zero(producer), id.into_int_value(), zero(producer)], + ) + .into_pointer_value(); create_load(producer, signals).into_pointer_value() } @@ -167,10 +174,7 @@ impl<'a> TemplateCtx<'a> { } /// Returns a pointer to the signal array - pub fn get_signal_array( - &self, - _producer: &dyn LLVMIRProducer<'a>, - ) -> AnyValueEnum<'a> { + pub fn get_signal_array(&self, _producer: &dyn LLVMIRProducer<'a>) -> AnyValueEnum<'a> { let signals = self.current_function.get_nth_param(self.signals_arg_offset as u32).unwrap(); signals.into_pointer_value().into() } @@ -186,10 +190,7 @@ impl<'a> BodyCtx<'a> for TemplateCtx<'a> { create_gep(producer, self.stack, &[zero(producer), index]) } - fn get_variable_array( - &self, - _producer: &dyn LLVMIRProducer<'a>, - ) -> AnyValueEnum<'a> { + fn get_variable_array(&self, _producer: &dyn LLVMIRProducer<'a>) -> AnyValueEnum<'a> { self.stack.into() } } diff --git a/compiler/src/intermediate_representation/block_bucket.rs b/compiler/src/intermediate_representation/block_bucket.rs index 0069982c8..12a1f5623 100644 --- a/compiler/src/intermediate_representation/block_bucket.rs +++ b/compiler/src/intermediate_representation/block_bucket.rs @@ -1,5 +1,7 @@ use code_producers::llvm_elements::{LLVMInstruction, LLVMIRProducer}; -use crate::intermediate_representation::{BucketId, Instruction, InstructionList, InstructionPointer, new_id, SExp, ToSExp, UpdateId}; +use crate::intermediate_representation::{ + BucketId, Instruction, InstructionList, InstructionPointer, new_id, SExp, ToSExp, UpdateId, +}; use crate::intermediate_representation::ir_interface::{Allocate, IntoInstruction, ObtainMeta}; use crate::translating_traits::WriteLLVMIR; @@ -10,7 +12,7 @@ pub struct BlockBucket { pub line: usize, pub message_id: usize, pub body: InstructionList, - pub n_iters: usize + pub n_iters: usize, } impl IntoInstruction for BlockBucket { @@ -46,7 +48,10 @@ impl ToString for BlockBucket { body = format!("{} - {};\n", body, i.to_string()); } body = format!("{}]", body); - format!("BLOCK(line:{},template_id:{},n_iterations:{},body:{})", line, template_id, self.n_iters, body) + format!( + "BLOCK(line:{},template_id:{},n_iterations:{},body:{})", + line, template_id, self.n_iters, body + ) } } @@ -57,7 +62,7 @@ impl ToSExp for BlockBucket { SExp::Atom(format!("line:{}", self.line)), SExp::Atom(format!("template_id:{}", self.message_id)), SExp::Atom(format!("n_iterations:{}", self.n_iters)), - SExp::List(self.body.iter().map(|i| i.to_sexp()).collect()) + SExp::List(self.body.iter().map(|i| i.to_sexp()).collect()), ]) } } @@ -72,7 +77,10 @@ impl UpdateId for BlockBucket { } impl WriteLLVMIR for BlockBucket { - fn produce_llvm_ir<'a, 'b>(&self, producer: &'b dyn LLVMIRProducer<'a>) -> Option> { + fn produce_llvm_ir<'a, 'b>( + &self, + producer: &'b dyn LLVMIRProducer<'a>, + ) -> Option> { Self::manage_debug_loc_from_curr(producer, self); let mut last = None; @@ -81,4 +89,4 @@ impl WriteLLVMIR for BlockBucket { } last } -} \ No newline at end of file +} diff --git a/compiler/src/intermediate_representation/constraint_bucket.rs b/compiler/src/intermediate_representation/constraint_bucket.rs index 74a9bc47d..ddf04fe75 100644 --- a/compiler/src/intermediate_representation/constraint_bucket.rs +++ b/compiler/src/intermediate_representation/constraint_bucket.rs @@ -1,5 +1,7 @@ use code_producers::c_elements::CProducer; -use code_producers::llvm_elements::{LLVMInstruction, new_constraint, to_basic_metadata_enum, LLVMIRProducer}; +use code_producers::llvm_elements::{ + LLVMInstruction, new_constraint, to_basic_metadata_enum, LLVMIRProducer, +}; use code_producers::llvm_elements::instructions::{create_call, create_load, get_instruction_arg}; use code_producers::llvm_elements::stdlib::{CONSTRAINT_VALUE_FN_NAME, CONSTRAINT_VALUES_FN_NAME}; use code_producers::wasm_elements::WASMProducer; @@ -10,21 +12,21 @@ use crate::translating_traits::{WriteC, WriteLLVMIR, WriteWasm}; #[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd)] pub enum ConstraintBucket { Substitution(InstructionPointer), - Equality(InstructionPointer) + Equality(InstructionPointer), } impl ConstraintBucket { pub fn unwrap(&self) -> &InstructionPointer { match self { ConstraintBucket::Substitution(i) => i, - ConstraintBucket::Equality(i) => i + ConstraintBucket::Equality(i) => i, } } pub fn unwrap_mut(&mut self) -> &mut InstructionPointer { match self { ConstraintBucket::Substitution(i) => i, - ConstraintBucket::Equality(i) => i + ConstraintBucket::Equality(i) => i, } } } @@ -45,20 +47,23 @@ impl ObtainMeta for ConstraintBucket { fn get_source_file_id(&self) -> &Option { match self { ConstraintBucket::Substitution(i) => i, - ConstraintBucket::Equality(i) => i - }.get_source_file_id() + ConstraintBucket::Equality(i) => i, + } + .get_source_file_id() } fn get_line(&self) -> usize { match self { ConstraintBucket::Substitution(i) => i, - ConstraintBucket::Equality(i) => i - }.get_line() + ConstraintBucket::Equality(i) => i, + } + .get_line() } fn get_message_id(&self) -> usize { match self { ConstraintBucket::Substitution(i) => i, - ConstraintBucket::Equality(i) => i - }.get_message_id() + ConstraintBucket::Equality(i) => i, + } + .get_message_id() } } @@ -68,18 +73,16 @@ impl ToString for ConstraintBucket { "CONSTRAINT:{}", match self { ConstraintBucket::Substitution(i) => i, - ConstraintBucket::Equality(i) => i - }.to_string() + ConstraintBucket::Equality(i) => i, + } + .to_string() ) } } impl ToSExp for ConstraintBucket { fn to_sexp(&self) -> SExp { - SExp::List(vec![ - SExp::Atom("CONSTRAINT".to_string()), - self.unwrap().to_sexp(), - ]) + SExp::List(vec![SExp::Atom("CONSTRAINT".to_string()), self.unwrap().to_sexp()]) } } @@ -90,14 +93,19 @@ impl UpdateId for ConstraintBucket { } impl WriteLLVMIR for ConstraintBucket { - fn produce_llvm_ir<'a, 'b>(&self, producer: &'b dyn LLVMIRProducer<'a>) -> Option> { + fn produce_llvm_ir<'a, 'b>( + &self, + producer: &'b dyn LLVMIRProducer<'a>, + ) -> Option> { Self::manage_debug_loc_from_curr(producer, self); // TODO: Create the constraint call let prev = match self { ConstraintBucket::Substitution(i) => i, - ConstraintBucket::Equality(i) => i - }.produce_llvm_ir(producer).expect("A constrained instruction MUST produce a value!"); + ConstraintBucket::Equality(i) => i, + } + .produce_llvm_ir(producer) + .expect("A constrained instruction MUST produce a value!"); const STORE_SRC_IDX: u32 = 1; const STORE_DST_IDX: u32 = 0; @@ -107,20 +115,27 @@ impl WriteLLVMIR for ConstraintBucket { ConstraintBucket::Substitution(_) => { let lhs = get_instruction_arg(prev.into_instruction_value(), STORE_DST_IDX); let rhs_ptr = get_instruction_arg(prev.into_instruction_value(), STORE_SRC_IDX); - let rhs = create_load(producer,rhs_ptr.into_pointer_value()); + let rhs = create_load(producer, rhs_ptr.into_pointer_value()); let constr = new_constraint(producer); - let call = create_call(producer,CONSTRAINT_VALUES_FN_NAME, &[ - to_basic_metadata_enum(lhs), - to_basic_metadata_enum(rhs), - to_basic_metadata_enum(constr)]); + let call = create_call( + producer, + CONSTRAINT_VALUES_FN_NAME, + &[ + to_basic_metadata_enum(lhs), + to_basic_metadata_enum(rhs), + to_basic_metadata_enum(constr), + ], + ); Some(call) } ConstraintBucket::Equality(_) => { let bool = get_instruction_arg(prev.into_instruction_value(), ASSERT_IDX); let constr = new_constraint(producer); - let call = create_call(producer, CONSTRAINT_VALUE_FN_NAME, &[ - to_basic_metadata_enum(bool), - to_basic_metadata_enum(constr)]); + let call = create_call( + producer, + CONSTRAINT_VALUE_FN_NAME, + &[to_basic_metadata_enum(bool), to_basic_metadata_enum(constr)], + ); Some(call) } } @@ -131,8 +146,9 @@ impl WriteWasm for ConstraintBucket { fn produce_wasm(&self, producer: &WASMProducer) -> Vec { match self { ConstraintBucket::Substitution(i) => i, - ConstraintBucket::Equality(i) => i - }.produce_wasm(producer) + ConstraintBucket::Equality(i) => i, + } + .produce_wasm(producer) } } @@ -140,7 +156,8 @@ impl WriteC for ConstraintBucket { fn produce_c(&self, producer: &CProducer, is_parallel: Option) -> (Vec, String) { match self { ConstraintBucket::Substitution(i) => i, - ConstraintBucket::Equality(i) => i - }.produce_c(producer, is_parallel) + ConstraintBucket::Equality(i) => i, + } + .produce_c(producer, is_parallel) } -} \ No newline at end of file +} diff --git a/compiler/src/intermediate_representation/nop_bucket.rs b/compiler/src/intermediate_representation/nop_bucket.rs index 3eb92a935..1b129f6ed 100644 --- a/compiler/src/intermediate_representation/nop_bucket.rs +++ b/compiler/src/intermediate_representation/nop_bucket.rs @@ -1,5 +1,7 @@ use code_producers::llvm_elements::{LLVMInstruction, LLVMIRProducer}; -use crate::intermediate_representation::{BucketId, Instruction, InstructionPointer, new_id, SExp, ToSExp, UpdateId}; +use crate::intermediate_representation::{ + BucketId, Instruction, InstructionPointer, new_id, SExp, ToSExp, UpdateId, +}; use crate::intermediate_representation::ir_interface::{Allocate, IntoInstruction, ObtainMeta}; use crate::translating_traits::WriteLLVMIR; @@ -51,7 +53,10 @@ impl UpdateId for NopBucket { } impl WriteLLVMIR for NopBucket { - fn produce_llvm_ir<'a, 'b>(&self, _producer: &'b dyn LLVMIRProducer<'a>) -> Option> { + fn produce_llvm_ir<'a, 'b>( + &self, + _producer: &'b dyn LLVMIRProducer<'a>, + ) -> Option> { None } -} \ No newline at end of file +} diff --git a/parser/src/errors.rs b/parser/src/errors.rs index 5af6dbd9b..cf81f3b47 100644 --- a/parser/src/errors.rs +++ b/parser/src/errors.rs @@ -60,7 +60,7 @@ impl MultipleMainError { } } -pub struct CompilerVersionError{ +pub struct CompilerVersionError { pub path: String, pub required_version: Version, pub version: Version, @@ -74,81 +74,79 @@ impl CompilerVersionError { } } - - -pub struct NoCompilerVersionWarning{ +pub struct NoCompilerVersionWarning { pub path: String, pub version: Version, } impl NoCompilerVersionWarning { pub fn produce_report(error: Self) -> Report { Report::warning( - format!("File {} does not include pragma version. Assuming pragma version {:?}", error.path, error.version), + format!( + "File {} does not include pragma version. Assuming pragma version {:?}", + error.path, error.version + ), ReportCode::NoCompilerVersionWarning, ) } } -pub struct AnonymousCompError{ +pub struct AnonymousCompError { pub location: FileLocation, - pub msg : String + pub msg: String, } impl AnonymousCompError { - pub fn produce_report( error : Self) -> Report { - Report::error( - format!("{}", error.msg), - ReportCode::AnonymousCompError, - ) + pub fn produce_report(error: Self) -> Report { + Report::error(format!("{}", error.msg), ReportCode::AnonymousCompError) } - pub fn anonymous_inside_condition_error(meta : Meta) -> Report { - let error = AnonymousCompError {msg: "An anonymous component cannot be used inside a condition ".to_string(), location : meta.location.clone()}; - let mut report = AnonymousCompError::produce_report(error); - let file_id = meta.get_file_id().clone(); - report.add_primary( - meta.location, - file_id, - "This is an anonymous component used inside a condition".to_string(), - ); - report + pub fn anonymous_inside_condition_error(meta: Meta) -> Report { + let error = AnonymousCompError { + msg: "An anonymous component cannot be used inside a condition ".to_string(), + location: meta.location.clone(), + }; + let mut report = AnonymousCompError::produce_report(error); + let file_id = meta.get_file_id().clone(); + report.add_primary( + meta.location, + file_id, + "This is an anonymous component used inside a condition".to_string(), + ); + report } - - pub fn anonymous_general_error(meta : Meta, msg : String) -> Report { - let error = AnonymousCompError {msg, location : meta.location.clone()}; - let mut report = AnonymousCompError::produce_report(error); - let file_id = meta.get_file_id().clone(); - report.add_primary( - meta.location, - file_id, - "This is the anonymous component whose use is not allowed".to_string(), - ); - report + + pub fn anonymous_general_error(meta: Meta, msg: String) -> Report { + let error = AnonymousCompError { msg, location: meta.location.clone() }; + let mut report = AnonymousCompError::produce_report(error); + let file_id = meta.get_file_id().clone(); + report.add_primary( + meta.location, + file_id, + "This is the anonymous component whose use is not allowed".to_string(), + ); + report } } -pub struct TupleError{ +pub struct TupleError { pub location: FileLocation, - pub msg : String + pub msg: String, } impl TupleError { - pub fn produce_report( error : Self) -> Report { - Report::error( - format!("{}", error.msg), - ReportCode::TupleError, - ) + pub fn produce_report(error: Self) -> Report { + Report::error(format!("{}", error.msg), ReportCode::TupleError) } - pub fn tuple_general_error(meta : Meta, msg : String) -> Report { - let error = TupleError {msg, location : meta.location.clone()}; - let mut report = TupleError::produce_report(error); - let file_id = meta.get_file_id().clone(); - report.add_primary( - meta.location, - file_id, - "This is the tuple whose use is not allowed".to_string(), - ); - report + pub fn tuple_general_error(meta: Meta, msg: String) -> Report { + let error = TupleError { msg, location: meta.location.clone() }; + let mut report = TupleError::produce_report(error); + let file_id = meta.get_file_id().clone(); + report.add_primary( + meta.location, + file_id, + "This is the tuple whose use is not allowed".to_string(), + ); + report } -} \ No newline at end of file +}