diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index 1ad4e29b1b..4127620428 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -1995,6 +1995,14 @@ fn (mut g Gen) const_decl(node ast.ConstDecl) { ast.IntegerLiteral { g.const_decl_simple_define(name, val) } + ast.ArrayInit { + if it.is_fixed { + styp := g.typ(it.typ) + g.definitions.writeln('$styp _const_$name = $val; // fixed array const') + } else { + g.const_decl_init_later(name, val, field.typ) + } + } ast.StringLiteral { g.definitions.writeln('string _const_$name; // a string literal, inited later') if g.pref.build_mode != .build_module { @@ -2002,11 +2010,7 @@ fn (mut g Gen) const_decl(node ast.ConstDecl) { } } else { - // Initialize more complex consts in `void _vinit(){}` - // (C doesn't allow init expressions that can't be resolved at compile time). - styp := g.typ(field.typ) - g.definitions.writeln('$styp _const_$name; // inited later') - g.inits.writeln('\t_const_$name = $val;') + g.const_decl_init_later(name, val, field.typ) } } } @@ -2021,6 +2025,14 @@ fn (mut g Gen) const_decl_simple_define(name, val string) { g.definitions.writeln(val) } +fn (mut g Gen) const_decl_init_later(name, val string, typ table.Type) { + // Initialize more complex consts in `void _vinit(){}` + // (C doesn't allow init expressions that can't be resolved at compile time). + styp := g.typ(typ) + g.definitions.writeln('$styp _const_$name; // inited later') + g.inits.writeln('\t_const_$name = $val;') +} + fn (mut g Gen) struct_init(struct_init ast.StructInit) { mut info := &table.Struct{} mut is_struct := false @@ -2172,7 +2184,6 @@ fn (mut g Gen) write_init_function() { } } - const ( builtins = ['string', 'array', 'KeyValue', 'DenseArray', 'map', 'Option'] ) @@ -2377,7 +2388,8 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) { // only floats should have precision specifier if fields.len > 2 || fields.len == 2 && !(node.expr_types[i].is_float()) || node.expr_types[i].is_signed() && !(fspec in [`d`, `c`, `x`, `X`, `o`]) || node.expr_types[i].is_unsigned() && !(fspec in [`u`, - `x`, `X`, `o`, `c`]) || node.expr_types[i].is_float() && !(fspec in [`E`, `F`, `G`, `e`, `f`, + `x`, `X`, `o`, `c`]) || node.expr_types[i].is_float() && !(fspec in [`E`, `F`, `G`, + `e`, `f`, `g`, `e`]) { verror('illegal format specifier ${fspec:c} for type ${g.table.get_type_name(node.expr_types[i])}') } @@ -3374,9 +3386,9 @@ fn (v &Gen) interface_table() string { // Speaker_Cat_index = 0 interface_index_name := '_${interface_name}_${ptr_ctype}_index' generated_casting_functions += ' -${interface_name} I_${cctype}_to_${interface_name}(${cctype} x) { +${interface_name} I_${cctype}_to_${interface_name}(${cctype}* x) { return (${interface_name}){ - ._object = (void*) memdup(&x, sizeof(${cctype})), + ._object = (void*) memdup(x, sizeof(${cctype})), ._interface_idx = ${interface_index_name} }; } ' @@ -3470,4 +3482,7 @@ fn (g &Gen) interface_call(typ, interface_type table.Type) { interface_styp := g.typ(interface_type).replace('*', '') styp := g.typ(typ).replace('*', '') g.write('I_${styp}_to_${interface_styp}(') + if !typ.is_ptr() { + g.write('&') + } } diff --git a/vlib/v/gen/fn.v b/vlib/v/gen/fn.v index d930140cf0..5d89faf61e 100644 --- a/vlib/v/gen/fn.v +++ b/vlib/v/gen/fn.v @@ -559,12 +559,12 @@ fn (mut g Gen) call_args(args []ast.CallArg, expected_types []table.Type) { fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type table.Type) { arg_is_ptr := expected_type.is_ptr() || expected_type.idx() in table.pointer_type_idxs expr_is_ptr := arg.typ.is_ptr() || arg.typ.idx() in table.pointer_type_idxs + exp_sym := g.table.get_type_symbol(expected_type) if arg.is_mut && !arg_is_ptr { g.write('&/*mut*/') } else if arg_is_ptr && !expr_is_ptr { if arg.is_mut { - sym := g.table.get_type_symbol(expected_type) - if sym.kind == .array { + if exp_sym.kind == .array { // Special case for mutable arrays. We can't `&` function // results, have to use `(array[]){ expr }[0]` hack. g.write('&/*111*/(array[]){') @@ -576,7 +576,7 @@ fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type table.Type) { if !g.is_json_fn { g.write('&/*qq*/') } - } else if !arg_is_ptr && expr_is_ptr { + } else if !arg_is_ptr && expr_is_ptr && exp_sym.kind != .interface_ { // Dereference a pointer if a value is required g.write('*/*d*/') }