1
2
3
4
5 package types
6
7 import (
8 "cmd/internal/obj"
9 "cmd/internal/objabi"
10 "fmt"
11 "sort"
12 "sync"
13 )
14
15
16 var pkgMap = make(map[string]*Pkg)
17
18
19 const MaxPkgHeight = 1e9
20
21 type Pkg struct {
22 Path string
23 Name string
24 Prefix string
25 Syms map[string]*Sym
26 Pathsym *obj.LSym
27
28
29
30
31
32 Height int
33
34 Direct bool
35 }
36
37
38
39
40 func NewPkg(path, name string) *Pkg {
41 if p := pkgMap[path]; p != nil {
42 if name != "" && p.Name != name {
43 panic(fmt.Sprintf("conflicting package names %s and %s for path %q", p.Name, name, path))
44 }
45 return p
46 }
47
48 p := new(Pkg)
49 p.Path = path
50 p.Name = name
51 p.Prefix = objabi.PathToPrefix(path)
52 p.Syms = make(map[string]*Sym)
53 pkgMap[path] = p
54
55 return p
56 }
57
58
59
60 func ImportedPkgList() []*Pkg {
61 var list []*Pkg
62 for _, p := range pkgMap {
63 if p.Direct {
64 list = append(list, p)
65 }
66 }
67 sort.Sort(byPath(list))
68 return list
69 }
70
71 type byPath []*Pkg
72
73 func (a byPath) Len() int { return len(a) }
74 func (a byPath) Less(i, j int) bool { return a[i].Path < a[j].Path }
75 func (a byPath) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
76
77 var nopkg = &Pkg{
78 Syms: make(map[string]*Sym),
79 }
80
81 func (pkg *Pkg) Lookup(name string) *Sym {
82 s, _ := pkg.LookupOK(name)
83 return s
84 }
85
86
87 func (pkg *Pkg) LookupOK(name string) (s *Sym, existed bool) {
88
89 if pkg == nil {
90 pkg = nopkg
91 }
92 if s := pkg.Syms[name]; s != nil {
93 return s, true
94 }
95
96 s = &Sym{
97 Name: name,
98 Pkg: pkg,
99 }
100 pkg.Syms[name] = s
101 return s, false
102 }
103
104 func (pkg *Pkg) LookupBytes(name []byte) *Sym {
105
106 if pkg == nil {
107 pkg = nopkg
108 }
109 if s := pkg.Syms[string(name)]; s != nil {
110 return s
111 }
112 str := InternString(name)
113 return pkg.Lookup(str)
114 }
115
116 var (
117 internedStringsmu sync.Mutex
118 internedStrings = map[string]string{}
119 )
120
121 func InternString(b []byte) string {
122 internedStringsmu.Lock()
123 s, ok := internedStrings[string(b)]
124 if !ok {
125 s = string(b)
126 internedStrings[s] = s
127 }
128 internedStringsmu.Unlock()
129 return s
130 }
131
132
133
134 func CleanroomDo(f func()) {
135 saved := pkgMap
136 pkgMap = make(map[string]*Pkg)
137 f()
138 pkgMap = saved
139 }
140
141 func IsDotAlias(sym *Sym) bool {
142 return sym.Def != nil && sym.Def.Sym() != sym
143 }
144
View as plain text