autofree: fix exprs N levels deep

pull/6297/head^2
Alexander Medvednikov 2020-09-06 13:02:29 +02:00
parent 047bf02985
commit 9fbea31f47
5 changed files with 19 additions and 13 deletions

View File

@ -307,7 +307,7 @@ pub:
comments []Comment comments []Comment
pub mut: pub mut:
typ table.Type typ table.Type
is_tmp_autofree bool // for autofree is_tmp_autofree bool
// tmp_name string // for autofree // tmp_name string // for autofree
} }

View File

@ -99,7 +99,7 @@ mut:
sql_side SqlExprSide // left or right, to distinguish idents in `name == name` sql_side SqlExprSide // left or right, to distinguish idents in `name == name`
inside_vweb_tmpl bool inside_vweb_tmpl bool
inside_return bool inside_return bool
strs_to_free string strs_to_free []string // strings.Builder
inside_call bool inside_call bool
has_main bool has_main bool
inside_const bool inside_const bool
@ -725,18 +725,21 @@ fn (mut g Gen) write_v_source_line_info(pos token.Position) {
fn (mut g Gen) stmt(node ast.Stmt) { fn (mut g Gen) stmt(node ast.Stmt) {
g.stmt_path_pos << g.out.len g.stmt_path_pos << g.out.len
/*
defer { defer {
// If we have temporary string exprs to free after this statement, do it. e.g.: // If we have temporary string exprs to free after this statement, do it. e.g.:
// `foo('a' + 'b')` => `tmp := 'a' + 'b'; foo(tmp); string_free(&tmp);` // `foo('a' + 'b')` => `tmp := 'a' + 'b'; foo(tmp); string_free(&tmp);`
if g.pref.autofree { if g.pref.autofree {
if g.strs_to_free != '' { if g.strs_to_free.len != 0 {
g.writeln(g.strs_to_free) g.writeln('// strs_to_free:')
g.strs_to_free = '' for s in g.strs_to_free {
g.writeln(s)
}
g.strs_to_free = []
// s := g.strs_to_free.str()
// g.strs_to_free.free()
} }
} }
} }
*/
// println('cgen.stmt()') // println('cgen.stmt()')
// g.writeln('//// stmt start') // g.writeln('//// stmt start')
match node { match node {

View File

@ -632,15 +632,16 @@ fn (mut g Gen) fn_call(node ast.CallExpr) {
// g.write(cur_line + ' /* cur line*/') // g.write(cur_line + ' /* cur line*/')
// g.write(tmp) // g.write(tmp)
// Now free the tmp arg vars right after the function call // Now free the tmp arg vars right after the function call
g.writeln(';') g.strs_to_free << (';')
for i, arg in node.args { for i, arg in node.args {
if arg.is_tmp_autofree { if arg.is_tmp_autofree {
fn_name := node.name.replace('.', '_') fn_name := node.name.replace('.', '_')
tmp := '_tt${g.tmp_count2}_arg_expr_${fn_name}_$i' tmp := '_tt${g.tmp_count2}_arg_expr_${fn_name}_$i'
g.writeln('string_free(&$tmp);') g.strs_to_free << ('string_free(&$tmp);')
// g.writeln('string_free(&$tmp);')
} }
} }
g.writeln('') // g.writeln('')
} }
} }

View File

@ -194,11 +194,12 @@ fn (mut g Gen) string_inter_literal_sb_optimized(call_expr ast.CallExpr) {
fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) { fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) {
mut cur_line := '' mut cur_line := ''
mut tmp := '' mut tmp := ''
free := !g.pref.experimental && g.pref.autofree && g.inside_call && !g.inside_return && free := false && !g.pref.experimental && g.pref.autofree && g.inside_call && !g.inside_return &&
g.inside_ternary == 0 && !g.inside_const g.inside_ternary == 0 && !g.inside_const
// && g.cur_fn != 0 && // && g.cur_fn != 0 &&
// g.cur_fn.name != '' // g.cur_fn.name != ''
if free { /*
if false && free {
// Save the string expr in a temporary variable, so that it can be removed after the call. // Save the string expr in a temporary variable, so that it can be removed after the call.
tmp = g.new_tmp_var() tmp = g.new_tmp_var()
/* /*
@ -214,6 +215,7 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) {
g.write('string $tmp = ') g.write('string $tmp = ')
g.strs_to_free += 'string_free(&$tmp); /*tmp str*/' g.strs_to_free += 'string_free(&$tmp); /*tmp str*/'
} }
*/
g.write('_STR("') g.write('_STR("')
// Build the string with % // Build the string with %
mut end_string := false mut end_string := false

View File

@ -25,7 +25,7 @@ fn handle_int(n int) {
fn str_tmp_expr() { fn str_tmp_expr() {
println('a' + 'b') // tmp expression result must be freed println('a' + 'b') // tmp expression result must be freed
handle_strings('c' + 'd', 'e' + 'f') // multiple tmp expressions must be freed handle_strings('c' + 'd', 'e' + 'f') // multiple tmp expressions must be freed
// handle_int(handle_strings('x' + 'y', 'f')) // exprs 2 levels deep must bee freed handle_int(handle_strings('x' + 'y', 'f')) // exprs 2 levels deep must bee freed
} }
struct Foo { struct Foo {