// tflag is documented in reflect/type.go.
//
// tflag values must be kept in sync with copies in:
-// - cmd/compile/internal/reflectdata/reflect.go
-// - cmd/link/internal/ld/decodesym.go
-// - reflect/type.go
-// - runtime/type.go
+// - cmd/compile/internal/reflectdata/reflect.go
+// - cmd/link/internal/ld/decodesym.go
+// - reflect/type.go
+// - runtime/type.go
const (
tflagUncommon = 1 << 0
tflagExtraStar = 1 << 1
// type itab struct {
// inter *interfacetype
// _type *_type
- // hash uint32
+ // hash uint32 // copy of _type.hash. Used for type switches.
// _ [4]byte
- // fun [1]uintptr // variable sized
+ // fun [1]uintptr // variable sized. fun[0]==0 means _type does not implement inter.
// }
o := objw.SymPtr(lsym, 0, writeType(iface), 0)
o = objw.SymPtr(lsym, o, writeType(typ), 0)
o = objw.Uint32(lsym, o, types.TypeHash(typ)) // copy of type hash
o += 4 // skip unused field
+ if !completeItab {
+ // If typ doesn't implement iface, make method entries be zero.
+ o = objw.Uintptr(lsym, o, 0)
+ entries = entries[:0]
+ }
for _, fn := range entries {
- if !completeItab {
- // If typ doesn't implement iface, make method entries be zero.
- o = objw.Uintptr(lsym, o, 0)
- } else {
- o = objw.SymPtrWeak(lsym, o, fn, 0) // method pointer for each method
- }
+ o = objw.SymPtrWeak(lsym, o, fn, 0) // method pointer for each method
}
// Nothing writes static itabs, so they are read only.
objw.Global(lsym, int32(o), int16(obj.DUPOK|obj.RODATA))
// Also wraps methods on instantiated generic types for use in itab entries.
// For an instantiated generic type G[int], we generate wrappers like:
// G[int] pointer shaped:
+//
// func (x G[int]) f(arg) {
// .inst.G[int].f(dictionary, x, arg)
-// }
+// }
+//
// G[int] not pointer shaped:
+//
// func (x *G[int]) f(arg) {
// .inst.G[int].f(dictionary, *x, arg)
-// }
+// }
+//
// These wrappers are always fully stenciled.
func methodWrapper(rcvr *types.Type, method *types.Field, forItab bool) *obj.LSym {
orig := rcvr