@@ -1386,27 +1386,18 @@ func (pr *pkgReader) dictNameOf(dict *readerDict) *ir.Name {
1386
1386
reflectdata .MarkTypeUsedInInterface (typ , lsym )
1387
1387
}
1388
1388
1389
- // For each (typ, iface) pair, we write *runtime._type pointers
1390
- // for typ and iface, as well as the *runtime.itab pointer for the
1391
- // pair. This is wasteful, but it simplifies worrying about tricky
1392
- // cases like instantiating type parameters with interface types.
1393
- //
1394
- // TODO(mdempsky): Add the needed *runtime._type pointers into the
1395
- // rtypes section above instead, and omit itabs entries when we
1396
- // statically know it won't be needed.
1389
+ // For each (typ, iface) pair, we write the *runtime.itab pointer
1390
+ // for the pair. For pairs that don't actually require an itab
1391
+ // (i.e., typ is an interface, or iface is an empty interface), we
1392
+ // write a nil pointer instead. This is wasteful, but rare in
1393
+ // practice (e.g., instantiating a type parameter with an interface
1394
+ // type).
1397
1395
assertOffset ("itabs" , dict .itabsOffset ())
1398
1396
for _ , info := range dict .itabs {
1399
1397
typ := pr .typIdx (info .typ , dict , true )
1400
1398
iface := pr .typIdx (info .iface , dict , true )
1401
1399
1402
- if ! iface .IsInterface () {
1403
- ot += 3 * types .PtrSize
1404
- continue
1405
- }
1406
-
1407
- ot = objw .SymPtr (lsym , ot , reflectdata .TypeLinksym (typ ), 0 )
1408
- ot = objw .SymPtr (lsym , ot , reflectdata .TypeLinksym (iface ), 0 )
1409
- if ! typ .IsInterface () && ! iface .IsEmptyInterface () {
1400
+ if ! typ .IsInterface () && iface .IsInterface () && ! iface .IsEmptyInterface () {
1410
1401
ot = objw .SymPtr (lsym , ot , reflectdata .ITabLsym (typ , iface ), 0 )
1411
1402
} else {
1412
1403
ot += types .PtrSize
@@ -1452,7 +1443,7 @@ func (dict *readerDict) itabsOffset() int {
1452
1443
// numWords returns the total number of words that comprise dict's
1453
1444
// runtime dictionary variable.
1454
1445
func (dict * readerDict ) numWords () int64 {
1455
- return int64 (dict .itabsOffset () + 3 * len (dict .itabs ))
1446
+ return int64 (dict .itabsOffset () + len (dict .itabs ))
1456
1447
}
1457
1448
1458
1449
// varType returns the type of dict's runtime dictionary variable.
@@ -3152,28 +3143,35 @@ func (r *reader) varDictIndex(name *ir.Name) {
3152
3143
}
3153
3144
}
3154
3145
3146
+ // itab returns a (typ, iface) pair of types.
3147
+ //
3148
+ // typRType and ifaceRType are expressions that evaluate to the
3149
+ // *runtime._type for typ and iface, respectively.
3150
+ //
3151
+ // If typ is a concrete type and iface is a non-empty interface type,
3152
+ // then itab is an expression that evaluates to the *runtime.itab for
3153
+ // the pair. Otherwise, itab is nil.
3155
3154
func (r * reader ) itab (pos src.XPos ) (typ * types.Type , typRType ir.Node , iface * types.Type , ifaceRType ir.Node , itab ir.Node ) {
3156
- if r .Bool () { // derived types
3157
- idx := r .Len ()
3158
- info := r .dict .itabs [idx ]
3159
- typ = r .p .typIdx (info .typ , r .dict , true )
3160
- typRType = r .rttiWord (pos , r .dict .itabsOffset ()+ 3 * idx )
3161
- iface = r .p .typIdx (info .iface , r .dict , true )
3162
- ifaceRType = r .rttiWord (pos , r .dict .itabsOffset ()+ 3 * idx + 1 )
3163
- itab = r .rttiWord (pos , r .dict .itabsOffset ()+ 3 * idx + 2 )
3164
- return
3155
+ typ , typRType = r .rtype0 (pos )
3156
+ iface , ifaceRType = r .rtype0 (pos )
3157
+
3158
+ idx := - 1
3159
+ if r .Bool () {
3160
+ idx = r .Len ()
3165
3161
}
3166
3162
3167
- typ = r .typ ()
3168
- iface = r .typ ()
3169
- if iface .IsInterface () {
3170
- typRType = reflectdata .TypePtrAt (pos , typ )
3171
- ifaceRType = reflectdata .TypePtrAt (pos , iface )
3172
- if ! typ .IsInterface () && ! iface .IsEmptyInterface () {
3163
+ if ! typ .IsInterface () && iface .IsInterface () && ! iface .IsEmptyInterface () {
3164
+ if idx >= 0 {
3165
+ itab = r .rttiWord (pos , r .dict .itabsOffset ()+ idx )
3166
+ } else {
3167
+ base .AssertfAt (! typ .HasShape (), pos , "%v is a shape type" , typ )
3168
+ base .AssertfAt (! iface .HasShape (), pos , "%v is a shape type" , iface )
3169
+
3173
3170
lsym := reflectdata .ITabLsym (typ , iface )
3174
3171
itab = typecheck .LinksymAddr (pos , lsym , types .Types [types .TUINT8 ])
3175
3172
}
3176
3173
}
3174
+
3177
3175
return
3178
3176
}
3179
3177
@@ -3215,9 +3213,7 @@ func (r *reader) exprType() ir.Node {
3215
3213
3216
3214
if r .Bool () {
3217
3215
typ , rtype , _ , _ , itab = r .itab (pos )
3218
- if typ .IsInterface () {
3219
- itab = nil
3220
- } else {
3216
+ if ! typ .IsInterface () {
3221
3217
rtype = nil // TODO(mdempsky): Leave set?
3222
3218
}
3223
3219
} else {
0 commit comments