-
Notifications
You must be signed in to change notification settings - Fork 358
/
trace.go
118 lines (107 loc) · 2.51 KB
/
trace.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package interp
import (
"fmt"
"reflect"
"strings"
)
// Set trace to true for debugging the cfg and other processes.
var trace = false
func traceIndent(n *node) string {
return strings.Repeat(" ", n.depth())
}
// tracePrintln works like fmt.Println, with indenting by depth
// and key info on given node.
func tracePrintln(n *node, v ...any) {
if !trace {
return
}
fmt.Println(append([]any{traceIndent(n), n}, v...)...)
}
// tracePrintTree is particularly useful in post-order for seeing the full
// structure of a given code segment of interest.
//
//nolint:unused // debugging facility
func tracePrintTree(n *node, v ...any) {
if !trace {
return
}
tracePrintln(n, v...)
n.Walk(func(n *node) bool {
tracePrintln(n)
return true
}, nil)
}
// nodeAddr returns the pointer address of node, short version.
func ptrAddr(v any) string {
p := fmt.Sprintf("%p", v)
return p[:2] + p[9:] // unique bits
}
// valString returns string rep of given value, showing underlying pointers etc.
//
//nolint:unused // debugging facility
func valString(v reflect.Value) string {
s := v.String()
if v.Kind() == reflect.Func || v.Kind() == reflect.Map || v.Kind() == reflect.Pointer || v.Kind() == reflect.Slice || v.Kind() == reflect.UnsafePointer {
p := fmt.Sprintf("%#x", v.Pointer())
ln := len(p)
s += " " + p[:2] + p[max(2, ln-4):]
}
return s
}
func (n *node) String() string {
s := n.kind.String()
if n.ident != "" {
s += " " + n.ident
}
s += " " + ptrAddr(n)
if n.sym != nil {
s += " sym:" + n.sym.String()
} else if n.typ != nil {
s += " typ:" + n.typ.String()
}
if n.findex >= 0 {
s += fmt.Sprintf(" fidx: %d lev: %d", n.findex, n.level)
}
if n.start != nil && n.start != n {
s += fmt.Sprintf(" ->start: %s %s", n.start.kind.String(), ptrAddr(n.start))
}
if n.tnext != nil {
s += fmt.Sprintf(" ->tnext: %s %s", n.tnext.kind.String(), ptrAddr(n.tnext))
}
if n.fnext != nil {
s += fmt.Sprintf(" ->fnext: %s %s", n.fnext.kind.String(), ptrAddr(n.fnext))
}
return s
}
func (n *node) depth() int {
if n.anc != nil {
return n.anc.depth() + 1
}
return 0
}
func (sy *symbol) String() string {
s := sy.kind.String()
if sy.typ != nil {
s += " (" + sy.typ.String() + ")"
}
if sy.rval.IsValid() {
s += " = " + sy.rval.String()
}
if sy.index >= 0 {
s += fmt.Sprintf(" idx: %d", sy.index)
}
if sy.node != nil {
s += " " + sy.node.String()
}
return s
}
func (t *itype) String() string {
if t.str != "" {
return t.str
}
s := t.cat.String()
if t.name != "" {
s += " (" + t.name + ")"
}
return s
}