autofree: handle early returns (part 1)
parent
fdfe2a4e68
commit
68077b7dbf
|
@ -766,12 +766,15 @@ fn (mut g Gen) stmts_with_tmp_var(stmts []ast.Stmt, tmp_var string) {
|
|||
// use the first stmt to get the scope
|
||||
stmt := stmts[0]
|
||||
// stmt := stmts[stmts.len-1]
|
||||
if stmt !is ast.FnDecl {
|
||||
if stmt !is ast.FnDecl && g.inside_ternary == 0 {
|
||||
// g.writeln('// autofree scope')
|
||||
// g.writeln('// autofree_scope_vars($stmt.position().pos) | ${typeof(stmt)}')
|
||||
// go back 1 position is important so we dont get the
|
||||
// internal scope of for loops and possibly other nodes
|
||||
g.autofree_scope_vars(stmt.position().pos - 1)
|
||||
// g.autofree_scope_vars(stmt.position().pos - 1)
|
||||
stmt_pos := stmt.position()
|
||||
g.writeln('// af scope_vars')
|
||||
g.autofree_scope_vars(stmt_pos.pos - 1, stmt_pos.line_nr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2022,7 +2025,7 @@ fn (mut g Gen) gen_clone_assignment(val ast.Expr, right_sym table.TypeSymbol, ad
|
|||
return true
|
||||
}
|
||||
|
||||
fn (mut g Gen) autofree_scope_vars(pos int) {
|
||||
fn (mut g Gen) autofree_scope_vars(pos int, line_nr int) {
|
||||
if g.is_builtin_mod {
|
||||
// In `builtin` everything is freed manually.
|
||||
return
|
||||
|
@ -2030,10 +2033,12 @@ fn (mut g Gen) autofree_scope_vars(pos int) {
|
|||
// eprintln('> free_scope_vars($pos)')
|
||||
scope := g.file.scope.innermost(pos)
|
||||
g.writeln('// autofree_scope_vars(pos=$pos scope.pos=$scope.start_pos scope.end_pos=$scope.end_pos)')
|
||||
g.autofree_scope_vars2(scope, scope.end_pos)
|
||||
// g.autofree_scope_vars2(scope, scope.end_pos)
|
||||
g.autofree_scope_vars2(scope, scope.start_pos, scope.end_pos, line_nr)
|
||||
}
|
||||
|
||||
fn (mut g Gen) autofree_scope_vars2(scope &ast.Scope, end_pos int) {
|
||||
// fn (mut g Gen) autofree_scope_vars2(scope &ast.Scope, end_pos int) {
|
||||
fn (mut g Gen) autofree_scope_vars2(scope &ast.Scope, start_pos int, end_pos int, line_nr int) {
|
||||
if isnil(scope) {
|
||||
return
|
||||
}
|
||||
|
@ -2046,7 +2051,8 @@ fn (mut g Gen) autofree_scope_vars2(scope &ast.Scope, end_pos int) {
|
|||
// continue
|
||||
// }
|
||||
v := *obj
|
||||
if v.pos.pos > end_pos {
|
||||
// if v.pos.pos > end_pos {
|
||||
if v.pos.pos > end_pos || (v.pos.pos < start_pos && v.pos.line_nr == line_nr) {
|
||||
// Do not free vars that were declared after this scope
|
||||
continue
|
||||
}
|
||||
|
@ -2068,8 +2074,11 @@ fn (mut g Gen) autofree_scope_vars2(scope &ast.Scope, end_pos int) {
|
|||
// return
|
||||
// }
|
||||
// ```
|
||||
// if !isnil(scope.parent) && line_nr > 0 {
|
||||
if !isnil(scope.parent) {
|
||||
// g.autofree_scope_vars2(scope.parent, end_pos)
|
||||
g.writeln('// af parent scope:')
|
||||
// g.autofree_scope_vars2(scope.parent, start_pos, end_pos, line_nr)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3415,6 +3424,7 @@ fn (mut g Gen) if_expr(node ast.IfExpr) {
|
|||
g.writeln('$styp $tmp; /* if prepend */')
|
||||
} else if node.is_expr || g.inside_ternary != 0 {
|
||||
g.inside_ternary++
|
||||
// g.inside_if_expr = true
|
||||
g.write('(')
|
||||
for i, branch in node.branches {
|
||||
if i > 0 {
|
||||
|
@ -3952,7 +3962,7 @@ fn (mut g Gen) return_statement(node ast.Return, af bool) {
|
|||
}
|
||||
if free {
|
||||
g.writeln('; // free tmp exprs')
|
||||
g.autofree_scope_vars(node.pos.pos + 1)
|
||||
g.autofree_scope_vars(node.pos.pos + 1, node.pos.line_nr)
|
||||
g.write('return $tmp')
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -155,7 +155,8 @@ fn (mut g Gen) gen_fn_decl(it ast.FnDecl, skip bool) {
|
|||
//
|
||||
if g.autofree && !g.pref.experimental {
|
||||
// TODO: remove this, when g.write_autofree_stmts_when_needed works properly
|
||||
g.autofree_scope_vars(it.body_pos.pos)
|
||||
g.writeln('// af scope_vars (fn decl)')
|
||||
g.autofree_scope_vars(it.body_pos.pos, it.body_pos.line_nr)
|
||||
}
|
||||
if it.return_type != table.void_type && it.stmts.len > 0 && it.stmts.last() !is ast.Return {
|
||||
default_expr := g.type_default(it.return_type)
|
||||
|
|
Loading…
Reference in New Issue