mirror of
https://github.com/vlang/v.git
synced 2025-08-03 17:57:59 -04:00
cgen: minor optimization removing repeated code (#23417)
This commit is contained in:
parent
6348e581de
commit
cc7caf4384
@ -5503,10 +5503,11 @@ fn (mut g Gen) return_stmt(node ast.Return) {
|
||||
g.inside_return = old_inside_return
|
||||
}
|
||||
|
||||
expr0 := if node.exprs.len > 0 { node.exprs[0] } else { ast.empty_expr }
|
||||
type0 := if node.exprs.len > 0 { node.types[0] } else { ast.void_type }
|
||||
exprs_len := node.exprs.len
|
||||
expr0 := if exprs_len > 0 { node.exprs[0] } else { ast.empty_expr }
|
||||
type0 := if exprs_len > 0 { node.types[0] } else { ast.void_type }
|
||||
|
||||
if node.exprs.len > 0 {
|
||||
if exprs_len > 0 {
|
||||
// skip `return $vweb.html()`
|
||||
if expr0 is ast.ComptimeCall && expr0.is_vweb {
|
||||
g.inside_return_tmpl = true
|
||||
@ -5516,10 +5517,11 @@ fn (mut g Gen) return_stmt(node ast.Return) {
|
||||
return
|
||||
}
|
||||
}
|
||||
ret_type := g.fn_decl.return_type
|
||||
|
||||
// got to do a correct check for multireturn
|
||||
sym := g.table.sym(g.unwrap_generic(g.fn_decl.return_type))
|
||||
mut fn_ret_type := g.fn_decl.return_type
|
||||
sym := g.table.sym(g.unwrap_generic(ret_type))
|
||||
mut fn_ret_type := ret_type
|
||||
if sym.kind == .alias {
|
||||
unaliased_type := g.table.unaliased_type(fn_ret_type)
|
||||
if unaliased_type.has_option_or_result() {
|
||||
@ -5533,7 +5535,7 @@ fn (mut g Gen) return_stmt(node ast.Return) {
|
||||
fn_return_is_fixed_array_non_result := fn_return_is_fixed_array
|
||||
&& !fn_ret_type.has_option_or_result()
|
||||
mut has_semicolon := false
|
||||
if node.exprs.len == 0 {
|
||||
if exprs_len == 0 {
|
||||
g.write_defer_stmts_when_needed()
|
||||
if fn_return_is_option || fn_return_is_result {
|
||||
styp := g.styp(fn_ret_type)
|
||||
@ -5556,8 +5558,8 @@ fn (mut g Gen) return_stmt(node ast.Return) {
|
||||
ret_typ := g.ret_styp(g.unwrap_generic(fn_ret_type))
|
||||
|
||||
// `return fn_call_opt()`
|
||||
if node.exprs.len == 1 && (fn_return_is_option || fn_return_is_result) && expr0 is ast.CallExpr
|
||||
&& expr0.return_type == g.fn_decl.return_type && expr0.or_block.kind == .absent {
|
||||
if exprs_len == 1 && (fn_return_is_option || fn_return_is_result) && expr0 is ast.CallExpr
|
||||
&& expr0.return_type == ret_type && expr0.or_block.kind == .absent {
|
||||
if g.defer_stmts.len > 0 {
|
||||
g.write('${ret_typ} ${tmpvar} = ')
|
||||
g.expr(expr0)
|
||||
@ -5574,7 +5576,7 @@ fn (mut g Gen) return_stmt(node ast.Return) {
|
||||
}
|
||||
mut use_tmp_var := g.defer_stmts.len > 0 || g.defer_profile_code.len > 0
|
||||
|| g.cur_lock.lockeds.len > 0
|
||||
|| (fn_return_is_multi && node.exprs.len >= 1 && fn_return_is_option)
|
||||
|| (fn_return_is_multi && exprs_len >= 1 && fn_return_is_option)
|
||||
|| fn_return_is_fixed_array_non_result
|
||||
|| (fn_return_is_multi && node.types.any(g.table.final_sym(it).kind == .array_fixed))
|
||||
// handle promoting none/error/function returning _option'
|
||||
@ -5601,7 +5603,7 @@ fn (mut g Gen) return_stmt(node ast.Return) {
|
||||
g.writeln(';')
|
||||
if use_tmp_var {
|
||||
// handle options when returning `none` for `?(int, ?int)`
|
||||
if fn_return_is_multi && node.exprs.len >= 1 {
|
||||
if fn_return_is_multi && exprs_len >= 1 {
|
||||
mr_info := sym.info as ast.MultiReturn
|
||||
for i in 0 .. mr_info.types.len {
|
||||
if mr_info.types[i].has_flag(.option) {
|
||||
@ -5646,8 +5648,8 @@ fn (mut g Gen) return_stmt(node ast.Return) {
|
||||
}
|
||||
}
|
||||
// regular cases
|
||||
if fn_return_is_multi && node.exprs.len > 0 && !g.expr_is_multi_return_call(expr0) {
|
||||
if node.exprs.len == 1 && (expr0 is ast.IfExpr || expr0 is ast.MatchExpr) {
|
||||
if fn_return_is_multi && exprs_len > 0 && !g.expr_is_multi_return_call(expr0) {
|
||||
if exprs_len == 1 && (expr0 is ast.IfExpr || expr0 is ast.MatchExpr) {
|
||||
// use a temporary for `return if cond { x,y } else { a,b }` or `return match expr { abc { x, y } else { z, w } }`
|
||||
g.write('${ret_typ} ${tmpvar} = ')
|
||||
g.expr(expr0)
|
||||
@ -5660,11 +5662,11 @@ fn (mut g Gen) return_stmt(node ast.Return) {
|
||||
mut styp := ''
|
||||
if fn_return_is_option {
|
||||
g.writeln('${ret_typ} ${tmpvar};')
|
||||
styp = g.base_type(g.fn_decl.return_type)
|
||||
styp = g.base_type(ret_type)
|
||||
g.write('_option_ok(&(${styp}[]) { ')
|
||||
} else if fn_return_is_result {
|
||||
g.writeln('${ret_typ} ${tmpvar};')
|
||||
styp = g.base_type(g.fn_decl.return_type)
|
||||
styp = g.base_type(ret_type)
|
||||
g.write('_result_ok(&(${styp}[]) { ')
|
||||
} else {
|
||||
if use_tmp_var {
|
||||
@ -5672,7 +5674,7 @@ fn (mut g Gen) return_stmt(node ast.Return) {
|
||||
} else {
|
||||
g.write('return ')
|
||||
}
|
||||
styp = g.styp(g.fn_decl.return_type)
|
||||
styp = g.styp(ret_type)
|
||||
}
|
||||
// Use this to keep the tmp assignments in order
|
||||
mut multi_unpack := ''
|
||||
@ -5705,7 +5707,7 @@ fn (mut g Gen) return_stmt(node ast.Return) {
|
||||
expr_types := expr_sym.mr_info().types
|
||||
for j, _ in expr_types {
|
||||
g.write('.arg${arg_idx}=${tmp}.arg${j}')
|
||||
if j < expr_types.len || i < node.exprs.len - 1 {
|
||||
if j < expr_types.len || i < exprs_len - 1 {
|
||||
g.write(',')
|
||||
}
|
||||
arg_idx++
|
||||
@ -5733,7 +5735,7 @@ fn (mut g Gen) return_stmt(node ast.Return) {
|
||||
g.expr(expr)
|
||||
}
|
||||
}
|
||||
if i < node.exprs.len - 1 {
|
||||
if i < exprs_len - 1 {
|
||||
g.write(', ')
|
||||
}
|
||||
arg_idx++
|
||||
@ -5764,7 +5766,7 @@ fn (mut g Gen) return_stmt(node ast.Return) {
|
||||
g.writeln('return ${tmpvar};')
|
||||
has_semicolon = true
|
||||
}
|
||||
} else if node.exprs.len >= 1 {
|
||||
} else if exprs_len >= 1 {
|
||||
if node.types.len == 0 {
|
||||
g.checker_bug('node.exprs.len == ${node.exprs.len} && node.types.len == 0',
|
||||
node.pos)
|
||||
@ -5904,26 +5906,26 @@ fn (mut g Gen) return_stmt(node ast.Return) {
|
||||
g.write('return ')
|
||||
}
|
||||
if expr0.is_auto_deref_var() && !fn_return_is_fixed_array {
|
||||
if g.fn_decl.return_type.is_ptr() {
|
||||
if ret_type.is_ptr() {
|
||||
var_str := g.expr_string(expr0)
|
||||
g.write(var_str.trim('&'))
|
||||
} else if g.fn_decl.return_type.has_flag(.option) {
|
||||
g.expr_with_opt(expr0, type0, g.fn_decl.return_type)
|
||||
} else if g.table.sym(g.fn_decl.return_type).kind in [.sum_type, .interface] {
|
||||
g.expr_with_cast(expr0, type0, g.fn_decl.return_type)
|
||||
} else if ret_type.has_flag(.option) {
|
||||
g.expr_with_opt(expr0, type0, ret_type)
|
||||
} else if g.table.sym(ret_type).kind in [.sum_type, .interface] {
|
||||
g.expr_with_cast(expr0, type0, ret_type)
|
||||
} else {
|
||||
g.write('*')
|
||||
g.expr(expr0)
|
||||
}
|
||||
} else {
|
||||
if g.fn_decl.return_type.has_flag(.option) {
|
||||
if ret_type.has_flag(.option) {
|
||||
expr0_is_alias_fn_ret := expr0 is ast.CallExpr && type0.has_flag(.option)
|
||||
&& g.table.type_kind(type0) in [.placeholder, .alias]
|
||||
// return foo() where foo() returns different option alias than current fn
|
||||
if expr0_is_alias_fn_ret {
|
||||
g.expr_opt_with_cast(expr0, type0, g.fn_decl.return_type)
|
||||
g.expr_opt_with_cast(expr0, type0, ret_type)
|
||||
} else {
|
||||
g.expr_with_opt(expr0, type0, g.fn_decl.return_type)
|
||||
g.expr_with_opt(expr0, type0, ret_type)
|
||||
}
|
||||
} else {
|
||||
if fn_return_is_fixed_array && !type0.has_option_or_result() {
|
||||
@ -5945,30 +5947,30 @@ fn (mut g Gen) return_stmt(node ast.Return) {
|
||||
if expr0 is ast.ArrayInit && expr0.is_fixed && expr0.has_init {
|
||||
if (expr0 as ast.ArrayInit).init_expr.is_literal() {
|
||||
g.write('{.ret_arr=')
|
||||
g.expr_with_cast(expr0, type0, g.fn_decl.return_type)
|
||||
g.expr_with_cast(expr0, type0, ret_type)
|
||||
g.writeln('};')
|
||||
} else {
|
||||
g.writeln('{0};')
|
||||
g.write('memcpy(${tmpvar}.ret_arr, ')
|
||||
g.expr_with_cast(expr0, type0, g.fn_decl.return_type)
|
||||
g.expr_with_cast(expr0, type0, ret_type)
|
||||
g.write(', sizeof(${g.styp(type0)}))')
|
||||
}
|
||||
} else {
|
||||
g.writeln('{0};')
|
||||
tmpvar2 := g.new_tmp_var()
|
||||
g.write('${g.styp(type0)} ${tmpvar2} = ')
|
||||
g.expr_with_cast(expr0, type0, g.fn_decl.return_type)
|
||||
g.expr_with_cast(expr0, type0, ret_type)
|
||||
g.writeln(';')
|
||||
g.write('memcpy(${tmpvar}.ret_arr, ${tmpvar2}, sizeof(${g.styp(type0)}))')
|
||||
}
|
||||
} else {
|
||||
g.writeln('{0};')
|
||||
g.write('memcpy(${tmpvar}.ret_arr, ')
|
||||
g.expr_with_cast(expr0, type0, g.fn_decl.return_type)
|
||||
g.expr_with_cast(expr0, type0, ret_type)
|
||||
g.write(', sizeof(${g.styp(type0)}))')
|
||||
}
|
||||
} else {
|
||||
g.expr_with_cast(expr0, type0, g.fn_decl.return_type)
|
||||
g.expr_with_cast(expr0, type0, ret_type)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -118,14 +118,15 @@ fn (mut g Gen) spawn_and_go_expr(node ast.SpawnExpr, mode SpawnGoMode) {
|
||||
g.expr(arg.expr)
|
||||
g.writeln(';')
|
||||
}
|
||||
s_ret_typ := g.styp(node.call_expr.return_type)
|
||||
if g.pref.os == .windows && node.call_expr.return_type != ast.void_type {
|
||||
call_ret_type := node.call_expr.return_type
|
||||
s_ret_typ := g.styp(call_ret_type)
|
||||
if g.pref.os == .windows && call_ret_type != ast.void_type {
|
||||
g.writeln('${arg_tmp_var}->ret_ptr = (void *) _v_malloc(sizeof(${s_ret_typ}));')
|
||||
}
|
||||
is_opt := node.call_expr.return_type.has_flag(.option)
|
||||
is_res := node.call_expr.return_type.has_flag(.result)
|
||||
is_opt := call_ret_type.has_flag(.option)
|
||||
is_res := call_ret_type.has_flag(.result)
|
||||
mut gohandle_name := ''
|
||||
if node.call_expr.return_type == ast.void_type {
|
||||
if call_ret_type == ast.void_type {
|
||||
if is_opt {
|
||||
gohandle_name = '__v_thread_Option_void'
|
||||
} else if is_res {
|
||||
@ -134,13 +135,12 @@ fn (mut g Gen) spawn_and_go_expr(node ast.SpawnExpr, mode SpawnGoMode) {
|
||||
gohandle_name = '__v_thread'
|
||||
}
|
||||
} else {
|
||||
ret_styp := g.styp(g.unwrap_generic(node.call_expr.return_type)).replace('*',
|
||||
'_ptr')
|
||||
ret_styp := g.styp(g.unwrap_generic(call_ret_type)).replace('*', '_ptr')
|
||||
gohandle_name = '__v_thread_${ret_styp}'
|
||||
}
|
||||
if is_spawn {
|
||||
if g.pref.os == .windows {
|
||||
simple_handle := if node.is_expr && node.call_expr.return_type != ast.void_type {
|
||||
simple_handle := if node.is_expr && call_ret_type != ast.void_type {
|
||||
'thread_handle_${tmp}'
|
||||
} else {
|
||||
'thread_${tmp}'
|
||||
@ -148,7 +148,7 @@ fn (mut g Gen) spawn_and_go_expr(node ast.SpawnExpr, mode SpawnGoMode) {
|
||||
stack_size := g.get_cur_thread_stack_size(expr.name)
|
||||
g.writeln('HANDLE ${simple_handle} = CreateThread(0, ${stack_size}, (LPTHREAD_START_ROUTINE)${wrapper_fn_name}, ${arg_tmp_var}, 0, 0); // fn: ${expr.name}')
|
||||
g.writeln('if (!${simple_handle}) panic_lasterr(tos3("`go ${name}()`: "));')
|
||||
if node.is_expr && node.call_expr.return_type != ast.void_type {
|
||||
if node.is_expr && call_ret_type != ast.void_type {
|
||||
g.writeln('${gohandle_name} thread_${tmp} = {')
|
||||
g.writeln('\t.ret_ptr = ${arg_tmp_var}->ret_ptr,')
|
||||
g.writeln2('\t.handle = thread_handle_${tmp}', '};')
|
||||
@ -195,12 +195,12 @@ fn (mut g Gen) spawn_and_go_expr(node ast.SpawnExpr, mode SpawnGoMode) {
|
||||
g.waiter_fn_definitions.writeln('${s_ret_typ} ${waiter_fn_name}(${gohandle_name} thread);')
|
||||
g.gowrappers.writeln('\n${s_ret_typ} ${waiter_fn_name}(${gohandle_name} thread) {')
|
||||
mut c_ret_ptr_ptr := 'NULL'
|
||||
if node.call_expr.return_type != ast.void_type {
|
||||
if call_ret_type != ast.void_type {
|
||||
g.gowrappers.writeln('\t${s_ret_typ}* ret_ptr;')
|
||||
c_ret_ptr_ptr = '&ret_ptr'
|
||||
}
|
||||
if g.pref.os == .windows {
|
||||
if node.call_expr.return_type == ast.void_type {
|
||||
if call_ret_type == ast.void_type {
|
||||
g.gowrappers.writeln('\tu32 stat = WaitForSingleObject(thread, INFINITE);')
|
||||
} else {
|
||||
g.gowrappers.writeln('\tu32 stat = WaitForSingleObject(thread.handle, INFINITE);')
|
||||
@ -211,13 +211,13 @@ fn (mut g Gen) spawn_and_go_expr(node ast.SpawnExpr, mode SpawnGoMode) {
|
||||
}
|
||||
g.gowrappers.writeln('\tif (stat != 0) { _v_panic(_SLIT("unable to join thread")); }')
|
||||
if g.pref.os == .windows {
|
||||
if node.call_expr.return_type == ast.void_type {
|
||||
if call_ret_type == ast.void_type {
|
||||
g.gowrappers.writeln('\tCloseHandle(thread);')
|
||||
} else {
|
||||
g.gowrappers.writeln('\tCloseHandle(thread.handle);')
|
||||
}
|
||||
}
|
||||
if node.call_expr.return_type != ast.void_type {
|
||||
if call_ret_type != ast.void_type {
|
||||
g.gowrappers.writeln('\t${s_ret_typ} ret = *ret_ptr;')
|
||||
g.gowrappers.writeln('\t_v_free(ret_ptr);')
|
||||
g.gowrappers.writeln('\treturn ret;')
|
||||
@ -288,7 +288,7 @@ fn (mut g Gen) spawn_and_go_expr(node ast.SpawnExpr, mode SpawnGoMode) {
|
||||
styp := g.styp(expr.receiver_type)
|
||||
g.type_definitions.writeln('\t${styp} arg0;')
|
||||
}
|
||||
need_return_ptr := g.pref.os == .windows && node.call_expr.return_type != ast.void_type
|
||||
need_return_ptr := g.pref.os == .windows && call_ret_type != ast.void_type
|
||||
for i, arg in expr.args {
|
||||
arg_sym := g.table.sym(arg.typ)
|
||||
if arg_sym.info is ast.FnType {
|
||||
@ -307,7 +307,7 @@ fn (mut g Gen) spawn_and_go_expr(node ast.SpawnExpr, mode SpawnGoMode) {
|
||||
thread_ret_type := if g.pref.os == .windows { 'u32' } else { 'void*' }
|
||||
g.type_definitions.writeln('${g.static_modifier} ${thread_ret_type} ${wrapper_fn_name}(${wrapper_struct_name} *arg);')
|
||||
g.gowrappers.writeln('${thread_ret_type} ${wrapper_fn_name}(${wrapper_struct_name} *arg) {')
|
||||
if node.call_expr.return_type != ast.void_type {
|
||||
if call_ret_type != ast.void_type {
|
||||
if g.pref.os == .windows {
|
||||
g.gowrappers.write_string('\t*((${s_ret_typ}*)(arg->ret_ptr)) = ')
|
||||
} else {
|
||||
@ -398,7 +398,7 @@ fn (mut g Gen) spawn_and_go_expr(node ast.SpawnExpr, mode SpawnGoMode) {
|
||||
if is_spawn {
|
||||
g.gowrappers.writeln('\t_v_free(arg);')
|
||||
}
|
||||
if g.pref.os != .windows && node.call_expr.return_type != ast.void_type {
|
||||
if g.pref.os != .windows && call_ret_type != ast.void_type {
|
||||
g.gowrappers.writeln('\treturn ret_ptr;')
|
||||
} else {
|
||||
g.gowrappers.writeln('\treturn 0;')
|
||||
|
Loading…
x
Reference in New Issue
Block a user