From dc7ec72ab053de68533f794621ea756fe66c35b0 Mon Sep 17 00:00:00 2001 From: Markus Westerlind Date: Sun, 6 Oct 2019 01:06:30 +0200 Subject: [PATCH] fix: Avoid infinite loops/extremely slow optimization --- vm/src/core/interpreter.rs | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/vm/src/core/interpreter.rs b/vm/src/core/interpreter.rs index 4fdf6feb33..52b7d0d627 100644 --- a/vm/src/core/interpreter.rs +++ b/vm/src/core/interpreter.rs @@ -974,7 +974,7 @@ impl<'a, 'e> Compiler<'a, 'e> { ) -> Option> { let mut replaced_expr = Vec::new(); let mut expr = Reduced::Local(expr); - loop { + for _ in 0..10 { let replaced_expr_len = replaced_expr.len(); let new_expr = self .peek_reduced_expr_fn(expr.clone(), &mut |cost, e| { @@ -1018,13 +1018,7 @@ impl<'a, 'e> Compiler<'a, 'e> { continue; } - return replaced_expr - .into_iter() - .rev() - .find(|(cost, e)| { - *cost <= 10 && !self.contains_unbound_variables(e.as_ref()) - }) - .map(|(_, e)| e.into_local(&self.allocator)); + break; } Some(e) => { expr = Reduced::Local(e); @@ -1032,6 +1026,12 @@ impl<'a, 'e> Compiler<'a, 'e> { } } } + + replaced_expr + .into_iter() + .rev() + .find(|(cost, e)| *cost <= 10 && !self.contains_unbound_variables(e.as_ref())) + .map(|(_, e)| e.into_local(&self.allocator)) } fn inline_call<'b>( @@ -1159,7 +1159,7 @@ impl<'a, 'e> Compiler<'a, 'e> { mut expr: ReducedExpr<'e>, report_reduction: &mut dyn FnMut(Cost, &ReducedExpr<'e>), ) -> CostBinding<'e> { - loop { + for _ in 0..10 { let new_bind = expr.clone().with(self.allocator, |resolver, expr| { match peek_through_lets(expr) { Expr::Ident(ref id, _) => { @@ -1229,6 +1229,10 @@ impl<'a, 'e> Compiler<'a, 'e> { } } } + CostBinding { + cost: 0, + bind: Binding::Expr(expr), + } } fn project_reduced(