@@ -9,100 +9,38 @@ import (
9
9
"cmd/internal/obj"
10
10
"fmt"
11
11
"os"
12
+ "sort"
12
13
)
13
14
14
15
/*
15
16
* runtime interface and reflection data structures
16
17
*/
17
18
var signatlist * NodeList
18
19
19
- func sigcmp (a * Sig , b * Sig ) int {
20
- i := stringsCompare (a .name , b .name )
21
- if i != 0 {
22
- return i
20
+ // byMethodNameAndPackagePath sorts method signatures by name, then package path.
21
+ type byMethodNameAndPackagePath []* Sig
22
+
23
+ func (x byMethodNameAndPackagePath ) Len () int { return len (x ) }
24
+ func (x byMethodNameAndPackagePath ) Swap (i , j int ) { x [i ], x [j ] = x [j ], x [i ] }
25
+ func (x byMethodNameAndPackagePath ) Less (i , j int ) bool {
26
+ return siglt (x [i ], x [j ])
27
+ }
28
+
29
+ // siglt reports whether a < b
30
+ func siglt (a , b * Sig ) bool {
31
+ if a .name != b .name {
32
+ return a .name < b .name
23
33
}
24
34
if a .pkg == b .pkg {
25
- return 0
35
+ return false
26
36
}
27
37
if a .pkg == nil {
28
- return - 1
38
+ return true
29
39
}
30
40
if b .pkg == nil {
31
- return + 1
32
- }
33
- return stringsCompare (a .pkg .Path , b .pkg .Path )
34
- }
35
-
36
- func lsort (l * Sig , f func (* Sig , * Sig ) int ) * Sig {
37
- if l == nil || l .link == nil {
38
- return l
39
- }
40
-
41
- l1 := l
42
- l2 := l
43
- for {
44
- l2 = l2 .link
45
- if l2 == nil {
46
- break
47
- }
48
- l2 = l2 .link
49
- if l2 == nil {
50
- break
51
- }
52
- l1 = l1 .link
53
- }
54
-
55
- l2 = l1 .link
56
- l1 .link = nil
57
- l1 = lsort (l , f )
58
- l2 = lsort (l2 , f )
59
-
60
- /* set up lead element */
61
- if f (l1 , l2 ) < 0 {
62
- l = l1
63
- l1 = l1 .link
64
- } else {
65
- l = l2
66
- l2 = l2 .link
67
- }
68
-
69
- le := l
70
-
71
- for {
72
- if l1 == nil {
73
- for l2 != nil {
74
- le .link = l2
75
- le = l2
76
- l2 = l2 .link
77
- }
78
-
79
- le .link = nil
80
- break
81
- }
82
-
83
- if l2 == nil {
84
- for l1 != nil {
85
- le .link = l1
86
- le = l1
87
- l1 = l1 .link
88
- }
89
-
90
- break
91
- }
92
-
93
- if f (l1 , l2 ) < 0 {
94
- le .link = l1
95
- le = l1
96
- l1 = l1 .link
97
- } else {
98
- le .link = l2
99
- le = l2
100
- l2 = l2 .link
101
- }
41
+ return false
102
42
}
103
-
104
- le .link = nil
105
- return l
43
+ return a .pkg .Path < b .pkg .Path
106
44
}
107
45
108
46
// Builds a type representing a Bucket structure for
@@ -335,11 +273,9 @@ func methodfunc(f *Type, receiver *Type) *Type {
335
273
return t
336
274
}
337
275
338
- /*
339
- * return methods of non-interface type t, sorted by name.
340
- * generates stub functions as needed.
341
- */
342
- func methods (t * Type ) * Sig {
276
+ // methods returns the methods of the non-interface type t, sorted by name.
277
+ // Generates stub functions as needed.
278
+ func methods (t * Type ) []* Sig {
343
279
// method type
344
280
mt := methtype (t , 0 )
345
281
@@ -357,11 +293,7 @@ func methods(t *Type) *Sig {
357
293
358
294
// make list of methods for t,
359
295
// generating code if necessary.
360
- var a * Sig
361
-
362
- var this * Type
363
- var b * Sig
364
- var method * Sym
296
+ var ms []* Sig
365
297
for f := mt .Xmethod ; f != nil ; f = f .Down {
366
298
if f .Etype != TFIELD {
367
299
Fatalf ("methods: not field %v" , f )
@@ -376,7 +308,7 @@ func methods(t *Type) *Sig {
376
308
continue
377
309
}
378
310
379
- method = f .Sym
311
+ method : = f .Sym
380
312
if method == nil {
381
313
continue
382
314
}
@@ -385,7 +317,7 @@ func methods(t *Type) *Sig {
385
317
// if pointer receiver but non-pointer t and
386
318
// this is not an embedded pointer inside a struct,
387
319
// method does not apply.
388
- this = getthisx (f .Type ).Type .Type
320
+ this : = getthisx (f .Type ).Type .Type
389
321
390
322
if Isptr [this .Etype ] && this .Type == t {
391
323
continue
@@ -394,85 +326,77 @@ func methods(t *Type) *Sig {
394
326
continue
395
327
}
396
328
397
- b = new (Sig )
398
- b .link = a
399
- a = b
329
+ var sig Sig
330
+ ms = append (ms , & sig )
400
331
401
- a .name = method .Name
332
+ sig .name = method .Name
402
333
if ! exportname (method .Name ) {
403
334
if method .Pkg == nil {
404
335
Fatalf ("methods: missing package" )
405
336
}
406
- a .pkg = method .Pkg
337
+ sig .pkg = method .Pkg
407
338
}
408
339
409
- a .isym = methodsym (method , it , 1 )
410
- a .tsym = methodsym (method , t , 0 )
411
- a .type_ = methodfunc (f .Type , t )
412
- a .mtype = methodfunc (f .Type , nil )
340
+ sig .isym = methodsym (method , it , 1 )
341
+ sig .tsym = methodsym (method , t , 0 )
342
+ sig .type_ = methodfunc (f .Type , t )
343
+ sig .mtype = methodfunc (f .Type , nil )
413
344
414
- if a .isym .Flags & SymSiggen == 0 {
415
- a .isym .Flags |= SymSiggen
345
+ if sig .isym .Flags & SymSiggen == 0 {
346
+ sig .isym .Flags |= SymSiggen
416
347
if ! Eqtype (this , it ) || this .Width < Types [Tptr ].Width {
417
348
compiling_wrappers = 1
418
- genwrapper (it , f , a .isym , 1 )
349
+ genwrapper (it , f , sig .isym , 1 )
419
350
compiling_wrappers = 0
420
351
}
421
352
}
422
353
423
- if a .tsym .Flags & SymSiggen == 0 {
424
- a .tsym .Flags |= SymSiggen
354
+ if sig .tsym .Flags & SymSiggen == 0 {
355
+ sig .tsym .Flags |= SymSiggen
425
356
if ! Eqtype (this , t ) {
426
357
compiling_wrappers = 1
427
- genwrapper (t , f , a .tsym , 0 )
358
+ genwrapper (t , f , sig .tsym , 0 )
428
359
compiling_wrappers = 0
429
360
}
430
361
}
431
362
}
432
363
433
- return lsort (a , sigcmp )
364
+ sort .Sort (byMethodNameAndPackagePath (ms ))
365
+ return ms
434
366
}
435
367
436
- /*
437
- * return methods of interface type t, sorted by name.
438
- */
439
- func imethods (t * Type ) * Sig {
440
- var a * Sig
441
- var method * Sym
442
- var isym * Sym
443
-
444
- var all * Sig
445
- var last * Sig
368
+ // imethods returns the methods of the interface type t, sorted by name.
369
+ func imethods (t * Type ) []* Sig {
370
+ var methods []* Sig
446
371
for f := t .Type ; f != nil ; f = f .Down {
447
372
if f .Etype != TFIELD {
448
373
Fatalf ("imethods: not field" )
449
374
}
450
375
if f .Type .Etype != TFUNC || f .Sym == nil {
451
376
continue
452
377
}
453
- method = f .Sym
454
- a = new (Sig )
455
- a .name = method .Name
378
+ method := f .Sym
379
+ var sig = Sig {
380
+ name : method .Name ,
381
+ }
456
382
if ! exportname (method .Name ) {
457
383
if method .Pkg == nil {
458
384
Fatalf ("imethods: missing package" )
459
385
}
460
- a .pkg = method .Pkg
386
+ sig .pkg = method .Pkg
461
387
}
462
388
463
- a .mtype = f .Type
464
- a .offset = 0
465
- a .type_ = methodfunc (f .Type , nil )
389
+ sig .mtype = f .Type
390
+ sig .offset = 0
391
+ sig .type_ = methodfunc (f .Type , nil )
466
392
467
- if last != nil && sigcmp (last , a ) >= 0 {
468
- Fatalf ("sigcmp vs sortinter %s %s" , last .name , a .name )
469
- }
470
- if last == nil {
471
- all = a
472
- } else {
473
- last .link = a
393
+ if n := len (methods ); n > 0 {
394
+ last := methods [n - 1 ]
395
+ if ! (siglt (last , & sig )) {
396
+ Fatalf ("sigcmp vs sortinter %s %s" , last .name , sig .name )
397
+ }
474
398
}
475
- last = a
399
+ methods = append ( methods , & sig )
476
400
477
401
// Compiler can only refer to wrappers for non-blank methods.
478
402
if isblanksym (method ) {
@@ -483,15 +407,15 @@ func imethods(t *Type) *Sig {
483
407
// IfaceType.Method is not in the reflect data.
484
408
// Generate the method body, so that compiled
485
409
// code can refer to it.
486
- isym = methodsym (method , t , 0 )
410
+ isym : = methodsym (method , t , 0 )
487
411
488
412
if isym .Flags & SymSiggen == 0 {
489
413
isym .Flags |= SymSiggen
490
414
genwrapper (t , f , isym , 0 )
491
415
}
492
416
}
493
417
494
- return all
418
+ return methods
495
419
}
496
420
497
421
var dimportpath_gopkg * Pkg
@@ -559,7 +483,7 @@ func dgopkgpath(s *Sym, ot int, pkg *Pkg) int {
559
483
*/
560
484
func dextratype (sym * Sym , off int , t * Type , ptroff int ) int {
561
485
m := methods (t )
562
- if t .Sym == nil && m == nil {
486
+ if t .Sym == nil && len ( m ) == 0 {
563
487
return off
564
488
}
565
489
@@ -568,10 +492,8 @@ func dextratype(sym *Sym, off int, t *Type, ptroff int) int {
568
492
569
493
dsymptr (sym , ptroff , sym , off )
570
494
571
- n := 0
572
- for a := m ; a != nil ; a = a .link {
495
+ for _ , a := range m {
573
496
dtypesym (a .type_ )
574
- n ++
575
497
}
576
498
577
499
ot := off
@@ -591,11 +513,12 @@ func dextratype(sym *Sym, off int, t *Type, ptroff int) int {
591
513
// slice header
592
514
ot = dsymptr (s , ot , s , ot + Widthptr + 2 * Widthint )
593
515
516
+ n := len (m )
594
517
ot = duintxx (s , ot , uint64 (n ), Widthint )
595
518
ot = duintxx (s , ot , uint64 (n ), Widthint )
596
519
597
520
// methods
598
- for a := m ; a != nil ; a = a . link {
521
+ for _ , a := range m {
599
522
// method
600
523
// ../../runtime/type.go:/method
601
524
ot = dgostringptr (s , ot , a .name )
@@ -1171,28 +1094,27 @@ ok:
1171
1094
1172
1095
case TINTER :
1173
1096
m := imethods (t )
1174
- n := 0
1175
- for a := m ; a != nil ; a = a . link {
1097
+ n := len ( m )
1098
+ for _ , a := range m {
1176
1099
dtypesym (a .type_ )
1177
- n ++
1178
1100
}
1179
1101
1180
- // ../../runtime/type.go:/InterfaceType
1102
+ // ../../../ runtime/type.go:/InterfaceType
1181
1103
ot = dcommontype (s , ot , t )
1182
1104
1183
1105
xt = ot - 2 * Widthptr
1184
1106
ot = dsymptr (s , ot , s , ot + Widthptr + 2 * Widthint )
1185
1107
ot = duintxx (s , ot , uint64 (n ), Widthint )
1186
1108
ot = duintxx (s , ot , uint64 (n ), Widthint )
1187
- for a := m ; a != nil ; a = a . link {
1188
- // ../../runtime/type.go:/imethod
1109
+ for _ , a := range m {
1110
+ // ../../../ runtime/type.go:/imethod
1189
1111
ot = dgostringptr (s , ot , a .name )
1190
1112
1191
1113
ot = dgopkgpath (s , ot , a .pkg )
1192
1114
ot = dsymptr (s , ot , dtypesym (a .type_ ), 0 )
1193
1115
}
1194
1116
1195
- // ../../runtime/type.go:/MapType
1117
+ // ../../../ runtime/type.go:/MapType
1196
1118
case TMAP :
1197
1119
s1 := dtypesym (t .Down )
1198
1120
0 commit comments