Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
felipensp committed Nov 25, 2024
1 parent e91a370 commit 0ce4ebb
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 39 deletions.
33 changes: 23 additions & 10 deletions vlib/v/gen/c/array.v
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ fn (mut g Gen) fixed_array_init(node ast.ArrayInit, array_type Type, var_name st
g.set_current_pos_as_last_stmt_pos()
return
}
if g.inside_struct_init && g.inside_cast {
if g.inside_struct_init && g.inside_cast && !g.inside_memset {
ret_typ_str := g.styp(node.typ)
g.write('(${ret_typ_str})')
}
Expand All @@ -158,7 +158,7 @@ fn (mut g Gen) fixed_array_init(node ast.ArrayInit, array_type Type, var_name st
} else if elem_sym.kind == .array_fixed && expr is ast.CallExpr
&& g.table.final_sym(expr.return_type).kind == .array_fixed {
elem_info := elem_sym.array_fixed_info()
tmp_var := g.expr_with_var(expr, node.expr_types[i])
tmp_var := g.expr_with_var(expr, node.expr_types[i], false)
g.fixed_array_var_init(tmp_var, false, elem_info.elem_type, elem_info.size)
} else {
if expr.is_auto_deref_var() {
Expand Down Expand Up @@ -1650,22 +1650,35 @@ fn (mut g Gen) fixed_array_init_with_cast(expr ast.ArrayInit, typ ast.Type) {
}

fn (mut g Gen) fixed_array_update_expr_field(expr_str string, field_type ast.Type, field_name string, is_auto_deref bool, elem_type ast.Type, size int) {
elem_sym := g.table.sym(elem_type)
if !g.inside_array_fixed_struct {
g.write('{')
defer {
g.write('}')
}
}
for i in 0 .. size {
g.write(expr_str)
if field_type.is_ptr() {
g.write('->')
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}]'
}
g.fixed_array_update_expr_field(init_str, field_type, field_name, is_auto_deref,
elem_sym.info.elem_type, elem_sym.info.size)
} else {
g.write('.')
}
g.write(c_name(field_name))
if !expr_str.starts_with('(') && !expr_str.starts_with('{') {
g.write('[${i}]')
g.write(expr_str)
if !expr_str.ends_with(']') {
if field_type.is_ptr() {
g.write('->')
} else {
g.write('.')
}
g.write(c_name(field_name))
}
if !expr_str.starts_with('(') && !expr_str.starts_with('{') {
g.write('[${i}]')
}
}
if i != size - 1 {
g.write(', ')
Expand Down
31 changes: 28 additions & 3 deletions vlib/v/gen/c/cgen.v
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ mut:
inside_for_c_stmt bool
inside_cast_in_heap int // inside cast to interface type in heap (resolve recursive calls)
inside_cast bool
inside_memset bool
inside_const bool
inside_array_item bool
inside_const_opt_or_res bool
Expand Down Expand Up @@ -1626,6 +1627,7 @@ static inline void __${sym.cname}_pushval(${sym.cname} ch, ${push_arg} val) {
}

pub fn (mut g Gen) write_alias_typesymbol_declaration(sym ast.TypeSymbol) {
mut levels := 0
parent := g.table.type_symbols[sym.parent_idx]
is_c_parent := parent.name.len > 2 && parent.name[0] == `C` && parent.name[1] == `.`
mut is_fixed_array_of_non_builtin := false
Expand All @@ -1639,18 +1641,38 @@ pub fn (mut g Gen) write_alias_typesymbol_declaration(sym ast.TypeSymbol) {
parent_styp = g.styp(sym.info.parent_type)
parent_sym := g.table.sym(sym.info.parent_type)
if parent_sym.info is ast.ArrayFixed {
elem_sym := g.table.sym(parent_sym.info.elem_type)
mut elem_sym := g.table.sym(parent_sym.info.elem_type)
if !elem_sym.is_builtin() {
is_fixed_array_of_non_builtin = true
}

mut parent_elem_info := parent_sym.info as ast.ArrayFixed
mut parent_elem_styp := g.styp(sym.info.parent_type)
mut out := ''
for {
if mut elem_sym.info is ast.ArrayFixed {
out =
'typedef ${elem_sym.cname} ${parent_elem_styp} [${parent_elem_info.size}]; //\n' +
out
parent_elem_styp = elem_sym.cname
parent_elem_info = elem_sym.info as ast.ArrayFixed
elem_sym = g.table.sym(elem_sym.info.elem_type)
levels++
} else {
break
}
}
if out != '' {
g.type_definitions.writeln(out)
}
}
}
}
if parent_styp == 'byte' && sym.cname == 'u8' {
// TODO: remove this check; it is here just to fix V rebuilding in -cstrict mode with clang-12
return
}
if is_fixed_array_of_non_builtin {
if is_fixed_array_of_non_builtin && levels == 0 {
g.alias_definitions.writeln('typedef ${parent_styp} ${sym.cname};')
} else {
g.type_definitions.writeln('typedef ${parent_styp} ${sym.cname};')
Expand Down Expand Up @@ -2557,14 +2579,17 @@ fn (mut g Gen) call_cfn_for_casting_expr(fname string, expr ast.Expr, exp_is_ptr
}

// use instead of expr() when you need a var to use as reference
fn (mut g Gen) expr_with_var(expr ast.Expr, expected_type ast.Type) string {
fn (mut g Gen) expr_with_var(expr ast.Expr, expected_type ast.Type, do_cast bool) string {
stmt_str := g.go_before_last_stmt().trim_space()
g.empty_line = true
tmp_var := g.new_tmp_var()
styp := g.styp(expected_type)

g.writeln('${styp} ${tmp_var};')
g.write('memcpy(&${tmp_var}, ')
if do_cast {
g.write('(${styp})')
}
g.expr(expr)
g.writeln(', sizeof(${styp}));')
g.write(stmt_str)
Expand Down
7 changes: 3 additions & 4 deletions vlib/v/gen/c/infix.v
Original file line number Diff line number Diff line change
Expand Up @@ -1029,11 +1029,10 @@ fn (mut g Gen) infix_expr_left_shift_op(node ast.InfixExpr) {
}
if node.right is ast.CastExpr && node.right.expr is ast.ArrayInit {
g.expr(node.right.expr)
} else if elem_sym.kind == .array_fixed
} else if elem_sym.info is ast.ArrayFixed
&& node.right in [ast.CallExpr, ast.DumpExpr] {
info := elem_sym.info as ast.ArrayFixed
tmpvar := g.expr_with_var(node.right, array_info.elem_type)
g.fixed_array_var_init(tmpvar, false, info.elem_type, info.size)
tmpvar := g.expr_with_var(node.right, array_info.elem_type, false)
g.fixed_array_var_init(tmpvar, false, elem_sym.info.elem_type, elem_sym.info.size)
} else {
g.expr_with_cast(node.right, right.typ, array_info.elem_type)
}
Expand Down
27 changes: 8 additions & 19 deletions vlib/v/gen/c/struct.v
Original file line number Diff line number Diff line change
Expand Up @@ -471,23 +471,11 @@ fn (mut g Gen) zero_struct_field(field ast.StructField) bool {
tmp_var)
return true
} else if final_sym.info is ast.ArrayFixed && field.default_expr !is ast.ArrayInit {
tmp_var := g.new_tmp_var()
s := g.go_before_last_stmt()
g.empty_line = true
styp := g.styp(field.typ)
g.writeln('${styp} ${tmp_var} = {0};')
g.write('memcpy(${tmp_var}, ')
g.expr(field.default_expr)
g.writeln(', sizeof(${styp}));')
g.empty_line = false
g.write2(s, '{')
for i in 0 .. final_sym.info.size {
g.write('${tmp_var}[${i}]')
if i != final_sym.info.size - 1 {
g.write(', ')
}
}
g.write('}')
old_inside_memset := g.inside_memset
g.inside_memset = true
tmp_var := g.expr_with_var(field.default_expr, field.default_expr_typ, true)
g.fixed_array_var_init(tmp_var, false, final_sym.info.elem_type, final_sym.info.size)
g.inside_memset = old_inside_memset
return true
}
g.expr(field.default_expr)
Expand Down Expand Up @@ -696,13 +684,14 @@ fn (mut g Gen) struct_init_field(sfield ast.StructInitField, language ast.Langua
field_unwrap_sym.info.elem_type, field_unwrap_sym.info.size)
}
ast.CastExpr, ast.CallExpr {
tmp_var := g.expr_with_var(sfield.expr, sfield.expected_type)
tmp_var := g.expr_with_var(sfield.expr, sfield.expected_type, false)
g.fixed_array_var_init(tmp_var, false, field_unwrap_sym.info.elem_type,
field_unwrap_sym.info.size)
}
ast.ArrayInit {
if sfield.expr.has_index {
tmp_var := g.expr_with_var(sfield.expr, sfield.expected_type)
tmp_var := g.expr_with_var(sfield.expr, sfield.expected_type,
false)
g.fixed_array_var_init(tmp_var, false, field_unwrap_sym.info.elem_type,
field_unwrap_sym.info.size)
} else if sfield.expr.has_callexpr {
Expand Down
10 changes: 7 additions & 3 deletions vlib/v/tests/fixed_array_update_expr_test.v
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module main

type Mat4 = [3]f32
type Mat22 = [2][2]f32
type Mat4 = [4]f32

@[heap]
struct Game {
Expand All @@ -11,7 +12,8 @@ mut:
@[heap]
struct GameObject {
mut:
transform Mat4 = Mat4([f32(1), 2, 3]!)
transform Mat22 = Mat22([[f32(1), 2]!, [f32(3), 4]!]!)
transform2 Mat4 = Mat4([f32(1), 2, 3, 4]!)
}

fn (mut gameobject GameObject) instance() &GameObject {
Expand All @@ -23,5 +25,7 @@ fn (mut gameobject GameObject) instance() &GameObject {
fn test_main() {
mut v := GameObject{}
mut v2 := v.instance()
assert v2.transform == Mat4([f32(1), 2, 3]!)
dump(v)
assert v2.transform == Mat22([[f32(1), 2]!, [f32(3), 4]!]!)
assert v2.transform2 == Mat4([f32(1), 2, 3, 4]!)
}

0 comments on commit 0ce4ebb

Please sign in to comment.