diff --git a/vlib/v/gen/c/array.v b/vlib/v/gen/c/array.v index ab3f9e4d0c..0d485bc32c 100644 --- a/vlib/v/gen/c/array.v +++ b/vlib/v/gen/c/array.v @@ -20,7 +20,7 @@ fn (mut g Gen) array_init(node ast.ArrayInit) { shared_styp = g.typ(shared_typ) g.writeln('($shared_styp*)__dup_shared_array(&($shared_styp){.val = ') } else if is_amp { - g.write('($styp*)memdup(ADDR($styp, ') + g.write('HEAP($styp, ') } if type_sym.kind == .array_fixed { g.write('{') @@ -95,7 +95,7 @@ fn (mut g Gen) array_init(node ast.ArrayInit) { if g.is_shared { g.write('}, sizeof($shared_styp))') } else if is_amp { - g.write('), sizeof($styp))') + g.write(')') } return } diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 97188053aa..831f71e912 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -1599,16 +1599,18 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw table.Type, expected_t && !expected_type.has_flag(.optional) { got_styp := g.cc_type(got_type, true) exp_styp := g.cc_type(expected_type, true) - g.write('I_${got_styp}_to_Interface_$exp_styp') - if expected_type.is_ptr() { - g.write('_ptr') + if expected_is_ptr { + g.write('HEAP($exp_styp, ') } - g.write('(') - if !got_type.is_ptr() { + g.write('I_${got_styp}_to_Interface_${exp_styp}(') + if !got_is_ptr { g.write('&') } g.expr(expr) g.write(')') + if expected_is_ptr { + g.write(')') + } return } // cast to sum type @@ -1638,19 +1640,19 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw table.Type, expected_t } else { g.write_sumtype_casting_fn(got_type, expected_type) if expected_is_ptr { - g.write('memdup(&($exp_sym.cname[]){') + g.write('HEAP($exp_sym.cname, ') } g.write('${got_sym.cname}_to_sumtype_${exp_sym.cname}(') if !got_is_ptr { - g.write('(&(($got_styp[]){') + g.write('ADDR($got_styp, (') g.expr(expr) - g.write('}[0])))') + g.write(')))') } else { g.expr(expr) g.write(')') } if expected_is_ptr { - g.write('}, sizeof($exp_sym.cname))') + g.write(')') } } return @@ -5846,7 +5848,6 @@ fn (mut g Gen) interface_table() string { current_iinidx++ // 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('$staticprefix $interface_name* I_${cctype}_to_Interface_${interface_name}_ptr($cctype* x);') mut cast_struct := strings.new_builder(100) cast_struct.writeln('($interface_name) {') cast_struct.writeln('\t\t._object = (void*) (x),') @@ -5876,11 +5877,6 @@ fn (mut g Gen) interface_table() string { // Casting functions for converting "$cctype" to interface "$interface_name" $staticprefix inline $interface_name I_${cctype}_to_Interface_${interface_name}($cctype* x) { return $cast_struct_str; -} - -$staticprefix $interface_name* I_${cctype}_to_Interface_${interface_name}_ptr($cctype* x) { - // TODO Remove memdup - return ($interface_name*) memdup(&$cast_struct_str, sizeof($interface_name)); }') if g.pref.build_mode != .build_module { diff --git a/vlib/v/gen/c/cheaders.v b/vlib/v/gen/c/cheaders.v index e549e06394..8d51ada843 100644 --- a/vlib/v/gen/c/cheaders.v +++ b/vlib/v/gen/c/cheaders.v @@ -295,6 +295,8 @@ static void* g_live_info = NULL; #define _SLIT(s) ((string){.str=(byteptr)("" s), .len=(sizeof(s)-1), .is_lit=1}) // take the address of an rvalue #define ADDR(type, expr) (&((type[]){expr}[0])) +// copy something to the heap +#define HEAP(type, expr) ((type*)memdup((void*)&((type[]){expr}[0]), sizeof(type))) #define _PUSH_MANY(arr, val, tmp, tmp_typ) {tmp_typ tmp = (val); array_push_many(arr, tmp.data, tmp.len);} #define _IN_MAP(val, m) map_exists_1(m, val)