autofree: fix `or {}`; ci: bring back gitly -autofree
parent
3f2133c65e
commit
0ea2fa228f
|
@ -170,7 +170,7 @@ jobs:
|
||||||
run: ./v -silent build-examples
|
run: ./v -silent build-examples
|
||||||
- name: Build examples with -autofree
|
- name: Build examples with -autofree
|
||||||
run: |
|
run: |
|
||||||
./v -autofree -experimental -o tetris examples/tetris/tetris.v
|
./v -autofree -o tetris examples/tetris/tetris.v
|
||||||
- name: v doctor
|
- name: v doctor
|
||||||
run: |
|
run: |
|
||||||
./v doctor
|
./v doctor
|
||||||
|
@ -182,7 +182,7 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
git clone --depth 1 https://github.com/vlang/ved
|
git clone --depth 1 https://github.com/vlang/ved
|
||||||
cd ved && ../v -o ved .
|
cd ved && ../v -o ved .
|
||||||
# ../v -autofree .
|
../v -autofree .
|
||||||
- name: Build V UI examples
|
- name: Build V UI examples
|
||||||
run: |
|
run: |
|
||||||
git clone --depth 1 https://github.com/vlang/ui
|
git clone --depth 1 https://github.com/vlang/ui
|
||||||
|
@ -538,6 +538,7 @@ jobs:
|
||||||
git clone --depth 1 https://github.com/vlang/gitly
|
git clone --depth 1 https://github.com/vlang/gitly
|
||||||
cd gitly
|
cd gitly
|
||||||
../v .
|
../v .
|
||||||
|
../v -autofree .
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
websocket_autobahn:
|
websocket_autobahn:
|
||||||
|
|
|
@ -311,9 +311,6 @@ pub mut:
|
||||||
generic_type table.Type // TODO array, to support multiple types
|
generic_type table.Type // TODO array, to support multiple types
|
||||||
generic_list_pos token.Position
|
generic_list_pos token.Position
|
||||||
free_receiver bool // true if the receiver expression needs to be freed
|
free_receiver bool // true if the receiver expression needs to be freed
|
||||||
// autofree_pregen string
|
|
||||||
// autofree_vars []AutofreeArgVar
|
|
||||||
// autofree_vars_ids []int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -371,6 +368,8 @@ pub mut:
|
||||||
pos token.Position
|
pos token.Position
|
||||||
is_used bool
|
is_used bool
|
||||||
is_changed bool // to detect mutable vars that are never changed
|
is_changed bool // to detect mutable vars that are never changed
|
||||||
|
is_or bool // `x := foo() or { ... }`
|
||||||
|
// (for setting the position after the or block for autofree)
|
||||||
}
|
}
|
||||||
|
|
||||||
// used for smartcasting only
|
// used for smartcasting only
|
||||||
|
|
|
@ -1079,7 +1079,7 @@ fn (mut g Gen) stmt(node ast.Stmt) {
|
||||||
}
|
}
|
||||||
ast.Module {
|
ast.Module {
|
||||||
// g.is_builtin_mod = node.name == 'builtin'
|
// g.is_builtin_mod = node.name == 'builtin'
|
||||||
g.is_builtin_mod = node.name in ['builtin', 'os', 'strconv', 'strings']
|
g.is_builtin_mod = node.name in ['builtin', 'os', 'strconv', 'strings', 'gg']
|
||||||
g.cur_mod = node.name
|
g.cur_mod = node.name
|
||||||
}
|
}
|
||||||
ast.Return {
|
ast.Return {
|
||||||
|
@ -2070,7 +2070,7 @@ fn (mut g Gen) autofree_scope_vars(pos int, line_nr int, free_parent_scopes bool
|
||||||
// TODO why can scope.pos be 0? (only outside fns?)
|
// TODO why can scope.pos be 0? (only outside fns?)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
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 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.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)
|
||||||
}
|
}
|
||||||
|
@ -2083,11 +2083,16 @@ fn (mut g Gen) autofree_scope_vars2(scope &ast.Scope, start_pos int, end_pos int
|
||||||
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')
|
g.writeln('// var "$obj.name" var.pos=$obj.pos.pos var.line_nr=$obj.pos.line_nr')
|
||||||
if obj.name == g.returned_var_name {
|
if obj.name == g.returned_var_name {
|
||||||
g.writeln('// skipping returned var')
|
g.writeln('// skipping returned var')
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if obj.is_or {
|
||||||
|
// Skip vars inited with the `or {}`, since they are generated
|
||||||
|
// after the or block in C.
|
||||||
|
continue
|
||||||
|
}
|
||||||
// if var.typ == 0 {
|
// if var.typ == 0 {
|
||||||
// // TODO why 0?
|
// // TODO why 0?
|
||||||
// continue
|
// continue
|
||||||
|
@ -2117,7 +2122,6 @@ 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) {
|
||||||
// g.autofree_scope_vars2(scope.parent, end_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)
|
||||||
}
|
}
|
||||||
|
@ -3918,7 +3922,7 @@ fn (mut g Gen) return_statement(node ast.Return) {
|
||||||
} else {
|
} else {
|
||||||
if g.pref.autofree && !g.is_builtin_mod {
|
if g.pref.autofree && !g.is_builtin_mod {
|
||||||
g.writeln('// free before return (no values returned)')
|
g.writeln('// free before return (no values returned)')
|
||||||
g.autofree_scope_vars(node.pos.pos + 1, node.pos.line_nr, true)
|
g.autofree_scope_vars(node.pos.pos - 1, node.pos.line_nr, true)
|
||||||
}
|
}
|
||||||
g.writeln('return;')
|
g.writeln('return;')
|
||||||
}
|
}
|
||||||
|
|
|
@ -423,7 +423,7 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
|
||||||
} else if !node.receiver_type.is_ptr() && node.left_type.is_ptr() && node.name != 'str' {
|
} else if !node.receiver_type.is_ptr() && node.left_type.is_ptr() && node.name != 'str' {
|
||||||
g.write('/*rec*/*')
|
g.write('/*rec*/*')
|
||||||
}
|
}
|
||||||
if node.free_receiver && !g.inside_lambda {
|
if node.free_receiver && !g.inside_lambda && !g.is_builtin_mod {
|
||||||
// The receiver expression needs to be freed, use the temp var.
|
// The receiver expression needs to be freed, use the temp var.
|
||||||
fn_name := node.name.replace('.', '_')
|
fn_name := node.name.replace('.', '_')
|
||||||
arg_name := '_arg_expr_${fn_name}_0_$node.pos.pos'
|
arg_name := '_arg_expr_${fn_name}_0_$node.pos.pos'
|
||||||
|
@ -652,7 +652,7 @@ fn (mut g Gen) autofree_call_pregen(node ast.CallExpr) {
|
||||||
} else {
|
} else {
|
||||||
scope.register(ast.Var{
|
scope.register(ast.Var{
|
||||||
name: t
|
name: t
|
||||||
typ: table.string_type // is_arg: true // TODO hack so that it's not freed twice when out of scope. it's probably better to use one model
|
typ: table.string_type
|
||||||
is_autofree_tmp: true
|
is_autofree_tmp: true
|
||||||
})
|
})
|
||||||
s = 'string $t = '
|
s = 'string $t = '
|
||||||
|
@ -662,10 +662,7 @@ fn (mut g Gen) autofree_call_pregen(node ast.CallExpr) {
|
||||||
// g.writeln(';// new af pre')
|
// g.writeln(';// new af pre')
|
||||||
s += ';// new af2 pre'
|
s += ';// new af2 pre'
|
||||||
g.strs_to_free0 << s
|
g.strs_to_free0 << s
|
||||||
// Now free the tmp arg vars right after the function call
|
// This tmp arg var will be freed with the rest of the vars at the end of the scope.
|
||||||
// g.strs_to_free << t
|
|
||||||
// g.nr_vars_to_free++
|
|
||||||
// g.strs_to_free << 'string_free(&$t);'
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -131,6 +131,7 @@ fn (mut p Parser) partial_assign_stmt(left []ast.Expr, left_comments []ast.Comme
|
||||||
is_static = true
|
is_static = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
r0 := right[0]
|
||||||
mut v := ast.Var{
|
mut v := ast.Var{
|
||||||
name: lx.name
|
name: lx.name
|
||||||
expr: if left.len == right.len { right[i] } else { ast.Expr{} }
|
expr: if left.len == right.len { right[i] } else { ast.Expr{} }
|
||||||
|
@ -138,6 +139,17 @@ fn (mut p Parser) partial_assign_stmt(left []ast.Expr, left_comments []ast.Comme
|
||||||
is_mut: lx.is_mut || p.inside_for
|
is_mut: lx.is_mut || p.inside_for
|
||||||
pos: lx.pos
|
pos: lx.pos
|
||||||
}
|
}
|
||||||
|
if p.pref.autofree {
|
||||||
|
if r0 is ast.CallExpr {
|
||||||
|
// Set correct variable position (after the or block)
|
||||||
|
// so that autofree doesn't free it in cgen before
|
||||||
|
// it's declared. (`Or` variables are declared after the or block).
|
||||||
|
if r0.or_block.pos.pos > 0 {
|
||||||
|
v.is_or = true
|
||||||
|
// v.pos = r0.or_block.pos.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
obj := ast.ScopeObject(v)
|
obj := ast.ScopeObject(v)
|
||||||
lx.obj = obj
|
lx.obj = obj
|
||||||
p.scope.register(obj)
|
p.scope.register(obj)
|
||||||
|
|
Loading…
Reference in New Issue