1
0
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:
Alexander Medvednikov 2020-11-16 17:26:54 +01:00
parent fdfe2a4e68
commit 68077b7dbf
2 changed files with 19 additions and 8 deletions

View File

@ -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 {

View File

@ -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)