mirror of
https://github.com/roc-lang/roc.git
synced 2024-11-14 16:27:15 +03:00
fix stack overflow in inc/dec
This commit is contained in:
parent
ac6d72d077
commit
25e96fcade
@ -307,10 +307,16 @@ mod gen_list {
|
||||
assert_concat_worked(2, 3);
|
||||
assert_concat_worked(3, 3);
|
||||
assert_concat_worked(4, 4);
|
||||
// TODO TCE seems to be broken for large concats
|
||||
// assert_concat_worked(150, 150);
|
||||
// assert_concat_worked(129, 350);
|
||||
// assert_concat_worked(350, 129);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn list_concat_large() {
|
||||
// these values produce mono ASTs so large that
|
||||
// it can cause a stack overflow. This has been solved
|
||||
// for current code, but may become a problem again in the future.
|
||||
assert_concat_worked(150, 150);
|
||||
assert_concat_worked(129, 350);
|
||||
assert_concat_worked(350, 129);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -568,9 +568,43 @@ impl<'a> Context<'a> {
|
||||
}
|
||||
|
||||
// TODO should not be pub
|
||||
pub fn visit_stmt(&self, stmt: &'a Stmt<'a>) -> (&'a Stmt<'a>, LiveVarSet) {
|
||||
fn visit_stmt(&self, stmt: &'a Stmt<'a>) -> (&'a Stmt<'a>, LiveVarSet) {
|
||||
use Stmt::*;
|
||||
|
||||
// let-chains can be very long, especially for large (list) literals
|
||||
// in (rust) debug mode, this function can overflow the stack for such values
|
||||
// so we have to write an explicit loop.
|
||||
{
|
||||
let mut cont = stmt;
|
||||
let mut triples = Vec::new_in(self.arena);
|
||||
while let Stmt::Let(symbol, expr, layout, new_cont) = cont {
|
||||
triples.push((symbol, expr, layout));
|
||||
cont = new_cont;
|
||||
}
|
||||
|
||||
if !triples.is_empty() {
|
||||
let mut ctx = self.clone();
|
||||
for (symbol, expr, layout) in triples.iter() {
|
||||
ctx = ctx.update_var_info(**symbol, layout, expr);
|
||||
}
|
||||
let (mut b, mut b_live_vars) = ctx.visit_stmt(cont);
|
||||
for (symbol, expr, layout) in triples.into_iter().rev() {
|
||||
let pair = ctx.visit_variable_declaration(
|
||||
*symbol,
|
||||
(*expr).clone(),
|
||||
(*layout).clone(),
|
||||
b,
|
||||
&b_live_vars,
|
||||
);
|
||||
|
||||
b = pair.0;
|
||||
b_live_vars = pair.1;
|
||||
}
|
||||
|
||||
return (b, b_live_vars);
|
||||
}
|
||||
}
|
||||
|
||||
match stmt {
|
||||
Let(symbol, expr, layout, cont) => {
|
||||
let ctx = self.update_var_info(*symbol, layout, expr);
|
||||
|
Loading…
Reference in New Issue
Block a user