From 202da3b6c9ab8127ab083fa568c0b75ee73d244e Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Thu, 26 Dec 2024 10:51:07 -0300 Subject: [PATCH] move autofree code to another file --- vlib/v/gen/c/cgen.v | 239 -------------------------------------------- 1 file changed, 239 deletions(-) diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 4dfc2e7b3e6a34..ca4b4e1328cff7 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -3297,245 +3297,6 @@ fn (mut g Gen) gen_clone_assignment(var_type ast.Type, val ast.Expr, typ ast.Typ return true } -fn (mut g Gen) autofree_scope_vars(pos int, line_nr int, free_parent_scopes bool) { - if !g.is_autofree { - return - } - // g.writeln('// afsv pos=${pos} line_nr=${line_nr} freeparent_scopes=${free_parent_scopes}') - g.autofree_scope_vars_stop(pos, line_nr, free_parent_scopes, -1) -} - -fn (mut g Gen) autofree_scope_vars_stop(pos int, line_nr int, free_parent_scopes bool, stop_pos int) { - if !g.is_autofree { - return - } - if g.is_builtin_mod { - // In `builtin` everything is freed manually. - return - } - if pos == -1 { - // TODO: why can pos be -1? - return - } - // eprintln('> free_scope_vars($pos)') - scope := g.file.scope.innermost(pos) - // g.writeln('// scope start pos=${scope.start_pos} ') - if scope.start_pos == 0 { - // TODO: why can scope.pos be 0? (only outside fns?) - return - } - g.trace_autofree('// 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.start_pos, scope.end_pos, line_nr, free_parent_scopes, - stop_pos) -} - -@[if trace_autofree ?] -fn (mut g Gen) trace_autofree(line string) { - g.writeln(line) -} - -//@[if print_autofree_vars ?] -// fn (mut g Gen) print_autofree_var(var string, position string, comment string) { -fn (mut g Gen) print_autofree_var(var ast.Var, comment string) { - if !g.pref.print_autofree_vars && g.pref.print_autofree_vars_in_fn == '' { - return - } - println('autofree: ${g.file.path}:${var.pos.line_nr}: skipping `${var.name}` in fn `${g.last_fn_c_name}`. ${comment}') -} - -fn (mut g Gen) autofree_scope_vars2(scope &ast.Scope, start_pos int, end_pos int, line_nr int, free_parent_scopes bool, - stop_pos int) { - if scope == unsafe { nil } { - return - } - g.trace_autofree('// scopeobjects.len == ${scope.objects.len}') - for _, obj in scope.objects { - match obj { - ast.Var { - g.trace_autofree('// var "${obj.name}" var.pos=${obj.pos.pos} var.line_nr=${obj.pos.line_nr}') - if obj.name == g.returned_var_name { - g.print_autofree_var(obj, 'returned from function') - g.trace_autofree('// skipping returned var') - continue - } - if obj.is_or { - // Skip vars inited with the `or {}`, since they are generated - // after the or block in C. - g.trace_autofree('// skipping `or {}` var "${obj.name}"') - continue - } - if obj.is_tmp { - // Skip for loop vars - g.print_autofree_var(obj, 'tmp var (loop?)') - g.trace_autofree('// skipping tmp var "${obj.name}"') - continue - } - if obj.is_inherited { - g.print_autofree_var(obj, 'inherited') - g.trace_autofree('// skipping inherited var "${obj.name}"') - continue - } - // if var.typ == 0 { - // // TODO: why 0? - // continue - // } - // if v.pos.pos > end_pos { - if obj.pos.pos > end_pos - || (obj.pos.pos < start_pos && obj.pos.line_nr == line_nr) - || (end_pos < scope.end_pos && obj.expr is ast.IfExpr) { - // Do not free vars that were declared after this scope - continue - } - g.autofree_variable(obj) - } - else {} - } - } - for g.autofree_scope_stmts.len > 0 { - g.write(g.autofree_scope_stmts.pop()) - } - // Free all vars in parent scopes as well: - // ``` - // s := ... - // if ... { - // s.free() - // return - // } - // ``` - // if scope.parent != unsafe { nil } && line_nr > 0 { - if free_parent_scopes && scope.parent != unsafe { nil } && !scope.detached_from_parent - && (stop_pos == -1 || scope.parent.start_pos >= stop_pos) { - g.trace_autofree('// af parent scope:') - g.autofree_scope_vars2(scope.parent, start_pos, end_pos, line_nr, true, stop_pos) - } -} - -fn (mut g Gen) autofree_variable(v ast.Var) { - // filter out invalid variables - if v.typ == 0 { - return - } - sym := g.table.sym(v.typ) - // if v.name.contains('output2') { - if g.is_autofree { - // eprintln(' > var name: ${v.name:-20s} | is_arg: ${v.is_arg.str():6} | var type: ${int(v.typ):8} | type_name: ${sym.name:-33s}') - } - // } - free_fn := g.styp(v.typ.set_nr_muls(0)) + '_free' - if sym.kind == .array { - if sym.has_method('free') { - g.autofree_var_call(free_fn, v) - return - } - g.autofree_var_call('array_free', v) - return - } - if sym.kind == .string { - // Don't free simple string literals. - match v.expr { - ast.StringLiteral { - g.print_autofree_var(v, 'string literal') - g.trace_autofree('// str literal') - } - else { - // NOTE/TODO: assign_stmt multi returns variables have no expr - // since the type comes from the called fns return type - /* - f := v.name[0] - if - //!(f >= `a` && f <= `d`) { - //f != `c` { - v.name!='cvar_name' { - t := typeof(v.expr) - return '// other ' + t + '\n' - } - */ - } - } - g.autofree_var_call('string_free', v) - return - } - // Free user reference types - is_user_ref := v.typ.is_ptr() && sym.name.after('.')[0].is_capital() - // if g.pref.experimental && v.typ.is_ptr() && sym.name.after('.')[0].is_capital() { - if is_user_ref { - if g.pref.experimental { - g.autofree_var_call('free', v) - } else { - g.print_autofree_var(v, 'user reference type, use -experimental to autofree those') - } - } - if sym.has_method('free') { - g.autofree_var_call(free_fn, v) - } -} - -fn (mut g Gen) autofree_var_call(free_fn_name string, v ast.Var) { - if v.is_arg { - // fn args should not be autofreed - return - } - if v.is_used && v.is_autofree_tmp { - // tmp expr vars do not need to be freed again here - return - } - if g.is_builtin_mod { - return - } - if !g.is_autofree { - return - } - // if v.is_autofree_tmp && !g.doing_autofree_tmp { - // return - // } - if v.name.contains('expr_write_string_1_') { - // TODO: remove this temporary hack - return - } - mut af := strings.new_builder(128) - if v.typ.is_ptr() { - af.write_string('\t') - if v.typ.share() == .shared_t { - af.write_string(free_fn_name.replace_each(['__shared__', ''])) - } else { - af.write_string(free_fn_name) - } - af.write_string('(') - if v.typ.has_flag(.option) { - base_type := g.base_type(v.typ) - af.write_string('(${base_type}*)') - } - if v.typ.share() == .shared_t { - af.write_string('&') - } - af.write_string(strings.repeat(`*`, v.typ.nr_muls() - 1)) // dereference if it is a pointer to a pointer - af.write_string(c_name(v.name)) - if v.typ.share() == .shared_t { - af.write_string('->val') - } - if v.typ.has_flag(.option) { - af.write_string('.data)') - } - - af.writeln('); // autofreed ptr var') - } else { - if v.typ == ast.error_type && !v.is_autofree_tmp { - return - } - if v.is_auto_heap { - af.writeln('\t${free_fn_name}(${c_name(v.name)}); // autofreed heap var ${g.cur_mod.name} ${g.is_builtin_mod}') - } else if v.typ.has_flag(.option) { - base_type := g.base_type(v.typ) - af.writeln('\tif (${c_name(v.name)}.state != 2) {') - af.writeln('\t\t${free_fn_name}((${base_type}*)${c_name(v.name)}.data); // autofreed option var ${g.cur_mod.name} ${g.is_builtin_mod}') - af.writeln('\t}') - } else { - af.writeln('\t${free_fn_name}(&${c_name(v.name)}); // autofreed var ${g.cur_mod.name} ${g.is_builtin_mod}') - } - } - g.autofree_scope_stmts << af.str() -} - fn (mut g Gen) map_fn_ptrs(key_typ ast.TypeSymbol) (string, string, string, string) { mut hash_fn := '' mut key_eq_fn := ''