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
|
// break, continue
|
||||||
pub struct BranchStmt {
|
pub struct BranchStmt {
|
||||||
pub:
|
pub:
|
||||||
kind token.Kind
|
kind token.Kind
|
||||||
label string
|
label string
|
||||||
pos token.Position
|
pos token.Position
|
||||||
|
parent_pos int
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CallExpr {
|
pub struct CallExpr {
|
||||||
|
@ -858,7 +858,8 @@ fn (mut g Gen) stmt(node ast.Stmt) {
|
|||||||
// continue or break
|
// continue or break
|
||||||
if g.pref.autofree && !g.is_builtin_mod {
|
if g.pref.autofree && !g.is_builtin_mod {
|
||||||
g.writeln('// free before continue/break')
|
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;')
|
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
|
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) {
|
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 {
|
if g.is_builtin_mod {
|
||||||
// In `builtin` everything is freed manually.
|
// In `builtin` everything is freed manually.
|
||||||
return
|
return
|
||||||
@ -2078,12 +2082,12 @@ fn (mut g Gen) autofree_scope_vars(pos int, line_nr int, free_parent_scopes bool
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
g.writeln('// autofree_scope_vars(pos=$pos line_nr=$line_nr scope.pos=$scope.start_pos scope.end_pos=$scope.end_pos)')
|
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, 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) {
|
if isnil(scope) {
|
||||||
return
|
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 !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.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 {
|
fn (mut p Parser) for_stmt() ast.Stmt {
|
||||||
p.check(.key_for)
|
p.check(.key_for)
|
||||||
pos := p.tok.position()
|
pos := p.tok.position()
|
||||||
|
p.branch_parent_pos = pos.pos
|
||||||
p.open_scope()
|
p.open_scope()
|
||||||
p.inside_for = true
|
p.inside_for = true
|
||||||
if p.tok.kind == .key_match {
|
if p.tok.kind == .key_match {
|
||||||
|
@ -60,6 +60,7 @@ mut:
|
|||||||
vet_errors []string
|
vet_errors []string
|
||||||
cur_fn_name string
|
cur_fn_name string
|
||||||
in_generic_params bool // indicates if parsing between `<` and `>` of a method/function
|
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
|
// for tests
|
||||||
@ -690,6 +691,7 @@ pub fn (mut p Parser) stmt(is_top_level bool) ast.Stmt {
|
|||||||
kind: tok.kind
|
kind: tok.kind
|
||||||
label: label
|
label: label
|
||||||
pos: tok.position()
|
pos: tok.position()
|
||||||
|
parent_pos: p.branch_parent_pos
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.key_unsafe {
|
.key_unsafe {
|
||||||
|
@ -258,17 +258,28 @@ fn free_before_break() {
|
|||||||
q := [1, 2, 3]
|
q := [1, 2, 3]
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
for {
|
for {
|
||||||
qq := [1, 2, 3]
|
aa := [1, 2, 3]
|
||||||
if true {
|
if true {
|
||||||
// breaking should free only vars in the closest for loop's scope
|
// breaking should free only vars in the closest for loop's scope
|
||||||
// `qq`, not `s`
|
// `qq`, not `s`
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
// nested 1
|
||||||
|
for {
|
||||||
|
bb := [4, 5, 6]
|
||||||
|
if true {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
// nested 2
|
||||||
|
for {
|
||||||
|
cc := [7, 8, 9]
|
||||||
|
if true {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
/*
|
|
||||||
mut i := 0
|
mut i := 0
|
||||||
for {
|
for {
|
||||||
i++
|
i++
|
||||||
@ -280,7 +291,6 @@ fn free_before_break() {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct User {
|
struct User {
|
||||||
|
Loading…
Reference in New Issue
Block a user