mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
autofree: handle early returns (part 1)
This commit is contained in:
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
|
// use the first stmt to get the scope
|
||||||
stmt := stmts[0]
|
stmt := stmts[0]
|
||||||
// stmt := stmts[stmts.len-1]
|
// 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')
|
||||||
// g.writeln('// autofree_scope_vars($stmt.position().pos) | ${typeof(stmt)}')
|
// g.writeln('// autofree_scope_vars($stmt.position().pos) | ${typeof(stmt)}')
|
||||||
// go back 1 position is important so we dont get the
|
// go back 1 position is important so we dont get the
|
||||||
// internal scope of for loops and possibly other nodes
|
// 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
|
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 {
|
if g.is_builtin_mod {
|
||||||
// In `builtin` everything is freed manually.
|
// In `builtin` everything is freed manually.
|
||||||
return
|
return
|
||||||
@ -2030,10 +2033,12 @@ fn (mut g Gen) autofree_scope_vars(pos int) {
|
|||||||
// eprintln('> free_scope_vars($pos)')
|
// eprintln('> free_scope_vars($pos)')
|
||||||
scope := g.file.scope.innermost(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.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) {
|
if isnil(scope) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -2046,7 +2051,8 @@ fn (mut g Gen) autofree_scope_vars2(scope &ast.Scope, end_pos int) {
|
|||||||
// continue
|
// continue
|
||||||
// }
|
// }
|
||||||
v := *obj
|
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
|
// Do not free vars that were declared after this scope
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -2068,8 +2074,11 @@ fn (mut g Gen) autofree_scope_vars2(scope &ast.Scope, end_pos int) {
|
|||||||
// return
|
// return
|
||||||
// }
|
// }
|
||||||
// ```
|
// ```
|
||||||
|
// if !isnil(scope.parent) && line_nr > 0 {
|
||||||
if !isnil(scope.parent) {
|
if !isnil(scope.parent) {
|
||||||
// g.autofree_scope_vars2(scope.parent, end_pos)
|
// 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 */')
|
g.writeln('$styp $tmp; /* if prepend */')
|
||||||
} else if node.is_expr || g.inside_ternary != 0 {
|
} else if node.is_expr || g.inside_ternary != 0 {
|
||||||
g.inside_ternary++
|
g.inside_ternary++
|
||||||
|
// g.inside_if_expr = true
|
||||||
g.write('(')
|
g.write('(')
|
||||||
for i, branch in node.branches {
|
for i, branch in node.branches {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
@ -3952,7 +3962,7 @@ fn (mut g Gen) return_statement(node ast.Return, af bool) {
|
|||||||
}
|
}
|
||||||
if free {
|
if free {
|
||||||
g.writeln('; // free tmp exprs')
|
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')
|
g.write('return $tmp')
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -155,7 +155,8 @@ fn (mut g Gen) gen_fn_decl(it ast.FnDecl, skip bool) {
|
|||||||
//
|
//
|
||||||
if g.autofree && !g.pref.experimental {
|
if g.autofree && !g.pref.experimental {
|
||||||
// TODO: remove this, when g.write_autofree_stmts_when_needed works properly
|
// 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 {
|
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)
|
default_expr := g.type_default(it.return_type)
|
||||||
|
Loading…
Reference in New Issue
Block a user