Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
felipensp committed Oct 17, 2024
1 parent 7da79fd commit 695dcb2
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 5 deletions.
11 changes: 7 additions & 4 deletions vlib/v/gen/c/assign.v
Original file line number Diff line number Diff line change
Expand Up @@ -723,10 +723,13 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
g.write(', ')
}
mut cloned := false
if g.is_autofree && right_sym.kind in [.array, .string]
&& !unwrapped_val_type.has_flag(.shared_f) {
if g.gen_clone_assignment(var_type, val, unwrapped_val_type, false) {
cloned = true
if g.is_autofree {
if right_sym.kind in [.array, .string] && !unwrapped_val_type.has_flag(.shared_f) {
if g.gen_clone_assignment(var_type, val, unwrapped_val_type, false) {
cloned = true
}
} else if right_sym.kind == .interface {
g.get_free_method(var_type)
}
}
if !cloned {
Expand Down
28 changes: 27 additions & 1 deletion vlib/v/gen/c/auto_free_methods.v
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ fn (mut g Gen) gen_free_method(typ ast.Type) string {
sym = g.table.sym(sym.info.parent_type)
}
}
if sym.has_method_with_generic_parent('free') {
if sym.kind != .interface && sym.has_method_with_generic_parent('free') {
return fn_name
}

Expand All @@ -57,6 +57,9 @@ fn (mut g Gen) gen_free_method(typ ast.Type) string {
ast.Map {
g.gen_free_for_map(objtyp, sym.info, styp, fn_name)
}
ast.Interface {
g.gen_free_for_interface(sym, sym.info, styp, fn_name)
}
else {
println(g.table.type_str(typ))
// print_backtrace()
Expand All @@ -67,6 +70,29 @@ fn (mut g Gen) gen_free_method(typ ast.Type) string {
return fn_name
}

fn (mut g Gen) gen_free_for_interface(sym ast.TypeSymbol, info ast.Interface, styp string, fn_name string) {
g.definitions.writeln('${g.static_modifier} void ${fn_name}(${styp}* it); // auto')
mut fn_builder := strings.new_builder(128)
defer {
g.auto_fn_definitions << fn_builder.str()
}
fn_builder.writeln('${g.static_modifier} void ${fn_name}(${styp}* it) {')
fn_builder.writeln('\tswitch (it->_typ) {')
for t in info.types {
sub_sym := g.table.sym(ast.mktyp(t))
if sub_sym.kind !in [.string, .array, .map, .struct] {
continue
}
fn_name_typ := g.get_free_method(t)
fn_builder.writeln('\t\tcase _${sym.cname}_${sub_sym.cname}_index:')
fn_builder.writeln('\t\t\t${fn_name_typ}(it);')
fn_builder.writeln('\t\t\tbreak;')
}
fn_builder.writeln('\t\tdefault:')
fn_builder.writeln('\t}')
fn_builder.writeln('}')
}

fn (mut g Gen) gen_free_for_struct(typ ast.Type, info ast.Struct, styp string, fn_name string) {
g.definitions.writeln('${g.static_modifier} void ${fn_name}(${styp}* it); // auto')
mut fn_builder := strings.new_builder(128)
Expand Down
20 changes: 20 additions & 0 deletions vlib/v/gen/c/testdata/interface_auto_free.c.must_have
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
void main__IFoo_free(main__IFoo* it) {
switch (it->_typ) {
case _main__IFoo_main__Foo_index:
main__Foo_free(it);
break;
case _main__IFoo_array_index:
array_free(it);
break;
case _main__IFoo_map_index:
map_free(it);
break;
case _main__IFoo_VAssertMetaInfo_index:
VAssertMetaInfo_free(it);
break;
case _main__IFoo_MessageError_index:
MessageError_free(it);
break;
default:
}
}
20 changes: 20 additions & 0 deletions vlib/v/gen/c/testdata/interface_auto_free.vv
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// vtest vflags: -autofree
module main

interface IFoo {
free()
}

struct Bar {
a int
}

struct Foo implements IFoo {
Bar
}

fn (f &Foo) free() {}

fn main() {
a := IFoo(Foo{})
}

0 comments on commit 695dcb2

Please sign in to comment.