From 936950f2667a0a44e21ba748cc55e38ff743e007 Mon Sep 17 00:00:00 2001 From: clararod9 Date: Tue, 19 Jul 2022 16:20:16 -0700 Subject: [PATCH 01/23] adding more precise analysis for the array dimensions and adding inicialization of variables to 0 --- compiler/Cargo.toml | 8 +-- compiler/src/hir/component_preprocess.rs | 1 + compiler/src/hir/merger.rs | 35 ++++++++++- compiler/src/hir/sugar_cleaner.rs | 52 +++++++++++++++- compiler/src/hir/type_inference.rs | 25 +++++++- compiler/src/lib.rs | 2 + constraint_generation/src/execute.rs | 48 ++++++++++++++- .../src/execution_data/filters.rs | 6 ++ .../src/abstract_syntax_tree/ast.rs | 5 ++ .../src/abstract_syntax_tree/ast_shortcuts.rs | 14 ++++- .../expression_builders.rs | 4 ++ .../abstract_syntax_tree/expression_impl.rs | 19 ++++++ program_structure/src/utils/memory_slice.rs | 59 +++++++++++++++---- .../functions_free_of_template_elements.rs | 6 ++ .../src/analyzers/symbol_analysis.rs | 18 ++++++ type_analysis/src/analyzers/tag_analysis.rs | 3 + type_analysis/src/analyzers/type_check.rs | 26 ++++++++ .../src/analyzers/type_given_function.rs | 17 ++++++ .../src/analyzers/unknown_known_analysis.rs | 6 ++ .../src/decorators/constants_handler.rs | 16 +++++ .../src/decorators/type_reduction.rs | 4 ++ 21 files changed, 350 insertions(+), 24 deletions(-) diff --git a/compiler/Cargo.toml b/compiler/Cargo.toml index d0691d115..c744f16d0 100644 --- a/compiler/Cargo.toml +++ b/compiler/Cargo.toml @@ -1,13 +1,13 @@ [package] name = "compiler" -version = "2.0.1" -authors = ["hermeGarcia "] +version = "2.0.4" +authors = ["Costa Group UCM","iden3"] edition = "2018" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] constant_tracking = {path = "../constant_tracking"} program_structure = {path = "../program_structure"} code_producers = {path = "../code_producers"} num-bigint-dig = "0.6.0" +num-traits = "0.2.6" + diff --git a/compiler/src/hir/component_preprocess.rs b/compiler/src/hir/component_preprocess.rs index 5ef5474e5..071dca73f 100644 --- a/compiler/src/hir/component_preprocess.rs +++ b/compiler/src/hir/component_preprocess.rs @@ -20,6 +20,7 @@ fn rm_statement(stmt: &mut Statement) { rm_substitution(stmt); } else{ + } } diff --git a/compiler/src/hir/merger.rs b/compiler/src/hir/merger.rs index 8f5bc80d5..d34df01d6 100644 --- a/compiler/src/hir/merger.rs +++ b/compiler/src/hir/merger.rs @@ -4,6 +4,8 @@ use super::sugar_cleaner; use super::very_concrete_program::*; use program_structure::ast::*; use program_structure::program_archive::ProgramArchive; +use num_traits::{ToPrimitive}; + pub fn run_preprocessing(vcp: &mut VCP, program_archive: ProgramArchive) { let mut state = build_function_knowledge(program_archive); @@ -242,11 +244,14 @@ fn produce_vcf_conditional(stmt: &Statement, state: &mut State, environment: &mu } fn produce_vcf_array(expr: &Expression, state: &mut State, environment: &E) { - use Expression::ArrayInLine; + use Expression::{ArrayInLine, UniformArray}; if let ArrayInLine { values, .. } = expr { for v in values { produce_vcf_expr(v, state, environment); } + } else if let UniformArray { value, dimension, .. } = expr { + produce_vcf_expr(value, state, environment); + produce_vcf_expr(dimension, state, environment); } else { unreachable!(); } @@ -491,11 +496,14 @@ fn link_call(expr: &mut Expression, state: &State, env: &E) { } fn link_array(expr: &mut Expression, state: &State, env: &E) { - use Expression::ArrayInLine; + use Expression::{ArrayInLine, UniformArray}; if let ArrayInLine { values, .. } = expr { for v in values { link_expression(v, state, env) } + } else if let UniformArray { value, dimension, .. } = expr { + link_expression(value, state, env); + link_expression(dimension, state, env); } else { unreachable!(); } @@ -584,13 +592,34 @@ fn cast_type_variable(expr: &Expression, state: &State, environment: &E) -> VCT } } +fn cast_dimension(ae_index: &Expression) -> Option { + use Expression::Number; + + if let Number(_, value) = ae_index { + value.to_usize() + } else { + Option::None + } +} + + fn cast_type_array(expr: &Expression, state: &State, environment: &E) -> VCT { - use Expression::ArrayInLine; + use Expression::{ArrayInLine, UniformArray}; if let ArrayInLine { values, .. } = expr { let mut result = vec![values.len()]; let mut inner_type = cast_type_expression(&values[0], state, environment); result.append(&mut inner_type); result + } else if let UniformArray { value, dimension, .. } = expr { + let usable_dimension = if let Option::Some(dimension) = cast_dimension(&dimension) { + dimension + } else { + unreachable!() + }; + let mut lengths = vec![usable_dimension]; + let mut inner_type = cast_type_expression(value, state, environment); + lengths.append(&mut inner_type); + lengths } else { unreachable!(); } diff --git a/compiler/src/hir/sugar_cleaner.rs b/compiler/src/hir/sugar_cleaner.rs index 41a73e0fd..f7c7cb53f 100644 --- a/compiler/src/hir/sugar_cleaner.rs +++ b/compiler/src/hir/sugar_cleaner.rs @@ -1,5 +1,7 @@ use super::very_concrete_program::*; use program_structure::ast::*; +use num_traits::{ToPrimitive}; + struct ExtendedSyntax { initializations: Vec, @@ -275,7 +277,7 @@ fn extend_switch(expr: &mut Expression, state: &mut State, context: &Context) -> } fn extend_array(expr: &mut Expression, state: &mut State, context: &Context) -> ExtendedSyntax { - use Expression::ArrayInLine; + use Expression::{ArrayInLine, UniformArray}; if let ArrayInLine { values, .. } = expr { let mut initializations = vec![]; for v in values.iter_mut() { @@ -284,6 +286,16 @@ fn extend_array(expr: &mut Expression, state: &mut State, context: &Context) -> } sugar_filter(values, state, &mut initializations); ExtendedSyntax { initializations } + } else if let UniformArray { value, dimension, .. } = expr { + let mut value_expand = extend_expression(value, state, context); + let mut dimension_expand = extend_expression(dimension, state, context); + value_expand.initializations.append(&mut dimension_expand.initializations); + let mut extended = value_expand; + let mut expr = vec![*value.clone(), *dimension.clone()]; + sugar_filter(&mut expr, state, &mut extended.initializations); + *dimension = Box::new(expr.pop().unwrap()); + *value = Box::new(expr.pop().unwrap()); + extended } else { unreachable!(); } @@ -492,9 +504,19 @@ fn rhe_switch_case(stmt: Statement, stmts: &mut Vec) { } } +fn cast_dimension(ae_index: &Expression) -> Option { + use Expression::Number; + + if let Number(_, value) = ae_index { + value.to_usize() + } else { + Option::None + } +} + fn rhe_array_case(stmt: Statement, stmts: &mut Vec) { use num_bigint_dig::BigInt; - use Expression::{ArrayInLine, Number}; + use Expression::{ArrayInLine, Number, UniformArray}; use Statement::Substitution; if let Substitution { var, access, op, rhe, meta } = stmt { if let ArrayInLine { values, .. } = rhe { @@ -516,10 +538,34 @@ fn rhe_array_case(stmt: Statement, stmts: &mut Vec) { stmts.push(sub); index += 1; } + } else if let UniformArray { value, dimension, .. } = rhe { + let usable_dimension = if let Option::Some(dimension) = cast_dimension(&dimension) { + dimension + } else { + unreachable!() + }; + let mut index: usize = 0; + while index < usable_dimension { + let mut index_meta = meta.clone(); + index_meta.get_mut_memory_knowledge().set_concrete_dimensions(vec![]); + let expr_index = Number(index_meta, BigInt::from(index)); + let as_access = Access::ArrayAccess(expr_index); + let mut accessed_with = access.clone(); + accessed_with.push(as_access); + let sub = Substitution { + op, + var: var.clone(), + access: accessed_with, + meta: meta.clone(), + rhe: *value.clone(), + }; + stmts.push(sub); + index += 1; + } } else { unreachable!() } } else { unreachable!() } -} +} \ No newline at end of file diff --git a/compiler/src/hir/type_inference.rs b/compiler/src/hir/type_inference.rs index 79756eeda..4baa811b9 100644 --- a/compiler/src/hir/type_inference.rs +++ b/compiler/src/hir/type_inference.rs @@ -2,6 +2,7 @@ use super::analysis_utilities::*; use super::very_concrete_program::*; use program_structure::ast::*; use std::collections::HashSet; +use num_traits::{ToPrimitive}; struct SearchInfo { environment: E, @@ -171,8 +172,18 @@ fn infer_type_variable(expr: &Expression, _state: &State, context: &mut SearchIn } } +fn cast_dimension(ae_index: &Expression) -> Option { + use Expression::Number; + + if let Number(_, value) = ae_index { + value.to_usize() + } else { + Option::None + } +} + fn infer_type_array(expr: &Expression, state: &State, context: &mut SearchInfo) -> Option { - use Expression::ArrayInLine; + use Expression::{ArrayInLine, UniformArray}; if let ArrayInLine { values, .. } = expr { let mut lengths = vec![values.len()]; let with_type = infer_type_expresion(&values[0], state, context); @@ -180,6 +191,18 @@ fn infer_type_array(expr: &Expression, state: &State, context: &mut SearchInfo) lengths.append(&mut l); lengths }) + } else if let UniformArray { value, dimension, .. } = expr { + let usable_dimension = if let Option::Some(dimension) = cast_dimension(&dimension) { + dimension + } else { + unreachable!() + }; + let mut lengths = vec![usable_dimension]; + let with_type = infer_type_expresion(&value, state, context); + with_type.map(|mut l| { + lengths.append(&mut l); + lengths + }) } else { unreachable!() } diff --git a/compiler/src/lib.rs b/compiler/src/lib.rs index 955840cd7..a9c4871e0 100644 --- a/compiler/src/lib.rs +++ b/compiler/src/lib.rs @@ -2,6 +2,8 @@ mod circuit_design; mod intermediate_representation; mod ir_processing; +pub extern crate num_bigint_dig as num_bigint; +pub extern crate num_traits; pub mod compiler_interface; pub mod hir; diff --git a/constraint_generation/src/execute.rs b/constraint_generation/src/execute.rs index 89228c22e..088a0c4c3 100644 --- a/constraint_generation/src/execute.rs +++ b/constraint_generation/src/execute.rs @@ -385,6 +385,41 @@ fn execute_expression( } FoldedValue { arithmetic_slice: Option::Some(array_slice), ..FoldedValue::default() } } + UniformArray { meta, value, dimension, .. } => { + let f_dimension = execute_expression(dimension, program_archive, runtime, flag_verbose)?; + let arithmetic_dimension = safe_unwrap_to_single_arithmetic_expression(f_dimension, line!()); + let usable_dimension = if let Option::Some(dimension) = cast_index(&arithmetic_dimension) { + dimension + } else { + unreachable!() + }; + + let f_value = execute_expression(value, program_archive, runtime, flag_verbose)?; + let slice_value = safe_unwrap_to_arithmetic_slice(f_value, line!()); + + let mut dims = vec![usable_dimension]; + for dim in slice_value.route() { + dims.push(*dim); + } + + let mut array_slice = AExpressionSlice::new_with_route(&dims, &AExpr::default()); + let mut row: SliceCapacity = 0; + while row < usable_dimension { + let memory_insert_result = AExpressionSlice::insert_values( + &mut array_slice, + &[row], + &slice_value, + ); + treat_result_with_memory_error( + memory_insert_result, + meta, + &mut runtime.runtime_errors, + &runtime.call_trace, + )?; + row += 1; + } + FoldedValue { arithmetic_slice: Option::Some(array_slice), ..FoldedValue::default() } + } InfixOp { meta, lhe, infix_op, rhe, .. } => { let l_fold = execute_expression(lhe, program_archive, runtime, flag_verbose)?; let r_fold = execute_expression(rhe, program_archive, runtime, flag_verbose)?; @@ -1161,6 +1196,14 @@ fn cast_indexing(ae_indexes: &[AExpr]) -> Option> { Option::Some(sc_indexes) } +fn cast_index(ae_index: &AExpr) -> Option { + if !ae_index.is_number() { + return Option::None; + } + let index = AExpr::get_usize(ae_index).unwrap(); + Option::Some(index) +} + /* Usable representation of a series of accesses performed over a symbol. AccessingInformation { @@ -1278,7 +1321,10 @@ fn treat_result_with_memory_error( ), MemoryError::OutOfBoundsError => { Report::error("Out of bounds exception".to_string(), RuntimeError) - } + }, + MemoryError::MismatchedDimensions => { + Report::error(" Typing error found: mismatched dimensions".to_string(), RuntimeError) + }, MemoryError::UnknownSizeDimension => { Report::error("Array dimension with unknown size".to_string(), RuntimeError) } diff --git a/constraint_generation/src/execution_data/filters.rs b/constraint_generation/src/execution_data/filters.rs index 6618fe21d..f8451869d 100644 --- a/constraint_generation/src/execution_data/filters.rs +++ b/constraint_generation/src/execution_data/filters.rs @@ -169,5 +169,11 @@ fn apply_computed_expr(expr: &mut Expression, analysis: &Analysis) { ArrayInLine { values, .. } => { apply_computed_expr_vec(values, analysis); } + UniformArray { value, dimension, .. } => { + *value = Box::new(computed_or_original(analysis, value)); + *dimension = Box::new(computed_or_original(analysis, dimension)); + apply_computed_expr(value, analysis); + apply_computed_expr(dimension, analysis); + } } } diff --git a/program_structure/src/abstract_syntax_tree/ast.rs b/program_structure/src/abstract_syntax_tree/ast.rs index 3b95907fc..f1805f693 100644 --- a/program_structure/src/abstract_syntax_tree/ast.rs +++ b/program_structure/src/abstract_syntax_tree/ast.rs @@ -252,6 +252,11 @@ pub enum Expression { meta: Meta, values: Vec, }, + UniformArray { + meta: Meta, + value: Box, + dimension: Box, + } } #[derive(Clone)] diff --git a/program_structure/src/abstract_syntax_tree/ast_shortcuts.rs b/program_structure/src/abstract_syntax_tree/ast_shortcuts.rs index 188351b54..cb199fa07 100644 --- a/program_structure/src/abstract_syntax_tree/ast_shortcuts.rs +++ b/program_structure/src/abstract_syntax_tree/ast_shortcuts.rs @@ -51,6 +51,8 @@ pub fn split_declaration_into_single_nodes( symbols: Vec, op: AssignOp, ) -> Statement { + use crate::ast_shortcuts::VariableType::Var; + let mut initializations = Vec::new(); for symbol in symbols { @@ -59,13 +61,23 @@ pub fn split_declaration_into_single_nodes( let name = symbol.name.clone(); let dimensions = symbol.is_array; let possible_init = symbol.init; - let single_declaration = build_declaration(with_meta, has_type, name, dimensions); + let single_declaration = build_declaration(with_meta, has_type, name, dimensions.clone()); initializations.push(single_declaration); if let Option::Some(init) = possible_init { let substitution = build_substitution(meta.clone(), symbol.name, vec![], op, init); initializations.push(substitution); } + else if xtype == Var { + let mut value = Expression:: Number(meta.clone(), BigInt::from(0)); + for dim_expr in dimensions.iter().rev(){ + value = build_uniform_array(meta.clone(), value, dim_expr.clone()); + } + + let substitution = + build_substitution(meta.clone(), symbol.name, vec![], op, value); + initializations.push(substitution); + } } build_initialization_block(meta, xtype, initializations) } \ No newline at end of file diff --git a/program_structure/src/abstract_syntax_tree/expression_builders.rs b/program_structure/src/abstract_syntax_tree/expression_builders.rs index b0dbeae4b..69358c8b8 100644 --- a/program_structure/src/abstract_syntax_tree/expression_builders.rs +++ b/program_structure/src/abstract_syntax_tree/expression_builders.rs @@ -44,3 +44,7 @@ pub fn build_call(meta: Meta, id: String, args: Vec) -> Expression { pub fn build_array_in_line(meta: Meta, values: Vec) -> Expression { ArrayInLine { meta, values } } + +pub fn build_uniform_array(meta: Meta, value: Expression, dimension: Expression) -> Expression { + UniformArray { meta, value: Box::new(value), dimension: Box::new(dimension) } +} diff --git a/program_structure/src/abstract_syntax_tree/expression_impl.rs b/program_structure/src/abstract_syntax_tree/expression_impl.rs index f84b77bd5..86d441286 100644 --- a/program_structure/src/abstract_syntax_tree/expression_impl.rs +++ b/program_structure/src/abstract_syntax_tree/expression_impl.rs @@ -11,6 +11,7 @@ impl Expression { | Number(meta, ..) | Call { meta, .. } | ArrayInLine { meta, .. } => meta, + | UniformArray { meta, .. } => meta, } } pub fn get_mut_meta(&mut self) -> &mut Meta { @@ -23,6 +24,7 @@ impl Expression { | Number(meta, ..) | Call { meta, .. } | ArrayInLine { meta, .. } => meta, + | UniformArray { meta, .. } => meta, } } @@ -30,6 +32,8 @@ impl Expression { use Expression::*; if let ArrayInLine { .. } = self { true + } else if let UniformArray { .. } = self{ + true } else { false } @@ -107,6 +111,9 @@ impl FillMeta for Expression { ArrayInLine { meta, values, .. } => { fill_array_inline(meta, values, file_id, element_id) } + UniformArray { meta, value, dimension, .. } => { + fill_uniform_array(meta, value, dimension, file_id, element_id) + } } } } @@ -173,3 +180,15 @@ fn fill_array_inline( v.fill(file_id, element_id); } } + +fn fill_uniform_array( + meta: &mut Meta, + value: &mut Expression, + dimensions: &mut Expression, + file_id: usize, + element_id: &mut usize, +) { + meta.set_file_id(file_id); + value.fill(file_id, element_id); + dimensions.fill(file_id, element_id); +} diff --git a/program_structure/src/utils/memory_slice.rs b/program_structure/src/utils/memory_slice.rs index 4c274c3d2..7bfc05050 100644 --- a/program_structure/src/utils/memory_slice.rs +++ b/program_structure/src/utils/memory_slice.rs @@ -5,6 +5,7 @@ pub enum MemoryError { AssignmentError, InvalidAccess, UnknownSizeDimension, + MismatchedDimensions, } pub type SliceCapacity = usize; pub type SimpleSlice = MemorySlice; @@ -48,6 +49,7 @@ impl MemorySlice { memory_slice: &MemorySlice, access: &[SliceCapacity], ) -> Result { + if access.len() > memory_slice.route.len() { return Result::Err(MemoryError::OutOfBoundsError); } @@ -65,6 +67,37 @@ impl MemorySlice { } Result::Ok(cell) } + pub fn check_correct_dims( + memory_slice: &MemorySlice, + access: &[SliceCapacity], + new_values: &MemorySlice, + ) -> Result<(), MemoryError> { + + if access.len() + new_values.route.len() > memory_slice.route.len() { + return Result::Err(MemoryError::OutOfBoundsError); + } + + let mut i: SliceCapacity = 0; + + while i < access.len() { + if access[i] >= memory_slice.route[i] { + return Result::Err(MemoryError::OutOfBoundsError); + } + i += 1; + } + + let initial_index_new: SliceCapacity = i; + i = 0; + + while i < new_values.route.len() { + if new_values.route[i] != memory_slice.route[initial_index_new + i] { + return Result::Err(MemoryError::MismatchedDimensions); + } + i += 1; + } + Result::Ok(()) + } + // Returns the new route and the total number of cells // that a slice with such route will have fn generate_new_route_from_access( @@ -131,17 +164,22 @@ impl MemorySlice { access: &[SliceCapacity], new_values: &MemorySlice, ) -> Result<(), MemoryError> { - let mut cell = MemorySlice::get_initial_cell(memory_slice, access)?; - if MemorySlice::get_number_of_cells(new_values) - > (MemorySlice::get_number_of_cells(memory_slice) - cell) - { - return Result::Err(MemoryError::OutOfBoundsError); - } - for value in new_values.values.iter() { - memory_slice.values[cell] = value.clone(); - cell += 1; + match MemorySlice::check_correct_dims(memory_slice, access, new_values){ + Result::Ok(_) => { + let mut cell = MemorySlice::get_initial_cell(memory_slice, access)?; + // if MemorySlice::get_number_of_cells(new_values) + // > (MemorySlice::get_number_of_cells(memory_slice) - cell) + // { + // return Result::Err(MemoryError::OutOfBoundsError); + // } + for value in new_values.values.iter() { + memory_slice.values[cell] = value.clone(); + cell += 1; + } + Result::Ok(()) + }, + Result::Err(error) => return Err(error), } - Result::Ok(()) } pub fn access_values( @@ -175,7 +213,6 @@ impl MemorySlice { pub fn is_single(&self) -> bool { self.route.is_empty() } - /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! Calling this function with a MemorySlice ! diff --git a/type_analysis/src/analyzers/functions_free_of_template_elements.rs b/type_analysis/src/analyzers/functions_free_of_template_elements.rs index 00ff96ac9..ca774f80a 100644 --- a/type_analysis/src/analyzers/functions_free_of_template_elements.rs +++ b/type_analysis/src/analyzers/functions_free_of_template_elements.rs @@ -175,5 +175,11 @@ fn analyse_expression( analyse_expression(value, function_names, reports); } } + UniformArray {value, dimension, .. } => { + analyse_expression(value, function_names, reports); + analyse_expression(dimension, function_names, reports); + + + } } } diff --git a/type_analysis/src/analyzers/symbol_analysis.rs b/type_analysis/src/analyzers/symbol_analysis.rs index da311b943..a0fb3e635 100644 --- a/type_analysis/src/analyzers/symbol_analysis.rs +++ b/type_analysis/src/analyzers/symbol_analysis.rs @@ -388,6 +388,24 @@ fn analyze_expression( ); } } + Expression::UniformArray{ value, dimension, .. } => { + analyze_expression( + value, + file_id, + function_info, + template_info, + reports, + environment, + ); + analyze_expression( + dimension, + file_id, + function_info, + template_info, + reports, + environment, + ); + }, _ => {} } } diff --git a/type_analysis/src/analyzers/tag_analysis.rs b/type_analysis/src/analyzers/tag_analysis.rs index 6daa5fb58..e98c5fee7 100644 --- a/type_analysis/src/analyzers/tag_analysis.rs +++ b/type_analysis/src/analyzers/tag_analysis.rs @@ -163,6 +163,9 @@ fn expression_inspection( ArrayInLine { .. } => { ExpressionResult::ArithmeticExpression(SignalElementType::FieldElement) } + UniformArray { .. } => { + ExpressionResult::ArithmeticExpression(SignalElementType::FieldElement) + } } } diff --git a/type_analysis/src/analyzers/type_check.rs b/type_analysis/src/analyzers/type_check.rs index 55dd6efaf..a4bb850f5 100644 --- a/type_analysis/src/analyzers/type_check.rs +++ b/type_analysis/src/analyzers/type_check.rs @@ -355,6 +355,32 @@ fn type_expression( } Result::Ok(FoldedType::arithmetic_type(inferred_dim + 1)) } + UniformArray { meta, value, dimension } => { + let value_type = type_expression(value, program_archive, analysis_information).unwrap(); + if value_type.is_template() { + add_report( + ReportCode::InvalidArrayType, + meta, + &mut analysis_information.reports, + ); + }; + let dim_type = type_expression(dimension, program_archive, analysis_information).unwrap(); + if dim_type.is_template() { + add_report( + ReportCode::InvalidArrayType, + expression.get_meta(), + &mut analysis_information.reports, + ); + } else if dim_type.dim() != 0 { + add_report( + ReportCode::InvalidArrayType, + expression.get_meta(), + &mut analysis_information.reports, + ); + } + + Result::Ok(FoldedType::arithmetic_type(value_type.dim() + 1)) + } InfixOp { lhe, rhe, .. } => { let lhe_response = type_expression(lhe, program_archive, analysis_information); let rhe_response = type_expression(rhe, program_archive, analysis_information); diff --git a/type_analysis/src/analyzers/type_given_function.rs b/type_analysis/src/analyzers/type_given_function.rs index 045b02e19..cdb608125 100644 --- a/type_analysis/src/analyzers/type_given_function.rs +++ b/type_analysis/src/analyzers/type_given_function.rs @@ -273,6 +273,23 @@ fn look_for_type_in_expression( &values[0], ) .map(|v| v + 1), + Expression::UniformArray { value, .. } => { + let value_type = look_for_type_in_expression( + function_name, + environment, + explored_functions, + function_data, + function_info, + value, + ); + if value_type.is_some(){ + Option::Some(value_type.unwrap() + 1) + } + else{ + None + } + + } Expression::Call { id, args, .. } => { if explored_functions.contains(id) { return Option::None; diff --git a/type_analysis/src/analyzers/unknown_known_analysis.rs b/type_analysis/src/analyzers/unknown_known_analysis.rs index 315f8df04..a3b360616 100644 --- a/type_analysis/src/analyzers/unknown_known_analysis.rs +++ b/type_analysis/src/analyzers/unknown_known_analysis.rs @@ -280,6 +280,11 @@ fn tag(expression: &Expression, environment: &Environment) -> Tag { ArrayInLine { values, .. } | Call { args: values, .. } => { expression_iterator(values, Known, Unknown, environment) } + UniformArray { value, dimension, .. } => { + let tag_value = tag(value, environment); + let tag_dimension = tag(dimension, environment); + max(tag_value, tag_dimension) + } InlineSwitchOp { cond, if_true, if_false, .. } => { let tag_cond = tag(cond, environment); let tag_true = tag(if_true, environment); @@ -397,6 +402,7 @@ fn unknown_index(exp: &Expression, environment: &Environment) -> bool { } (false, bucket) } + UniformArray{ value, dimension, .. } => (false, vec![value.as_ref(), dimension.as_ref()]), }; let mut has_unknown_index = init; let mut index = 0; diff --git a/type_analysis/src/decorators/constants_handler.rs b/type_analysis/src/decorators/constants_handler.rs index 4c828c458..db4b59da1 100644 --- a/type_analysis/src/decorators/constants_handler.rs +++ b/type_analysis/src/decorators/constants_handler.rs @@ -221,6 +221,7 @@ fn has_constant_value(expr: &Expression, environment: &Constants) -> bool { } Variable { name, .. } => variable(name, environment), ArrayInLine { .. } => array_inline(), + UniformArray { .. } => uniform_array(), } } @@ -239,6 +240,9 @@ fn call(params: &[Expression], environment: &Constants) -> bool { fn array_inline() -> bool { false } +fn uniform_array() -> bool { + false +} fn variable(name: &str, environment: &Constants) -> bool { *environment.get_variable_or_break(name, file!(), line!()) } @@ -380,6 +384,7 @@ fn expand_expression(expr: Expression, environment: &ExpressionHolder) -> Expres match expr { Number(meta, value) => expand_number(meta, value), ArrayInLine { meta, values } => expand_array(meta, values, environment), + UniformArray { meta, value, dimension} => expand_uniform_array(meta, *value, *dimension, environment), Call { id, meta, args } => expand_call(id, meta, args, environment), InfixOp { meta, lhe, rhe, infix_op } => { expand_infix(meta, *lhe, infix_op, *rhe, environment) @@ -409,6 +414,17 @@ fn expand_array( build_array_in_line(meta, values) } +fn expand_uniform_array( + meta: Meta, + old_value: Expression, + old_dimension: Expression, + environment: &ExpressionHolder, +) -> Expression { + let value = expand_expression(old_value, environment); + let dimension = expand_expression(old_dimension, environment); + build_uniform_array(meta, value, dimension) +} + fn expand_call( id: String, meta: Meta, diff --git a/type_analysis/src/decorators/type_reduction.rs b/type_analysis/src/decorators/type_reduction.rs index ec86ee2eb..3099f0ba7 100644 --- a/type_analysis/src/decorators/type_reduction.rs +++ b/type_analysis/src/decorators/type_reduction.rs @@ -60,6 +60,10 @@ fn reduce_types_in_expression(expression: &mut Expression, environment: &Environ } Call { args, .. } => reduce_types_in_vec_of_expressions(args, environment), ArrayInLine { values, .. } => reduce_types_in_vec_of_expressions(values, environment), + UniformArray { value, dimension, .. } => { + reduce_types_in_expression(value, environment); + reduce_types_in_expression(dimension, environment); + } Number(..) => {} } } From f4bce2d60d868a718c681b34f9a65a04a81f8855 Mon Sep 17 00:00:00 2001 From: alrubio Date: Thu, 21 Jul 2022 12:50:43 +0200 Subject: [PATCH 02/23] error trace added to wasm --- code_producers/src/wasm_elements/mod.rs | 5 +++ .../src/wasm_elements/wasm_code_generator.rs | 10 +++++ .../src/wasm_elements/witness_calculator.js | 27 ++++++------ compiler/src/circuit_design/function.rs | 5 ++- compiler/src/circuit_design/template.rs | 13 +++--- compiler/src/hir/very_concrete_program.rs | 1 + .../assert_bucket.rs | 3 +- .../call_bucket.rs | 35 ++++++++++++++- .../create_component_bucket.rs | 43 +++++++++++++++++-- .../return_bucket.rs | 1 + .../store_bucket.rs | 20 ++++++++- .../intermediate_representation/translate.rs | 6 ++- .../src/execution_data/executed_template.rs | 1 + 13 files changed, 141 insertions(+), 29 deletions(-) diff --git a/code_producers/src/wasm_elements/mod.rs b/code_producers/src/wasm_elements/mod.rs index afc2eaafd..8fc2396a8 100644 --- a/code_producers/src/wasm_elements/mod.rs +++ b/code_producers/src/wasm_elements/mod.rs @@ -47,6 +47,7 @@ pub struct WASMProducer { create_loop_sub_cmp_tag: String, create_loop_offset_tag: String, create_loop_counter_tag: String, + merror_tag: String, } impl Default for WASMProducer { @@ -101,6 +102,7 @@ impl Default for WASMProducer { create_loop_sub_cmp_tag: "$createloopsubcmp".to_string(), create_loop_offset_tag: "$createloopoffset".to_string(), create_loop_counter_tag: "$createloopcounter".to_string(), + merror_tag: "$merror".to_string(), } } } @@ -359,6 +361,9 @@ impl WASMProducer { pub fn get_create_loop_counter_tag(&self) -> &str { &self.create_loop_counter_tag } + pub fn get_merror_tag(&self) -> &str { + &self.merror_tag + } pub fn needs_comments(&self) -> bool{ self.wat_flag } diff --git a/code_producers/src/wasm_elements/wasm_code_generator.rs b/code_producers/src/wasm_elements/wasm_code_generator.rs index 80327c5b0..0f28b888c 100644 --- a/code_producers/src/wasm_elements/wasm_code_generator.rs +++ b/code_producers/src/wasm_elements/wasm_code_generator.rs @@ -494,6 +494,10 @@ pub fn generate_imports_list() -> Vec { "(import \"runtime\" \"exceptionHandler\" (func $exceptionHandler (type $_t_i32)))" .to_string(), ); + imports.push( + "(import \"runtime\" \"printErrorMessage\" (func $printErrorMessage (type $_t_void)))" + .to_string(), + ); imports.push( "(import \"runtime\" \"showSharedRWMemory\" (func $showSharedRWMemory (type $_t_void)))" .to_string(), @@ -893,6 +897,7 @@ pub fn set_input_signal_generator(producer: &WASMProducer) -> Vec Vec 0 error instructions.push(format!("(local {} i32)", producer.get_cstack_tag())); instructions.push(format!("(local {} i32)", producer.get_lvar_tag())); instructions.push(format!("(local {} i32)", producer.get_expaux_tag())); @@ -45,6 +46,7 @@ impl WriteWasm for FunctionCodeInfo { instructions.push(format!("(local {} i32)", producer.get_store_aux_2_tag())); instructions.push(format!("(local {} i32)", producer.get_copy_counter_tag())); instructions.push(format!("(local {} i32)", producer.get_call_lvar_tag())); + instructions.push(format!(" (local {} i32)", producer.get_merror_tag())); let local_info_size_u32 = producer.get_local_info_size_u32(); //set lvar (start of auxiliar memory for vars) instructions.push(set_constant("0")); @@ -76,6 +78,7 @@ impl WriteWasm for FunctionCodeInfo { let mut instructions_body = t.produce_wasm(producer); instructions.append(&mut instructions_body); } + instructions.push(set_constant("0")); instructions.push(")".to_string()); instructions } diff --git a/compiler/src/circuit_design/template.rs b/compiler/src/circuit_design/template.rs index 35054d859..519849a59 100644 --- a/compiler/src/circuit_design/template.rs +++ b/compiler/src/circuit_design/template.rs @@ -41,7 +41,8 @@ impl WriteWasm for TemplateCodeInfo { instructions.push(format!(" (param {} i32)", producer.get_signal_offset_tag())); instructions.push("(result i32)".to_string()); instructions.push(format!(" (local {} i32)", producer.get_offset_tag())); //here is a local var to be returned - instructions.push(set_constant(&producer.get_component_free_pos().to_string())); + instructions.push(format!(" (local {} i32)", producer.get_merror_tag())); + instructions.push(set_constant(&producer.get_component_free_pos().to_string())); instructions.push(load32(None)); instructions.push(set_local(producer.get_offset_tag())); // set component id @@ -66,20 +67,16 @@ impl WriteWasm for TemplateCodeInfo { instructions.push(set_constant(&nbytes_component.to_string())); instructions.push(add32()); instructions.push(store32(None)); - //if has no intput should be run - if self.number_of_inputs == 0 { - instructions.push(get_local(producer.get_offset_tag())); - instructions.push(call(&format!("${}_run", self.header))); - } //add the position of the component in the tree as result instructions.push(get_local(producer.get_offset_tag())); instructions.push(")".to_string()); // run function code - let funcdef2 = format!("(func ${}_run (type $_t_i32)", self.header); + let funcdef2 = format!("(func ${}_run (type $_t_i32ri32)", self.header); instructions.push(funcdef2); instructions.push(format!(" (param {} i32)", producer.get_offset_tag())); + instructions.push("(result i32)".to_string()); //state 0 = OK; > 0 error instructions.push(format!(" (local {} i32)", producer.get_cstack_tag())); instructions.push(format!(" (local {} i32)", producer.get_signal_start_tag())); instructions.push(format!(" (local {} i32)", producer.get_sub_cmp_tag())); @@ -95,6 +92,7 @@ impl WriteWasm for TemplateCodeInfo { instructions.push(format!(" (local {} i32)", producer.get_create_loop_sub_cmp_tag())); instructions.push(format!(" (local {} i32)", producer.get_create_loop_offset_tag())); instructions.push(format!(" (local {} i32)", producer.get_create_loop_counter_tag())); + instructions.push(format!(" (local {} i32)", producer.get_merror_tag())); let local_info_size_u32 = producer.get_local_info_size_u32(); // in the future we can add some info like pointer to run father or text father //set lvar (start of auxiliar memory for vars) instructions.push(set_constant("0")); @@ -137,6 +135,7 @@ impl WriteWasm for TemplateCodeInfo { //free stack let mut free_stack_code = free_stack(producer); instructions.append(&mut free_stack_code); + instructions.push(set_constant("0")); instructions.push(")".to_string()); instructions } diff --git a/compiler/src/hir/very_concrete_program.rs b/compiler/src/hir/very_concrete_program.rs index 857ca2db0..6a5387542 100644 --- a/compiler/src/hir/very_concrete_program.rs +++ b/compiler/src/hir/very_concrete_program.rs @@ -58,6 +58,7 @@ pub struct Trigger { pub component_name: String, pub indexed_with: Vec, pub external_signals: Vec, + pub has_inputs: bool, } #[derive(Clone)] diff --git a/compiler/src/intermediate_representation/assert_bucket.rs b/compiler/src/intermediate_representation/assert_bucket.rs index c6988a122..320d4925c 100644 --- a/compiler/src/intermediate_representation/assert_bucket.rs +++ b/compiler/src/intermediate_representation/assert_bucket.rs @@ -55,8 +55,9 @@ impl WriteWasm for AssertBucket { instructions.push(set_constant(&self.message_id.to_string())); instructions.push(set_constant(&self.line.to_string())); instructions.push(call("$buildBufferMessage")); + instructions.push(call("$printErrorMessage")); instructions.push(set_constant(&exception_code_assert_fail().to_string())); - instructions.push(call("$exceptionHandler")); + instructions.push(add_return()); instructions.push(add_end()); if producer.needs_comments() { instructions.push(";; end of assert bucket".to_string()); diff --git a/compiler/src/intermediate_representation/call_bucket.rs b/compiler/src/intermediate_representation/call_bucket.rs index 48069e9a4..3e669132b 100644 --- a/compiler/src/intermediate_representation/call_bucket.rs +++ b/compiler/src/intermediate_representation/call_bucket.rs @@ -139,6 +139,12 @@ impl WriteWasm for CallBucket { instructions.push(add32()); instructions.push(set_constant("1")); instructions.push(call(&format!("${}", self.symbol))); + instructions.push(tee_local(producer.get_merror_tag())); + instructions.push(add_if()); + instructions.push(call("$printErrorMessage")); + instructions.push(get_local(producer.get_merror_tag())); + instructions.push(add_return()); + instructions.push(add_end()); } ReturnType::Final(data) => { let mut my_template_header = Option::::None; @@ -263,6 +269,15 @@ impl WriteWasm for CallBucket { } instructions.push(set_constant(&data.context.size.to_string())); instructions.push(call(&format!("${}", self.symbol))); + instructions.push(tee_local(producer.get_merror_tag())); + instructions.push(add_if()); + instructions.push(set_constant(&self.message_id.to_string())); + instructions.push(set_constant(&self.line.to_string())); + instructions.push(call("$buildBufferMessage")); + instructions.push(call("$printErrorMessage")); + instructions.push(get_local(producer.get_merror_tag())); + instructions.push(add_return()); + instructions.push(add_end()); match &data.dest_address_type { AddressType::SubcmpSignal { .. } => { // if subcomponent input check if run needed @@ -296,6 +311,15 @@ impl WriteWasm for CallBucket { LocationRule::Indexed { .. } => { if let Some(name) = &my_template_header { instructions.push(call(&format!("${}_run", name))); + instructions.push(tee_local(producer.get_merror_tag())); + instructions.push(add_if()); + instructions.push(set_constant(&self.message_id.to_string())); + instructions.push(set_constant(&self.line.to_string())); + instructions.push(call("$buildBufferMessage")); + instructions.push(call("$printErrorMessage")); + instructions.push(get_local(producer.get_merror_tag())); + instructions.push(add_return()); + instructions.push(add_end()); } else { assert!(false); } @@ -305,8 +329,17 @@ impl WriteWasm for CallBucket { instructions.push(load32(None)); // get template id instructions.push(call_indirect( &"$runsmap".to_string(), - &"(type $_t_i32)".to_string(), + &"(type $_t_i32ri32)".to_string(), )); + instructions.push(tee_local(producer.get_merror_tag())); + instructions.push(add_if()); + instructions.push(set_constant(&self.message_id.to_string())); + instructions.push(set_constant(&self.line.to_string())); + instructions.push(call("$buildBufferMessage")); + instructions.push(call("$printErrorMessage")); + instructions.push(get_local(producer.get_merror_tag())); + instructions.push(add_return()); + instructions.push(add_end()); } } if producer.needs_comments() { diff --git a/compiler/src/intermediate_representation/create_component_bucket.rs b/compiler/src/intermediate_representation/create_component_bucket.rs index c6e5da7aa..bf91abc5e 100644 --- a/compiler/src/intermediate_representation/create_component_bucket.rs +++ b/compiler/src/intermediate_representation/create_component_bucket.rs @@ -23,6 +23,7 @@ pub struct CreateCmpBucket { pub component_offset: usize, pub component_offset_jump:usize, pub number_of_cmp: usize, + pub has_inputs: bool, pub is_parallel: bool, } @@ -86,8 +87,25 @@ impl WriteWasm for CreateCmpBucket { instructions.push(add32()); if self.number_of_cmp == 1 { instructions.push(call(&format!("${}_create", self.symbol))); - instructions.push(store32(None)); //store the offset given by create in the subcomponent address - } else { + if !self.has_inputs { + instructions.push(tee_local(producer.get_temp_tag())); //here we use $temp to keep the offset created subcomponet + instructions.push(store32(None)); //store the offset given by create in the subcomponent address + instructions.push(get_local(producer.get_temp_tag())); + instructions.push(call(&format!("${}_run", self.symbol))); + instructions.push(tee_local(producer.get_merror_tag())); + instructions.push(add_if()); + instructions.push(set_constant(&self.message_id.to_string())); + instructions.push(set_constant(&self.line.to_string())); + instructions.push(call("$buildBufferMessage")); + instructions.push(call("$printErrorMessage")); + instructions.push(get_local(producer.get_merror_tag())); + instructions.push(add_return()); + instructions.push(add_end()); + } + else { + instructions.push(store32(None)); //store the offset given by create in the subcomponent address + } + } else { instructions.push(set_local(producer.get_create_loop_offset_tag())); if self.number_of_cmp == self.defined_positions.len() { instructions.push(set_constant(&self.number_of_cmp.to_string())); @@ -98,7 +116,24 @@ impl WriteWasm for CreateCmpBucket { instructions.push(get_local(producer.get_create_loop_offset_tag())); //sub_component signal address start instructions.push(call(&format!("${}_create", self.symbol))); - instructions.push(store32(None)); //store the offset given by create in the subcomponent address + if !self.has_inputs { + instructions.push(tee_local(producer.get_temp_tag())); //here we use $temp to keep the offset created subcomponet + instructions.push(store32(None)); //store the offset given by create in the subcomponent address + instructions.push(get_local(producer.get_temp_tag())); + instructions.push(call(&format!("${}_run", self.symbol))); + instructions.push(tee_local(producer.get_merror_tag())); + instructions.push(add_if()); + instructions.push(set_constant(&self.message_id.to_string())); + instructions.push(set_constant(&self.line.to_string())); + instructions.push(call("$buildBufferMessage")); + instructions.push(call("$printErrorMessage")); + instructions.push(get_local(producer.get_merror_tag())); + instructions.push(add_return()); + instructions.push(add_end()); + } + else { + instructions.push(store32(None)); //store the offset given by create in the subcomponent address + } instructions.push(get_local(producer.get_create_loop_counter_tag())); instructions.push(set_constant("1")); instructions.push(sub32()); @@ -218,4 +253,4 @@ impl WriteC for CreateCmpBucket { instructions.push("}".to_string()); (instructions, "".to_string()) } -} \ No newline at end of file +} diff --git a/compiler/src/intermediate_representation/return_bucket.rs b/compiler/src/intermediate_representation/return_bucket.rs index cea3cf640..42748b364 100644 --- a/compiler/src/intermediate_representation/return_bucket.rs +++ b/compiler/src/intermediate_representation/return_bucket.rs @@ -85,6 +85,7 @@ impl WriteWasm for ReturnBucket { } let mut free_stack_code = free_stack(producer); instructions.append(&mut free_stack_code); + instructions.push(set_constant("0")); instructions.push(add_return()); if producer.needs_comments() { instructions.push(";; end of return bucket".to_string()); diff --git a/compiler/src/intermediate_representation/store_bucket.rs b/compiler/src/intermediate_representation/store_bucket.rs index 745722453..d409ca652 100644 --- a/compiler/src/intermediate_representation/store_bucket.rs +++ b/compiler/src/intermediate_representation/store_bucket.rs @@ -245,6 +245,15 @@ impl WriteWasm for StoreBucket { LocationRule::Indexed { .. } => { if let Some(name) = &my_template_header { instructions.push(call(&format!("${}_run", name))); + instructions.push(tee_local(producer.get_merror_tag())); + instructions.push(add_if()); + instructions.push(set_constant(&self.message_id.to_string())); + instructions.push(set_constant(&self.line.to_string())); + instructions.push(call("$buildBufferMessage")); + instructions.push(call("$printErrorMessage")); + instructions.push(get_local(producer.get_merror_tag())); + instructions.push(add_return()); + instructions.push(add_end()); } else { assert!(false); } @@ -254,8 +263,17 @@ impl WriteWasm for StoreBucket { instructions.push(load32(None)); // get template id instructions.push(call_indirect( &"$runsmap".to_string(), - &"(type $_t_i32)".to_string(), + &"(type $_t_i32ri32)".to_string(), )); + instructions.push(tee_local(producer.get_merror_tag())); + instructions.push(add_if()); + instructions.push(set_constant(&self.message_id.to_string())); + instructions.push(set_constant(&self.line.to_string())); + instructions.push(call("$buildBufferMessage")); + instructions.push(call("$printErrorMessage")); + instructions.push(get_local(producer.get_merror_tag())); + instructions.push(add_return()); + instructions.push(add_end()); } } if producer.needs_comments() { diff --git a/compiler/src/intermediate_representation/translate.rs b/compiler/src/intermediate_representation/translate.rs index df119722b..721a104d7 100644 --- a/compiler/src/intermediate_representation/translate.rs +++ b/compiler/src/intermediate_representation/translate.rs @@ -315,11 +315,12 @@ fn create_uniform_components(state: &mut State, triggers: &[Trigger], cluster: T sub_cmp_id: symbol.access_instruction.clone(), template_id: c_info.template_id, signal_offset: c_info.offset, - component_offset: c_info.component_offset, + component_offset: c_info.component_offset, + has_inputs: c_info.has_inputs, number_of_cmp: compute_number_cmp(&symbol.dimensions), dimensions: symbol.dimensions, signal_offset_jump: offset_jump, - component_offset_jump: component_offset_jump, + component_offset_jump: component_offset_jump, } .allocate(); state.code.push(creation_instr); @@ -377,6 +378,7 @@ fn create_mixed_components(state: &mut State, triggers: &[Trigger], cluster: Tri template_id: c_info.template_id, signal_offset: c_info.offset, component_offset: c_info.component_offset, + has_inputs: c_info.has_inputs, number_of_cmp: 1, signal_offset_jump: 0, component_offset_jump: 0, diff --git a/constraint_generation/src/execution_data/executed_template.rs b/constraint_generation/src/execution_data/executed_template.rs index 8299093b2..ebe7f9674 100644 --- a/constraint_generation/src/execution_data/executed_template.rs +++ b/constraint_generation/src/execution_data/executed_template.rs @@ -192,6 +192,7 @@ impl ExecutedTemplate { runs: instances[data.goes_to].template_header.clone(), template_id: data.goes_to, external_signals: instances[data.goes_to].signals.clone(), + has_inputs: instances[data.goes_to].number_of_inputs > 0, }; triggers.push(trigger); } From f16f63fb65794109e9ac268f630c93f4a0912368 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Isabel=20M=C3=A1rquez?= Date: Thu, 11 Aug 2022 15:58:15 +0200 Subject: [PATCH 03/23] Log with strings and expressions --- compiler/src/hir/merger.rs | 17 +++-- compiler/src/hir/sugar_cleaner.rs | 11 +++- .../ir_interface.rs | 1 + .../intermediate_representation/log_bucket.rs | 65 +++++++++++++------ .../intermediate_representation/translate.rs | 30 +++++++-- compiler/src/ir_processing/build_stack.rs | 13 +++- compiler/src/ir_processing/reduce_stack.rs | 15 ++++- compiler/src/ir_processing/set_arena_size.rs | 7 +- constraint_generation/src/execute.rs | 24 +++---- .../src/execution_data/filters.rs | 10 ++- parser/src/lang.lalrpop | 33 +++++++++- .../src/abstract_syntax_tree/ast.rs | 15 ++++- .../statement_builders.rs | 4 +- .../abstract_syntax_tree/statement_impl.rs | 10 ++- .../src/program_library/error_code.rs | 2 + .../functions_free_of_template_elements.rs | 9 ++- .../src/analyzers/symbol_analysis.rs | 10 ++- type_analysis/src/analyzers/type_check.rs | 31 ++++++++- .../src/decorators/constants_handler.rs | 10 ++- .../src/decorators/type_reduction.rs | 14 +++- 20 files changed, 266 insertions(+), 65 deletions(-) diff --git a/compiler/src/hir/merger.rs b/compiler/src/hir/merger.rs index 8f5bc80d5..6a5154a98 100644 --- a/compiler/src/hir/merger.rs +++ b/compiler/src/hir/merger.rs @@ -152,8 +152,13 @@ fn produce_vcf_assert(stmt: &Statement, state: &mut State, environment: &E) { fn produce_vcf_log_call(stmt: &Statement, state: &mut State, environment: &E) { use Statement::LogCall; - if let LogCall { arg, .. } = stmt { - produce_vcf_expr(arg, state, environment); + if let LogCall { args, .. } = stmt { + for arglog in args { + if let LogArgument::LogExp(arg) = arglog { + produce_vcf_expr(arg, state, environment); + } + else {unreachable!(); } + } } else { unreachable!(); } @@ -392,8 +397,12 @@ fn link_while(stmt: &mut Statement, state: &State, env: &mut E) { fn link_log_call(stmt: &mut Statement, state: &State, env: &mut E) { use Statement::LogCall; - if let LogCall { arg, .. } = stmt { - link_expression(arg, state, env); + if let LogCall { args, .. } = stmt { + for arglog in args { + if let LogArgument::LogExp(arg) = arglog{ + link_expression(arg, state, env); + } + } } else { unreachable!(); } diff --git a/compiler/src/hir/sugar_cleaner.rs b/compiler/src/hir/sugar_cleaner.rs index 41a73e0fd..07b9f866c 100644 --- a/compiler/src/hir/sugar_cleaner.rs +++ b/compiler/src/hir/sugar_cleaner.rs @@ -164,8 +164,15 @@ fn extend_return(stmt: &mut Statement, state: &mut State, context: &Context) -> fn extend_log_call(stmt: &mut Statement, state: &mut State, context: &Context) -> Vec { use Statement::LogCall; - if let LogCall { arg, .. } = stmt { - extend_expression(arg, state, context).initializations + if let LogCall { args, .. } = stmt { + let mut initializations = Vec::new(); + for arglog in args { + if let LogArgument::LogExp(arg) = arglog { + let mut exp = extend_expression(arg, state, context); + initializations.append(&mut exp.initializations); + } + } + initializations } else { unreachable!() } diff --git a/compiler/src/intermediate_representation/ir_interface.rs b/compiler/src/intermediate_representation/ir_interface.rs index 564bf6799..57dcef181 100644 --- a/compiler/src/intermediate_representation/ir_interface.rs +++ b/compiler/src/intermediate_representation/ir_interface.rs @@ -10,6 +10,7 @@ pub use super::log_bucket::LogBucket; pub use super::loop_bucket::LoopBucket; pub use super::return_bucket::ReturnBucket; pub use super::store_bucket::StoreBucket; +pub use super::log_bucket::LogBucketArgs; pub use super::types::{InstrContext, ValueType}; pub use super::value_bucket::ValueBucket; diff --git a/compiler/src/intermediate_representation/log_bucket.rs b/compiler/src/intermediate_representation/log_bucket.rs index 5b2bb046a..aef93ea72 100644 --- a/compiler/src/intermediate_representation/log_bucket.rs +++ b/compiler/src/intermediate_representation/log_bucket.rs @@ -3,11 +3,18 @@ use crate::translating_traits::*; use code_producers::c_elements::*; use code_producers::wasm_elements::*; + +#[derive(Clone)] +pub enum LogBucketArgs { + LogExp(InstructionPointer), + LogString(usize) +} + #[derive(Clone)] pub struct LogBucket { pub line: usize, pub message_id: usize, - pub print: InstructionPointer, + pub argsprint: Vec, pub is_parallel: bool, } @@ -36,8 +43,15 @@ impl ToString for LogBucket { fn to_string(&self) -> String { let line = self.line.to_string(); let template_id = self.message_id.to_string(); - let print = self.print.to_string(); - format!("LOG(line: {},template_id: {},evaluate: {})", line, template_id, print) + let mut ret = String::new(); + for print in self.argsprint.clone() { + if let LogBucketArgs::LogExp(exp) = print { + let print = exp.to_string(); + let log = format!("LOG(line: {},template_id: {},evaluate: {})", line, template_id, print); + ret = ret + &log; + } + } + ret } } @@ -47,11 +61,15 @@ impl WriteWasm for LogBucket { let mut instructions = vec![]; if producer.needs_comments() { instructions.push(";; log bucket".to_string()); - } - let mut instructions_print = self.print.produce_wasm(producer); - instructions.append(&mut instructions_print); - instructions.push(call("$copyFr2SharedRWMemory")); - instructions.push(call("$showSharedRWMemory")); + } + for logarg in self.argsprint.clone() { + if let LogBucketArgs::LogExp(exp) = logarg { + let mut instructions_print = exp.produce_wasm(producer); + instructions.append(&mut instructions_print); + instructions.push(call("$copyFr2SharedRWMemory")); + instructions.push(call("$showSharedRWMemory")); + } + } if producer.needs_comments() { instructions.push(";; end of log bucket".to_string()); } @@ -62,19 +80,24 @@ impl WriteWasm for LogBucket { impl WriteC for LogBucket { fn produce_c(&self, producer: &CProducer) -> (Vec, String) { use c_code_generator::*; - let (argument_code, argument_result) = self.print.produce_c(producer); - let to_string_call = build_call("Fr_element2str".to_string(), vec![argument_result]); - let temp_var = "temp".to_string(); - let into_temp = format!("char* temp = {}", to_string_call); - let print_c = - build_call("printf".to_string(), vec!["\"%s\\n\"".to_string(), temp_var.clone()]); - let delete_temp = format!("delete [] {}", temp_var); - let mut log_c = argument_code; - log_c.push("{".to_string()); - log_c.push(format!("{};", into_temp)); - log_c.push(format!("{};", print_c)); - log_c.push(format!("{};", delete_temp)); - log_c.push("}".to_string()); + let mut log_c = Vec::new(); + for logarg in self.argsprint.clone() { + if let LogBucketArgs::LogExp(exp) = logarg { + let (mut argument_code, argument_result) = exp.produce_c(producer); + let to_string_call = build_call("Fr_element2str".to_string(), vec![argument_result]); + let temp_var = "temp".to_string(); + let into_temp = format!("char* temp = {}", to_string_call); + let print_c = + build_call("printf".to_string(), vec!["\"%s\\n\"".to_string(), temp_var.clone()]); + let delete_temp = format!("delete [] {}", temp_var); + log_c.append(&mut argument_code); + log_c.push("{".to_string()); + log_c.push(format!("{};", into_temp)); + log_c.push(format!("{};", print_c)); + log_c.push(format!("{};", delete_temp)); + log_c.push("}".to_string()); + } + } (log_c, "".to_string()) } } diff --git a/compiler/src/intermediate_representation/translate.rs b/compiler/src/intermediate_representation/translate.rs index df119722b..e739c0c25 100644 --- a/compiler/src/intermediate_representation/translate.rs +++ b/compiler/src/intermediate_representation/translate.rs @@ -1,5 +1,6 @@ use super::ir_interface::*; use crate::hir::very_concrete_program::*; +use crate::intermediate_representation::log_bucket::LogBucketArgs; use constant_tracking::ConstantTracker; use num_bigint_dig::BigInt; use program_structure::ast::*; @@ -90,6 +91,8 @@ struct State { component_address_stack: usize, is_parallel: bool, code: InstructionList, + // string_table + pub string_table: HashMap, } impl State { @@ -114,6 +117,7 @@ impl State { fresh_cmp_id: cmp_id_offset, max_stack_depth: 0, code: vec![], + string_table : HashMap::new(), } } fn reserve(fresh: &mut usize, size: usize) -> usize { @@ -581,14 +585,32 @@ fn translate_assert(stmt: Statement, state: &mut State, context: &Context) { fn translate_log(stmt: Statement, state: &mut State, context: &Context) { use Statement::LogCall; - if let LogCall { meta, arg, .. } = stmt { + if let LogCall { meta, args, .. } = stmt { let line = context.files.get_line(meta.start, meta.get_file_id()).unwrap(); - let code = translate_expression(arg, state, context); + let mut logbucket_args = Vec::new(); + for arglog in args { + match arglog { + LogArgument::LogExp(arg) => { + let code = translate_expression(arg, state, context); + logbucket_args.push(LogBucketArgs::LogExp(code)); + } + LogArgument::LogStr(exp) => { + match state.string_table.get(&exp) { + Some( idx) => {logbucket_args.push(LogBucketArgs::LogString(*idx));}, + None => { + logbucket_args.push(LogBucketArgs::LogString(state.string_table.len())); + state.string_table.insert(exp, state.string_table.len()); + }, + } + + } + } + } let log = LogBucket { line, message_id: state.message_id, - print: code, - is_parallel: state.is_parallel + is_parallel: state.is_parallel, + argsprint: logbucket_args, }.allocate(); state.code.push(log); } diff --git a/compiler/src/ir_processing/build_stack.rs b/compiler/src/ir_processing/build_stack.rs index dbebe6228..061b634ee 100644 --- a/compiler/src/ir_processing/build_stack.rs +++ b/compiler/src/ir_processing/build_stack.rs @@ -1,4 +1,5 @@ use crate::intermediate_representation::ir_interface::*; + pub fn build_list(instructions: &mut InstructionList, fresh: usize) -> usize { let mut max_depth = 0; for i in instructions { @@ -87,7 +88,17 @@ pub fn build_return(bucket: &mut ReturnBucket, fresh: usize) -> usize { } pub fn build_log(bucket: &mut LogBucket, fresh: usize) -> usize { - build_instruction(&mut bucket.print, fresh) + let mut in_log = usize::min_value(); + for arglog in bucket.argsprint.clone() { + match arglog { + LogBucketArgs::LogExp(mut arg) => { + let new_log = build_instruction(&mut arg, fresh); + in_log = std::cmp::max(in_log, new_log); + } + LogBucketArgs::LogString(..) => {} + } + } + in_log } pub fn build_assert(bucket: &mut AssertBucket, fresh: usize) -> usize { diff --git a/compiler/src/ir_processing/reduce_stack.rs b/compiler/src/ir_processing/reduce_stack.rs index 39c8ee9b1..e90e8ef3f 100644 --- a/compiler/src/ir_processing/reduce_stack.rs +++ b/compiler/src/ir_processing/reduce_stack.rs @@ -82,7 +82,20 @@ pub fn reduce_loop(mut bucket: LoopBucket) -> Instruction { } pub fn reduce_log(mut bucket: LogBucket) -> Instruction { - bucket.print = Allocate::allocate(reduce_instruction(*bucket.print)); + let mut new_args_prints : Vec = Vec::new(); + for print in bucket.argsprint { + match print { + LogBucketArgs::LogExp(exp)=> { + let print_aux = Allocate::allocate(reduce_instruction(*exp)); + new_args_prints.push(LogBucketArgs::LogExp(print_aux)); + + }, + LogBucketArgs::LogString(..) => {}, + } + + } + + bucket.argsprint = new_args_prints; IntoInstruction::into_instruction(bucket) } diff --git a/compiler/src/ir_processing/set_arena_size.rs b/compiler/src/ir_processing/set_arena_size.rs index e372a8d9c..46208b7d4 100644 --- a/compiler/src/ir_processing/set_arena_size.rs +++ b/compiler/src/ir_processing/set_arena_size.rs @@ -77,7 +77,12 @@ pub fn visit_return(bucket: &mut ReturnBucket, function_to_arena_size: &HashMap< } pub fn visit_log(bucket: &mut LogBucket, function_to_arena_size: &HashMap) { - visit_instruction(&mut bucket.print, function_to_arena_size); + for print in bucket.argsprint.clone() { + if let LogBucketArgs::LogExp(mut exp) = print { + visit_instruction(&mut exp, function_to_arena_size); + } + } + } pub fn visit_assert(bucket: &mut AssertBucket, function_to_arena_size: &HashMap) { diff --git a/constraint_generation/src/execute.rs b/constraint_generation/src/execute.rs index 607e1c095..b117c9ee9 100644 --- a/constraint_generation/src/execute.rs +++ b/constraint_generation/src/execute.rs @@ -300,20 +300,22 @@ fn execute_statement( ExecutionEnvironment::remove_variable_block(&mut runtime.environment); return_value } - LogCall { arg, .. } => { + LogCall { args, .. } => { if flag_verbose{ - let f_result = execute_expression(arg, program_archive, runtime, flag_verbose)?; - let arith = safe_unwrap_to_single_arithmetic_expression(f_result, line!()); - if AExpr::is_number(&arith){ - println!("{}", arith); - } - else{ - println!("Unknown") - } + for arglog in args { + if let LogArgument::LogExp(arg) = arglog{ + let f_result = execute_expression(arg, program_archive, runtime, flag_verbose)?; + let arith = safe_unwrap_to_single_arithmetic_expression(f_result, line!()); + if AExpr::is_number(&arith){ + println!("{}", arith); + } + else{ + println!("Unknown") + } + } + } } Option::None - - } Assert { arg, meta, .. } => { let f_result = execute_expression(arg, program_archive, runtime, flag_verbose)?; diff --git a/constraint_generation/src/execution_data/filters.rs b/constraint_generation/src/execution_data/filters.rs index bd7f0837b..0b9697067 100644 --- a/constraint_generation/src/execution_data/filters.rs +++ b/constraint_generation/src/execution_data/filters.rs @@ -86,9 +86,13 @@ pub fn apply_computed(stmt: &mut Statement, analysis: &Analysis) { apply_computed_expr(lhe, analysis); apply_computed_expr(rhe, analysis); } - LogCall { arg, .. } => { - *arg = computed_or_original(analysis, arg); - apply_computed_expr(arg, analysis); + LogCall { args, .. } => { + for arglog in args { + if let LogArgument::LogExp(arg) = arglog{ + *arg = computed_or_original(analysis, arg); + apply_computed_expr(arg, analysis); + } + } } Assert { arg, .. } => { *arg = computed_or_original(analysis, arg); diff --git a/parser/src/lang.lalrpop b/parser/src/lang.lalrpop index d1ec879cc..2bad18ea2 100644 --- a/parser/src/lang.lalrpop +++ b/parser/src/lang.lalrpop @@ -313,8 +313,8 @@ ParseStatement2 : Statement = { "===" ";" => build_constraint_equality(Meta::new(s,e),lhe,rhe), - "log" "(" ")" ";" - => build_log_call(Meta::new(s,e),arg), + "log" "(" ")" ";" + => build_log_call(Meta::new(s,e),args), "assert" "(" ")" ";" => build_assert(Meta::new(s,e),arg), @@ -322,6 +322,7 @@ ParseStatement2 : Statement = { ParseBlock }; + ParseStatement3 : Statement = { ";" => dec, @@ -363,6 +364,34 @@ Listable: Vec = { }, }; +ParseString : LogArgument = { + "\"" "\"" + => { + build_log_string(e) + }, +}; + +ParseLogExp: LogArgument = { + + => { + build_log_expression(e) + } +} + +ParseLogArgument : LogArgument = { + ParseLogExp, + ParseString +}; + +LogListable: Vec = { + ",")*> + => { + let mut e = e; + e.push(tail); + e + }, +}; + InfixOpTier : Expression = { > => build_infix(Meta::new(s,e),lhe,infix_op,rhe), diff --git a/program_structure/src/abstract_syntax_tree/ast.rs b/program_structure/src/abstract_syntax_tree/ast.rs index 7e6caf52e..f1012bc12 100644 --- a/program_structure/src/abstract_syntax_tree/ast.rs +++ b/program_structure/src/abstract_syntax_tree/ast.rs @@ -202,7 +202,7 @@ pub enum Statement { }, LogCall { meta: Meta, - arg: Expression, + args: Vec, }, Block { meta: Meta, @@ -330,6 +330,19 @@ pub enum TypeReduction { Signal, } +#[derive(Clone)] +pub enum LogArgument { + LogStr(String), + LogExp(Expression), +} +pub fn build_log_string(acc: String) -> LogArgument { + LogArgument::LogStr(acc) +} +pub fn build_log_expression(expr: Expression) -> LogArgument { + LogArgument::LogExp(expr) +} + + #[derive(Default, Clone)] pub struct TypeKnowledge { reduces_to: Option, diff --git a/program_structure/src/abstract_syntax_tree/statement_builders.rs b/program_structure/src/abstract_syntax_tree/statement_builders.rs index dd41514e8..91c8bfcc7 100644 --- a/program_structure/src/abstract_syntax_tree/statement_builders.rs +++ b/program_structure/src/abstract_syntax_tree/statement_builders.rs @@ -53,8 +53,8 @@ pub fn build_constraint_equality(meta: Meta, lhe: Expression, rhe: Expression) - ConstraintEquality { meta, lhe, rhe } } -pub fn build_log_call(meta: Meta, arg: Expression) -> Statement { - LogCall { meta, arg } +pub fn build_log_call(meta: Meta, args: Vec) -> Statement { + LogCall { meta, args } } pub fn build_assert(meta: Meta, arg: Expression) -> Statement { diff --git a/program_structure/src/abstract_syntax_tree/statement_impl.rs b/program_structure/src/abstract_syntax_tree/statement_impl.rs index ece2dbcf9..c78912ad8 100644 --- a/program_structure/src/abstract_syntax_tree/statement_impl.rs +++ b/program_structure/src/abstract_syntax_tree/statement_impl.rs @@ -137,7 +137,7 @@ impl FillMeta for Statement { ConstraintEquality { meta, lhe, rhe } => { fill_constraint_equality(meta, lhe, rhe, file_id, element_id) } - LogCall { meta, arg, .. } => fill_log_call(meta, arg, file_id, element_id), + LogCall { meta, args, .. } => fill_log_call(meta, args, file_id, element_id), Block { meta, stmts, .. } => fill_block(meta, stmts, file_id, element_id), Assert { meta, arg, .. } => fill_assert(meta, arg, file_id, element_id), } @@ -229,9 +229,13 @@ fn fill_constraint_equality( rhe.fill(file_id, element_id); } -fn fill_log_call(meta: &mut Meta, arg: &mut Expression, file_id: usize, element_id: &mut usize) { +fn fill_log_call(meta: &mut Meta, args: &mut Vec, file_id: usize, element_id: &mut usize) { meta.set_file_id(file_id); - arg.fill(file_id, element_id); + for arg in args { + if let LogArgument::LogExp(e) = arg { + e.fill(file_id, element_id); + } + } } fn fill_block(meta: &mut Meta, stmts: &mut [Statement], file_id: usize, element_id: &mut usize) { diff --git a/program_structure/src/program_library/error_code.rs b/program_structure/src/program_library/error_code.rs index 041df2d29..45c5eb373 100644 --- a/program_structure/src/program_library/error_code.rs +++ b/program_structure/src/program_library/error_code.rs @@ -72,6 +72,7 @@ pub enum ReportCode { CustomGateConstraint, CustomGateSubComponent, CustomGatesPragmaError, + LabelTooLongError(usize), } impl fmt::Display for ReportCode { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { @@ -146,6 +147,7 @@ impl fmt::Display for ReportCode { CustomGateConstraint => "CG02", CustomGateSubComponent => "CG03", CustomGatesPragmaError => "CG04", + LabelTooLongError(..) => "L01", }; f.write_str(string_format) } diff --git a/type_analysis/src/analyzers/functions_free_of_template_elements.rs b/type_analysis/src/analyzers/functions_free_of_template_elements.rs index 00ff96ac9..5e9640c18 100644 --- a/type_analysis/src/analyzers/functions_free_of_template_elements.rs +++ b/type_analysis/src/analyzers/functions_free_of_template_elements.rs @@ -101,7 +101,14 @@ fn analyse_statement( analyse_expression(lhe, function_names, reports); analyse_expression(rhe, function_names, reports); } - LogCall { arg, .. } | Assert { arg, .. } => { + LogCall { args, .. } => { + for logarg in args { + if let LogArgument::LogExp(arg) = logarg { + analyse_expression(arg, function_names, reports); + } + } + } + Assert { arg, .. } => { analyse_expression(arg, function_names, reports); } Return { value, .. } => { diff --git a/type_analysis/src/analyzers/symbol_analysis.rs b/type_analysis/src/analyzers/symbol_analysis.rs index 941127563..7e7bf2c9c 100644 --- a/type_analysis/src/analyzers/symbol_analysis.rs +++ b/type_analysis/src/analyzers/symbol_analysis.rs @@ -1,4 +1,4 @@ -use program_structure::ast::{Access, Expression, Meta, Statement}; +use program_structure::ast::{Access, Expression, Meta, Statement, LogArgument}; use program_structure::error_code::ReportCode; use program_structure::error_definition::{Report, ReportCollection}; use program_structure::file_definition::{self, FileID, FileLocation}; @@ -220,8 +220,12 @@ fn analyze_statement( reports.push(report); } } - Statement::LogCall { arg, .. } => { - analyze_expression(arg, file_id, function_info, template_info, reports, environment) + Statement::LogCall { args, .. } => { + for logarg in args { + if let LogArgument::LogExp(arg) = logarg { + analyze_expression(arg, file_id, function_info, template_info, reports, environment); + } + } } Statement::Assert { arg, .. } => { analyze_expression(arg, file_id, function_info, template_info, reports, environment) diff --git a/type_analysis/src/analyzers/type_check.rs b/type_analysis/src/analyzers/type_check.rs index 55dd6efaf..e56d5504a 100644 --- a/type_analysis/src/analyzers/type_check.rs +++ b/type_analysis/src/analyzers/type_check.rs @@ -242,7 +242,35 @@ fn type_statement( ); } } - LogCall { arg, meta } | Assert { arg, meta } => { + LogCall { args, meta } => { + for arglog in args { + if let LogArgument::LogExp(arg) = arglog{ + let arg_response = type_expression(arg, program_archive, analysis_information); + let arg_type = if let Result::Ok(t) = arg_response { + t + } else { + return; + }; + if arg_type.is_template() || arg_type.dim() > 0 { + add_report( + ReportCode::MustBeSingleArithmetic, + meta, + &mut analysis_information.reports, + ) + } + } + else if let LogArgument::LogStr(label) = arglog { + if label.len() > 240 { + add_report( + ReportCode::LabelTooLongError(label.len()), + meta, + &mut analysis_information.reports, + ) + } + } + } + } + Assert { arg, meta } => { let arg_response = type_expression(arg, program_archive, analysis_information); let arg_type = if let Result::Ok(t) = arg_response { t @@ -760,6 +788,7 @@ fn add_report(error_code: ReportCode, meta: &Meta, reports: &mut ReportCollectio WrongNumberOfArguments(expected, got) => { format!("Expecting {} arguments, {} where obtained", expected, got) } + LabelTooLongError(len) => {format!("Label too long. Label is {} characters but must be <240", len)}, _ => panic!("Unimplemented error code"), }; report.add_primary(location, file_id, message); diff --git a/type_analysis/src/decorators/constants_handler.rs b/type_analysis/src/decorators/constants_handler.rs index 4c828c458..018e9aa75 100644 --- a/type_analysis/src/decorators/constants_handler.rs +++ b/type_analysis/src/decorators/constants_handler.rs @@ -277,7 +277,7 @@ fn expand_statement(stmt: &mut Statement, environment: &mut ExpressionHolder) { Declaration { dimensions, .. } => expand_declaration(dimensions, environment), Substitution { access, rhe, .. } => expand_substitution(access, rhe, environment), ConstraintEquality { lhe, rhe, .. } => expand_constraint_equality(lhe, rhe, environment), - LogCall { arg, .. } => expand_log_call(arg, environment), + LogCall { args, .. } => expand_log_call(args, environment), Assert { arg, .. } => expand_assert(arg, environment), Block { stmts, .. } => expand_block(stmts, environment), } @@ -359,8 +359,12 @@ fn expand_constraint_equality( *rhe = expand_expression(rhe.clone(), environment); } -fn expand_log_call(arg: &mut Expression, environment: &ExpressionHolder) { - *arg = expand_expression(arg.clone(), environment); +fn expand_log_call(args: &mut Vec, environment: &ExpressionHolder) { + for arglog in args { + if let LogArgument::LogExp(arg) = arglog { + *arg = expand_expression(arg.clone(), environment); + } + } } fn expand_assert(arg: &mut Expression, environment: &ExpressionHolder) { diff --git a/type_analysis/src/decorators/type_reduction.rs b/type_analysis/src/decorators/type_reduction.rs index ec86ee2eb..c8dbc083a 100644 --- a/type_analysis/src/decorators/type_reduction.rs +++ b/type_analysis/src/decorators/type_reduction.rs @@ -39,7 +39,10 @@ fn reduce_types_in_statement(stmt: &mut Statement, environment: &mut Environment IfThenElse { cond, if_case, else_case, .. } => { reduce_types_in_conditional(cond, if_case, else_case, environment) } - LogCall { arg, .. } => reduce_types_in_expression(arg, environment), + LogCall { args, .. } => { + reduce_types_in_log_call(args, environment) + + }, Assert { arg, .. } => reduce_types_in_expression(arg, environment), Return { value, .. } => reduce_types_in_expression(value, environment), ConstraintEquality { lhe, rhe, .. } => { @@ -47,6 +50,15 @@ fn reduce_types_in_statement(stmt: &mut Statement, environment: &mut Environment } } } + +fn reduce_types_in_log_call(args: &mut Vec, environment: &Environment){ + for arg in args { + if let LogArgument::LogExp(exp) = arg { + reduce_types_in_expression(exp, environment); + } + } +} + fn reduce_types_in_expression(expression: &mut Expression, environment: &Environment) { use Expression::*; match expression { From 3f7581e71b2d893ef53c811e53c0ec3be52b5621 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Isabel=20M=C3=A1rquez?= Date: Thu, 11 Aug 2022 20:20:09 +0200 Subject: [PATCH 04/23] Log with more than one arguments and strings working --- compiler/src/hir/merger.rs | 2 +- parser/src/lang.lalrpop | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/src/hir/merger.rs b/compiler/src/hir/merger.rs index 6a5154a98..da7f38587 100644 --- a/compiler/src/hir/merger.rs +++ b/compiler/src/hir/merger.rs @@ -157,7 +157,7 @@ fn produce_vcf_log_call(stmt: &Statement, state: &mut State, environment: &E) { if let LogArgument::LogExp(arg) = arglog { produce_vcf_expr(arg, state, environment); } - else {unreachable!(); } + else {}// unimplemented!(); } } } else { unreachable!(); diff --git a/parser/src/lang.lalrpop b/parser/src/lang.lalrpop index 2bad18ea2..9246b6df3 100644 --- a/parser/src/lang.lalrpop +++ b/parser/src/lang.lalrpop @@ -365,7 +365,7 @@ Listable: Vec = { }; ParseString : LogArgument = { - "\"" "\"" + => { build_log_string(e) }, From 43204932ad0ddeec419af3bdbc3def731e11ad11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Isabel=20M=C3=A1rquez?= Date: Fri, 12 Aug 2022 06:47:24 +0200 Subject: [PATCH 05/23] Log with more than one arguments and strings working --- .../statement_builders.rs | 21 ++++++++++++++++++- .../src/program_library/error_code.rs | 2 -- type_analysis/src/analyzers/type_check.rs | 10 --------- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/program_structure/src/abstract_syntax_tree/statement_builders.rs b/program_structure/src/abstract_syntax_tree/statement_builders.rs index 91c8bfcc7..3caee213e 100644 --- a/program_structure/src/abstract_syntax_tree/statement_builders.rs +++ b/program_structure/src/abstract_syntax_tree/statement_builders.rs @@ -54,7 +54,26 @@ pub fn build_constraint_equality(meta: Meta, lhe: Expression, rhe: Expression) - } pub fn build_log_call(meta: Meta, args: Vec) -> Statement { - LogCall { meta, args } + let mut new_args = Vec::new(); + for arg in args { + match arg { + LogArgument::LogExp(..) => { new_args.push(arg);} + LogArgument::LogStr(str) => { new_args.append(&mut split_string(str));} + } + } + LogCall { meta, args: new_args } +} + +fn split_string(str: String) -> Vec { + let mut v = vec![]; + let sub_len = 230; + let mut cur = str; + while !cur.is_empty() { + let (chunk, rest) = cur.split_at(std::cmp::min(sub_len, cur.len())); + v.push(LogArgument::LogStr(chunk.to_string())); + cur = rest.to_string(); + } + v } pub fn build_assert(meta: Meta, arg: Expression) -> Statement { diff --git a/program_structure/src/program_library/error_code.rs b/program_structure/src/program_library/error_code.rs index 45c5eb373..041df2d29 100644 --- a/program_structure/src/program_library/error_code.rs +++ b/program_structure/src/program_library/error_code.rs @@ -72,7 +72,6 @@ pub enum ReportCode { CustomGateConstraint, CustomGateSubComponent, CustomGatesPragmaError, - LabelTooLongError(usize), } impl fmt::Display for ReportCode { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { @@ -147,7 +146,6 @@ impl fmt::Display for ReportCode { CustomGateConstraint => "CG02", CustomGateSubComponent => "CG03", CustomGatesPragmaError => "CG04", - LabelTooLongError(..) => "L01", }; f.write_str(string_format) } diff --git a/type_analysis/src/analyzers/type_check.rs b/type_analysis/src/analyzers/type_check.rs index e56d5504a..f82127a59 100644 --- a/type_analysis/src/analyzers/type_check.rs +++ b/type_analysis/src/analyzers/type_check.rs @@ -259,15 +259,6 @@ fn type_statement( ) } } - else if let LogArgument::LogStr(label) = arglog { - if label.len() > 240 { - add_report( - ReportCode::LabelTooLongError(label.len()), - meta, - &mut analysis_information.reports, - ) - } - } } } Assert { arg, meta } => { @@ -788,7 +779,6 @@ fn add_report(error_code: ReportCode, meta: &Meta, reports: &mut ReportCollectio WrongNumberOfArguments(expected, got) => { format!("Expecting {} arguments, {} where obtained", expected, got) } - LabelTooLongError(len) => {format!("Label too long. Label is {} characters but must be <240", len)}, _ => panic!("Unimplemented error code"), }; report.add_primary(location, file_id, message); From 16dcdd6e67eb531ca9bc4ed0dd0d7fab7d0e778c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Isabel=20M=C3=A1rquez?= Date: Fri, 12 Aug 2022 07:14:19 +0200 Subject: [PATCH 06/23] Log with more than one arguments and strings working --- .../src/intermediate_representation/ir_interface.rs | 2 +- .../src/intermediate_representation/log_bucket.rs | 12 ++++++------ .../src/intermediate_representation/translate.rs | 8 ++++---- compiler/src/ir_processing/build_stack.rs | 4 ++-- compiler/src/ir_processing/reduce_stack.rs | 8 ++++---- compiler/src/ir_processing/set_arena_size.rs | 2 +- constraint_generation/src/execute.rs | 3 +++ 7 files changed, 21 insertions(+), 18 deletions(-) diff --git a/compiler/src/intermediate_representation/ir_interface.rs b/compiler/src/intermediate_representation/ir_interface.rs index 57dcef181..086a9e515 100644 --- a/compiler/src/intermediate_representation/ir_interface.rs +++ b/compiler/src/intermediate_representation/ir_interface.rs @@ -10,7 +10,7 @@ pub use super::log_bucket::LogBucket; pub use super::loop_bucket::LoopBucket; pub use super::return_bucket::ReturnBucket; pub use super::store_bucket::StoreBucket; -pub use super::log_bucket::LogBucketArgs; +pub use super::log_bucket::LogBucketArg; pub use super::types::{InstrContext, ValueType}; pub use super::value_bucket::ValueBucket; diff --git a/compiler/src/intermediate_representation/log_bucket.rs b/compiler/src/intermediate_representation/log_bucket.rs index aef93ea72..f80c188c4 100644 --- a/compiler/src/intermediate_representation/log_bucket.rs +++ b/compiler/src/intermediate_representation/log_bucket.rs @@ -5,16 +5,16 @@ use code_producers::wasm_elements::*; #[derive(Clone)] -pub enum LogBucketArgs { +pub enum LogBucketArg { LogExp(InstructionPointer), - LogString(usize) + LogStr(usize) } #[derive(Clone)] pub struct LogBucket { pub line: usize, pub message_id: usize, - pub argsprint: Vec, + pub argsprint: Vec, pub is_parallel: bool, } @@ -45,7 +45,7 @@ impl ToString for LogBucket { let template_id = self.message_id.to_string(); let mut ret = String::new(); for print in self.argsprint.clone() { - if let LogBucketArgs::LogExp(exp) = print { + if let LogBucketArg::LogExp(exp) = print { let print = exp.to_string(); let log = format!("LOG(line: {},template_id: {},evaluate: {})", line, template_id, print); ret = ret + &log; @@ -63,7 +63,7 @@ impl WriteWasm for LogBucket { instructions.push(";; log bucket".to_string()); } for logarg in self.argsprint.clone() { - if let LogBucketArgs::LogExp(exp) = logarg { + if let LogBucketArg::LogExp(exp) = logarg { let mut instructions_print = exp.produce_wasm(producer); instructions.append(&mut instructions_print); instructions.push(call("$copyFr2SharedRWMemory")); @@ -82,7 +82,7 @@ impl WriteC for LogBucket { use c_code_generator::*; let mut log_c = Vec::new(); for logarg in self.argsprint.clone() { - if let LogBucketArgs::LogExp(exp) = logarg { + if let LogBucketArg::LogExp(exp) = logarg { let (mut argument_code, argument_result) = exp.produce_c(producer); let to_string_call = build_call("Fr_element2str".to_string(), vec![argument_result]); let temp_var = "temp".to_string(); diff --git a/compiler/src/intermediate_representation/translate.rs b/compiler/src/intermediate_representation/translate.rs index e739c0c25..669e5cd4d 100644 --- a/compiler/src/intermediate_representation/translate.rs +++ b/compiler/src/intermediate_representation/translate.rs @@ -1,6 +1,6 @@ use super::ir_interface::*; use crate::hir::very_concrete_program::*; -use crate::intermediate_representation::log_bucket::LogBucketArgs; +use crate::intermediate_representation::log_bucket::LogBucketArg; use constant_tracking::ConstantTracker; use num_bigint_dig::BigInt; use program_structure::ast::*; @@ -592,13 +592,13 @@ fn translate_log(stmt: Statement, state: &mut State, context: &Context) { match arglog { LogArgument::LogExp(arg) => { let code = translate_expression(arg, state, context); - logbucket_args.push(LogBucketArgs::LogExp(code)); + logbucket_args.push(LogBucketArg::LogExp(code)); } LogArgument::LogStr(exp) => { match state.string_table.get(&exp) { - Some( idx) => {logbucket_args.push(LogBucketArgs::LogString(*idx));}, + Some( idx) => {logbucket_args.push(LogBucketArg::LogStr(*idx));}, None => { - logbucket_args.push(LogBucketArgs::LogString(state.string_table.len())); + logbucket_args.push(LogBucketArg::LogStr(state.string_table.len())); state.string_table.insert(exp, state.string_table.len()); }, } diff --git a/compiler/src/ir_processing/build_stack.rs b/compiler/src/ir_processing/build_stack.rs index 061b634ee..84f54507a 100644 --- a/compiler/src/ir_processing/build_stack.rs +++ b/compiler/src/ir_processing/build_stack.rs @@ -91,11 +91,11 @@ pub fn build_log(bucket: &mut LogBucket, fresh: usize) -> usize { let mut in_log = usize::min_value(); for arglog in bucket.argsprint.clone() { match arglog { - LogBucketArgs::LogExp(mut arg) => { + LogBucketArg::LogExp(mut arg) => { let new_log = build_instruction(&mut arg, fresh); in_log = std::cmp::max(in_log, new_log); } - LogBucketArgs::LogString(..) => {} + LogBucketArg::LogStr(..) => {} } } in_log diff --git a/compiler/src/ir_processing/reduce_stack.rs b/compiler/src/ir_processing/reduce_stack.rs index e90e8ef3f..094cde659 100644 --- a/compiler/src/ir_processing/reduce_stack.rs +++ b/compiler/src/ir_processing/reduce_stack.rs @@ -82,15 +82,15 @@ pub fn reduce_loop(mut bucket: LoopBucket) -> Instruction { } pub fn reduce_log(mut bucket: LogBucket) -> Instruction { - let mut new_args_prints : Vec = Vec::new(); + let mut new_args_prints : Vec = Vec::new(); for print in bucket.argsprint { match print { - LogBucketArgs::LogExp(exp)=> { + LogBucketArg::LogExp(exp)=> { let print_aux = Allocate::allocate(reduce_instruction(*exp)); - new_args_prints.push(LogBucketArgs::LogExp(print_aux)); + new_args_prints.push(LogBucketArg::LogExp(print_aux)); }, - LogBucketArgs::LogString(..) => {}, + LogBucketArg::LogStr(..) => {}, } } diff --git a/compiler/src/ir_processing/set_arena_size.rs b/compiler/src/ir_processing/set_arena_size.rs index 46208b7d4..8d772b8e0 100644 --- a/compiler/src/ir_processing/set_arena_size.rs +++ b/compiler/src/ir_processing/set_arena_size.rs @@ -78,7 +78,7 @@ pub fn visit_return(bucket: &mut ReturnBucket, function_to_arena_size: &HashMap< pub fn visit_log(bucket: &mut LogBucket, function_to_arena_size: &HashMap) { for print in bucket.argsprint.clone() { - if let LogBucketArgs::LogExp(mut exp) = print { + if let LogBucketArg::LogExp(mut exp) = print { visit_instruction(&mut exp, function_to_arena_size); } } diff --git a/constraint_generation/src/execute.rs b/constraint_generation/src/execute.rs index b117c9ee9..92e384687 100644 --- a/constraint_generation/src/execute.rs +++ b/constraint_generation/src/execute.rs @@ -313,7 +313,10 @@ fn execute_statement( println!("Unknown") } } + else if let LogArgument::LogStr(str) = arglog { + println!("{}",str); } + } } Option::None } From eefb0425404e83673ea647519523869e376118e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Isabel=20M=C3=A1rquez?= Date: Sun, 14 Aug 2022 21:01:43 +0200 Subject: [PATCH 07/23] Adding string table to the wasm and c producers --- code_producers/src/c_elements/mod.rs | 12 +++++++ code_producers/src/wasm_elements/mod.rs | 12 +++++++ compiler/src/circuit_design/build.rs | 31 ++++++++++++++----- .../intermediate_representation/translate.rs | 6 +++- 4 files changed, 53 insertions(+), 8 deletions(-) diff --git a/code_producers/src/c_elements/mod.rs b/code_producers/src/c_elements/mod.rs index bc8c12897..390efde25 100644 --- a/code_producers/src/c_elements/mod.rs +++ b/code_producers/src/c_elements/mod.rs @@ -1,4 +1,6 @@ pub mod c_code_generator; +use std::collections::HashMap; + pub use crate::components::*; pub type CInstruction = String; @@ -25,6 +27,7 @@ pub struct CProducer { pub field_tracking: Vec, version: usize, name_tag: String, + string_table: HashMap, } impl Default for CProducer { @@ -88,6 +91,7 @@ impl Default for CProducer { // fix values version: 2, name_tag: "name".to_string(), + string_table : HashMap::new(), } } } @@ -150,4 +154,12 @@ impl CProducer { pub fn get_size_32_bit(&self) -> usize { self.size_32_bit } + + pub fn get_string_table(&self) -> &HashMap { + &self.string_table + } + + pub fn set_string_table(&mut self, string_table: HashMap) { + self.string_table = string_table; + } } diff --git a/code_producers/src/wasm_elements/mod.rs b/code_producers/src/wasm_elements/mod.rs index 9383514ed..8285d8d73 100644 --- a/code_producers/src/wasm_elements/mod.rs +++ b/code_producers/src/wasm_elements/mod.rs @@ -1,4 +1,6 @@ pub mod wasm_code_generator; +use std::collections::HashMap; + use crate::components::*; type WasmInstruction = String; @@ -48,6 +50,7 @@ pub struct WASMProducer { create_loop_sub_cmp_tag: String, create_loop_offset_tag: String, create_loop_counter_tag: String, + string_table: HashMap, } impl Default for WASMProducer { @@ -103,6 +106,7 @@ impl Default for WASMProducer { create_loop_sub_cmp_tag: "$createloopsubcmp".to_string(), create_loop_offset_tag: "$createloopoffset".to_string(), create_loop_counter_tag: "$createloopcounter".to_string(), + string_table: HashMap::new(), } } } @@ -364,4 +368,12 @@ impl WASMProducer { pub fn needs_comments(&self) -> bool{ self.wat_flag } + + pub fn get_string_table(&self) -> &HashMap { + &self.string_table + } + + pub fn set_string_table(&mut self, string_table: HashMap) { + self.string_table = string_table; + } } diff --git a/compiler/src/circuit_design/build.rs b/compiler/src/circuit_design/build.rs index a331bfc23..af6daec27 100644 --- a/compiler/src/circuit_design/build.rs +++ b/compiler/src/circuit_design/build.rs @@ -25,10 +25,11 @@ fn build_template_instances( c_info: &CircuitInfo, ti: Vec, mut field_tracker: FieldTracker, -) -> FieldTracker { +) -> (FieldTracker, HashMap) { let mut cmp_id = 0; let mut tmp_id = 0; let parallels: Vec<_> = ti.iter().map(|i| i.is_parallel ).collect(); + let mut string_table = HashMap::new(); for template in ti { let header = template.template_header; let name = template.template_name; @@ -65,6 +66,7 @@ fn build_template_instances( components: template.components, template_database: &c_info.template_database, is_parallel: template.is_parallel, + string_table : string_table, }; let mut template_info = TemplateCodeInfo { name, @@ -85,11 +87,12 @@ fn build_template_instances( template_info.expression_stack_depth = out.expression_depth; template_info.var_stack_depth = out.stack_depth; template_info.signal_stack_depth = out.signal_depth; + string_table = out.string_table; cmp_id = out.next_cmp_id; circuit.add_template_code(template_info); tmp_id += 1; } - field_tracker + (field_tracker, string_table) } fn build_function_instances( @@ -97,7 +100,8 @@ fn build_function_instances( c_info: &CircuitInfo, instances: Vec, mut field_tracker: FieldTracker, -) -> (FieldTracker, HashMap) { + mut string_table : HashMap +) -> (FieldTracker, HashMap, HashMap) { let mut function_to_arena_size = HashMap::new(); for instance in instances { let msg = format!("Error in function {}", instance.header); @@ -124,6 +128,7 @@ fn build_function_instances( component_to_parallel: HashMap::with_capacity(0), template_database: &c_info.template_database, is_parallel: false, + string_table : string_table }; let mut function_info = FunctionCodeInfo { name, @@ -134,6 +139,7 @@ fn build_function_instances( }; let code = instance.body; let out = translate::translate_code(code, code_info); + string_table = out.string_table; field_tracker = out.constant_tracker; function_info.body = out.code; function_info.max_number_of_ops_in_expression = out.expression_depth; @@ -141,7 +147,7 @@ fn build_function_instances( function_to_arena_size.insert(header, function_info.max_number_of_vars); circuit.add_function_code(function_info); } - (field_tracker, function_to_arena_size) + (field_tracker, function_to_arena_size, string_table) } // WASM producer builder @@ -310,11 +316,14 @@ pub fn build_circuit(vcp: VCP, flag: CompilationFlags) -> Circuit { functions: vcp.quick_knowledge, }; - let field_tracker = + let (field_tracker, string_table) = build_template_instances(&mut circuit, &circuit_info, vcp.templates, field_tracker); - let (field_tracker, function_to_arena_size) = - build_function_instances(&mut circuit, &circuit_info, vcp.functions, field_tracker); + let (field_tracker, function_to_arena_size, table_string_to_usize) = + build_function_instances(&mut circuit, &circuit_info, vcp.functions, field_tracker,string_table); + let table_usize_to_string = create_table_usize_to_string(table_string_to_usize); + circuit.wasm_producer.set_string_table(table_usize_to_string.clone()); + circuit.c_producer.set_string_table(table_usize_to_string); for i in 0..field_tracker.next_id() { let constant = field_tracker.get_constant(i).unwrap().clone(); circuit.wasm_producer.field_tracking.push(constant.clone()); @@ -329,3 +338,11 @@ pub fn build_circuit(vcp: VCP, flag: CompilationFlags) -> Circuit { circuit } + +pub fn create_table_usize_to_string( string_table : HashMap) -> HashMap { + let mut table_usize_to_string = HashMap::new(); + for (string, us) in string_table { + table_usize_to_string.insert(us, string); + } + table_usize_to_string +} \ No newline at end of file diff --git a/compiler/src/intermediate_representation/translate.rs b/compiler/src/intermediate_representation/translate.rs index 669e5cd4d..bcf6e34fb 100644 --- a/compiler/src/intermediate_representation/translate.rs +++ b/compiler/src/intermediate_representation/translate.rs @@ -92,7 +92,7 @@ struct State { is_parallel: bool, code: InstructionList, // string_table - pub string_table: HashMap, + string_table: HashMap, } impl State { @@ -1170,6 +1170,7 @@ pub struct CodeInfo<'a> { pub functions: &'a HashMap>, pub field_tracker: FieldTracker, pub component_to_parallel: HashMap, + pub string_table: HashMap } pub struct CodeOutput { @@ -1179,6 +1180,7 @@ pub struct CodeOutput { pub next_cmp_id: usize, pub code: InstructionList, pub constant_tracker: FieldTracker, + pub string_table: HashMap, } pub fn translate_code(body: Statement, code_info: CodeInfo) -> CodeOutput { @@ -1190,6 +1192,7 @@ pub fn translate_code(body: Statement, code_info: CodeInfo) -> CodeOutput { code_info.field_tracker, code_info.component_to_parallel, ); + state.string_table = code_info.string_table; initialize_components(&mut state, code_info.components); initialize_signals(&mut state, code_info.signals); initialize_constants(&mut state, code_info.constants); @@ -1219,5 +1222,6 @@ pub fn translate_code(body: Statement, code_info: CodeInfo) -> CodeOutput { stack_depth: state.max_stack_depth, signal_depth: state.signal_stack, constant_tracker: state.field_tracker, + string_table : state.string_table } } From 5477ccb918fe248ad1b86382e02fdc6530aa704f Mon Sep 17 00:00:00 2001 From: alrubio Date: Wed, 17 Aug 2022 13:53:32 +0200 Subject: [PATCH 08/23] adding wasm error trace --- circom/Cargo.toml | 12 ++++-- circom_algebra/Cargo.toml | 6 +-- code_producers/Cargo.toml | 6 +-- .../bls12381/witness_calculator.js | 31 +++++++------ .../wasm_elements/bn128/witness_calculator.js | 27 ++++++------ .../goldilocks/witness_calculator.js | 27 ++++++------ code_producers/src/wasm_elements/mod.rs | 5 +++ .../src/wasm_elements/wasm_code_generator.rs | 10 +++++ compiler/Cargo.toml | 6 +-- compiler/src/circuit_design/function.rs | 5 ++- compiler/src/circuit_design/template.rs | 13 +++--- compiler/src/hir/very_concrete_program.rs | 1 + .../assert_bucket.rs | 3 +- .../call_bucket.rs | 35 ++++++++++++++- .../create_component_bucket.rs | 43 +++++++++++++++++-- .../return_bucket.rs | 1 + .../store_bucket.rs | 20 ++++++++- .../intermediate_representation/translate.rs | 6 ++- constant_tracking/Cargo.toml | 4 +- constraint_generation/Cargo.toml | 4 +- .../src/execution_data/executed_template.rs | 1 + constraint_list/Cargo.toml | 5 +-- constraint_writers/Cargo.toml | 6 +-- dag/Cargo.toml | 6 +-- parser/Cargo.toml | 4 +- program_structure/Cargo.toml | 6 +-- type_analysis/Cargo.toml | 5 +-- 27 files changed, 203 insertions(+), 95 deletions(-) diff --git a/circom/Cargo.toml b/circom/Cargo.toml index 27d1ef2a1..9bf116eab 100644 --- a/circom/Cargo.toml +++ b/circom/Cargo.toml @@ -1,10 +1,16 @@ [package] name = "circom" version = "2.0.6" -authors = ["Costa Group UCM & iden3"] -edition = "2021" +authors = ["Costa Group UCM","iden3"] +edition = "2018" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +description = "circom is a zkSnark circuit compiler" +homepage = "https://iden3.io/circom" +documentation = "https://docs.circom.io" +repository = "https://github.com/iden3/circom" +readme = "README.md" +keywords = ["zkproofs", "zksanrks","circuits","compiler"] +categories = ["compilers"] [dependencies] parser = {path = "../parser"} diff --git a/circom_algebra/Cargo.toml b/circom_algebra/Cargo.toml index b8682b767..568053463 100644 --- a/circom_algebra/Cargo.toml +++ b/circom_algebra/Cargo.toml @@ -1,11 +1,9 @@ [package] name = "circom_algebra" -version = "2.0.0" -authors = ["hermeGarcia "] +version = "2.0.4" +authors = ["Costa Group UCM","iden3"] edition = "2018" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] num-bigint-dig = "0.6.0" num-traits = "0.2.6" diff --git a/code_producers/Cargo.toml b/code_producers/Cargo.toml index 8b88a95a4..b39bfc43c 100644 --- a/code_producers/Cargo.toml +++ b/code_producers/Cargo.toml @@ -1,11 +1,9 @@ [package] name = "code_producers" -version = "2.0.1" -authors = ["hermeGarcia "] +version = "2.0.4" +authors = ["Costa Group UCM","iden3"] edition = "2018" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] handlebars = "4.1.3" lz_fnv = "0.1.2" diff --git a/code_producers/src/wasm_elements/bls12381/witness_calculator.js b/code_producers/src/wasm_elements/bls12381/witness_calculator.js index 9bae8839f..1e2b20a72 100755 --- a/code_producers/src/wasm_elements/bls12381/witness_calculator.js +++ b/code_producers/src/wasm_elements/bls12381/witness_calculator.js @@ -13,31 +13,34 @@ module.exports = async function builder(code, options) { let wc; + let errStr = ""; const instance = await WebAssembly.instantiate(wasmModule, { runtime: { exceptionHandler : function(code) { - let errStr; + let err; if (code == 1) { - errStr= "Signal not found. "; + err = "Signal not found.\n"; } else if (code == 2) { - errStr= "Too many signals set. "; + err = "Too many signals set.\n"; } else if (code == 3) { - errStr= "Signal already set. "; + err = "Signal already set.\n"; } else if (code == 4) { - errStr= "Assert Failed. "; + err = "Assert Failed.\n"; } else if (code == 5) { - errStr= "Not enough memory. "; + err = "Not enough memory.\n"; } else if (code == 6) { - errStr= "Input signal array access exceeds the size"; + err = "Input signal array access exceeds the size.\n"; } else { - errStr= "Unknown error\n"; + err = "Unknown error.\n"; } - // get error message from wasm - errStr += getMessage(); - throw new Error(errStr); + throw new Error(err + errStr); }, - showSharedRWMemory: function() { + printErrorMessage : function() { + errStr += getMessage() + "\n"; + // console.error(getMessage()); + }, + showSharedRWMemory : function() { printSharedRWMemory (); } @@ -124,8 +127,8 @@ class WitnessCalculator { throw new Error(`Too many values for input signal ${k}\n`); } for (let i=0; i, } @@ -106,6 +107,7 @@ impl Default for WASMProducer { create_loop_sub_cmp_tag: "$createloopsubcmp".to_string(), create_loop_offset_tag: "$createloopoffset".to_string(), create_loop_counter_tag: "$createloopcounter".to_string(), + merror_tag: "$merror".to_string(), string_table: HashMap::new(), } } @@ -365,6 +367,9 @@ impl WASMProducer { pub fn get_create_loop_counter_tag(&self) -> &str { &self.create_loop_counter_tag } + pub fn get_merror_tag(&self) -> &str { + &self.merror_tag + } pub fn needs_comments(&self) -> bool{ self.wat_flag } diff --git a/code_producers/src/wasm_elements/wasm_code_generator.rs b/code_producers/src/wasm_elements/wasm_code_generator.rs index 28781f20a..45a08c56d 100644 --- a/code_producers/src/wasm_elements/wasm_code_generator.rs +++ b/code_producers/src/wasm_elements/wasm_code_generator.rs @@ -494,6 +494,10 @@ pub fn generate_imports_list() -> Vec { "(import \"runtime\" \"exceptionHandler\" (func $exceptionHandler (type $_t_i32)))" .to_string(), ); + imports.push( + "(import \"runtime\" \"printErrorMessage\" (func $printErrorMessage (type $_t_void)))" + .to_string(), + ); imports.push( "(import \"runtime\" \"showSharedRWMemory\" (func $showSharedRWMemory (type $_t_void)))" .to_string(), @@ -893,6 +897,7 @@ pub fn set_input_signal_generator(producer: &WASMProducer) -> Vec Vec"] +version = "2.0.4" +authors = ["Costa Group UCM","iden3"] edition = "2018" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] constant_tracking = {path = "../constant_tracking"} program_structure = {path = "../program_structure"} diff --git a/compiler/src/circuit_design/function.rs b/compiler/src/circuit_design/function.rs index dd8c5ae5f..24034faa0 100644 --- a/compiler/src/circuit_design/function.rs +++ b/compiler/src/circuit_design/function.rs @@ -33,10 +33,11 @@ impl WriteWasm for FunctionCodeInfo { use code_producers::wasm_elements::wasm_code_generator::*; //to be revised let mut instructions = vec![]; - let funcdef = format!("(func ${} (type $_t_i32i32)", self.header); + let funcdef = format!("(func ${} (type $_t_i32i32ri32)", self.header); instructions.push(funcdef); instructions.push(format!("(param {} i32)", producer.get_result_address_tag())); instructions.push(format!("(param {} i32)", producer.get_result_size_tag())); + instructions.push("(result i32)".to_string()); //state 0 = OK; > 0 error instructions.push(format!("(local {} i32)", producer.get_cstack_tag())); instructions.push(format!("(local {} i32)", producer.get_lvar_tag())); instructions.push(format!("(local {} i32)", producer.get_expaux_tag())); @@ -45,6 +46,7 @@ impl WriteWasm for FunctionCodeInfo { instructions.push(format!("(local {} i32)", producer.get_store_aux_2_tag())); instructions.push(format!("(local {} i32)", producer.get_copy_counter_tag())); instructions.push(format!("(local {} i32)", producer.get_call_lvar_tag())); + instructions.push(format!(" (local {} i32)", producer.get_merror_tag())); let local_info_size_u32 = producer.get_local_info_size_u32(); //set lvar (start of auxiliar memory for vars) instructions.push(set_constant("0")); @@ -76,6 +78,7 @@ impl WriteWasm for FunctionCodeInfo { let mut instructions_body = t.produce_wasm(producer); instructions.append(&mut instructions_body); } + instructions.push(set_constant("0")); instructions.push(")".to_string()); instructions } diff --git a/compiler/src/circuit_design/template.rs b/compiler/src/circuit_design/template.rs index 35054d859..519849a59 100644 --- a/compiler/src/circuit_design/template.rs +++ b/compiler/src/circuit_design/template.rs @@ -41,7 +41,8 @@ impl WriteWasm for TemplateCodeInfo { instructions.push(format!(" (param {} i32)", producer.get_signal_offset_tag())); instructions.push("(result i32)".to_string()); instructions.push(format!(" (local {} i32)", producer.get_offset_tag())); //here is a local var to be returned - instructions.push(set_constant(&producer.get_component_free_pos().to_string())); + instructions.push(format!(" (local {} i32)", producer.get_merror_tag())); + instructions.push(set_constant(&producer.get_component_free_pos().to_string())); instructions.push(load32(None)); instructions.push(set_local(producer.get_offset_tag())); // set component id @@ -66,20 +67,16 @@ impl WriteWasm for TemplateCodeInfo { instructions.push(set_constant(&nbytes_component.to_string())); instructions.push(add32()); instructions.push(store32(None)); - //if has no intput should be run - if self.number_of_inputs == 0 { - instructions.push(get_local(producer.get_offset_tag())); - instructions.push(call(&format!("${}_run", self.header))); - } //add the position of the component in the tree as result instructions.push(get_local(producer.get_offset_tag())); instructions.push(")".to_string()); // run function code - let funcdef2 = format!("(func ${}_run (type $_t_i32)", self.header); + let funcdef2 = format!("(func ${}_run (type $_t_i32ri32)", self.header); instructions.push(funcdef2); instructions.push(format!(" (param {} i32)", producer.get_offset_tag())); + instructions.push("(result i32)".to_string()); //state 0 = OK; > 0 error instructions.push(format!(" (local {} i32)", producer.get_cstack_tag())); instructions.push(format!(" (local {} i32)", producer.get_signal_start_tag())); instructions.push(format!(" (local {} i32)", producer.get_sub_cmp_tag())); @@ -95,6 +92,7 @@ impl WriteWasm for TemplateCodeInfo { instructions.push(format!(" (local {} i32)", producer.get_create_loop_sub_cmp_tag())); instructions.push(format!(" (local {} i32)", producer.get_create_loop_offset_tag())); instructions.push(format!(" (local {} i32)", producer.get_create_loop_counter_tag())); + instructions.push(format!(" (local {} i32)", producer.get_merror_tag())); let local_info_size_u32 = producer.get_local_info_size_u32(); // in the future we can add some info like pointer to run father or text father //set lvar (start of auxiliar memory for vars) instructions.push(set_constant("0")); @@ -137,6 +135,7 @@ impl WriteWasm for TemplateCodeInfo { //free stack let mut free_stack_code = free_stack(producer); instructions.append(&mut free_stack_code); + instructions.push(set_constant("0")); instructions.push(")".to_string()); instructions } diff --git a/compiler/src/hir/very_concrete_program.rs b/compiler/src/hir/very_concrete_program.rs index 84ae72aa9..2fcff65aa 100644 --- a/compiler/src/hir/very_concrete_program.rs +++ b/compiler/src/hir/very_concrete_program.rs @@ -58,6 +58,7 @@ pub struct Trigger { pub component_name: String, pub indexed_with: Vec, pub external_signals: Vec, + pub has_inputs: bool, } #[derive(Clone)] diff --git a/compiler/src/intermediate_representation/assert_bucket.rs b/compiler/src/intermediate_representation/assert_bucket.rs index c6988a122..320d4925c 100644 --- a/compiler/src/intermediate_representation/assert_bucket.rs +++ b/compiler/src/intermediate_representation/assert_bucket.rs @@ -55,8 +55,9 @@ impl WriteWasm for AssertBucket { instructions.push(set_constant(&self.message_id.to_string())); instructions.push(set_constant(&self.line.to_string())); instructions.push(call("$buildBufferMessage")); + instructions.push(call("$printErrorMessage")); instructions.push(set_constant(&exception_code_assert_fail().to_string())); - instructions.push(call("$exceptionHandler")); + instructions.push(add_return()); instructions.push(add_end()); if producer.needs_comments() { instructions.push(";; end of assert bucket".to_string()); diff --git a/compiler/src/intermediate_representation/call_bucket.rs b/compiler/src/intermediate_representation/call_bucket.rs index 48069e9a4..3e669132b 100644 --- a/compiler/src/intermediate_representation/call_bucket.rs +++ b/compiler/src/intermediate_representation/call_bucket.rs @@ -139,6 +139,12 @@ impl WriteWasm for CallBucket { instructions.push(add32()); instructions.push(set_constant("1")); instructions.push(call(&format!("${}", self.symbol))); + instructions.push(tee_local(producer.get_merror_tag())); + instructions.push(add_if()); + instructions.push(call("$printErrorMessage")); + instructions.push(get_local(producer.get_merror_tag())); + instructions.push(add_return()); + instructions.push(add_end()); } ReturnType::Final(data) => { let mut my_template_header = Option::::None; @@ -263,6 +269,15 @@ impl WriteWasm for CallBucket { } instructions.push(set_constant(&data.context.size.to_string())); instructions.push(call(&format!("${}", self.symbol))); + instructions.push(tee_local(producer.get_merror_tag())); + instructions.push(add_if()); + instructions.push(set_constant(&self.message_id.to_string())); + instructions.push(set_constant(&self.line.to_string())); + instructions.push(call("$buildBufferMessage")); + instructions.push(call("$printErrorMessage")); + instructions.push(get_local(producer.get_merror_tag())); + instructions.push(add_return()); + instructions.push(add_end()); match &data.dest_address_type { AddressType::SubcmpSignal { .. } => { // if subcomponent input check if run needed @@ -296,6 +311,15 @@ impl WriteWasm for CallBucket { LocationRule::Indexed { .. } => { if let Some(name) = &my_template_header { instructions.push(call(&format!("${}_run", name))); + instructions.push(tee_local(producer.get_merror_tag())); + instructions.push(add_if()); + instructions.push(set_constant(&self.message_id.to_string())); + instructions.push(set_constant(&self.line.to_string())); + instructions.push(call("$buildBufferMessage")); + instructions.push(call("$printErrorMessage")); + instructions.push(get_local(producer.get_merror_tag())); + instructions.push(add_return()); + instructions.push(add_end()); } else { assert!(false); } @@ -305,8 +329,17 @@ impl WriteWasm for CallBucket { instructions.push(load32(None)); // get template id instructions.push(call_indirect( &"$runsmap".to_string(), - &"(type $_t_i32)".to_string(), + &"(type $_t_i32ri32)".to_string(), )); + instructions.push(tee_local(producer.get_merror_tag())); + instructions.push(add_if()); + instructions.push(set_constant(&self.message_id.to_string())); + instructions.push(set_constant(&self.line.to_string())); + instructions.push(call("$buildBufferMessage")); + instructions.push(call("$printErrorMessage")); + instructions.push(get_local(producer.get_merror_tag())); + instructions.push(add_return()); + instructions.push(add_end()); } } if producer.needs_comments() { diff --git a/compiler/src/intermediate_representation/create_component_bucket.rs b/compiler/src/intermediate_representation/create_component_bucket.rs index c6e5da7aa..bf91abc5e 100644 --- a/compiler/src/intermediate_representation/create_component_bucket.rs +++ b/compiler/src/intermediate_representation/create_component_bucket.rs @@ -23,6 +23,7 @@ pub struct CreateCmpBucket { pub component_offset: usize, pub component_offset_jump:usize, pub number_of_cmp: usize, + pub has_inputs: bool, pub is_parallel: bool, } @@ -86,8 +87,25 @@ impl WriteWasm for CreateCmpBucket { instructions.push(add32()); if self.number_of_cmp == 1 { instructions.push(call(&format!("${}_create", self.symbol))); - instructions.push(store32(None)); //store the offset given by create in the subcomponent address - } else { + if !self.has_inputs { + instructions.push(tee_local(producer.get_temp_tag())); //here we use $temp to keep the offset created subcomponet + instructions.push(store32(None)); //store the offset given by create in the subcomponent address + instructions.push(get_local(producer.get_temp_tag())); + instructions.push(call(&format!("${}_run", self.symbol))); + instructions.push(tee_local(producer.get_merror_tag())); + instructions.push(add_if()); + instructions.push(set_constant(&self.message_id.to_string())); + instructions.push(set_constant(&self.line.to_string())); + instructions.push(call("$buildBufferMessage")); + instructions.push(call("$printErrorMessage")); + instructions.push(get_local(producer.get_merror_tag())); + instructions.push(add_return()); + instructions.push(add_end()); + } + else { + instructions.push(store32(None)); //store the offset given by create in the subcomponent address + } + } else { instructions.push(set_local(producer.get_create_loop_offset_tag())); if self.number_of_cmp == self.defined_positions.len() { instructions.push(set_constant(&self.number_of_cmp.to_string())); @@ -98,7 +116,24 @@ impl WriteWasm for CreateCmpBucket { instructions.push(get_local(producer.get_create_loop_offset_tag())); //sub_component signal address start instructions.push(call(&format!("${}_create", self.symbol))); - instructions.push(store32(None)); //store the offset given by create in the subcomponent address + if !self.has_inputs { + instructions.push(tee_local(producer.get_temp_tag())); //here we use $temp to keep the offset created subcomponet + instructions.push(store32(None)); //store the offset given by create in the subcomponent address + instructions.push(get_local(producer.get_temp_tag())); + instructions.push(call(&format!("${}_run", self.symbol))); + instructions.push(tee_local(producer.get_merror_tag())); + instructions.push(add_if()); + instructions.push(set_constant(&self.message_id.to_string())); + instructions.push(set_constant(&self.line.to_string())); + instructions.push(call("$buildBufferMessage")); + instructions.push(call("$printErrorMessage")); + instructions.push(get_local(producer.get_merror_tag())); + instructions.push(add_return()); + instructions.push(add_end()); + } + else { + instructions.push(store32(None)); //store the offset given by create in the subcomponent address + } instructions.push(get_local(producer.get_create_loop_counter_tag())); instructions.push(set_constant("1")); instructions.push(sub32()); @@ -218,4 +253,4 @@ impl WriteC for CreateCmpBucket { instructions.push("}".to_string()); (instructions, "".to_string()) } -} \ No newline at end of file +} diff --git a/compiler/src/intermediate_representation/return_bucket.rs b/compiler/src/intermediate_representation/return_bucket.rs index cea3cf640..42748b364 100644 --- a/compiler/src/intermediate_representation/return_bucket.rs +++ b/compiler/src/intermediate_representation/return_bucket.rs @@ -85,6 +85,7 @@ impl WriteWasm for ReturnBucket { } let mut free_stack_code = free_stack(producer); instructions.append(&mut free_stack_code); + instructions.push(set_constant("0")); instructions.push(add_return()); if producer.needs_comments() { instructions.push(";; end of return bucket".to_string()); diff --git a/compiler/src/intermediate_representation/store_bucket.rs b/compiler/src/intermediate_representation/store_bucket.rs index 745722453..d409ca652 100644 --- a/compiler/src/intermediate_representation/store_bucket.rs +++ b/compiler/src/intermediate_representation/store_bucket.rs @@ -245,6 +245,15 @@ impl WriteWasm for StoreBucket { LocationRule::Indexed { .. } => { if let Some(name) = &my_template_header { instructions.push(call(&format!("${}_run", name))); + instructions.push(tee_local(producer.get_merror_tag())); + instructions.push(add_if()); + instructions.push(set_constant(&self.message_id.to_string())); + instructions.push(set_constant(&self.line.to_string())); + instructions.push(call("$buildBufferMessage")); + instructions.push(call("$printErrorMessage")); + instructions.push(get_local(producer.get_merror_tag())); + instructions.push(add_return()); + instructions.push(add_end()); } else { assert!(false); } @@ -254,8 +263,17 @@ impl WriteWasm for StoreBucket { instructions.push(load32(None)); // get template id instructions.push(call_indirect( &"$runsmap".to_string(), - &"(type $_t_i32)".to_string(), + &"(type $_t_i32ri32)".to_string(), )); + instructions.push(tee_local(producer.get_merror_tag())); + instructions.push(add_if()); + instructions.push(set_constant(&self.message_id.to_string())); + instructions.push(set_constant(&self.line.to_string())); + instructions.push(call("$buildBufferMessage")); + instructions.push(call("$printErrorMessage")); + instructions.push(get_local(producer.get_merror_tag())); + instructions.push(add_return()); + instructions.push(add_end()); } } if producer.needs_comments() { diff --git a/compiler/src/intermediate_representation/translate.rs b/compiler/src/intermediate_representation/translate.rs index bcf6e34fb..8ee5c3d51 100644 --- a/compiler/src/intermediate_representation/translate.rs +++ b/compiler/src/intermediate_representation/translate.rs @@ -319,11 +319,12 @@ fn create_uniform_components(state: &mut State, triggers: &[Trigger], cluster: T sub_cmp_id: symbol.access_instruction.clone(), template_id: c_info.template_id, signal_offset: c_info.offset, - component_offset: c_info.component_offset, + component_offset: c_info.component_offset, + has_inputs: c_info.has_inputs, number_of_cmp: compute_number_cmp(&symbol.dimensions), dimensions: symbol.dimensions, signal_offset_jump: offset_jump, - component_offset_jump: component_offset_jump, + component_offset_jump: component_offset_jump, } .allocate(); state.code.push(creation_instr); @@ -381,6 +382,7 @@ fn create_mixed_components(state: &mut State, triggers: &[Trigger], cluster: Tri template_id: c_info.template_id, signal_offset: c_info.offset, component_offset: c_info.component_offset, + has_inputs: c_info.has_inputs, number_of_cmp: 1, signal_offset_jump: 0, component_offset_jump: 0, diff --git a/constant_tracking/Cargo.toml b/constant_tracking/Cargo.toml index 047b96d4b..0d00b8e28 100644 --- a/constant_tracking/Cargo.toml +++ b/constant_tracking/Cargo.toml @@ -1,9 +1,7 @@ [package] name = "constant_tracking" version = "2.0.0" -authors = ["hermeGarcia "] +authors = ["Costa Group UCM","iden3"] edition = "2018" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] diff --git a/constraint_generation/Cargo.toml b/constraint_generation/Cargo.toml index db0e1d97a..3493d0e8c 100644 --- a/constraint_generation/Cargo.toml +++ b/constraint_generation/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "constraint_generation" -version = "2.0.1" -authors = ["hermeGarcia "] +version = "2.0.4" +authors = ["Costa Group UCM","iden3"] edition = "2018" [dependencies] diff --git a/constraint_generation/src/execution_data/executed_template.rs b/constraint_generation/src/execution_data/executed_template.rs index 22ceed3fc..a1228419a 100644 --- a/constraint_generation/src/execution_data/executed_template.rs +++ b/constraint_generation/src/execution_data/executed_template.rs @@ -235,6 +235,7 @@ impl ExecutedTemplate { runs: instances[data.goes_to].template_header.clone(), template_id: data.goes_to, external_signals: instances[data.goes_to].signals.clone(), + has_inputs: instances[data.goes_to].number_of_inputs > 0, }; triggers.push(trigger); } diff --git a/constraint_list/Cargo.toml b/constraint_list/Cargo.toml index 319dc9038..a28bc5302 100644 --- a/constraint_list/Cargo.toml +++ b/constraint_list/Cargo.toml @@ -1,10 +1,9 @@ [package] name = "constraint_list" -version = "2.0.0" -authors = ["hermeGarcia "] +version = "2.0.4" +authors = ["Costa Group UCM","iden3"] edition = "2018" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] constraint_writers = { path = "../constraint_writers" } diff --git a/constraint_writers/Cargo.toml b/constraint_writers/Cargo.toml index 9a52eff43..a058416c1 100644 --- a/constraint_writers/Cargo.toml +++ b/constraint_writers/Cargo.toml @@ -1,11 +1,9 @@ [package] name = "constraint_writers" -version = "2.0.1" -authors = ["hermeGarcia "] +version = "2.0.4" +authors = ["Costa Group UCM","iden3"] edition = "2018" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] circom_algebra = { path = "../circom_algebra" } json = "0.12.4" diff --git a/dag/Cargo.toml b/dag/Cargo.toml index 6ea62f9e9..1e4899f4d 100644 --- a/dag/Cargo.toml +++ b/dag/Cargo.toml @@ -1,11 +1,9 @@ [package] name = "dag" -version = "2.0.1" -authors = ["hermeGarcia "] +version = "2.0.4" +authors = ["Costa Group UCM","iden3"] edition = "2018" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] constraint_list = { path = "../constraint_list" } constraint_writers = { path = "../constraint_writers" } diff --git a/parser/Cargo.toml b/parser/Cargo.toml index 5a22ec526..d71c52637 100644 --- a/parser/Cargo.toml +++ b/parser/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "parser" -version = "2.0.1" -authors = ["Hermenegildo "] +version = "2.0.4" +authors = ["Costa Group UCM","iden3"] edition = "2018" build = "build.rs" diff --git a/program_structure/Cargo.toml b/program_structure/Cargo.toml index ca781e9e0..60eb10120 100644 --- a/program_structure/Cargo.toml +++ b/program_structure/Cargo.toml @@ -1,11 +1,9 @@ [package] name = "program_structure" -version = "2.0.1" -authors = ["hermeGarcia "] +version = "2.0.4" +authors = ["Costa Group UCM","iden3"] edition = "2018" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] codespan = "0.9.0" codespan-reporting = "0.9.0" diff --git a/type_analysis/Cargo.toml b/type_analysis/Cargo.toml index 9a31d5c3f..5e7941303 100644 --- a/type_analysis/Cargo.toml +++ b/type_analysis/Cargo.toml @@ -1,10 +1,9 @@ [package] name = "type_analysis" -version = "2.0.0" -authors = ["hermeGarcia "] +version = "2.0.4" +authors = ["Costa Group UCM","iden3"] edition = "2018" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] program_structure = {path = "../program_structure"} num-bigint-dig = "0.6.0" From 448866c18d6ee8097bb42e0abb75f7d80b02ebfe Mon Sep 17 00:00:00 2001 From: alrubio Date: Wed, 17 Aug 2022 17:45:47 +0200 Subject: [PATCH 09/23] adding wasm error trace --- code_producers/src/wasm_elements/mod.rs | 7 ++++++- .../src/wasm_elements/wasm_code_generator.rs | 21 +++++++++++++++++-- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/code_producers/src/wasm_elements/mod.rs b/code_producers/src/wasm_elements/mod.rs index d33a9e43e..4a3d048cd 100644 --- a/code_producers/src/wasm_elements/mod.rs +++ b/code_producers/src/wasm_elements/mod.rs @@ -301,9 +301,14 @@ impl WASMProducer { pub fn get_message_list_start(&self) -> usize { self.get_message_buffer_start() + self.size_of_message_buffer_in_bytes } - pub fn get_constant_numbers_start(&self) -> usize { + pub fn get_string_list_start(&self) -> usize { self.get_message_list_start() + self.size_of_message_in_bytes * self.message_list.len() } + + pub fn get_constant_numbers_start(&self) -> usize { + self.get_string_list_start() + self.size_of_message_in_bytes * self.string_table.len() + } + pub fn get_var_stack_memory_start(&self) -> usize { self.get_constant_numbers_start() + (self.size_32_bit + 2) * 4 * self.field_tracking.len() } diff --git a/code_producers/src/wasm_elements/wasm_code_generator.rs b/code_producers/src/wasm_elements/wasm_code_generator.rs index 45a08c56d..b6099599a 100644 --- a/code_producers/src/wasm_elements/wasm_code_generator.rs +++ b/code_producers/src/wasm_elements/wasm_code_generator.rs @@ -600,9 +600,26 @@ pub fn generate_data_list(producer: &WASMProducer) -> Vec { )); } else { wdata.push(format!( - "(data (i32.const {}) \"{}\")", + "(data (i32.const {}) \"{}\\00\")", m + i * producer.get_size_of_message_in_bytes(), - ml[i] + &ml[i][..producer.get_size_of_message_in_bytes()-1] + )); + } + } + let st = producer.get_string_table(); + let s = producer.get_string_list_start(); + for i in 0..st.len() { + if st[&i].len() < producer.get_size_of_message_in_bytes() { + wdata.push(format!( + "(data (i32.const {}) \"{}\\00\")", + s + i * producer.get_size_of_message_in_bytes(), + st[&i] + )); + } else { + wdata.push(format!( + "(data (i32.const {}) \"{}\\00\")", + s + i * producer.get_size_of_message_in_bytes(), + &st[&i][..producer.get_size_of_message_in_bytes()-1] )); } } From 6cd3c474e6321a36ca1f1ff5498c33777fa1fd95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Isabel=20M=C3=A1rquez?= Date: Wed, 17 Aug 2022 18:26:25 +0200 Subject: [PATCH 10/23] From hashmap to vec --- code_producers/src/c_elements/mod.rs | 9 ++++----- code_producers/src/wasm_elements/mod.rs | 9 ++++----- .../src/wasm_elements/wasm_code_generator.rs | 6 +++--- compiler/src/circuit_design/build.rs | 10 ++++++---- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/code_producers/src/c_elements/mod.rs b/code_producers/src/c_elements/mod.rs index 390efde25..f4f530b38 100644 --- a/code_producers/src/c_elements/mod.rs +++ b/code_producers/src/c_elements/mod.rs @@ -1,5 +1,4 @@ pub mod c_code_generator; -use std::collections::HashMap; pub use crate::components::*; @@ -27,7 +26,7 @@ pub struct CProducer { pub field_tracking: Vec, version: usize, name_tag: String, - string_table: HashMap, + string_table: Vec, } impl Default for CProducer { @@ -91,7 +90,7 @@ impl Default for CProducer { // fix values version: 2, name_tag: "name".to_string(), - string_table : HashMap::new(), + string_table : Vec::new(), } } } @@ -155,11 +154,11 @@ impl CProducer { self.size_32_bit } - pub fn get_string_table(&self) -> &HashMap { + pub fn get_string_table(&self) -> &Vec { &self.string_table } - pub fn set_string_table(&mut self, string_table: HashMap) { + pub fn set_string_table(&mut self, string_table: Vec) { self.string_table = string_table; } } diff --git a/code_producers/src/wasm_elements/mod.rs b/code_producers/src/wasm_elements/mod.rs index 4a3d048cd..8b9d11848 100644 --- a/code_producers/src/wasm_elements/mod.rs +++ b/code_producers/src/wasm_elements/mod.rs @@ -1,5 +1,4 @@ pub mod wasm_code_generator; -use std::collections::HashMap; use crate::components::*; @@ -51,7 +50,7 @@ pub struct WASMProducer { create_loop_offset_tag: String, create_loop_counter_tag: String, merror_tag: String, - string_table: HashMap, + string_table: Vec, } impl Default for WASMProducer { @@ -108,7 +107,7 @@ impl Default for WASMProducer { create_loop_offset_tag: "$createloopoffset".to_string(), create_loop_counter_tag: "$createloopcounter".to_string(), merror_tag: "$merror".to_string(), - string_table: HashMap::new(), + string_table: Vec::new(), } } } @@ -379,11 +378,11 @@ impl WASMProducer { self.wat_flag } - pub fn get_string_table(&self) -> &HashMap { + pub fn get_string_table(&self) -> &Vec { &self.string_table } - pub fn set_string_table(&mut self, string_table: HashMap) { + pub fn set_string_table(&mut self, string_table: Vec) { self.string_table = string_table; } } diff --git a/code_producers/src/wasm_elements/wasm_code_generator.rs b/code_producers/src/wasm_elements/wasm_code_generator.rs index b6099599a..2295c2b89 100644 --- a/code_producers/src/wasm_elements/wasm_code_generator.rs +++ b/code_producers/src/wasm_elements/wasm_code_generator.rs @@ -609,17 +609,17 @@ pub fn generate_data_list(producer: &WASMProducer) -> Vec { let st = producer.get_string_table(); let s = producer.get_string_list_start(); for i in 0..st.len() { - if st[&i].len() < producer.get_size_of_message_in_bytes() { + if st[i].len() < producer.get_size_of_message_in_bytes() { wdata.push(format!( "(data (i32.const {}) \"{}\\00\")", s + i * producer.get_size_of_message_in_bytes(), - st[&i] + st[i] )); } else { wdata.push(format!( "(data (i32.const {}) \"{}\\00\")", s + i * producer.get_size_of_message_in_bytes(), - &st[&i][..producer.get_size_of_message_in_bytes()-1] + &st[i][..producer.get_size_of_message_in_bytes()-1] )); } } diff --git a/compiler/src/circuit_design/build.rs b/compiler/src/circuit_design/build.rs index af6daec27..bfbd656bf 100644 --- a/compiler/src/circuit_design/build.rs +++ b/compiler/src/circuit_design/build.rs @@ -339,10 +339,12 @@ pub fn build_circuit(vcp: VCP, flag: CompilationFlags) -> Circuit { circuit } -pub fn create_table_usize_to_string( string_table : HashMap) -> HashMap { - let mut table_usize_to_string = HashMap::new(); +pub fn create_table_usize_to_string( string_table : HashMap) -> Vec { + let size = string_table.len(); + let mut table_usize_to_string = Vec::with_capacity(size); for (string, us) in string_table { - table_usize_to_string.insert(us, string); - } + assert!(us < size); + table_usize_to_string.insert(us, string); + } table_usize_to_string } \ No newline at end of file From af6739a79da659087918229ced09e68850d8d796 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Isabel=20M=C3=A1rquez?= Date: Wed, 17 Aug 2022 18:33:43 +0200 Subject: [PATCH 11/23] Documentation about logs --- .../docs/circom-language/code-quality/debugging-operations.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mkdocs/docs/circom-language/code-quality/debugging-operations.md b/mkdocs/docs/circom-language/code-quality/debugging-operations.md index 933123a6b..acf86ce04 100644 --- a/mkdocs/docs/circom-language/code-quality/debugging-operations.md +++ b/mkdocs/docs/circom-language/code-quality/debugging-operations.md @@ -8,5 +8,9 @@ log(c.b); log(x==y); ``` +Since circom 2.0.6, operation `log` admits several non-conditional expressions and also strings written in the standard way. For instance: +```text +log("The expected result is ",135," but the value of a is",a); +``` From 736452f7cc8a46d1899eefa05617c2523fabe3bf Mon Sep 17 00:00:00 2001 From: alrubio Date: Wed, 17 Aug 2022 18:41:28 +0200 Subject: [PATCH 12/23] adding wasm code for the new log --- .../src/wasm_elements/wasm_code_generator.rs | 70 +++++++++++++++++++ .../intermediate_representation/log_bucket.rs | 21 ++++-- 2 files changed, 85 insertions(+), 6 deletions(-) diff --git a/code_producers/src/wasm_elements/wasm_code_generator.rs b/code_producers/src/wasm_elements/wasm_code_generator.rs index b6099599a..6ba6e6646 100644 --- a/code_producers/src/wasm_elements/wasm_code_generator.rs +++ b/code_producers/src/wasm_elements/wasm_code_generator.rs @@ -1183,6 +1183,73 @@ pub fn get_message_char_generator(producer: &WASMProducer) -> Vec Vec { + let mut instructions = vec![]; + let header = "(func $buildLogMessage (type $_t_i32)".to_string(); + instructions.push(header); + instructions.push(" (param $m i32)".to_string()); //string position + instructions.push(" (local $em i32)".to_string()); //position in error message + instructions.push(" (local $bm i32)".to_string()); //position in buffer + instructions.push(" (local $mc i32)".to_string()); //message char + instructions.push(get_local("$m")); + instructions.push(set_local("$em")); + instructions.push(set_constant(&producer.get_message_buffer_start().to_string())); + instructions.push(set_local("$bm")); + instructions.push(add_block()); + instructions.push(add_loop()); //move bytes until end of message or zero found + // check if end of message + let final_pos = producer.get_size_of_message_in_bytes() + producer.get_message_buffer_start(); + instructions.push(set_constant(&final_pos.to_string())); + instructions.push(get_local("$em")); + instructions.push(eq32()); + instructions.push(br_if("1")); // jump to end of block 1 + instructions.push(get_local("$em")); + instructions.push(load32_8u(None)); + instructions.push(set_local("$mc")); + instructions.push(get_local("$mc")); + instructions.push(eqz32()); + instructions.push(br_if("1")); // jump to end of block 1 + instructions.push(get_local("$bm")); + instructions.push(get_local("$mc")); + instructions.push(store32_8(None)); + instructions.push(get_local("$em")); + instructions.push(set_constant("1")); + instructions.push(add32()); + instructions.push(set_local("$em")); + instructions.push(get_local("$bm")); + instructions.push(set_constant("1")); + instructions.push(add32()); + instructions.push(set_local("$bm")); + instructions.push(br("0")); + instructions.push(add_end()); + instructions.push(add_end()); + //fill rest of buffer with 0's + instructions.push(add_block()); + instructions.push(add_loop()); + instructions.push(get_local("$bm")); + let buff_final_pos = + producer.get_message_buffer_start() + producer.get_size_of_message_buffer_in_bytes(); + instructions.push(set_constant(&buff_final_pos.to_string())); + instructions.push(eq32()); + instructions.push(br_if("1")); //jump to the end of block + instructions.push(get_local("$bm")); + instructions.push(set_constant("0")); + instructions.push(store32_8(None)); // stores the digit in the buffer + instructions.push(get_local("$bm")); + instructions.push(set_constant("1")); + instructions.push(add32()); + instructions.push(set_local("$bm")); + instructions.push(br("0")); // jump to the loop + instructions.push(add_end()); + instructions.push(add_end()); + // initialize message buffer position to 0 + instructions.push(set_constant(&producer.get_message_buffer_counter_position().to_string())); + instructions.push(set_constant("0")); + instructions.push(store32(None)); + instructions.push(")".to_string()); + instructions +} + pub fn build_buffer_message_generator(producer: &WASMProducer) -> Vec { let mut instructions = vec![]; let header = "(func $buildBufferMessage (type $_t_i32i32)".to_string(); @@ -1699,6 +1766,9 @@ mod tests { code_aux = build_buffer_message_generator(&producer); code.append(&mut code_aux); + code_aux = build_log_message_generator(&producer); + code.append(&mut code_aux); + //code_aux = main_sample_generator(&producer); //code.append(&mut code_aux); diff --git a/compiler/src/intermediate_representation/log_bucket.rs b/compiler/src/intermediate_representation/log_bucket.rs index f80c188c4..ff2e05f34 100644 --- a/compiler/src/intermediate_representation/log_bucket.rs +++ b/compiler/src/intermediate_representation/log_bucket.rs @@ -63,13 +63,22 @@ impl WriteWasm for LogBucket { instructions.push(";; log bucket".to_string()); } for logarg in self.argsprint.clone() { - if let LogBucketArg::LogExp(exp) = logarg { - let mut instructions_print = exp.produce_wasm(producer); - instructions.append(&mut instructions_print); - instructions.push(call("$copyFr2SharedRWMemory")); - instructions.push(call("$showSharedRWMemory")); + match &logarg { + LogBucketArg::LogExp(exp) => { + let mut instructions_print = exp.produce_wasm(producer); + instructions.append(&mut instructions_print); + instructions.push(call("$copyFr2SharedRWMemory")); + instructions.push(call("$showSharedRWMemory")); + } + LogBucketArg::LogStr(stringid) => { + let pos = producer.get_string_list_start() + + stringid * producer.get_size_of_message_in_bytes(); + instructions.push(set_constant(&pos.to_string())); + instructions.push(call("$buildBufferMessage")); + instructions.push(call("$writeBufferMessage")); + } } - } + } if producer.needs_comments() { instructions.push(";; end of log bucket".to_string()); } From b1a34cd70519f3774732b489591b038ea374fe3e Mon Sep 17 00:00:00 2001 From: alrubio Date: Wed, 17 Aug 2022 18:48:08 +0200 Subject: [PATCH 13/23] adding wasm code for the new log --- code_producers/src/wasm_elements/wasm_code_generator.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/code_producers/src/wasm_elements/wasm_code_generator.rs b/code_producers/src/wasm_elements/wasm_code_generator.rs index 5185526c0..bb064ad20 100644 --- a/code_producers/src/wasm_elements/wasm_code_generator.rs +++ b/code_producers/src/wasm_elements/wasm_code_generator.rs @@ -498,6 +498,10 @@ pub fn generate_imports_list() -> Vec { "(import \"runtime\" \"printErrorMessage\" (func $printErrorMessage (type $_t_void)))" .to_string(), ); + imports.push( + "(import \"runtime\" \"writeBufferMessage\" (func $writeBufferMessage (type $_t_void)))" + .to_string(), + ); imports.push( "(import \"runtime\" \"showSharedRWMemory\" (func $showSharedRWMemory (type $_t_void)))" .to_string(), From a7b015308fb026c6e3862968ec5bcf503d5448ee Mon Sep 17 00:00:00 2001 From: clararod9 Date: Wed, 17 Aug 2022 18:10:16 -0700 Subject: [PATCH 14/23] adding c and solving bugs --- compiler/src/circuit_design/build.rs | 6 +++--- .../intermediate_representation/log_bucket.rs | 17 ++++++++++++++++- .../intermediate_representation/translate.rs | 1 + compiler/src/ir_processing/reduce_stack.rs | 4 +++- constraint_generation/src/execute.rs | 4 ++-- 5 files changed, 25 insertions(+), 7 deletions(-) diff --git a/compiler/src/circuit_design/build.rs b/compiler/src/circuit_design/build.rs index bfbd656bf..e3190dfc6 100644 --- a/compiler/src/circuit_design/build.rs +++ b/compiler/src/circuit_design/build.rs @@ -341,10 +341,10 @@ pub fn build_circuit(vcp: VCP, flag: CompilationFlags) -> Circuit { pub fn create_table_usize_to_string( string_table : HashMap) -> Vec { let size = string_table.len(); - let mut table_usize_to_string = Vec::with_capacity(size); + let mut table_usize_to_string = vec![String::new(); size]; + for (string, us) in string_table { - assert!(us < size); - table_usize_to_string.insert(us, string); + table_usize_to_string[us] = string; } table_usize_to_string } \ No newline at end of file diff --git a/compiler/src/intermediate_representation/log_bucket.rs b/compiler/src/intermediate_representation/log_bucket.rs index ff2e05f34..0643afded 100644 --- a/compiler/src/intermediate_representation/log_bucket.rs +++ b/compiler/src/intermediate_representation/log_bucket.rs @@ -90,7 +90,7 @@ impl WriteC for LogBucket { fn produce_c(&self, producer: &CProducer) -> (Vec, String) { use c_code_generator::*; let mut log_c = Vec::new(); - for logarg in self.argsprint.clone() { + for logarg in &self.argsprint { if let LogBucketArg::LogExp(exp) = logarg { let (mut argument_code, argument_result) = exp.produce_c(producer); let to_string_call = build_call("Fr_element2str".to_string(), vec![argument_result]); @@ -106,6 +106,21 @@ impl WriteC for LogBucket { log_c.push(format!("{};", delete_temp)); log_c.push("}".to_string()); } + else if let LogBucketArg::LogStr(string_id) = logarg { + let string_value = &producer.get_string_table()[*string_id]; + + let print_c = + build_call( + "printf".to_string(), + vec![format!("\"{}\\n\"", string_value)] + ); + log_c.push("{".to_string()); + log_c.push(format!("{};", print_c)); + log_c.push("}".to_string()); + } + else{ + unreachable!(); + } } (log_c, "".to_string()) } diff --git a/compiler/src/intermediate_representation/translate.rs b/compiler/src/intermediate_representation/translate.rs index 8ee5c3d51..9f3bb30a4 100644 --- a/compiler/src/intermediate_representation/translate.rs +++ b/compiler/src/intermediate_representation/translate.rs @@ -608,6 +608,7 @@ fn translate_log(stmt: Statement, state: &mut State, context: &Context) { } } } + let log = LogBucket { line, message_id: state.message_id, diff --git a/compiler/src/ir_processing/reduce_stack.rs b/compiler/src/ir_processing/reduce_stack.rs index 094cde659..0698133ea 100644 --- a/compiler/src/ir_processing/reduce_stack.rs +++ b/compiler/src/ir_processing/reduce_stack.rs @@ -90,7 +90,9 @@ pub fn reduce_log(mut bucket: LogBucket) -> Instruction { new_args_prints.push(LogBucketArg::LogExp(print_aux)); }, - LogBucketArg::LogStr(..) => {}, + LogBucketArg::LogStr(s) => { + new_args_prints.push(LogBucketArg::LogStr(s)); + }, } } diff --git a/constraint_generation/src/execute.rs b/constraint_generation/src/execute.rs index 92e384687..b0d4315cd 100644 --- a/constraint_generation/src/execute.rs +++ b/constraint_generation/src/execute.rs @@ -313,8 +313,8 @@ fn execute_statement( println!("Unknown") } } - else if let LogArgument::LogStr(str) = arglog { - println!("{}",str); + else if let LogArgument::LogStr(s) = arglog { + println!("{}",s); } } } From ae67e8e58e6dfad2abc9b1b4f23fe54b0b7e85cb Mon Sep 17 00:00:00 2001 From: alrubio Date: Thu, 18 Aug 2022 07:44:57 +0200 Subject: [PATCH 15/23] small changes in wasm gnwration and js --- .../src/wasm_elements/bn128/witness_calculator.js | 3 +++ compiler/src/intermediate_representation/log_bucket.rs | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/code_producers/src/wasm_elements/bn128/witness_calculator.js b/code_producers/src/wasm_elements/bn128/witness_calculator.js index 1e2b20a72..879b38112 100755 --- a/code_producers/src/wasm_elements/bn128/witness_calculator.js +++ b/code_producers/src/wasm_elements/bn128/witness_calculator.js @@ -40,6 +40,9 @@ module.exports = async function builder(code, options) { errStr += getMessage() + "\n"; // console.error(getMessage()); }, + writeBufferMessage : function() { + process.stdout.write(getMessage()); + }, showSharedRWMemory : function() { printSharedRWMemory (); } diff --git a/compiler/src/intermediate_representation/log_bucket.rs b/compiler/src/intermediate_representation/log_bucket.rs index ff2e05f34..a230aa52c 100644 --- a/compiler/src/intermediate_representation/log_bucket.rs +++ b/compiler/src/intermediate_representation/log_bucket.rs @@ -79,6 +79,14 @@ impl WriteWasm for LogBucket { } } } + // add nl + instructions.push(set_constant(&producer.get_message_buffer_start().to_string())); + instructions.push(set_constant("0x0a000000")); + instructions.push(store32(None)); // stores \n000 + instructions.push(set_constant(&producer.get_message_buffer_counter_position().to_string())); + instructions.push(set_constant("0")); + instructions.push(store32(None)); + instructions.push(call("$writeBufferMessage")); if producer.needs_comments() { instructions.push(";; end of log bucket".to_string()); } From f84a4c582824cd0ff12e019d366cfada011b84c0 Mon Sep 17 00:00:00 2001 From: alrubio Date: Thu, 18 Aug 2022 08:25:42 +0200 Subject: [PATCH 16/23] first version of wasm working --- .../src/wasm_elements/bn128/witness_calculator.js | 3 ++- compiler/src/circuit_design/circuit.rs | 8 ++++++++ compiler/src/intermediate_representation/log_bucket.rs | 4 ++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/code_producers/src/wasm_elements/bn128/witness_calculator.js b/code_producers/src/wasm_elements/bn128/witness_calculator.js index 879b38112..0c7c48c7a 100755 --- a/code_producers/src/wasm_elements/bn128/witness_calculator.js +++ b/code_producers/src/wasm_elements/bn128/witness_calculator.js @@ -81,7 +81,8 @@ module.exports = async function builder(code, options) { for (let j=0; j Date: Thu, 18 Aug 2022 13:00:16 +0200 Subject: [PATCH 17/23] Empty log and documentation --- .../code-quality/debugging-operations.md | 9 ++++++--- parser/src/lang.lalrpop | 10 ++++++++-- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/mkdocs/docs/circom-language/code-quality/debugging-operations.md b/mkdocs/docs/circom-language/code-quality/debugging-operations.md index acf86ce04..09a5b111e 100644 --- a/mkdocs/docs/circom-language/code-quality/debugging-operations.md +++ b/mkdocs/docs/circom-language/code-quality/debugging-operations.md @@ -8,9 +8,12 @@ log(c.b); log(x==y); ``` -Since circom 2.0.6, operation `log` admits several non-conditional expressions and also strings written in the standard way. For instance: +Since circom 2.0.6, operation `log` admits a list of non-conditional expressions and also strings written in the standard way. For instance: ```text log("The expected result is ",135," but the value of a is",a); ``` - - +Finally, this operations admits an empty list of expressions which is equivalent to print an end-of-line. The next two instructions are equivalent: +```text +log(""); +log(); +``` diff --git a/parser/src/lang.lalrpop b/parser/src/lang.lalrpop index 9246b6df3..37a01843d 100644 --- a/parser/src/lang.lalrpop +++ b/parser/src/lang.lalrpop @@ -313,8 +313,7 @@ ParseStatement2 : Statement = { "===" ";" => build_constraint_equality(Meta::new(s,e),lhe,rhe), - "log" "(" ")" ";" - => build_log_call(Meta::new(s,e),args), + ParseStatementLog, "assert" "(" ")" ";" => build_assert(Meta::new(s,e),arg), @@ -322,6 +321,13 @@ ParseStatement2 : Statement = { ParseBlock }; +ParseStatementLog : Statement = { + "log" "(" ")" ";" + => build_log_call(Meta::new(s,e),args), + + "log" "(" ")" ";" + => build_log_call(Meta::new(s,e),Vec::new()), +}; ParseStatement3 : Statement = { ";" From 279f2f9300df7c0d801f2bee91cfa414b83f9590 Mon Sep 17 00:00:00 2001 From: clararod9 Date: Thu, 18 Aug 2022 10:12:46 -0700 Subject: [PATCH 18/23] Log message in same line mode verbose and c --- .../src/intermediate_representation/log_bucket.rs | 11 +++++++++-- constraint_generation/src/execute.rs | 7 ++++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/compiler/src/intermediate_representation/log_bucket.rs b/compiler/src/intermediate_representation/log_bucket.rs index edbb4c2b5..a6e846a98 100644 --- a/compiler/src/intermediate_representation/log_bucket.rs +++ b/compiler/src/intermediate_representation/log_bucket.rs @@ -105,7 +105,7 @@ impl WriteC for LogBucket { let temp_var = "temp".to_string(); let into_temp = format!("char* temp = {}", to_string_call); let print_c = - build_call("printf".to_string(), vec!["\"%s\\n\"".to_string(), temp_var.clone()]); + build_call("printf".to_string(), vec!["\"%s\"".to_string(), temp_var.clone()]); let delete_temp = format!("delete [] {}", temp_var); log_c.append(&mut argument_code); log_c.push("{".to_string()); @@ -120,7 +120,7 @@ impl WriteC for LogBucket { let print_c = build_call( "printf".to_string(), - vec![format!("\"{}\\n\"", string_value)] + vec![format!("\"{}\"", string_value)] ); log_c.push("{".to_string()); log_c.push(format!("{};", print_c)); @@ -130,6 +130,13 @@ impl WriteC for LogBucket { unreachable!(); } } + let print_end_line = build_call( + "printf".to_string(), + vec![format!("\"\\n\"")] + ); + log_c.push("{".to_string()); + log_c.push(format!("{};", print_end_line)); + log_c.push("}".to_string()); (log_c, "".to_string()) } } diff --git a/constraint_generation/src/execute.rs b/constraint_generation/src/execute.rs index b0d4315cd..d76c45036 100644 --- a/constraint_generation/src/execute.rs +++ b/constraint_generation/src/execute.rs @@ -307,16 +307,17 @@ fn execute_statement( let f_result = execute_expression(arg, program_archive, runtime, flag_verbose)?; let arith = safe_unwrap_to_single_arithmetic_expression(f_result, line!()); if AExpr::is_number(&arith){ - println!("{}", arith); + print!("{}", arith); } else{ - println!("Unknown") + print!("Unknown") } } else if let LogArgument::LogStr(s) = arglog { - println!("{}",s); + print!("{}",s); } } + println!(""); } Option::None } From 6ef9079b4efb6072401d854323176708d10de7ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Isabel=20M=C3=A1rquez?= Date: Fri, 19 Aug 2022 20:12:53 +0200 Subject: [PATCH 19/23] log_with_strings + 25.from-costa-circom --- constraint_generation/src/execute.rs | 64 +++++++++++++++++---- constraint_generation/src/lib.rs | 9 +-- program_structure/src/utils/memory_slice.rs | 19 +++++- 3 files changed, 75 insertions(+), 17 deletions(-) diff --git a/constraint_generation/src/execute.rs b/constraint_generation/src/execute.rs index d99f1ce99..5826e581b 100644 --- a/constraint_generation/src/execute.rs +++ b/constraint_generation/src/execute.rs @@ -81,9 +81,7 @@ enum ExecutionError { pub fn constraint_execution( program_archive: &ProgramArchive, flag_verbose: bool, - prime: &String, -) -> Result { - let main_file_id = program_archive.get_file_id_main(); + prime: &String,) -> Result<(ExecutedProgram, ReportCollection), ReportCollection> { let main_file_id = program_archive.get_file_id_main(); let mut runtime_information = RuntimeInformation::new(*main_file_id, program_archive.id_max, prime); runtime_information.public_inputs = program_archive.get_public_inputs_main_component().clone(); let folded_value_result = execute_expression( @@ -96,7 +94,7 @@ pub fn constraint_execution( Result::Err(_) => Result::Err(runtime_information.runtime_errors), Result::Ok(folded_value) => { debug_assert!(FoldedValue::valid_node_pointer(&folded_value)); - Result::Ok(runtime_information.exec_program) + Result::Ok((runtime_information.exec_program, runtime_information.runtime_errors)) } } } @@ -156,7 +154,7 @@ fn execute_statement( arithmetic_values .push(safe_unwrap_to_single_arithmetic_expression(f_dimensions, line!())); } - treat_result_with_memory_error( + treat_result_with_memory_error_void( valid_array_declaration(&arithmetic_values), meta, &mut runtime.runtime_errors, @@ -385,7 +383,7 @@ fn execute_expression( &[row], &arithmetic_slice_array[row], ); - treat_result_with_memory_error( + treat_result_with_memory_error_void( memory_insert_result, meta, &mut runtime.runtime_errors, @@ -420,7 +418,7 @@ fn execute_expression( &[row], &slice_value, ); - treat_result_with_memory_error( + treat_result_with_memory_error_void( memory_insert_result, meta, &mut runtime.runtime_errors, @@ -589,7 +587,7 @@ fn perform_assign( AExpressionSlice::new_with_route(symbol_content.route(), &AExpr::NonQuadratic); let memory_result = AExpressionSlice::insert_values(symbol_content, &vec![], &new_value); - treat_result_with_memory_error( + treat_result_with_memory_error_void( memory_result, meta, &mut runtime.runtime_errors, @@ -601,7 +599,7 @@ fn perform_assign( &accessing_information.before_signal, &r_slice, ); - treat_result_with_memory_error( + treat_result_with_memory_error_void( memory_result, meta, &mut runtime.runtime_errors, @@ -641,7 +639,7 @@ fn perform_assign( &SignalSlice::new(&true), ) }; - treat_result_with_memory_error( + treat_result_with_memory_error_void( access_response, meta, &mut runtime.runtime_errors, @@ -684,7 +682,7 @@ fn perform_assign( node_pointer, &runtime.exec_program, ); - treat_result_with_memory_error( + treat_result_with_memory_error_void( memory_result, meta, &mut runtime.runtime_errors, @@ -701,7 +699,7 @@ fn perform_assign( &signal_accessed, &accessing_information.after_signal, ); - treat_result_with_memory_error( + treat_result_with_memory_error_void( memory_response, meta, &mut runtime.runtime_errors, @@ -1314,6 +1312,47 @@ fn treat_result_with_arithmetic_error( } } +fn treat_result_with_memory_error_void( + memory_error: Result<(), MemoryError>, + meta: &Meta, + runtime_errors: &mut ReportCollection, + call_trace: &[String], +) -> Result<(), ()> { + use ReportCode::RuntimeError; + match memory_error { + Result::Ok(()) => Result::Ok(()), + Result::Err(MemoryError::MismatchedDimensionsWeak) => { + let report = Report::warning("Typing warning: Mismatched dimensions, assigning to an array an expression of smaller length, the remaining positions are assigned to 0".to_string(), RuntimeError); + add_report_to_runtime(report, meta, runtime_errors, call_trace); + Ok(()) + }, + Result::Err(memory_error) => { + let report = match memory_error { + MemoryError::InvalidAccess => { + Report::error("Exception caused by invalid access".to_string(), RuntimeError) + } + MemoryError::AssignmentError => Report::error( + "Exception caused by invalid assignment".to_string(), + RuntimeError, + ), + MemoryError::OutOfBoundsError => { + Report::error("Out of bounds exception".to_string(), RuntimeError) + }, + MemoryError::MismatchedDimensions => { + Report::error(" Typing error found: mismatched dimensions, assigning to an array an expression of greater length".to_string(), RuntimeError) + }, + + MemoryError::UnknownSizeDimension => { + Report::error("Array dimension with unknown size".to_string(), RuntimeError) + } + _ => unreachable!(), + }; + add_report_to_runtime(report, meta, runtime_errors, call_trace); + Result::Err(()) + } + } +} + fn treat_result_with_memory_error( memory_error: Result, meta: &Meta, @@ -1341,6 +1380,7 @@ fn treat_result_with_memory_error( MemoryError::UnknownSizeDimension => { Report::error("Array dimension with unknown size".to_string(), RuntimeError) } + _ => unreachable!(), }; add_report_to_runtime(report, meta, runtime_errors, call_trace); Result::Err(()) diff --git a/constraint_generation/src/lib.rs b/constraint_generation/src/lib.rs index 0ce8da265..cd56b580b 100644 --- a/constraint_generation/src/lib.rs +++ b/constraint_generation/src/lib.rs @@ -36,12 +36,13 @@ pub type ConstraintWriter = Box; type BuildResponse = Result<(ConstraintWriter, VCP), ()>; pub fn build_circuit(program: ProgramArchive, config: BuildConfig) -> BuildResponse { let files = program.file_library.clone(); - let exe = instantiation(&program, config.flag_verbose, &config.prime).map_err(|r| { + let (exe, warnings) = instantiation(&program, config.flag_verbose, &config.prime).map_err(|r| { Report::print_reports(&r, &files); })?; let (mut dag, mut vcp, warnings) = export(exe, program, config.flag_verbose).map_err(|r| { Report::print_reports(&r, &files); })?; + Report::print_reports(&warnings, &files); if config.inspect_constraints { Report::print_reports(&warnings, &files); } @@ -54,16 +55,16 @@ pub fn build_circuit(program: ProgramArchive, config: BuildConfig) -> BuildRespo } } -type InstantiationResponse = Result; +type InstantiationResponse = Result<(ExecutedProgram, ReportCollection), ReportCollection>; fn instantiation(program: &ProgramArchive, flag_verbose: bool, prime: &String) -> InstantiationResponse { let execution_result = execute::constraint_execution(&program, flag_verbose, prime); match execution_result { - Ok(program_exe) => { + Ok((program_exe, warnings)) => { let no_nodes = program_exe.number_of_nodes(); let success = Colour::Green.paint("template instances"); let nodes_created = format!("{}: {}", success, no_nodes); println!("{}", &nodes_created); - InstantiationResponse::Ok(program_exe) + InstantiationResponse::Ok(program_exe,warnings) } Err(reports) => InstantiationResponse::Err(reports), } diff --git a/program_structure/src/utils/memory_slice.rs b/program_structure/src/utils/memory_slice.rs index 7bfc05050..5ccfd80c3 100644 --- a/program_structure/src/utils/memory_slice.rs +++ b/program_structure/src/utils/memory_slice.rs @@ -6,6 +6,7 @@ pub enum MemoryError { InvalidAccess, UnknownSizeDimension, MismatchedDimensions, + MismatchedDimensionsWeak } pub type SliceCapacity = usize; pub type SimpleSlice = MemorySlice; @@ -90,7 +91,10 @@ impl MemorySlice { i = 0; while i < new_values.route.len() { - if new_values.route[i] != memory_slice.route[initial_index_new + i] { + if new_values.route[i] < memory_slice.route[initial_index_new + i] { + return Result::Err(MemoryError::MismatchedDimensionsWeak); + } + if new_values.route[i] > memory_slice.route[initial_index_new + i] { return Result::Err(MemoryError::MismatchedDimensions); } i += 1; @@ -178,6 +182,19 @@ impl MemorySlice { } Result::Ok(()) }, + Result::Err(MemoryError::MismatchedDimensionsWeak) => { + let mut cell = MemorySlice::get_initial_cell(memory_slice, access)?; + // if MemorySlice::get_number_of_cells(new_values) + // > (MemorySlice::get_number_of_cells(memory_slice) - cell) + // { + // return Result::Err(MemoryError::OutOfBoundsError); + // } + for value in new_values.values.iter() { + memory_slice.values[cell] = value.clone(); + cell += 1; + } + Result::Err(MemoryError::MismatchedDimensionsWeak) + }, Result::Err(error) => return Err(error), } } From e46dfa8b841e978b2249718cfee7092685353188 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20Isabel=20M=C3=A1rquez?= Date: Fri, 19 Aug 2022 20:15:40 +0200 Subject: [PATCH 20/23] log_with_strings + 25.from-costa-circom --- constraint_generation/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/constraint_generation/src/lib.rs b/constraint_generation/src/lib.rs index cd56b580b..2430180bd 100644 --- a/constraint_generation/src/lib.rs +++ b/constraint_generation/src/lib.rs @@ -39,10 +39,10 @@ pub fn build_circuit(program: ProgramArchive, config: BuildConfig) -> BuildRespo let (exe, warnings) = instantiation(&program, config.flag_verbose, &config.prime).map_err(|r| { Report::print_reports(&r, &files); })?; + Report::print_reports(&warnings, &files); let (mut dag, mut vcp, warnings) = export(exe, program, config.flag_verbose).map_err(|r| { Report::print_reports(&r, &files); })?; - Report::print_reports(&warnings, &files); if config.inspect_constraints { Report::print_reports(&warnings, &files); } @@ -64,7 +64,7 @@ fn instantiation(program: &ProgramArchive, flag_verbose: bool, prime: &String) - let success = Colour::Green.paint("template instances"); let nodes_created = format!("{}: {}", success, no_nodes); println!("{}", &nodes_created); - InstantiationResponse::Ok(program_exe,warnings) + InstantiationResponse::Ok((program_exe,warnings)) } Err(reports) => InstantiationResponse::Err(reports), } From b8244d0b03f948ab6e061c1f487830650e16049d Mon Sep 17 00:00:00 2001 From: clararod9 Date: Fri, 19 Aug 2022 12:14:14 -0700 Subject: [PATCH 21/23] removing conflicting code from merge --- compiler/src/intermediate_representation/log_bucket.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/compiler/src/intermediate_representation/log_bucket.rs b/compiler/src/intermediate_representation/log_bucket.rs index 2f33aa722..dd05d3ab9 100644 --- a/compiler/src/intermediate_representation/log_bucket.rs +++ b/compiler/src/intermediate_representation/log_bucket.rs @@ -16,7 +16,6 @@ pub struct LogBucket { pub message_id: usize, pub argsprint: Vec, pub is_parallel: bool, - pub label: Option, } impl IntoInstruction for LogBucket { From 86245ffa6dd859aed906f764f3caaa29ecb75cf3 Mon Sep 17 00:00:00 2001 From: clararod9 Date: Fri, 19 Aug 2022 12:28:10 -0700 Subject: [PATCH 22/23] removing conflicting code from merge --- .../src/wasm_elements/bls12381/witness_calculator.js | 6 +----- .../src/wasm_elements/goldilocks/witness_calculator.js | 6 +----- compiler/src/intermediate_representation/log_bucket.rs | 2 -- compiler/src/intermediate_representation/translate.rs | 2 -- .../src/abstract_syntax_tree/statement_builders.rs | 1 - program_structure/src/program_library/error_code.rs | 2 -- type_analysis/src/analyzers/type_check.rs | 1 - 7 files changed, 2 insertions(+), 18 deletions(-) diff --git a/code_producers/src/wasm_elements/bls12381/witness_calculator.js b/code_producers/src/wasm_elements/bls12381/witness_calculator.js index 76c8f69f7..a967f35fd 100755 --- a/code_producers/src/wasm_elements/bls12381/witness_calculator.js +++ b/code_producers/src/wasm_elements/bls12381/witness_calculator.js @@ -79,11 +79,7 @@ module.exports = async function builder(code, options) { arr[shared_rw_memory_size-1-j] = instance.exports.readSharedRWMemory(j); } const label = getMessage(); - if(label){ - console.log(label + ':', fromArray32(arr)); - }else{ - console.log(fromArray32(arr)); - } + console.log(fromArray32(arr)); } diff --git a/code_producers/src/wasm_elements/goldilocks/witness_calculator.js b/code_producers/src/wasm_elements/goldilocks/witness_calculator.js index b0c97e89e..190fcd17e 100755 --- a/code_producers/src/wasm_elements/goldilocks/witness_calculator.js +++ b/code_producers/src/wasm_elements/goldilocks/witness_calculator.js @@ -79,11 +79,7 @@ module.exports = async function builder(code, options) { arr[shared_rw_memory_size-1-j] = instance.exports.readSharedRWMemory(j); } const label = getMessage(); - if(label){ - console.log(label + ':', fromArray32(arr)); - }else{ - console.log(fromArray32(arr)); - } + console.log(fromArray32(arr)); } }; diff --git a/compiler/src/intermediate_representation/log_bucket.rs b/compiler/src/intermediate_representation/log_bucket.rs index dd05d3ab9..a6e846a98 100644 --- a/compiler/src/intermediate_representation/log_bucket.rs +++ b/compiler/src/intermediate_representation/log_bucket.rs @@ -61,7 +61,6 @@ impl WriteWasm for LogBucket { let mut instructions = vec![]; if producer.needs_comments() { instructions.push(";; log bucket".to_string()); - } for logarg in self.argsprint.clone() { match &logarg { @@ -98,7 +97,6 @@ impl WriteWasm for LogBucket { impl WriteC for LogBucket { fn produce_c(&self, producer: &CProducer) -> (Vec, String) { use c_code_generator::*; - let mut log_c = Vec::new(); for logarg in &self.argsprint { if let LogBucketArg::LogExp(exp) = logarg { diff --git a/compiler/src/intermediate_representation/translate.rs b/compiler/src/intermediate_representation/translate.rs index 3e8fd21e5..9f3bb30a4 100644 --- a/compiler/src/intermediate_representation/translate.rs +++ b/compiler/src/intermediate_representation/translate.rs @@ -587,7 +587,6 @@ fn translate_assert(stmt: Statement, state: &mut State, context: &Context) { fn translate_log(stmt: Statement, state: &mut State, context: &Context) { use Statement::LogCall; - if let LogCall { meta, args, .. } = stmt { let line = context.files.get_line(meta.start, meta.get_file_id()).unwrap(); let mut logbucket_args = Vec::new(); @@ -613,7 +612,6 @@ fn translate_log(stmt: Statement, state: &mut State, context: &Context) { let log = LogBucket { line, message_id: state.message_id, - is_parallel: state.is_parallel, argsprint: logbucket_args, }.allocate(); diff --git a/program_structure/src/abstract_syntax_tree/statement_builders.rs b/program_structure/src/abstract_syntax_tree/statement_builders.rs index 03ca87f09..3caee213e 100644 --- a/program_structure/src/abstract_syntax_tree/statement_builders.rs +++ b/program_structure/src/abstract_syntax_tree/statement_builders.rs @@ -53,7 +53,6 @@ pub fn build_constraint_equality(meta: Meta, lhe: Expression, rhe: Expression) - ConstraintEquality { meta, lhe, rhe } } - pub fn build_log_call(meta: Meta, args: Vec) -> Statement { let mut new_args = Vec::new(); for arg in args { diff --git a/program_structure/src/program_library/error_code.rs b/program_structure/src/program_library/error_code.rs index 919bcb481..151808254 100644 --- a/program_structure/src/program_library/error_code.rs +++ b/program_structure/src/program_library/error_code.rs @@ -72,7 +72,6 @@ pub enum ReportCode { CustomGateConstraintError, CustomGateSubComponentError, CustomGatesPragmaError, - LabelTooLongError(usize), CustomGatesVersionError, } impl fmt::Display for ReportCode { @@ -148,7 +147,6 @@ impl fmt::Display for ReportCode { CustomGateConstraintError => "CG02", CustomGateSubComponentError => "CG03", CustomGatesPragmaError => "CG04", - LabelTooLongError(..) => "L01", CustomGatesVersionError => "CG05", }; f.write_str(string_format) diff --git a/type_analysis/src/analyzers/type_check.rs b/type_analysis/src/analyzers/type_check.rs index 0e77d8d26..9e363e74a 100644 --- a/type_analysis/src/analyzers/type_check.rs +++ b/type_analysis/src/analyzers/type_check.rs @@ -805,7 +805,6 @@ fn add_report(error_code: ReportCode, meta: &Meta, reports: &mut ReportCollectio WrongNumberOfArguments(expected, got) => { format!("Expecting {} arguments, {} where obtained", expected, got) } - LabelTooLongError(len) => format!("Label too long. Label is {} characters but must be <240", len), _ => panic!("Unimplemented error code"), }; report.add_primary(location, file_id, message); From fc742cd16e15f43d480ffb347817bb508e796874 Mon Sep 17 00:00:00 2001 From: clararod9 Date: Fri, 19 Aug 2022 12:32:42 -0700 Subject: [PATCH 23/23] removing conflicting code from merge --- .../wasm_elements/bls12381/witness_calculator.js | 1 - .../wasm_elements/goldilocks/witness_calculator.js | 1 - .../src/wasm_elements/wasm_code_generator.rs | 14 +------------- 3 files changed, 1 insertion(+), 15 deletions(-) diff --git a/code_producers/src/wasm_elements/bls12381/witness_calculator.js b/code_producers/src/wasm_elements/bls12381/witness_calculator.js index a967f35fd..0db042162 100755 --- a/code_producers/src/wasm_elements/bls12381/witness_calculator.js +++ b/code_producers/src/wasm_elements/bls12381/witness_calculator.js @@ -78,7 +78,6 @@ module.exports = async function builder(code, options) { for (let j=0; j Vec