mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
cgen: store return vals in tmp vars with -autofree
This commit is contained in:
parent
92eea7f95a
commit
5eb76606ae
@ -103,6 +103,12 @@ pub fn mkdir(path string) ?bool {
|
||||
if path == '.' {
|
||||
return true
|
||||
}
|
||||
/*
|
||||
mut k := 0
|
||||
defer {
|
||||
k = 1
|
||||
}
|
||||
*/
|
||||
apath := os.real_path(path)
|
||||
/*
|
||||
$if linux {
|
||||
|
@ -394,16 +394,11 @@ fn (g &Gen) cc_type(t table.Type) string {
|
||||
if info.generic_types.len > 0 {
|
||||
mut sgtyps := '_T'
|
||||
for gt in info.generic_types {
|
||||
gts := g.table.get_type_symbol(if gt.has_flag(.generic) {
|
||||
g.unwrap_generic(gt)
|
||||
} else {
|
||||
gt
|
||||
})
|
||||
gts := g.table.get_type_symbol(if gt.has_flag(.generic) { g.unwrap_generic(gt) } else { gt })
|
||||
sgtyps += '_$gts.name'
|
||||
}
|
||||
styp += sgtyps
|
||||
}
|
||||
else if styp.contains('<') {
|
||||
} else if styp.contains('<') {
|
||||
// TODO: yuck
|
||||
styp = styp.replace('<', '_T_').replace('>', '').replace(',', '_')
|
||||
}
|
||||
@ -772,7 +767,9 @@ fn (mut g Gen) stmt(node ast.Stmt) {
|
||||
}
|
||||
ast.Return {
|
||||
g.write_defer_stmts_when_needed()
|
||||
g.write_autofree_stmts_when_needed(node)
|
||||
if g.pref.autofree {
|
||||
g.write_autofree_stmts_when_needed(node)
|
||||
}
|
||||
g.return_statement(node)
|
||||
}
|
||||
ast.SqlStmt {
|
||||
@ -1095,18 +1092,18 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
|
||||
info := sym.info as table.Array
|
||||
styp := g.typ(info.elem_type)
|
||||
g.write('$styp _var_$left.pos.pos = *($styp*)array_get(')
|
||||
g.expr(it.left)
|
||||
g.expr(left.left)
|
||||
g.write(', ')
|
||||
g.expr(it.index)
|
||||
g.expr(left.index)
|
||||
g.writeln(');')
|
||||
} else if sym.kind == .map {
|
||||
info := sym.info as table.Map
|
||||
styp := g.typ(info.value_type)
|
||||
zero := g.type_default(info.value_type)
|
||||
g.write('$styp _var_$left.pos.pos = *($styp*)map_get(')
|
||||
g.expr(it.left)
|
||||
g.expr(left.left)
|
||||
g.write(', ')
|
||||
g.expr(it.index)
|
||||
g.expr(left.index)
|
||||
g.writeln(', &($styp[]){ $zero });')
|
||||
}
|
||||
}
|
||||
@ -2486,7 +2483,21 @@ fn (mut g Gen) return_statement(node ast.Return) {
|
||||
g.writeln('return $opt_tmp;')
|
||||
return
|
||||
}
|
||||
g.write('return ')
|
||||
free := g.pref.autofree && node.exprs[0] is ast.CallExpr
|
||||
mut tmp := ''
|
||||
if free {
|
||||
// `return foo(a, b, c)`
|
||||
// `tmp := foo(a, b, c); free(a); free(b); free(c); return tmp;`
|
||||
// Save return value in a temp var so that it all args (a,b,c) can be freed
|
||||
tmp = g.new_tmp_var()
|
||||
g.write(g.typ(g.fn_decl.return_type))
|
||||
g.write(' ')
|
||||
g.write(tmp)
|
||||
g.write(' = ')
|
||||
// g.write('return $tmp;')
|
||||
} else {
|
||||
g.write('return ')
|
||||
}
|
||||
cast_interface := sym.kind == .interface_ && node.types[0] != g.fn_decl.return_type
|
||||
if cast_interface {
|
||||
g.interface_call(node.types[0], g.fn_decl.return_type)
|
||||
@ -2495,6 +2506,10 @@ fn (mut g Gen) return_statement(node ast.Return) {
|
||||
if cast_interface {
|
||||
g.write(')')
|
||||
}
|
||||
if free {
|
||||
g.writeln(';')
|
||||
g.write('return $tmp')
|
||||
}
|
||||
} else {
|
||||
g.write('return')
|
||||
}
|
||||
@ -2824,7 +2839,7 @@ fn (mut g Gen) write_init_function() {
|
||||
g.writeln('void _vcleanup() {')
|
||||
// g.writeln('puts("cleaning up...");')
|
||||
g.writeln(g.cleanups.str())
|
||||
//g.writeln('\tfree(g_str_buf);')
|
||||
// g.writeln('\tfree(g_str_buf);')
|
||||
g.writeln('}')
|
||||
if g.pref.printfn_list.len > 0 && '_vcleanup' in g.pref.printfn_list {
|
||||
println(g.out.after(fn_vcleanup_start_pos))
|
||||
|
@ -74,7 +74,7 @@ fn (mut g Gen) gen_fn_decl(it ast.FnDecl) {
|
||||
}
|
||||
mut impl_fn_name := name
|
||||
if is_live_wrap {
|
||||
impl_fn_name = 'impl_live_${name}'
|
||||
impl_fn_name = 'impl_live_$name'
|
||||
}
|
||||
g.last_fn_c_name = impl_fn_name
|
||||
//
|
||||
@ -113,17 +113,16 @@ fn (mut g Gen) gen_fn_decl(it ast.FnDecl) {
|
||||
// an early exit, which will leave the mutex locked.
|
||||
mut fn_args_list := []string{}
|
||||
for ia, fa in fargs {
|
||||
fn_args_list << '${fargtypes[ia]} ${fa}'
|
||||
fn_args_list << '${fargtypes[ia]} $fa'
|
||||
}
|
||||
mut live_fncall := '${impl_fn_name}(' + fargs.join(', ') + ');'
|
||||
mut live_fnreturn := ''
|
||||
if type_name != 'void' {
|
||||
live_fncall = '${type_name} res = ${live_fncall}'
|
||||
live_fncall = '$type_name res = $live_fncall'
|
||||
live_fnreturn = 'return res;'
|
||||
}
|
||||
g.definitions.writeln('$type_name ${name}(' + fn_args_list.join(', ') + ');')
|
||||
g.hotcode_definitions.writeln('$type_name ${name}(' + fn_args_list.join(', ') +
|
||||
'){')
|
||||
g.hotcode_definitions.writeln('$type_name ${name}(' + fn_args_list.join(', ') + '){')
|
||||
g.hotcode_definitions.writeln(' pthread_mutex_lock(&live_fn_mutex);')
|
||||
g.hotcode_definitions.writeln(' $live_fncall')
|
||||
g.hotcode_definitions.writeln(' pthread_mutex_unlock(&live_fn_mutex);')
|
||||
@ -140,7 +139,7 @@ fn (mut g Gen) gen_fn_decl(it ast.FnDecl) {
|
||||
// /////////
|
||||
if g.autofree {
|
||||
// TODO: remove this, when g.write_autofree_stmts_when_needed works properly
|
||||
g.writeln(g.autofree_scope_vars(it.body_pos.pos))
|
||||
// g.writeln(g.autofree_scope_vars(it.body_pos.pos))
|
||||
}
|
||||
g.writeln('}')
|
||||
g.defer_stmts = []
|
||||
@ -154,12 +153,9 @@ fn (mut g Gen) write_autofree_stmts_when_needed(r ast.Return) {
|
||||
// TODO: write_autofree_stmts_when_needed should not free the returned variables.
|
||||
// It may require rewriting g.return_statement to assign the expressions
|
||||
// to temporary variables, then protecting *them* from autofreeing ...
|
||||
/*
|
||||
g.writeln('/* autofreeings before return: -------')
|
||||
//g.write( g.autofree_scope_vars(r.pos.pos) )
|
||||
g.write( g.autofree_scope_vars(g.fn_decl.body_pos.pos) )
|
||||
g.writeln('--------------------------------------------------- */')
|
||||
*/
|
||||
// g.writeln('// autofreeings before return: -------')
|
||||
// g.writeln(g.autofree_scope_vars(g.fn_decl.body_pos.pos))
|
||||
// g.writeln('//--------------------------------------------------- ') // //g.write( g.autofree_scope_vars(r.pos.pos) )
|
||||
}
|
||||
|
||||
fn (mut g Gen) write_defer_stmts_when_needed() {
|
||||
@ -248,7 +244,9 @@ fn (mut g Gen) call_expr(node ast.CallExpr) {
|
||||
return
|
||||
}
|
||||
g.inside_call = true
|
||||
defer {g.inside_call = false}
|
||||
defer {
|
||||
g.inside_call = false
|
||||
}
|
||||
gen_or := node.or_block.kind != .absent
|
||||
cur_line := if gen_or && g.is_assign_rhs {
|
||||
line := g.go_before_stmt(0)
|
||||
@ -336,8 +334,8 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
|
||||
g.gen_str_for_type_with_styp(node.receiver_type, styp)
|
||||
}
|
||||
// TODO performance, detect `array` method differently
|
||||
if left_sym.kind == .array &&
|
||||
node.name in ['repeat', 'sort_with_compare', 'free', 'push_many', 'trim', 'first', 'last', 'clone', 'reverse', 'slice'] {
|
||||
if left_sym.kind == .array && node.name in
|
||||
['repeat', 'sort_with_compare', 'free', 'push_many', 'trim', 'first', 'last', 'clone', 'reverse', 'slice'] {
|
||||
// && rec_sym.name == 'array' {
|
||||
// && rec_sym.name == 'array' && receiver_name.starts_with('array') {
|
||||
// `array_byte_clone` => `array_clone`
|
||||
|
Loading…
Reference in New Issue
Block a user