Skip to content

Commit ca48d7d

Browse files
authored
cgen: cache return_stmt()'s node.exprs[0] and node.types[0] (#23408)
1 parent d1d47d6 commit ca48d7d

1 file changed

Lines changed: 63 additions & 64 deletions

File tree

‎vlib/v/gen/c/cgen.v‎

Lines changed: 63 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -5521,11 +5521,14 @@ fn (mut g Gen) return_stmt(node ast.Return) {
55215521
g.inside_return = old_inside_return
55225522
}
55235523

5524+
expr0 := if node.exprs.len > 0 { node.exprs[0] } else { ast.empty_expr }
5525+
type0 := if node.exprs.len > 0 { node.types[0] } else { ast.void_type }
5526+
55245527
if node.exprs.len > 0 {
55255528
// skip `return $vweb.html()`
5526-
if node.exprs[0] is ast.ComptimeCall && node.exprs[0].is_vweb {
5529+
if expr0 is ast.ComptimeCall && expr0.is_vweb {
55275530
g.inside_return_tmpl = true
5528-
g.expr(node.exprs[0])
5531+
g.expr(expr0)
55295532
g.inside_return_tmpl = false
55305533
g.writeln(';')
55315534
return
@@ -5571,19 +5574,18 @@ fn (mut g Gen) return_stmt(node ast.Return) {
55715574
ret_typ := g.ret_styp(g.unwrap_generic(fn_ret_type))
55725575

55735576
// `return fn_call_opt()`
5574-
if node.exprs.len == 1 && (fn_return_is_option || fn_return_is_result)
5575-
&& node.exprs[0] is ast.CallExpr && node.exprs[0].return_type == g.fn_decl.return_type
5576-
&& node.exprs[0].or_block.kind == .absent {
5577+
if node.exprs.len == 1 && (fn_return_is_option || fn_return_is_result) && expr0 is ast.CallExpr
5578+
&& expr0.return_type == g.fn_decl.return_type && expr0.or_block.kind == .absent {
55775579
if g.defer_stmts.len > 0 {
55785580
g.write('${ret_typ} ${tmpvar} = ')
5579-
g.expr(node.exprs[0])
5581+
g.expr(expr0)
55805582
g.writeln(';')
55815583
g.write_defer_stmts_when_needed()
55825584
g.writeln('return ${tmpvar};')
55835585
} else {
55845586
g.write_defer_stmts_when_needed()
55855587
g.write('return ')
5586-
g.expr(node.exprs[0])
5588+
g.expr(expr0)
55875589
g.writeln(';')
55885590
}
55895591
return
@@ -5595,14 +5597,14 @@ fn (mut g Gen) return_stmt(node ast.Return) {
55955597
|| (fn_return_is_multi && node.types.any(g.table.final_sym(it).kind == .array_fixed))
55965598
// handle promoting none/error/function returning _option'
55975599
if fn_return_is_option {
5598-
option_none := node.exprs[0] is ast.None
5599-
ftyp := g.styp(node.types[0])
5600+
option_none := expr0 is ast.None
5601+
ftyp := g.styp(type0)
56005602
mut is_regular_option := ftyp == '_option'
5601-
if option_none || is_regular_option || node.types[0] == ast.error_type_idx {
5603+
if option_none || is_regular_option || type0 == ast.error_type_idx {
56025604
if g.fn_decl != unsafe { nil } && g.fn_decl.is_test {
56035605
test_error_var := g.new_tmp_var()
56045606
g.write('${ret_typ} ${test_error_var} = ')
5605-
g.gen_option_error(fn_ret_type, node.exprs[0])
5607+
g.gen_option_error(fn_ret_type, expr0)
56065608
g.writeln(';')
56075609
g.write_defer_stmts_when_needed()
56085610
g.gen_failing_return_error_for_test_fn(node, test_error_var)
@@ -5613,7 +5615,7 @@ fn (mut g Gen) return_stmt(node ast.Return) {
56135615
} else {
56145616
g.write('return ')
56155617
}
5616-
g.gen_option_error(fn_ret_type, node.exprs[0])
5618+
g.gen_option_error(fn_ret_type, expr0)
56175619
g.writeln(';')
56185620
if use_tmp_var {
56195621
// handle options when returning `none` for `?(int, ?int)`
@@ -5635,13 +5637,13 @@ fn (mut g Gen) return_stmt(node ast.Return) {
56355637
}
56365638
// handle promoting error/function returning result
56375639
if fn_return_is_result {
5638-
ftyp := g.styp(node.types[0])
5640+
ftyp := g.styp(type0)
56395641
mut is_regular_result := ftyp == result_name
5640-
if is_regular_result || node.types[0] == ast.error_type_idx {
5642+
if is_regular_result || type0 == ast.error_type_idx {
56415643
if g.fn_decl != unsafe { nil } && g.fn_decl.is_test {
56425644
test_error_var := g.new_tmp_var()
56435645
g.write('${ret_typ} ${test_error_var} = ')
5644-
g.gen_result_error(fn_ret_type, node.exprs[0])
5646+
g.gen_result_error(fn_ret_type, expr0)
56455647
g.writeln(';')
56465648
g.write_defer_stmts_when_needed()
56475649
g.gen_failing_return_error_for_test_fn(node, test_error_var)
@@ -5652,7 +5654,7 @@ fn (mut g Gen) return_stmt(node ast.Return) {
56525654
} else {
56535655
g.write('return ')
56545656
}
5655-
g.gen_result_error(fn_ret_type, node.exprs[0])
5657+
g.gen_result_error(fn_ret_type, expr0)
56565658
g.writeln(';')
56575659
if use_tmp_var {
56585660
g.write_defer_stmts_when_needed()
@@ -5662,11 +5664,11 @@ fn (mut g Gen) return_stmt(node ast.Return) {
56625664
}
56635665
}
56645666
// regular cases
5665-
if fn_return_is_multi && node.exprs.len > 0 && !g.expr_is_multi_return_call(node.exprs[0]) {
5666-
if node.exprs.len == 1 && (node.exprs[0] is ast.IfExpr || node.exprs[0] is ast.MatchExpr) {
5667+
if fn_return_is_multi && node.exprs.len > 0 && !g.expr_is_multi_return_call(expr0) {
5668+
if node.exprs.len == 1 && (expr0 is ast.IfExpr || expr0 is ast.MatchExpr) {
56675669
// use a temporary for `return if cond { x,y } else { a,b }` or `return match expr { abc { x, y } else { z, w } }`
56685670
g.write('${ret_typ} ${tmpvar} = ')
5669-
g.expr(node.exprs[0])
5671+
g.expr(expr0)
56705672
g.writeln(';')
56715673
g.write_defer_stmts_when_needed()
56725674
g.writeln('return ${tmpvar};')
@@ -5786,30 +5788,29 @@ fn (mut g Gen) return_stmt(node ast.Return) {
57865788
node.pos)
57875789
}
57885790
// normal return
5789-
return_sym := g.table.final_sym(g.unwrap_generic(node.types[0]))
5790-
expr0 := node.exprs[0]
5791+
return_sym := g.table.final_sym(g.unwrap_generic(type0))
57915792
// `return opt_ok(expr)` for functions that expect an option
57925793
expr_type_is_opt := match expr0 {
57935794
ast.CallExpr {
57945795
expr0.return_type.has_flag(.option) && expr0.or_block.kind == .absent
57955796
}
57965797
else {
5797-
node.types[0].has_flag(.option)
5798+
type0.has_flag(.option)
57985799
}
57995800
}
58005801
if fn_return_is_option && !expr_type_is_opt && return_sym.name != option_name {
58015802
if fn_return_is_fixed_array && (expr0 in [ast.StructInit, ast.CallExpr, ast.CastExpr]
58025803
|| (expr0 is ast.ArrayInit && expr0.has_callexpr))
5803-
&& g.table.final_sym(node.types[0]).kind == .array_fixed {
5804+
&& g.table.final_sym(type0).kind == .array_fixed {
58045805
styp := g.styp(fn_ret_type.clear_option_and_result())
58055806
if expr0 is ast.CallExpr {
5806-
tmp_var := g.expr_with_fixed_array(expr0, node.types[0], fn_ret_type)
5807+
tmp_var := g.expr_with_fixed_array(expr0, type0, fn_ret_type)
58075808
g.writeln('${ret_typ} ${tmpvar} = ${tmp_var};')
58085809
} else {
58095810
g.writeln('${ret_typ} ${tmpvar} = (${ret_typ}){ .state=0, .err=_const_none__, .data={EMPTY_STRUCT_INITIALIZATION} };')
58105811
if expr0 is ast.StructInit {
58115812
g.write('memcpy(${tmpvar}.data, ')
5812-
tmp_var := g.expr_with_opt(expr0, node.types[0], fn_ret_type)
5813+
tmp_var := g.expr_with_opt(expr0, type0, fn_ret_type)
58135814
g.writeln('.data, sizeof(${styp}));')
58145815
if tmp_var != '' {
58155816
g.writeln('${tmpvar}.state = ${tmp_var}.state;')
@@ -5824,8 +5825,8 @@ fn (mut g Gen) return_stmt(node ast.Return) {
58245825
g.writeln('${ret_typ} ${tmpvar};')
58255826
styp := g.base_type(fn_ret_type)
58265827
g.write('_option_ok(&(${styp}[]) { ')
5827-
if !g.unwrap_generic(fn_ret_type).is_ptr() && node.types[0].is_ptr() {
5828-
if !(node.exprs[0] is ast.Ident && !g.is_amp) {
5828+
if !g.unwrap_generic(fn_ret_type).is_ptr() && type0.is_ptr() {
5829+
if !(expr0 is ast.Ident && !g.is_amp) {
58295830
g.write('*')
58305831
}
58315832
}
@@ -5834,7 +5835,7 @@ fn (mut g Gen) return_stmt(node ast.Return) {
58345835
g.fixed_array_var_init(g.expr_string(expr0), expr0.is_auto_deref_var(),
58355836
info.elem_type, info.size)
58365837
} else {
5837-
g.expr_with_cast(expr0, node.types[0], fn_ret_type.clear_option_and_result())
5838+
g.expr_with_cast(expr0, type0, fn_ret_type.clear_option_and_result())
58385839
}
58395840
g.writeln(' }, (${option_name}*)(&${tmpvar}), sizeof(${styp}));')
58405841
}
@@ -5848,17 +5849,17 @@ fn (mut g Gen) return_stmt(node ast.Return) {
58485849
expr0.return_type.has_flag(.result) && expr0.or_block.kind == .absent
58495850
}
58505851
else {
5851-
node.types[0].has_flag(.result)
5852+
type0.has_flag(.result)
58525853
}
58535854
}
58545855
if fn_return_is_result && !expr_type_is_result && return_sym.name != result_name {
58555856
g.writeln('${ret_typ} ${tmpvar} = {0};')
58565857
if fn_return_is_fixed_array && expr0 !is ast.ArrayInit
5857-
&& g.table.final_sym(node.types[0]).kind == .array_fixed {
5858+
&& g.table.final_sym(type0).kind == .array_fixed {
58585859
styp := g.styp(fn_ret_type.clear_option_and_result())
58595860
g.write('memcpy(${tmpvar}.data, ')
58605861
if expr0 in [ast.CallExpr, ast.StructInit] {
5861-
g.expr_with_opt(expr0, node.types[0], fn_ret_type)
5862+
g.expr_with_opt(expr0, type0, fn_ret_type)
58625863
g.write('.data')
58635864
} else {
58645865
g.expr(expr0)
@@ -5867,19 +5868,19 @@ fn (mut g Gen) return_stmt(node ast.Return) {
58675868
} else {
58685869
styp := g.base_type(fn_ret_type)
58695870
g.write('_result_ok(&(${styp}[]) { ')
5870-
if !fn_ret_type.is_ptr() && node.types[0].is_ptr() {
5871-
if !((node.exprs[0] is ast.Ident && !g.is_amp) || sym.kind == .interface) {
5871+
if !fn_ret_type.is_ptr() && type0.is_ptr() {
5872+
if !((expr0 is ast.Ident && !g.is_amp) || sym.kind == .interface) {
58725873
g.write('*')
58735874
}
58745875
}
58755876
if fn_ret_type.has_flag(.option) {
5876-
g.expr_with_opt(expr0, node.types[0], fn_ret_type.clear_flag(.result))
5877+
g.expr_with_opt(expr0, type0, fn_ret_type.clear_flag(.result))
58775878
} else if return_sym.kind == .array_fixed && expr0 !is ast.ArrayInit {
58785879
info := return_sym.info as ast.ArrayFixed
58795880
g.fixed_array_var_init(g.expr_string(expr0), expr0.is_auto_deref_var(),
58805881
info.elem_type, info.size)
58815882
} else {
5882-
g.expr_with_cast(expr0, node.types[0], fn_ret_type.clear_flag(.result))
5883+
g.expr_with_cast(expr0, type0, fn_ret_type.clear_flag(.result))
58835884
}
58845885
g.writeln(' }, (${result_name}*)(&${tmpvar}), sizeof(${styp}));')
58855886
}
@@ -5892,12 +5893,11 @@ fn (mut g Gen) return_stmt(node ast.Return) {
58925893
// set free_parent_scopes to true, since all variables defined in parent
58935894
// scopes need to be freed before the return
58945895
if g.is_autofree {
5895-
expr := node.exprs[0]
5896-
if expr is ast.Ident {
5897-
g.returned_var_name = expr.name
5896+
if expr0 is ast.Ident {
5897+
g.returned_var_name = expr0.name
58985898
}
58995899
if !use_tmp_var && !g.is_builtin_mod {
5900-
use_tmp_var = expr is ast.CallExpr
5900+
use_tmp_var = expr0 is ast.CallExpr
59015901
}
59025902
}
59035903
// Create a temporary variable for the return expression
@@ -5926,68 +5926,67 @@ fn (mut g Gen) return_stmt(node ast.Return) {
59265926
var_str := g.expr_string(expr0)
59275927
g.write(var_str.trim('&'))
59285928
} else if g.fn_decl.return_type.has_flag(.option) {
5929-
g.expr_with_opt(expr0, node.types[0], g.fn_decl.return_type)
5929+
g.expr_with_opt(expr0, type0, g.fn_decl.return_type)
59305930
} else if g.table.sym(g.fn_decl.return_type).kind in [.sum_type, .interface] {
5931-
g.expr_with_cast(expr0, node.types[0], g.fn_decl.return_type)
5931+
g.expr_with_cast(expr0, type0, g.fn_decl.return_type)
59325932
} else {
59335933
g.write('*')
59345934
g.expr(expr0)
59355935
}
59365936
} else {
59375937
if g.fn_decl.return_type.has_flag(.option) {
5938-
expr0_is_alias_fn_ret := expr0 is ast.CallExpr && node.types[0].has_flag(.option)
5939-
&& g.table.type_kind(node.types[0]) in [.placeholder, .alias]
5938+
expr0_is_alias_fn_ret := expr0 is ast.CallExpr && type0.has_flag(.option)
5939+
&& g.table.type_kind(type0) in [.placeholder, .alias]
59405940
// return foo() where foo() returns different option alias than current fn
59415941
if expr0_is_alias_fn_ret {
5942-
g.expr_opt_with_cast(node.exprs[0], node.types[0], g.fn_decl.return_type)
5942+
g.expr_opt_with_cast(expr0, type0, g.fn_decl.return_type)
59435943
} else {
5944-
g.expr_with_opt(node.exprs[0], node.types[0], g.fn_decl.return_type)
5944+
g.expr_with_opt(expr0, type0, g.fn_decl.return_type)
59455945
}
59465946
} else {
5947-
if fn_return_is_fixed_array && !node.types[0].has_option_or_result() {
5947+
if fn_return_is_fixed_array && !type0.has_option_or_result() {
59485948
if node.exprs[0] is ast.Ident {
59495949
g.writeln('{0};')
5950-
typ := if expr0.is_auto_deref_var() {
5951-
node.types[0].deref()
5950+
typ := if node.exprs[0].is_auto_deref_var() {
5951+
type0.deref()
59525952
} else {
5953-
node.types[0]
5953+
type0
59545954
}
59555955
typ_sym := g.table.final_sym(typ)
59565956
if typ_sym.kind == .array_fixed
59575957
&& (typ_sym.info as ast.ArrayFixed).is_fn_ret {
5958-
g.write('memcpy(${tmpvar}.ret_arr, ${g.expr_string(node.exprs[0])}.ret_arr, sizeof(${g.styp(typ)}))')
5958+
g.write('memcpy(${tmpvar}.ret_arr, ${g.expr_string(expr0)}.ret_arr, sizeof(${g.styp(typ)}))')
59595959
} else {
5960-
g.write('memcpy(${tmpvar}.ret_arr, ${g.expr_string(node.exprs[0])}, sizeof(${g.styp(typ)}))')
5960+
g.write('memcpy(${tmpvar}.ret_arr, ${g.expr_string(expr0)}, sizeof(${g.styp(typ)}))')
59615961
}
5962-
} else if node.exprs[0] in [ast.ArrayInit, ast.StructInit] {
5963-
if node.exprs[0] is ast.ArrayInit && node.exprs[0].is_fixed
5964-
&& node.exprs[0].has_init {
5965-
if (node.exprs[0] as ast.ArrayInit).init_expr.is_literal() {
5962+
} else if expr0 in [ast.ArrayInit, ast.StructInit] {
5963+
if expr0 is ast.ArrayInit && expr0.is_fixed && expr0.has_init {
5964+
if (expr0 as ast.ArrayInit).init_expr.is_literal() {
59665965
g.write('{.ret_arr=')
5967-
g.expr_with_cast(node.exprs[0], node.types[0], g.fn_decl.return_type)
5966+
g.expr_with_cast(expr0, type0, g.fn_decl.return_type)
59685967
g.writeln('};')
59695968
} else {
59705969
g.writeln('{0};')
59715970
g.write('memcpy(${tmpvar}.ret_arr, ')
5972-
g.expr_with_cast(node.exprs[0], node.types[0], g.fn_decl.return_type)
5973-
g.write(', sizeof(${g.styp(node.types[0])}))')
5971+
g.expr_with_cast(expr0, type0, g.fn_decl.return_type)
5972+
g.write(', sizeof(${g.styp(type0)}))')
59745973
}
59755974
} else {
59765975
g.writeln('{0};')
59775976
tmpvar2 := g.new_tmp_var()
5978-
g.write('${g.styp(node.types[0])} ${tmpvar2} = ')
5979-
g.expr_with_cast(node.exprs[0], node.types[0], g.fn_decl.return_type)
5977+
g.write('${g.styp(type0)} ${tmpvar2} = ')
5978+
g.expr_with_cast(expr0, type0, g.fn_decl.return_type)
59805979
g.writeln(';')
5981-
g.write('memcpy(${tmpvar}.ret_arr, ${tmpvar2}, sizeof(${g.styp(node.types[0])}))')
5980+
g.write('memcpy(${tmpvar}.ret_arr, ${tmpvar2}, sizeof(${g.styp(type0)}))')
59825981
}
59835982
} else {
59845983
g.writeln('{0};')
59855984
g.write('memcpy(${tmpvar}.ret_arr, ')
5986-
g.expr_with_cast(node.exprs[0], node.types[0], g.fn_decl.return_type)
5987-
g.write(', sizeof(${g.styp(node.types[0])}))')
5985+
g.expr_with_cast(expr0, type0, g.fn_decl.return_type)
5986+
g.write(', sizeof(${g.styp(type0)}))')
59885987
}
59895988
} else {
5990-
g.expr_with_cast(node.exprs[0], node.types[0], g.fn_decl.return_type)
5989+
g.expr_with_cast(expr0, type0, g.fn_decl.return_type)
59915990
}
59925991
}
59935992
}

0 commit comments

Comments
 (0)