mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
cgen: autofree - know where to stop freeing parent scops on continue/break
This commit is contained in:
parent
fafe30b6aa
commit
83f651c29a
@ -286,9 +286,10 @@ pub mut:
|
||||
// break, continue
|
||||
pub struct BranchStmt {
|
||||
pub:
|
||||
kind token.Kind
|
||||
label string
|
||||
pos token.Position
|
||||
kind token.Kind
|
||||
label string
|
||||
pos token.Position
|
||||
parent_pos int
|
||||
}
|
||||
|
||||
pub struct CallExpr {
|
||||
|
@ -858,7 +858,8 @@ fn (mut g Gen) stmt(node ast.Stmt) {
|
||||
// continue or break
|
||||
if g.pref.autofree && !g.is_builtin_mod {
|
||||
g.writeln('// free before continue/break')
|
||||
g.autofree_scope_vars(node.pos.pos - 1, node.pos.line_nr, false)
|
||||
g.autofree_scope_vars_stop(node.pos.pos - 1, node.pos.line_nr, true,
|
||||
node.parent_pos)
|
||||
}
|
||||
g.writeln('$node.kind;')
|
||||
}
|
||||
@ -2061,8 +2062,11 @@ 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, line_nr int) {
|
||||
fn (mut g Gen) autofree_scope_vars(pos int, line_nr int, free_parent_scopes bool) {
|
||||
g.autofree_scope_vars_stop(pos, line_nr, free_parent_scopes, -1)
|
||||
}
|
||||
|
||||
fn (mut g Gen) autofree_scope_vars_stop(pos int, line_nr int, free_parent_scopes bool, stop_pos int) {
|
||||
if g.is_builtin_mod {
|
||||
// In `builtin` everything is freed manually.
|
||||
return
|
||||
@ -2078,12 +2082,12 @@ fn (mut g Gen) autofree_scope_vars(pos int, line_nr int, free_parent_scopes bool
|
||||
return
|
||||
}
|
||||
g.writeln('// autofree_scope_vars(pos=$pos line_nr=$line_nr 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.start_pos, scope.end_pos, line_nr, free_parent_scopes)
|
||||
g.autofree_scope_vars2(scope, scope.start_pos, scope.end_pos, line_nr, free_parent_scopes,
|
||||
stop_pos)
|
||||
}
|
||||
|
||||
// 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, free_parent_scopes bool) {
|
||||
fn (mut g Gen) autofree_scope_vars2(scope &ast.Scope, start_pos int, end_pos int, line_nr int, free_parent_scopes bool, stop_pos int) {
|
||||
if isnil(scope) {
|
||||
return
|
||||
}
|
||||
@ -2129,9 +2133,10 @@ fn (mut g Gen) autofree_scope_vars2(scope &ast.Scope, start_pos int, end_pos int
|
||||
// }
|
||||
// ```
|
||||
// if !isnil(scope.parent) && line_nr > 0 {
|
||||
if free_parent_scopes && !isnil(scope.parent) {
|
||||
if free_parent_scopes && !isnil(scope.parent) &&
|
||||
(stop_pos == -1 || scope.parent.start_pos >= stop_pos) {
|
||||
g.writeln('// af parent scope:')
|
||||
g.autofree_scope_vars2(scope.parent, start_pos, end_pos, line_nr, true)
|
||||
g.autofree_scope_vars2(scope.parent, start_pos, end_pos, line_nr, true, stop_pos)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@ import v.table
|
||||
fn (mut p Parser) for_stmt() ast.Stmt {
|
||||
p.check(.key_for)
|
||||
pos := p.tok.position()
|
||||
p.branch_parent_pos = pos.pos
|
||||
p.open_scope()
|
||||
p.inside_for = true
|
||||
if p.tok.kind == .key_match {
|
||||
|
@ -60,6 +60,7 @@ mut:
|
||||
vet_errors []string
|
||||
cur_fn_name string
|
||||
in_generic_params bool // indicates if parsing between `<` and `>` of a method/function
|
||||
branch_parent_pos int // used in BranchStmt (continue/break) autofree stop position
|
||||
}
|
||||
|
||||
// for tests
|
||||
@ -690,6 +691,7 @@ pub fn (mut p Parser) stmt(is_top_level bool) ast.Stmt {
|
||||
kind: tok.kind
|
||||
label: label
|
||||
pos: tok.position()
|
||||
parent_pos: p.branch_parent_pos
|
||||
}
|
||||
}
|
||||
.key_unsafe {
|
||||
|
@ -258,17 +258,28 @@ fn free_before_break() {
|
||||
q := [1, 2, 3]
|
||||
break
|
||||
}
|
||||
/*
|
||||
for {
|
||||
qq := [1, 2, 3]
|
||||
aa := [1, 2, 3]
|
||||
if true {
|
||||
// breaking should free only vars in the closest for loop's scope
|
||||
// `qq`, not `s`
|
||||
break
|
||||
}
|
||||
// nested 1
|
||||
for {
|
||||
bb := [4, 5, 6]
|
||||
if true {
|
||||
break
|
||||
}
|
||||
// nested 2
|
||||
for {
|
||||
cc := [7, 8, 9]
|
||||
if true {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
/*
|
||||
mut i := 0
|
||||
for {
|
||||
i++
|
||||
@ -280,7 +291,6 @@ fn free_before_break() {
|
||||
continue
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
struct User {
|
||||
|
Loading…
Reference in New Issue
Block a user