diff --git a/vlib/os/os_nix.c.v b/vlib/os/os_nix.c.v index 7f42837a90..99c1bfc287 100644 --- a/vlib/os/os_nix.c.v +++ b/vlib/os/os_nix.c.v @@ -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 { diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index e1ad01b5fd..0152d654d2 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -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)) diff --git a/vlib/v/gen/fn.v b/vlib/v/gen/fn.v index f038c56dba..81a2b95b49 100644 --- a/vlib/v/gen/fn.v +++ b/vlib/v/gen/fn.v @@ -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`