checker/cgen: auto initialize `shared` elements of structs (#9669)
parent
3241611871
commit
954c436d28
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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{
|
||||
|
|
Loading…
Reference in New Issue