From 1c992de86d2a4bf8fedde859decaed494c7bef0d Mon Sep 17 00:00:00 2001 From: yuyi Date: Thu, 12 Sep 2024 00:33:48 +0800 Subject: [PATCH] cgen: fix array of fns index call with embeded array index (fix #17381) (#22198) --- vlib/v/gen/c/index.v | 7 +- ..._index_call_with_embeded_array_call_test.v | 64 +++++++++++++++++++ 2 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 vlib/v/tests/builtin_arrays/array_of_fns_index_call_with_embeded_array_call_test.v diff --git a/vlib/v/gen/c/index.v b/vlib/v/gen/c/index.v index dbae0a9d881f01..7f86fb36a15c54 100644 --- a/vlib/v/gen/c/index.v +++ b/vlib/v/gen/c/index.v @@ -234,6 +234,7 @@ fn (mut g Gen) index_of_array(node ast.IndexExpr, sym ast.TypeSymbol) { } } else { is_direct_array_access := g.is_direct_array_access || node.is_direct + is_fn_index_call := g.is_fn_index_call && elem_sym.info is ast.FnType // do not clone inside `opt_ok(opt_ok(&(string[]) {..})` before returns needs_clone := info.elem_type == ast.string_type_idx && g.is_autofree && !(g.inside_return && g.fn_decl != unsafe { nil } && g.fn_decl.return_type.has_flag(.option)) @@ -257,7 +258,7 @@ fn (mut g Gen) index_of_array(node ast.IndexExpr, sym ast.TypeSymbol) { if needs_clone { g.write('/*2*/string_clone(') } - if g.is_fn_index_call { + if is_fn_index_call { if elem_sym.info is ast.FnType { g.write('((') g.write_fn_ptr_decl(&elem_sym.info, '') @@ -297,13 +298,13 @@ fn (mut g Gen) index_of_array(node ast.IndexExpr, sym ast.TypeSymbol) { g.write('data)[') g.expr(node.index) g.write(']') - if g.is_fn_index_call { + if is_fn_index_call { g.write(')') } } else { g.write(', ') g.expr(node.index) - if g.is_fn_index_call { + if is_fn_index_call { g.write(')))') } else { g.write('))') diff --git a/vlib/v/tests/builtin_arrays/array_of_fns_index_call_with_embeded_array_call_test.v b/vlib/v/tests/builtin_arrays/array_of_fns_index_call_with_embeded_array_call_test.v new file mode 100644 index 00000000000000..e7f7ad56d13203 --- /dev/null +++ b/vlib/v/tests/builtin_arrays/array_of_fns_index_call_with_embeded_array_call_test.v @@ -0,0 +1,64 @@ +fn max_speed(functions []fn (int) int, g fn (int) int, end_time int) int { + mut s := [0] + mut gears := []int{len: end_time, init: 0} + + for t in 0 .. end_time { + stay_in_gear_speed := if t - 1 >= 0 { functions[gears[t - 1]](s[t - 1]) } else { 0 } + shift_gear_speed := if t - 2 >= 0 { functions[gears[t - 2] + 1](g(s[t - 2])) } else { 0 } + if stay_in_gear_speed > shift_gear_speed { + gears[t] = if t - 1 >= 0 { gears[t - 1] } else { 0 } + s << stay_in_gear_speed + } else { + gears[t] = if t - 2 >= 0 { gears[t - 2] } else { 0 } + 1 + s << shift_gear_speed + } + } + return s[end_time] +} + +@[direct_array_access] +fn max_speed_direct_access(functions []fn (int) int, g fn (int) int, end_time int) int { + mut s := [0] + mut gears := []int{len: end_time, init: 0} + + for t in 0 .. end_time { + stay_in_gear_speed := if t - 1 >= 0 { functions[gears[t - 1]](s[t - 1]) } else { 0 } + shift_gear_speed := if t - 2 >= 0 { functions[gears[t - 2] + 1](g(s[t - 2])) } else { 0 } + if stay_in_gear_speed > shift_gear_speed { + gears[t] = if t - 1 >= 0 { gears[t - 1] } else { 0 } + s << stay_in_gear_speed + } else { + gears[t] = if t - 2 >= 0 { gears[t - 2] } else { 0 } + 1 + s << shift_gear_speed + } + } + return s[end_time] +} + +fn first_gear(speed int) int { + return speed + 1 +} + +fn second_gear(speed int) int { + return speed + 1 +} + +fn third_gear(speed int) int { + return speed + 1 +} + +fn decelerate(speed int) int { + return speed - 3 +} + +fn test_array_of_fns_index_call_with_embeded_array_call() { + funcs := [first_gear, second_gear, third_gear] + + speed1 := max_speed(funcs, decelerate, 3) + println(speed1) + assert speed1 == 1 + + speed2 := max_speed_direct_access(funcs, decelerate, 3) + println(speed2) + assert speed2 == 1 +}