Skip to content

Commit

Permalink
cgen: fix update expr with embed fixed array with multiple dimensions (
Browse files Browse the repository at this point in the history
  • Loading branch information
felipensp authored Dec 3, 2024
1 parent 8960765 commit d3b5dbd
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 32 deletions.
26 changes: 8 additions & 18 deletions vlib/v/gen/c/array.v
Original file line number Diff line number Diff line change
Expand Up @@ -1657,12 +1657,17 @@ fn (mut g Gen) fixed_array_update_expr_field(expr_str string, field_type ast.Typ
g.write('}')
}
}
embed_field := if is_update_embed {
g.get_embed_field_name(field_type, field_name)
} else {
''
}
for i in 0 .. size {
if elem_sym.info is ast.ArrayFixed {
init_str := if g.inside_array_fixed_struct {
'${expr_str}'
} else {
'${expr_str}->${c_name(field_name)}[${i}]'
'${expr_str}->${embed_field}${c_name(field_name)}[${i}]'
}
g.fixed_array_update_expr_field(init_str, field_type, field_name, is_auto_deref,
elem_sym.info.elem_type, elem_sym.info.size, is_update_embed)
Expand All @@ -1675,26 +1680,11 @@ fn (mut g Gen) fixed_array_update_expr_field(expr_str string, field_type ast.Typ
g.write('.')
}
if is_update_embed {
update_sym := g.table.sym(field_type)
_, embeds := g.table.find_field_from_embeds(update_sym, field_name) or {
ast.StructField{}, []ast.Type{}
}
for embed in embeds {
esym := g.table.sym(embed)
ename := esym.embed_name()
g.write(ename)
if embed.is_ptr() {
g.write('->')
} else {
g.write('.')
}
}
g.write(embed_field)
}
g.write(c_name(field_name))
}
if !expr_str.starts_with('(') && !expr_str.starts_with('{') {
g.write('[${i}]')
}
g.write('[${i}]')
}
if i != size - 1 {
g.write(', ')
Expand Down
33 changes: 19 additions & 14 deletions vlib/v/gen/c/struct.v
Original file line number Diff line number Diff line change
Expand Up @@ -326,20 +326,7 @@ fn (mut g Gen) struct_init(node ast.StructInit) {
g.write('.')
}
if node.is_update_embed {
update_sym := g.table.sym(node.update_expr_type)
_, embeds := g.table.find_field_from_embeds(update_sym, field.name) or {
ast.StructField{}, []ast.Type{}
}
for embed in embeds {
esym := g.table.sym(embed)
ename := esym.embed_name()
g.write(ename)
if embed.is_ptr() {
g.write('->')
} else {
g.write('.')
}
}
g.write(g.get_embed_field_name(node.update_expr_type, field.name))
}
g.write(c_name(field.name))
}
Expand Down Expand Up @@ -402,6 +389,24 @@ fn (mut g Gen) struct_init(node ast.StructInit) {
}
}

fn (mut g Gen) get_embed_field_name(field_type ast.Type, field_name string) string {
update_sym := g.table.sym(field_type)
_, embeds := g.table.find_field_from_embeds(update_sym, field_name) or {
ast.StructField{}, []ast.Type{}
}
mut s := ''
for embed in embeds {
esym := g.table.sym(embed)
ename := esym.embed_name()
if embed.is_ptr() {
s += '${ename}->'
} else {
s += '${ename}.'
}
}
return s
}

fn (mut g Gen) zero_struct_field(field ast.StructField) bool {
old_inside_cast_in_heap := g.inside_cast_in_heap
g.inside_cast_in_heap = 0
Expand Down
48 changes: 48 additions & 0 deletions vlib/v/tests/fixed_array_2_dims_embed_test.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
module main

type Mat4 = [16]f32
type Mat14 = [1][16]f32

@[heap]
struct GameObject {
mut:
transform Mat4
transform2 Mat14
}

@[heap]
struct Ship {
GameObject
}

fn Ship.new() &Ship {
mut ship := &Ship{}
return ship
}

fn (mut ship Ship) clone() &Ship {
return &Ship{
...ship
}
}

fn test_main() {
mut v1 := Ship.new()
v1.transform[0] = 1.0
v1.transform[15] = 2.0
v1.transform2[0][0] = 1.0
v1.transform2[0][15] = 2.0
mut v2 := v1.clone()
eprintln('v1=${v1.transform}\nv2=${v2.transform}')
assert v1.transform == v2.transform
assert v1.transform2 == v2.transform2
assert v1.transform[0] == 1.0
assert v2.transform[0] == 1.0
assert v1.transform[15] == 2.0
assert v2.transform[15] == 2.0

assert v1.transform2[0][0] == 1.0
assert v2.transform2[0][0] == 1.0
assert v1.transform2[0][15] == 2.0
assert v2.transform2[0][15] == 2.0
}

0 comments on commit d3b5dbd

Please sign in to comment.