diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index fc4ba99b94aca1..084b1a22b91c4b 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -574,7 +574,6 @@ pub mut: stmts []Stmt defer_stmts []DeferStmt trace_fns map[string]FnTrace - has_trace_fns bool return_type Type return_type_pos token.Pos // `string` in `fn (u User) name() string` position has_return bool diff --git a/vlib/v/ast/table.v b/vlib/v/ast/table.v index ba49e3deefaf47..a635955960e391 100644 --- a/vlib/v/ast/table.v +++ b/vlib/v/ast/table.v @@ -2485,3 +2485,14 @@ pub fn (t &Table) get_array_dims(arr Array) (int, Type) { } return dims, elem_type } + +pub fn (t &Table) get_trace_fn_name(cur_fn FnDecl, node CallExpr) (string, string) { + generic_name := node.concrete_types.map(t.type_to_str(it)).join('_') + hash_fn := '_v__trace__${cur_fn.name}_${node.name}_${generic_name}_${node.pos.line_nr}' + fn_name := if node.concrete_types.len > 0 { + '${node.name}_T_${generic_name}' + } else { + node.name + } + return hash_fn, fn_name +} diff --git a/vlib/v/checker/fn.v b/vlib/v/checker/fn.v index de0a55af223959..6ae78b3c9514ea 100644 --- a/vlib/v/checker/fn.v +++ b/vlib/v/checker/fn.v @@ -1523,13 +1523,7 @@ fn (mut c Checker) register_trace_call(node ast.CallExpr, func ast.Fn) { is_traceable := c.pref.is_callstack && c.table.cur_fn != unsafe { nil } && c.pref.is_callstack && c.file.imports.any(it.mod == 'v.debug') && node.name != 'v.debug.callstack' if is_traceable { - generic_name := node.concrete_types.map(c.table.type_to_str(it)).join('_') - hash_fn := '_v__trace__${c.table.cur_fn.name}_${node.name}_${generic_name}_${node.pos.line_nr}' - fn_name := if generic_name != '' { - '${node.name}_T_${generic_name}' - } else { - node.name - } + hash_fn, fn_name := c.table.get_trace_fn_name(c.table.cur_fn, node) calling_fn := if func.is_method { '${c.table.type_to_str(c.unwrap_generic(node.left_type))}_${fn_name}' } else { @@ -1543,7 +1537,6 @@ fn (mut c Checker) register_trace_call(node ast.CallExpr, func ast.Fn) { func: &func is_fn_var: node.is_fn_var } - c.table.cur_fn.has_trace_fns = true } } diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 075db8012f601d..2463136006a2f2 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -141,63 +141,62 @@ mut: inside_dump_fn bool expected_fixed_arr bool inside_for_c_stmt bool - // inside_comptime_for_field bool - inside_cast_in_heap int // inside cast to interface type in heap (resolve recursive calls) - inside_cast bool - inside_const bool - inside_array_item bool - inside_const_opt_or_res bool - inside_lambda bool - inside_cinit bool - inside_interface_deref bool - last_tmp_call_var []string - loop_depth int - ternary_names map[string]string - ternary_level_names map[string][]string - arraymap_set_pos int // map or array set value position - stmt_path_pos []int // positions of each statement start, for inserting C statements before the current statement - skip_stmt_pos bool // for handling if expressions + autofree (since both prepend C statements) - left_is_opt bool // left hand side on assignment is an option - right_is_opt bool // right hand side on assignment is an option - assign_ct_type ast.Type // left hand side resolved comptime type - indent int - empty_line bool - assign_op token.Kind // *=, =, etc (for array_set) - defer_stmts []ast.DeferStmt - defer_ifdef string - defer_profile_code string - defer_vars []string - str_types []StrType // types that need automatic str() generation - generated_str_fns []StrType // types that already have a str() function - str_fn_names []string // remove duplicate function names - threaded_fns shared []string // for generating unique wrapper types and fns for `go xxx()` - waiter_fns shared []string // functions that wait for `go xxx()` to finish - needed_equality_fns []ast.Type - generated_eq_fns []ast.Type - array_sort_fn shared []string - array_contains_types []ast.Type - array_index_types []ast.Type - auto_fn_definitions []string // auto generated functions definition list - sumtype_casting_fns []SumtypeCastingFn - anon_fn_definitions []string // anon generated functions definition list - sumtype_definitions map[int]bool // `_TypeA_to_sumtype_TypeB()` fns that have been generated - trace_fn_definitions []string - json_types []ast.Type // to avoid json gen duplicates - pcs []ProfileCounterMeta // -prof profile counter fn_names => fn counter name - hotcode_fn_names []string - hotcode_fpaths []string - embedded_files []ast.EmbeddedFile - sql_i int - sql_stmt_name string - sql_bind_name string - sql_idents []string - sql_idents_types []ast.Type - sql_left_type ast.Type - sql_table_name string - sql_fkey string - sql_parent_id string - sql_side SqlExprSide // left or right, to distinguish idents in `name == name` - strs_to_free0 []string // strings.Builder + inside_cast_in_heap int // inside cast to interface type in heap (resolve recursive calls) + inside_cast bool + inside_const bool + inside_array_item bool + inside_const_opt_or_res bool + inside_lambda bool + inside_cinit bool + inside_interface_deref bool + last_tmp_call_var []string + loop_depth int + ternary_names map[string]string + ternary_level_names map[string][]string + arraymap_set_pos int // map or array set value position + stmt_path_pos []int // positions of each statement start, for inserting C statements before the current statement + skip_stmt_pos bool // for handling if expressions + autofree (since both prepend C statements) + left_is_opt bool // left hand side on assignment is an option + right_is_opt bool // right hand side on assignment is an option + assign_ct_type ast.Type // left hand side resolved comptime type + indent int + empty_line bool + assign_op token.Kind // *=, =, etc (for array_set) + defer_stmts []ast.DeferStmt + defer_ifdef string + defer_profile_code string + defer_vars []string + str_types []StrType // types that need automatic str() generation + generated_str_fns []StrType // types that already have a str() function + str_fn_names []string // remove duplicate function names + threaded_fns shared []string // for generating unique wrapper types and fns for `go xxx()` + waiter_fns shared []string // functions that wait for `go xxx()` to finish + needed_equality_fns []ast.Type + generated_eq_fns []ast.Type + array_sort_fn shared []string + array_contains_types []ast.Type + array_index_types []ast.Type + auto_fn_definitions []string // auto generated functions definition list + sumtype_casting_fns []SumtypeCastingFn + anon_fn_definitions []string // anon generated functions definition list + sumtype_definitions map[int]bool // `_TypeA_to_sumtype_TypeB()` fns that have been generated + trace_fn_definitions []string + json_types []ast.Type // to avoid json gen duplicates + pcs []ProfileCounterMeta // -prof profile counter fn_names => fn counter name + hotcode_fn_names []string + hotcode_fpaths []string + embedded_files []ast.EmbeddedFile + sql_i int + sql_stmt_name string + sql_bind_name string + sql_idents []string + sql_idents_types []ast.Type + sql_left_type ast.Type + sql_table_name string + sql_fkey string + sql_parent_id string + sql_side SqlExprSide // left or right, to distinguish idents in `name == name` + strs_to_free0 []string // strings.Builder // strs_to_free []string // strings.Builder // tmp_arg_vars_to_free []string // autofree_pregen map[string]string diff --git a/vlib/v/gen/c/fn.v b/vlib/v/gen/c/fn.v index 376fb2d1d3e7a9..a062b45c6b65f3 100644 --- a/vlib/v/gen/c/fn.v +++ b/vlib/v/gen/c/fn.v @@ -1535,7 +1535,7 @@ fn (mut g Gen) method_call(node ast.CallExpr) { } g.write('${name}${noscan}(') } else { - if g.cur_fn != unsafe { nil } && g.cur_fn.has_trace_fns { + if g.cur_fn != unsafe { nil } && g.cur_fn.trace_fns.len > 0 { g.gen_trace_call(node, name) g.write('(') } else { @@ -1984,7 +1984,7 @@ fn (mut g Gen) fn_call(node ast.CallExpr) { } } if !is_fn_var { - if g.cur_fn != unsafe { nil } && g.cur_fn.has_trace_fns { + if g.cur_fn != unsafe { nil } && g.cur_fn.trace_fns.len > 0 { g.gen_trace_call(node, name) if node.is_fn_var { return @@ -2037,10 +2037,9 @@ fn (mut g Gen) fn_call(node ast.CallExpr) { // gen_trace_call generates call to the wrapper trace fn if the call is traceable fn (mut g Gen) gen_trace_call(node ast.CallExpr, name string) { - generic_name := node.concrete_types.map(g.table.type_to_str(it)).join('_') - trace_fn_name := '_v__trace__${g.cur_fn.name}_${node.name}_${generic_name}_${node.pos.line_nr}' - if _ := g.cur_fn.trace_fns[trace_fn_name] { - g.write(c_name(trace_fn_name)) + hash_fn, _ := g.table.get_trace_fn_name(g.cur_fn, node) + if _ := g.cur_fn.trace_fns[hash_fn] { + g.write(c_name(hash_fn)) if node.is_fn_var { g.write('(${node.name})') }