1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

autofree: free all vars in parent scopes recursively

This commit is contained in:
Alexander Medvednikov 2020-11-09 15:56:20 +01:00
parent c76e486765
commit 2254f41722

View File

@ -1929,17 +1929,29 @@ fn (mut g Gen) autofree_scope_vars(pos int) {
// In `builtin` everything is freed manually. // In `builtin` everything is freed manually.
return return
} }
g.writeln('// autofree_scope_vars($pos)')
// 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.autofree_scope_vars2(scope, scope.end_pos)
}
fn (mut g Gen) autofree_scope_vars2(scope &ast.Scope, end_pos int) {
if isnil(scope) {
return
}
for _, obj in scope.objects { for _, obj in scope.objects {
match obj { match obj {
ast.Var { ast.Var {
g.writeln('// var $obj.name pos=$obj.pos.pos')
// if var.typ == 0 { // if var.typ == 0 {
// // TODO why 0? // // TODO why 0?
// continue // continue
// } // }
v := *obj v := *obj
if v.pos.pos > end_pos {
// Do not free vars that were declared after this scope
continue
}
is_optional := v.typ.has_flag(.optional) is_optional := v.typ.has_flag(.optional)
if is_optional { if is_optional {
// TODO: free optionals // TODO: free optionals
@ -1950,6 +1962,17 @@ fn (mut g Gen) autofree_scope_vars(pos int) {
else {} else {}
} }
} }
// Free all vars in parent scopes as well:
// ```
// s := ...
// if ... {
// s.free()
// return
// }
// ```
if !isnil(scope.parent) {
// g.autofree_scope_vars2(scope.parent, end_pos)
}
} }
fn (mut g Gen) autofree_variable(v ast.Var) { fn (mut g Gen) autofree_variable(v ast.Var) {