1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

checker/cgen: auto initialize shared elements of structs (#9669)

This commit is contained in:
Uwe Krüger 2021-04-11 09:30:23 +02:00 committed by GitHub
parent 3241611871
commit 954c436d28
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 63 additions and 6 deletions

View File

@ -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 { if field.has_default_expr || field.name in inited_fields {
continue 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', c.error('reference field `${type_sym.name}.$field.name` must be initialized',
struct_init.pos) struct_init.pos)
} }

View File

@ -5743,23 +5743,36 @@ fn (mut g Gen) type_default(typ_ ast.Type) string {
return '{0}' return '{0}'
} }
// Always set pointers to 0 // Always set pointers to 0
if typ.is_ptr() { if typ.is_ptr() && !typ.has_flag(.shared_f) {
return '0' return '0'
} }
sym := g.table.get_type_symbol(typ) sym := g.table.get_type_symbol(typ)
if sym.kind == .array { 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) mut elem_type_str := util.no_dots(elem_sym)
if elem_type_str.starts_with('C__') { if elem_type_str.starts_with('C__') {
elem_type_str = elem_type_str[3..] 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 { if sym.kind == .map {
info := sym.map_info() info := sym.map_info()
key_typ := g.table.get_type_symbol(info.key_type) 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) 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. // User struct defined in another module.
// if typ.contains('__') { // if typ.contains('__') {
@ -5786,7 +5799,12 @@ fn (mut g Gen) type_default(typ_ ast.Type) string {
} else { } else {
init_str += '0}' 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 // if typ.ends_with('Fn') { // TODO
// return '0' // return '0'

View File

@ -8,6 +8,18 @@ struct Abc {
i int 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() { fn test_shared_struct_in_struct() {
shared y := Xyz{ shared y := Xyz{
n: 7 n: 7
@ -50,6 +62,20 @@ struct Efg {
i int 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() { fn test_shared_array_in_struct() {
x := Efg{ x := Efg{
a: [1.25, 2.75, 7, 13.0625] a: [1.25, 2.75, 7, 13.0625]
@ -76,6 +102,18 @@ struct Hjk {
i int 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() { fn test_shared_map_in_struct() {
x := Hjk{ x := Hjk{
m: map{ m: map{