1
0
Fork 0
mirror of synced 2025-09-23 12:18:44 +00:00

Merge pull request #847 from Zokrates/fix-complex-type-side-effects

Remove side effects on complex types
This commit is contained in:
Thibaut Schaeffer 2021-05-05 16:25:08 +02:00 committed by GitHub
commit d4494cb9c2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 28 additions and 78 deletions

View file

@ -0,0 +1 @@
Remove side effects on complex types (bug)

View file

@ -9,7 +9,6 @@ mod constant_inliner;
mod flat_propagation; mod flat_propagation;
mod flatten_complex_types; mod flatten_complex_types;
mod propagation; mod propagation;
mod redefinition;
mod reducer; mod reducer;
mod shift_checker; mod shift_checker;
mod uint_optimizer; mod uint_optimizer;
@ -20,7 +19,6 @@ mod variable_write_remover;
use self::bounds_checker::BoundsChecker; use self::bounds_checker::BoundsChecker;
use self::flatten_complex_types::Flattener; use self::flatten_complex_types::Flattener;
use self::propagation::Propagator; use self::propagation::Propagator;
use self::redefinition::RedefinitionOptimizer;
use self::reducer::reduce_program; use self::reducer::reduce_program;
use self::shift_checker::ShiftChecker; use self::shift_checker::ShiftChecker;
use self::uint_optimizer::UintOptimizer; use self::uint_optimizer::UintOptimizer;
@ -84,8 +82,6 @@ impl<'ast, T: Field> TypedProgram<'ast, T> {
// propagate // propagate
let r = Propagator::propagate(r).map_err(Error::from)?; let r = Propagator::propagate(r).map_err(Error::from)?;
// optimize redefinitions
let r = RedefinitionOptimizer::optimize(r);
// remove assignment to variable index // remove assignment to variable index
let r = VariableWriteRemover::apply(r); let r = VariableWriteRemover::apply(r);
// remove variable access to complex types // remove variable access to complex types

View file

@ -1,73 +0,0 @@
use crate::typed_absy::folder::*;
use crate::typed_absy::*;
use std::collections::HashMap;
use zokrates_field::Field;
pub struct RedefinitionOptimizer<'ast> {
identifiers: HashMap<Identifier<'ast>, Identifier<'ast>>,
}
impl<'ast> RedefinitionOptimizer<'ast> {
fn new() -> Self {
RedefinitionOptimizer {
identifiers: HashMap::new(),
}
}
pub fn optimize<T: Field>(p: TypedProgram<'ast, T>) -> TypedProgram<'ast, T> {
RedefinitionOptimizer::new().fold_program(p)
}
}
fn try_id<'ast, T: Field>(e: &TypedExpression<'ast, T>) -> Option<Identifier<'ast>> {
match e {
TypedExpression::FieldElement(FieldElementExpression::Identifier(id)) => Some(id.clone()),
TypedExpression::Boolean(BooleanExpression::Identifier(id)) => Some(id.clone()),
TypedExpression::Array(a) => match a.as_inner() {
ArrayExpressionInner::Identifier(id) => Some(id.clone()),
_ => None,
},
TypedExpression::Struct(a) => match a.as_inner() {
StructExpressionInner::Identifier(id) => Some(id.clone()),
_ => None,
},
TypedExpression::Uint(a) => match a.as_inner() {
UExpressionInner::Identifier(id) => Some(id.clone()),
_ => None,
},
_ => None,
}
}
impl<'ast, T: Field> Folder<'ast, T> for RedefinitionOptimizer<'ast> {
fn fold_function(&mut self, f: TypedFunction<'ast, T>) -> TypedFunction<'ast, T> {
self.identifiers = HashMap::new();
fold_function(self, f)
}
fn fold_statement(&mut self, s: TypedStatement<'ast, T>) -> Vec<TypedStatement<'ast, T>> {
match s {
TypedStatement::Definition(TypedAssignee::Identifier(var), expr) => {
let expr = self.fold_expression(expr);
match try_id(&expr) {
Some(id) => {
let target = self.identifiers.get(&id).unwrap_or(&id).clone();
self.identifiers.insert(var.id, target);
vec![]
}
None => vec![TypedStatement::Definition(
TypedAssignee::Identifier(var),
expr,
)],
}
}
s => fold_statement(self, s),
}
}
fn fold_name(&mut self, s: Identifier<'ast>) -> Identifier<'ast> {
self.identifiers.get(&s).cloned().unwrap_or(s)
}
}

View file

@ -1,5 +1,5 @@
{ {
"entry_point": "./tests/tests/structs/identity.code", "entry_point": "./tests/tests/structs/identity.zok",
"curves": ["Bn128", "Bls12_381", "Bls12_377", "Bw6_761"], "curves": ["Bn128", "Bls12_381", "Bls12_377", "Bw6_761"],
"tests": [ "tests": [
{ {

View file

@ -0,0 +1,16 @@
{
"entry_point": "./tests/tests/structs/mutate_argument.zok",
"curves": ["Bn128", "Bls12_381", "Bls12_377", "Bw6_761"],
"tests": [
{
"input": {
"values": ["1"]
},
"output": {
"Ok": {
"values": ["2", "1"]
}
}
}
]
}

View file

@ -0,0 +1,10 @@
struct Foo {
field a
}
def mutate(field[1] f) -> field[1]:
f[0] = f[0] + 1
return f
def main(field[1] f) -> (field[1], field[1]):
return mutate(f), f