diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 64fe23ccab..87da3dd193 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -646,7 +646,8 @@ pub fn (mut c Checker) struct_init(mut struct_init ast.StructInit) ast.Type { if field.has_default_expr || field.name in inited_fields { continue } - if field.typ.is_ptr() && !struct_init.has_update_expr && !c.pref.translated { + if field.typ.is_ptr() && !field.typ.has_flag(.shared_f) + && !struct_init.has_update_expr && !c.pref.translated { c.error('reference field `${type_sym.name}.$field.name` must be initialized', struct_init.pos) } diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 13b7797e90..bafbce455b 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -5743,23 +5743,36 @@ fn (mut g Gen) type_default(typ_ ast.Type) string { return '{0}' } // Always set pointers to 0 - if typ.is_ptr() { + if typ.is_ptr() && !typ.has_flag(.shared_f) { return '0' } sym := g.table.get_type_symbol(typ) if sym.kind == .array { - elem_sym := g.typ(sym.array_info().elem_type) + elem_typ := sym.array_info().elem_type + elem_sym := g.typ(elem_typ) mut elem_type_str := util.no_dots(elem_sym) if elem_type_str.starts_with('C__') { elem_type_str = elem_type_str[3..] } - return '__new_array(0, 1, sizeof($elem_type_str))' + init_str := '__new_array(0, 1, sizeof($elem_type_str))' + if typ.has_flag(.shared_f) { + atyp := '__shared__Array_${g.table.get_type_symbol(elem_typ).cname}' + return '($atyp*)__dup_shared_array(&($atyp){.val = $init_str}, sizeof($atyp))' + } else { + return init_str + } } if sym.kind == .map { info := sym.map_info() key_typ := g.table.get_type_symbol(info.key_type) hash_fn, key_eq_fn, clone_fn, free_fn := g.map_fn_ptrs(key_typ) - return 'new_map(sizeof(${g.typ(info.key_type)}), sizeof(${g.typ(info.value_type)}), $hash_fn, $key_eq_fn, $clone_fn, $free_fn)' + init_str := 'new_map(sizeof(${g.typ(info.key_type)}), sizeof(${g.typ(info.value_type)}), $hash_fn, $key_eq_fn, $clone_fn, $free_fn)' + if typ.has_flag(.shared_f) { + mtyp := '__shared__Map_${key_typ.cname}_${g.table.get_type_symbol(info.value_type).cname}' + return '($mtyp*)__dup_shared_map(&($mtyp){.val = $init_str}, sizeof($mtyp))' + } else { + return init_str + } } // User struct defined in another module. // if typ.contains('__') { @@ -5786,7 +5799,12 @@ fn (mut g Gen) type_default(typ_ ast.Type) string { } else { init_str += '0}' } - return init_str + if typ.has_flag(.shared_f) { + styp := '__shared__${g.table.get_type_symbol(typ).cname}' + return '($styp*)__dup${styp}(&($styp){.val = $init_str}, sizeof($styp))' + } else { + return init_str + } } // if typ.ends_with('Fn') { // TODO // return '0' diff --git a/vlib/v/tests/shared_elem_test.v b/vlib/v/tests/shared_elem_test.v index 671d42aec5..c2b10f6be0 100644 --- a/vlib/v/tests/shared_elem_test.v +++ b/vlib/v/tests/shared_elem_test.v @@ -8,6 +8,18 @@ struct Abc { i int } +fn test_shared_struct_auto_struct() { + e := Abc{} + shared a := e.a + lock a { + a.n = 17 + } + r := rlock a { + a.n + } + assert r == 17 +} + fn test_shared_struct_in_struct() { shared y := Xyz{ n: 7 @@ -50,6 +62,20 @@ struct Efg { i int } +fn test_shared_auto_init_array() { + e := Efg{} + shared a := e.a + lock a { + a << 23.0625 + a << -133.25 + a << 0.125 + } + r := rlock a { + a[1] + } + assert r == -133.25 +} + fn test_shared_array_in_struct() { x := Efg{ a: [1.25, 2.75, 7, 13.0625] @@ -76,6 +102,18 @@ struct Hjk { i int } +fn test_shared_auto_init_map() { + a := Hjk{} + shared m := a.m + lock m { + m['xcv'] = -31.125 + } + r := rlock m { + m['xcv'] + } + assert r == -31.125 +} + fn test_shared_map_in_struct() { x := Hjk{ m: map{