From 14519bbf5c1b3825b08134768be3b83400b53417 Mon Sep 17 00:00:00 2001 From: Enzo Date: Wed, 9 Jun 2021 21:44:18 +0200 Subject: [PATCH] cgen: clean up interface methods generation (#10400) --- vlib/v/gen/c/cgen.v | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 84627eb058..d08ef499b4 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -6405,32 +6405,26 @@ fn (mut g Gen) interface_table() string { interface_name := ityp.cname // generate a struct that references interface methods methods_struct_name := 'struct _${interface_name}_interface_methods' - mut methods_typ_def := strings.new_builder(100) mut methods_struct_def := strings.new_builder(100) methods_struct_def.writeln('$methods_struct_name {') - mut imethods := map[string]string{} // a map from speak -> _Speaker_speak_fn mut methodidx := map[string]int{} for k, method in inter_info.methods { methodidx[method.name] = k - typ_name := '_${interface_name}_${method.name}_fn' ret_styp := g.typ(method.return_type) - methods_typ_def.write_string('typedef $ret_styp (*$typ_name)(void* _') + methods_struct_def.write_string('\t$ret_styp (*_method_${c_name(method.name)})(void* _') // the first param is the receiver, it's handled by `void*` above for i in 1 .. method.params.len { arg := method.params[i] - methods_typ_def.write_string(', ${g.typ(arg.typ)} $arg.name') + methods_struct_def.write_string(', ${g.typ(arg.typ)} $arg.name') } // TODO g.fn_args(method.args[1..], method.is_variadic) - methods_typ_def.writeln(');') - methods_struct_def.writeln('\t$typ_name _method_${c_name(method.name)};') - imethods[method.name] = typ_name + methods_struct_def.writeln(');') } methods_struct_def.writeln('};') // generate an array of the interface methods for the structs using the interface // as well as case functions from the struct to the interface mut methods_struct := strings.new_builder(100) // - mut staticprefix := 'static' iname_table_length := inter_info.types.len if iname_table_length == 0 { // msvc can not process `static struct x[0] = {};` @@ -6467,7 +6461,7 @@ fn (mut g Gen) interface_table() string { current_iinidx++ if ityp.name != 'vweb.DbInterface' { // TODO remove this // eprintln('>>> current_iinidx: ${current_iinidx-iinidx_minimum_base} | interface_index_name: $interface_index_name') - sb.writeln('$staticprefix $interface_name I_${cctype}_to_Interface_${interface_name}($cctype* x);') + sb.writeln('static $interface_name I_${cctype}_to_Interface_${interface_name}($cctype* x);') mut cast_struct := strings.new_builder(100) cast_struct.writeln('($interface_name) {') cast_struct.writeln('\t\t._$cctype = x,') @@ -6495,7 +6489,7 @@ fn (mut g Gen) interface_table() string { cast_functions.writeln(' // Casting functions for converting "$cctype" to interface "$interface_name" -$staticprefix inline $interface_name I_${cctype}_to_Interface_${interface_name}($cctype* x) { +static inline $interface_name I_${cctype}_to_Interface_${interface_name}($cctype* x) { return $cast_struct_str; }') } @@ -6504,7 +6498,7 @@ $staticprefix inline $interface_name I_${cctype}_to_Interface_${interface_name}( methods_struct.writeln('\t{') } for _, method in st_sym.methods { - if method.name !in imethods { + if method.name !in methodidx { // a method that is not part of the interface should be just skipped continue } @@ -6560,7 +6554,6 @@ $staticprefix inline $interface_name I_${cctype}_to_Interface_${interface_name}( sb.writeln('') if inter_info.methods.len > 0 { sb.writeln(methods_wrapper.str()) - sb.writeln(methods_typ_def.str()) sb.writeln(methods_struct_def.str()) sb.writeln(methods_struct.str()) }