@@ -42,9 +42,39 @@ func (prog *Program) MethodValue(sel *types.Selection) *Function {
42
42
43
43
var cr creator
44
44
45
- prog .methodsMu .Lock ()
46
- m := prog .addMethod (prog .createMethodSet (T ), sel , & cr )
47
- prog .methodsMu .Unlock ()
45
+ m := func () * Function {
46
+ prog .methodsMu .Lock ()
47
+ defer prog .methodsMu .Unlock ()
48
+
49
+ // Get or create SSA method set.
50
+ mset , ok := prog .methodSets .At (T ).(* methodSet )
51
+ if ! ok {
52
+ mset = & methodSet {mapping : make (map [string ]* Function )}
53
+ prog .methodSets .Set (T , mset )
54
+ }
55
+
56
+ // Get or create SSA method.
57
+ id := sel .Obj ().Id ()
58
+ fn , ok := mset .mapping [id ]
59
+ if ! ok {
60
+ obj := sel .Obj ().(* types.Func )
61
+ _ , ptrObj := deptr (recvType (obj ))
62
+ _ , ptrRecv := deptr (T )
63
+ needsPromotion := len (sel .Index ()) > 1
64
+ needsIndirection := ! ptrObj && ptrRecv
65
+ if needsPromotion || needsIndirection {
66
+ fn = createWrapper (prog , toSelection (sel ), & cr )
67
+ } else {
68
+ fn = prog .objectMethod (obj , & cr )
69
+ }
70
+ if fn .Signature .Recv () == nil {
71
+ panic (fn )
72
+ }
73
+ mset .mapping [id ] = fn
74
+ }
75
+
76
+ return fn
77
+ }()
48
78
49
79
b := builder {created : & cr }
50
80
b .iterate ()
@@ -111,54 +141,6 @@ type methodSet struct {
111
141
mapping map [string ]* Function // populated lazily
112
142
}
113
143
114
- // Precondition: T is a concrete type, e.g. !isInterface(T) and not parameterized.
115
- // Requires prog.methodsMu.
116
- func (prog * Program ) createMethodSet (T types.Type ) * methodSet {
117
- if prog .mode & SanityCheckFunctions != 0 {
118
- if types .IsInterface (T ) || prog .parameterized .isParameterized (T ) {
119
- panic ("type is interface or parameterized" )
120
- }
121
- }
122
-
123
- mset , ok := prog .methodSets .At (T ).(* methodSet )
124
- if ! ok {
125
- mset = & methodSet {mapping : make (map [string ]* Function )}
126
- prog .methodSets .Set (T , mset )
127
- }
128
- return mset
129
- }
130
-
131
- // Adds any created functions to cr.
132
- // Precondition: T is a concrete type, e.g. !isInterface(T) and not parameterized.
133
- // Requires prog.methodsMu.
134
- func (prog * Program ) addMethod (mset * methodSet , sel * types.Selection , cr * creator ) * Function {
135
- if sel .Kind () == types .MethodExpr {
136
- panic (sel )
137
- }
138
- id := sel .Obj ().Id ()
139
- fn := mset .mapping [id ]
140
- if fn == nil {
141
- sel := toSelection (sel )
142
- obj := sel .obj .(* types.Func )
143
-
144
- _ , ptrObj := deptr (recvType (obj ))
145
- _ , ptrRecv := deptr (sel .recv )
146
-
147
- needsPromotion := len (sel .index ) > 1
148
- needsIndirection := ! ptrObj && ptrRecv
149
- if needsPromotion || needsIndirection {
150
- fn = createWrapper (prog , sel , cr )
151
- } else {
152
- fn = prog .objectMethod (obj , cr )
153
- }
154
- if fn .Signature .Recv () == nil {
155
- panic (fn ) // missing receiver
156
- }
157
- mset .mapping [id ] = fn
158
- }
159
- return fn
160
- }
161
-
162
144
// RuntimeTypes returns a new unordered slice containing all types in
163
145
// the program for which a runtime type is required.
164
146
//
0 commit comments