mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
autofree: fix or {}
; ci: bring back gitly -autofree
This commit is contained in:
parent
3f2133c65e
commit
0ea2fa228f
5
.github/workflows/ci.yml
vendored
5
.github/workflows/ci.yml
vendored
@ -170,7 +170,7 @@ jobs:
|
||||
run: ./v -silent build-examples
|
||||
- name: Build examples with -autofree
|
||||
run: |
|
||||
./v -autofree -experimental -o tetris examples/tetris/tetris.v
|
||||
./v -autofree -o tetris examples/tetris/tetris.v
|
||||
- name: v doctor
|
||||
run: |
|
||||
./v doctor
|
||||
@ -182,7 +182,7 @@ jobs:
|
||||
run: |
|
||||
git clone --depth 1 https://github.com/vlang/ved
|
||||
cd ved && ../v -o ved .
|
||||
# ../v -autofree .
|
||||
../v -autofree .
|
||||
- name: Build V UI examples
|
||||
run: |
|
||||
git clone --depth 1 https://github.com/vlang/ui
|
||||
@ -538,6 +538,7 @@ jobs:
|
||||
git clone --depth 1 https://github.com/vlang/gitly
|
||||
cd gitly
|
||||
../v .
|
||||
../v -autofree .
|
||||
cd ..
|
||||
|
||||
websocket_autobahn:
|
||||
|
@ -311,9 +311,6 @@ pub mut:
|
||||
generic_type table.Type // TODO array, to support multiple types
|
||||
generic_list_pos token.Position
|
||||
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
|
||||
is_used bool
|
||||
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
|
||||
|
@ -1079,7 +1079,7 @@ fn (mut g Gen) stmt(node ast.Stmt) {
|
||||
}
|
||||
ast.Module {
|
||||
// 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
|
||||
}
|
||||
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?)
|
||||
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.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 {
|
||||
match obj {
|
||||
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 {
|
||||
g.writeln('// skipping returned var')
|
||||
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 {
|
||||
// // TODO why 0?
|
||||
// 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 free_parent_scopes && !isnil(scope.parent) {
|
||||
// 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, true)
|
||||
}
|
||||
@ -3918,7 +3922,7 @@ fn (mut g Gen) return_statement(node ast.Return) {
|
||||
} else {
|
||||
if g.pref.autofree && !g.is_builtin_mod {
|
||||
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;')
|
||||
}
|
||||
|
@ -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' {
|
||||
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.
|
||||
fn_name := node.name.replace('.', '_')
|
||||
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 {
|
||||
scope.register(ast.Var{
|
||||
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
|
||||
})
|
||||
s = 'string $t = '
|
||||
@ -662,10 +662,7 @@ fn (mut g Gen) autofree_call_pregen(node ast.CallExpr) {
|
||||
// g.writeln(';// new af pre')
|
||||
s += ';// new af2 pre'
|
||||
g.strs_to_free0 << s
|
||||
// Now free the tmp arg vars right after the function call
|
||||
// g.strs_to_free << t
|
||||
// g.nr_vars_to_free++
|
||||
// g.strs_to_free << 'string_free(&$t);'
|
||||
// This tmp arg var will be freed with the rest of the vars at the end of the scope.
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -131,6 +131,7 @@ fn (mut p Parser) partial_assign_stmt(left []ast.Expr, left_comments []ast.Comme
|
||||
is_static = true
|
||||
}
|
||||
}
|
||||
r0 := right[0]
|
||||
mut v := ast.Var{
|
||||
name: lx.name
|
||||
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
|
||||
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)
|
||||
lx.obj = obj
|
||||
p.scope.register(obj)
|
||||
|
Loading…
Reference in New Issue
Block a user