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(2, 3);
|
||||||
assert_concat_worked(3, 3);
|
assert_concat_worked(3, 3);
|
||||||
assert_concat_worked(4, 4);
|
assert_concat_worked(4, 4);
|
||||||
// TODO TCE seems to be broken for large concats
|
}
|
||||||
// assert_concat_worked(150, 150);
|
|
||||||
// assert_concat_worked(129, 350);
|
#[test]
|
||||||
// assert_concat_worked(350, 129);
|
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]
|
#[test]
|
||||||
|
@ -568,9 +568,43 @@ impl<'a> Context<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO should not be pub
|
// 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::*;
|
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 {
|
match stmt {
|
||||||
Let(symbol, expr, layout, cont) => {
|
Let(symbol, expr, layout, cont) => {
|
||||||
let ctx = self.update_var_info(*symbol, layout, expr);
|
let ctx = self.update_var_info(*symbol, layout, expr);
|
||||||
|
Loading…
Reference in New Issue
Block a user