internal/abi: move direct/indirect flag from Kind to TFlag

This info makes more sense in the flags instead of as a high
bit of the kind. This makes kind access simpler because we now
don't need to mask anything.

Cleaned up most direct field accesses to use methods instead.
(reflect making new types is the only remaining direct accessor.)

IfaceIndir -> !IsDirectIface everywhere.

gocore has been updated to handle the new location. So has delve.
TODO: any other tools need updating?

Change-Id: I123f97a4d4bdd0bff1641ee7e276d1cc0bd7e8eb
Reviewed-on: https://go-review.googlesource.com/c/go/+/681936
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: David Chase <drchase@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
Keith Randall
2025-06-14 17:06:20 -07:00
parent e0b07dc22e
commit f7d167fe71
29 changed files with 95 additions and 110 deletions

View File

@@ -491,6 +491,9 @@ func dcommontype(c rttype.Cursor, t *types.Type) {
exported = types.IsExported(t.Elem().Sym().Name)
}
}
if types.IsDirectIface(t) {
tflag |= abi.TFlagDirectIface
}
if tflag != abi.TFlag(uint8(tflag)) {
// this should optimize away completely
@@ -511,9 +514,6 @@ func dcommontype(c rttype.Cursor, t *types.Type) {
c.Field("FieldAlign_").WriteUint8(uint8(t.Alignment()))
kind := kinds[t.Kind()]
if types.IsDirectIface(t) {
kind |= abi.KindDirectIface
}
c.Field("Kind_").WriteUint8(uint8(kind))
c.Field("Equal").WritePtr(eqfunc)

View File

@@ -47,7 +47,6 @@ func TestIntendedInlining(t *testing.T) {
"getMCache",
"heapSetTypeNoHeader",
"heapSetTypeSmallHeader",
"isDirectIface",
"itabHashFunc",
"nextslicecap",
"noescape",
@@ -109,6 +108,7 @@ func TestIntendedInlining(t *testing.T) {
"(*Buffer).tryGrowByReslice",
},
"internal/abi": {
"(*Type).IsDirectIface",
"UseInterfaceSwitchCache",
},
"internal/runtime/math": {

View File

@@ -38,7 +38,7 @@ func uncommonSize(arch *sys.Arch) int { return int(abi.UncommonSize()) }
// Type.commonType.kind
func decodetypeKind(arch *sys.Arch, p []byte) abi.Kind {
return abi.Kind(p[2*arch.PtrSize+7]) & abi.KindMask // 0x13 / 0x1f
return abi.Kind(p[2*arch.PtrSize+7]) // 0x13
}
// Type.commonType.size

View File

@@ -24,7 +24,7 @@ type Type struct {
TFlag TFlag // extra type information flags
Align_ uint8 // alignment of variable with this type
FieldAlign_ uint8 // alignment of struct field with this type
Kind_ Kind // enumeration for C
Kind_ Kind // what kind of type this is (string, int, ...)
// function for comparing objects of this type
// (ptr to object A, ptr to object B) -> ==?
Equal func(unsafe.Pointer, unsafe.Pointer) bool
@@ -78,12 +78,6 @@ const (
UnsafePointer
)
const (
// TODO (khr, drchase) why aren't these in TFlag? Investigate, fix if possible.
KindDirectIface Kind = 1 << 5
KindMask Kind = (1 << 5) - 1
)
// TFlag is used by a Type to signal what extra type information is
// available in the memory directly following the Type value.
type TFlag uint8
@@ -125,6 +119,15 @@ const (
// has type **byte instead of *byte. The runtime will store a
// pointer to the GC pointer bitmask in *GCData.
TFlagGCMaskOnDemand TFlag = 1 << 4
// TFlagDirectIface means that a value of this type is stored directly
// in the data field of an interface, instead of indirectly. Normally
// this means the type is pointer-ish.
TFlagDirectIface TFlag = 1 << 5
// Leaving this breadcrumb behind for dlv. It should not be used, and no
// Kind should be big enough to set this bit.
KindDirectIface Kind = 1 << 5
)
// NameOff is the offset to a name from moduledata.types. See resolveNameOff in runtime.
@@ -190,7 +193,7 @@ func TypeFor[T any]() *Type {
return (*PtrType)(unsafe.Pointer(TypeOf((*T)(nil)))).Elem
}
func (t *Type) Kind() Kind { return t.Kind_ & KindMask }
func (t *Type) Kind() Kind { return t.Kind_ }
func (t *Type) HasName() bool {
return t.TFlag&TFlagNamed != 0
@@ -199,14 +202,9 @@ func (t *Type) HasName() bool {
// Pointers reports whether t contains pointers.
func (t *Type) Pointers() bool { return t.PtrBytes != 0 }
// IfaceIndir reports whether t is stored indirectly in an interface value.
func (t *Type) IfaceIndir() bool {
return t.Kind_&KindDirectIface == 0
}
// isDirectIface reports whether t is stored directly in an interface value.
// IsDirectIface reports whether t is stored directly in an interface value.
func (t *Type) IsDirectIface() bool {
return t.Kind_&KindDirectIface != 0
return t.TFlag&TFlagDirectIface != 0
}
func (t *Type) GcSlice(begin, end uintptr) []byte {

View File

@@ -70,7 +70,7 @@ func Zero(typ Type) Value {
}
t := typ.common()
fl := flag(t.Kind())
if t.IfaceIndir() {
if !t.IsDirectIface() {
return Value{t, unsafe_New(t), fl | flagIndir}
}
return Value{t, nil, fl}

View File

@@ -52,7 +52,7 @@ type Value struct {
// - flagIndir: val holds a pointer to the data
// - flagAddr: v.CanAddr is true (implies flagIndir and ptr is non-nil)
// - flagMethod: v is a method value.
// If ifaceIndir(typ), code can assume that flagIndir is set.
// If !typ.IsDirectIface(), code can assume that flagIndir is set.
//
// The remaining 22+ bits give a method number for method values.
// If flag.kind() != Func, code can assume that flagMethod is unset.
@@ -118,7 +118,7 @@ func packEface(v Value) any {
e := (*abi.EmptyInterface)(unsafe.Pointer(&i))
// First, fill in the data portion of the interface.
switch {
case t.IfaceIndir():
case !t.IsDirectIface():
if v.flag&flagIndir == 0 {
panic("bad indir")
}
@@ -155,7 +155,7 @@ func unpackEface(i any) Value {
return Value{}
}
f := flag(t.Kind())
if t.IfaceIndir() {
if !t.IsDirectIface() {
f |= flagIndir
}
return Value{t, e.Data, f}

View File

@@ -859,7 +859,7 @@ func mapKeyError2(t *abi.Type, p unsafe.Pointer) error {
return unhashableTypeError{t}
}
if t.Kind_&abi.KindDirectIface != 0 {
if t.IsDirectIface() {
return mapKeyError2(t, unsafe.Pointer(pdata))
} else {
return mapKeyError2(t, *pdata)

View File

@@ -166,7 +166,7 @@ func (a *abiSeq) addRcvr(rcvr *abi.Type) (*abiStep, bool) {
// The receiver is always one word.
a.valueStart = append(a.valueStart, len(a.steps))
var ok, ptr bool
if rcvr.IfaceIndir() || rcvr.Pointers() {
if !rcvr.IsDirectIface() || rcvr.Pointers() {
ok = a.assignIntN(0, goarch.PtrSize, 1, 0b1)
ptr = true
} else {

View File

@@ -27,7 +27,7 @@ import (
//
//go:linkname unusedIfaceIndir reflect.ifaceIndir
func unusedIfaceIndir(t *abi.Type) bool {
return t.Kind_&abi.KindDirectIface == 0
return !t.IsDirectIface()
}
//go:linkname valueInterface

View File

@@ -7,7 +7,6 @@
package reflect
import (
"internal/abi"
"unsafe"
)
@@ -17,7 +16,7 @@ func MapBucketOf(x, y Type) Type {
func CachedBucketOf(m Type) Type {
t := m.(*rtype)
if Kind(t.t.Kind_&abi.KindMask) != Map {
if Kind(t.t.Kind()) != Map {
panic("not map")
}
tt := (*mapType)(unsafe.Pointer(t))

View File

@@ -65,7 +65,7 @@ func MapOf(key, elem Type) Type {
var imap any = (map[unsafe.Pointer]unsafe.Pointer)(nil)
mt := **(**mapType)(unsafe.Pointer(&imap))
mt.Str = resolveReflectName(newName(s, "", false, false))
mt.TFlag = 0
mt.TFlag = abi.TFlagDirectIface
mt.Hash = fnv1(etyp.Hash, 'm', byte(ktyp.Hash>>24), byte(ktyp.Hash>>16), byte(ktyp.Hash>>8), byte(ktyp.Hash))
mt.Key = ktyp
mt.Elem = etyp

View File

@@ -1813,7 +1813,7 @@ func ChanOf(dir ChanDir, t Type) Type {
var ichan any = (chan unsafe.Pointer)(nil)
prototype := *(**chanType)(unsafe.Pointer(&ichan))
ch := *prototype
ch.TFlag = abi.TFlagRegularMemory
ch.TFlag = abi.TFlagRegularMemory | abi.TFlagDirectIface
ch.Dir = abi.ChanDir(dir)
ch.Str = resolveReflectName(newName(s, "", false, false))
ch.Hash = fnv1(typ.Hash, 'c', byte(dir))
@@ -1894,7 +1894,7 @@ func FuncOf(in, out []Type, variadic bool) Type {
hash = fnv1(hash, byte(t.t.Hash>>24), byte(t.t.Hash>>16), byte(t.t.Hash>>8), byte(t.t.Hash))
}
ft.TFlag = 0
ft.TFlag = abi.TFlagDirectIface
ft.Hash = hash
ft.InCount = uint16(len(in))
ft.OutCount = uint16(len(out))
@@ -2313,7 +2313,7 @@ func StructOf(fields []StructField) Type {
// Issue 15924.
panic("reflect: embedded type with methods not implemented if type is not first field")
}
if len(fields) > 1 && ft.Kind_&abi.KindDirectIface != 0 {
if len(fields) > 1 && ft.IsDirectIface() {
panic("reflect: embedded type with methods not implemented for non-pointer type")
}
for _, m := range unt.Methods() {
@@ -2524,11 +2524,11 @@ func StructOf(fields []StructField) Type {
}
switch {
case len(fs) == 1 && !fs[0].Typ.IfaceIndir():
case len(fs) == 1 && fs[0].Typ.IsDirectIface():
// structs of 1 direct iface type can be direct
typ.Kind_ |= abi.KindDirectIface
typ.TFlag |= abi.TFlagDirectIface
default:
typ.Kind_ &^= abi.KindDirectIface
typ.TFlag &^= abi.TFlagDirectIface
}
return addToCache(toType(&typ.Type))
@@ -2694,11 +2694,11 @@ func ArrayOf(length int, elem Type) Type {
}
switch {
case length == 1 && !typ.IfaceIndir():
case length == 1 && typ.IsDirectIface():
// array of 1 direct iface type can be direct
array.Kind_ |= abi.KindDirectIface
array.TFlag |= abi.TFlagDirectIface
default:
array.Kind_ &^= abi.KindDirectIface
array.TFlag &^= abi.TFlagDirectIface
}
ti, _ := lookupCache.LoadOrStore(ckey, toRType(&array.Type))
@@ -2834,7 +2834,7 @@ func addTypeBits(bv *bitVector, offset uintptr, t *abi.Type) {
return
}
switch Kind(t.Kind_ & abi.KindMask) {
switch Kind(t.Kind()) {
case Chan, Func, Map, Pointer, Slice, String, UnsafePointer:
// 1 pointer at start of representation
for bv.n < uint32(offset/goarch.PtrSize) {

View File

@@ -55,7 +55,7 @@ type Value struct {
// - flagIndir: val holds a pointer to the data
// - flagAddr: v.CanAddr is true (implies flagIndir and ptr is non-nil)
// - flagMethod: v is a method value.
// If ifaceIndir(typ), code can assume that flagIndir is set.
// If !typ.IsDirectIface(), code can assume that flagIndir is set.
//
// The remaining 22+ bits give a method number for method values.
// If flag.kind() != Func, code can assume that flagMethod is unset.
@@ -125,7 +125,7 @@ func packEface(v Value) any {
e := abi.EmptyInterface{}
// First, fill in the data portion of the interface.
switch {
case t.IfaceIndir():
case !t.IsDirectIface():
if v.flag&flagIndir == 0 {
panic("bad indir")
}
@@ -159,7 +159,7 @@ func unpackEface(i any) Value {
return Value{}
}
f := flag(t.Kind())
if t.IfaceIndir() {
if !t.IsDirectIface() {
f |= flagIndir
}
return Value{t, e.Data, f}
@@ -624,7 +624,7 @@ func (v Value) call(op string, in []Value) []Value {
}
// Handle pointers passed in registers.
if !tv.IfaceIndir() {
if tv.IsDirectIface() {
// Pointer-valued data gets put directly
// into v.ptr.
if steps[0].kind != abiStepPointer {
@@ -714,7 +714,7 @@ func callReflect(ctxt *makeFuncImpl, frame unsafe.Pointer, retValid *bool, regs
v := Value{typ, nil, flag(typ.Kind())}
steps := abid.call.stepsForValue(i)
if st := steps[0]; st.kind == abiStepStack {
if typ.IfaceIndir() {
if !typ.IsDirectIface() {
// value cannot be inlined in interface data.
// Must make a copy, because f might keep a reference to it,
// and we cannot let f keep a reference to the stack frame
@@ -728,7 +728,7 @@ func callReflect(ctxt *makeFuncImpl, frame unsafe.Pointer, retValid *bool, regs
v.ptr = *(*unsafe.Pointer)(add(ptr, st.stkOff, "1-ptr"))
}
} else {
if typ.IfaceIndir() {
if !typ.IsDirectIface() {
// All that's left is values passed in registers that we need to
// create space for the values.
v.flag |= flagIndir
@@ -914,7 +914,7 @@ func storeRcvr(v Value, p unsafe.Pointer) {
// the interface data word becomes the receiver word
iface := (*nonEmptyInterface)(v.ptr)
*(*unsafe.Pointer)(p) = iface.word
} else if v.flag&flagIndir != 0 && !t.IfaceIndir() {
} else if v.flag&flagIndir != 0 && t.IsDirectIface() {
*(*unsafe.Pointer)(p) = *(*unsafe.Pointer)(v.ptr)
} else {
*(*unsafe.Pointer)(p) = v.ptr
@@ -1224,7 +1224,7 @@ func (v Value) Elem() Value {
case Pointer:
ptr := v.ptr
if v.flag&flagIndir != 0 {
if v.typ().IfaceIndir() {
if !v.typ().IsDirectIface() {
// This is a pointer to a not-in-heap object. ptr points to a uintptr
// in the heap. That uintptr is the address of a not-in-heap object.
// In general, pointers to not-in-heap objects can be total junk.
@@ -1852,7 +1852,7 @@ func (v Value) lenNonSlice() int {
// copyVal returns a Value containing the map key or value at ptr,
// allocating a new variable as needed.
func copyVal(typ *abi.Type, fl flag, ptr unsafe.Pointer) Value {
if typ.IfaceIndir() {
if !typ.IsDirectIface() {
// Copy result so future changes to the map
// won't change the underlying value.
c := unsafe_New(typ)
@@ -2076,7 +2076,7 @@ func (v Value) recv(nb bool) (val Value, ok bool) {
t := tt.Elem
val = Value{t, nil, flag(t.Kind())}
var p unsafe.Pointer
if t.IfaceIndir() {
if !t.IsDirectIface() {
p = unsafe_New(t)
val.ptr = p
val.flag |= flagIndir
@@ -2952,7 +2952,7 @@ func Select(cases []SelectCase) (chosen int, recv Value, recvOK bool) {
t := tt.Elem
p := runcases[chosen].val
fl := flag(t.Kind())
if t.IfaceIndir() {
if !t.IsDirectIface() {
recv = Value{t, p, fl | flagIndir}
} else {
recv = Value{t, *(*unsafe.Pointer)(p), fl}
@@ -3065,7 +3065,7 @@ func Zero(typ Type) Value {
}
t := &typ.(*rtype).t
fl := flag(t.Kind())
if t.IfaceIndir() {
if !t.IsDirectIface() {
var p unsafe.Pointer
if t.Size() <= abi.ZeroValSize {
p = unsafe.Pointer(&zeroVal[0])
@@ -3088,7 +3088,7 @@ func New(typ Type) Value {
}
t := &typ.(*rtype).t
pt := ptrTo(t)
if pt.IfaceIndir() {
if !pt.IsDirectIface() {
// This is a pointer to a not-in-heap type.
panic("reflect: New of type that may not be allocated in heap (possibly undefined cgo C type)")
}

View File

@@ -144,7 +144,7 @@ func interhash(p unsafe.Pointer, h uintptr) uintptr {
// we want to report the struct, not the slice).
panic(errorString("hash of unhashable type " + toRType(t).string()))
}
if isDirectIface(t) {
if t.IsDirectIface() {
return c1 * typehash(t, unsafe.Pointer(&a.data), h^c0)
} else {
return c1 * typehash(t, a.data, h^c0)
@@ -171,7 +171,7 @@ func nilinterhash(p unsafe.Pointer, h uintptr) uintptr {
// See comment in interhash above.
panic(errorString("hash of unhashable type " + toRType(t).string()))
}
if isDirectIface(t) {
if t.IsDirectIface() {
return c1 * typehash(t, unsafe.Pointer(&a.data), h^c0)
} else {
return c1 * typehash(t, a.data, h^c0)
@@ -211,7 +211,7 @@ func typehash(t *_type, p unsafe.Pointer, h uintptr) uintptr {
return memhash(p, h, t.Size_)
}
}
switch t.Kind_ & abi.KindMask {
switch t.Kind() {
case abi.Float32:
return f32hash(p, h)
case abi.Float64:
@@ -306,7 +306,7 @@ func efaceeq(t *_type, x, y unsafe.Pointer) bool {
if eq == nil {
panic(errorString("comparing uncomparable type " + toRType(t).string()))
}
if isDirectIface(t) {
if t.IsDirectIface() {
// Direct interface types are ptr, chan, map, func, and single-element structs/arrays thereof.
// Maps and funcs are not comparable, so they can't reach here.
// Ptrs, chans, and single-element items can be compared directly using ==.
@@ -323,7 +323,7 @@ func ifaceeq(tab *itab, x, y unsafe.Pointer) bool {
if eq == nil {
panic(errorString("comparing uncomparable type " + toRType(t).string()))
}
if isDirectIface(t) {
if t.IsDirectIface() {
// See comment in efaceeq.
return x == y
}

View File

@@ -111,7 +111,7 @@ func arena_newArena() unsafe.Pointer {
//go:linkname arena_arena_New arena.runtime_arena_arena_New
func arena_arena_New(arena unsafe.Pointer, typ any) any {
t := (*_type)(efaceOf(&typ).data)
if t.Kind_&abi.KindMask != abi.Pointer {
if t.Kind() != abi.Pointer {
throw("arena_New: non-pointer type")
}
te := (*ptrtype)(unsafe.Pointer(t)).Elem
@@ -145,7 +145,7 @@ func arena_heapify(s any) any {
var v unsafe.Pointer
e := efaceOf(&s)
t := e._type
switch t.Kind_ & abi.KindMask {
switch t.Kind() {
case abi.String:
v = stringStructOf((*string)(e.data)).str
case abi.Slice:
@@ -162,7 +162,7 @@ func arena_heapify(s any) any {
}
// Heap-allocate storage for a copy.
var x any
switch t.Kind_ & abi.KindMask {
switch t.Kind() {
case abi.String:
s1 := s.(string)
s2, b := rawstring(len(s1))
@@ -293,11 +293,11 @@ func (a *userArena) slice(sl any, cap int) {
}
i := efaceOf(&sl)
typ := i._type
if typ.Kind_&abi.KindMask != abi.Pointer {
if typ.Kind() != abi.Pointer {
panic("slice result of non-ptr type")
}
typ = (*ptrtype)(unsafe.Pointer(typ)).Elem
if typ.Kind_&abi.KindMask != abi.Slice {
if typ.Kind() != abi.Slice {
panic("slice of non-ptr-to-slice type")
}
typ = (*slicetype)(unsafe.Pointer(typ)).Elem

View File

@@ -543,18 +543,18 @@ func cgoCheckPointer(ptr any, arg any) {
t := ep._type
top := true
if arg != nil && (t.Kind_&abi.KindMask == abi.Pointer || t.Kind_&abi.KindMask == abi.UnsafePointer) {
if arg != nil && (t.Kind() == abi.Pointer || t.Kind() == abi.UnsafePointer) {
p := ep.data
if t.Kind_&abi.KindDirectIface == 0 {
if !t.IsDirectIface() {
p = *(*unsafe.Pointer)(p)
}
if p == nil || !cgoIsGoPointer(p) {
return
}
aep := efaceOf(&arg)
switch aep._type.Kind_ & abi.KindMask {
switch aep._type.Kind() {
case abi.Bool:
if t.Kind_&abi.KindMask == abi.UnsafePointer {
if t.Kind() == abi.UnsafePointer {
// We don't know the type of the element.
break
}
@@ -578,7 +578,7 @@ func cgoCheckPointer(ptr any, arg any) {
// Check the array rather than the pointer.
pt := (*abi.PtrType)(unsafe.Pointer(aep._type))
t = pt.Elem
if t.Kind_&abi.KindMask != abi.Array {
if t.Kind() != abi.Array {
throw("can't happen")
}
ep = aep
@@ -588,7 +588,7 @@ func cgoCheckPointer(ptr any, arg any) {
}
}
cgoCheckArg(t, ep.data, t.Kind_&abi.KindDirectIface == 0, top, cgoCheckPointerFail)
cgoCheckArg(t, ep.data, !t.IsDirectIface(), top, cgoCheckPointerFail)
}
const cgoCheckPointerFail = "cgo argument has Go pointer to unpinned Go pointer"
@@ -605,7 +605,7 @@ func cgoCheckArg(t *_type, p unsafe.Pointer, indir, top bool, msg string) {
return
}
switch t.Kind_ & abi.KindMask {
switch t.Kind() {
default:
throw("can't happen")
case abi.Array:
@@ -614,7 +614,7 @@ func cgoCheckArg(t *_type, p unsafe.Pointer, indir, top bool, msg string) {
if at.Len != 1 {
throw("can't happen")
}
cgoCheckArg(at.Elem, p, at.Elem.Kind_&abi.KindDirectIface == 0, top, msg)
cgoCheckArg(at.Elem, p, !at.Elem.IsDirectIface(), top, msg)
return
}
for i := uintptr(0); i < at.Len; i++ {
@@ -652,7 +652,7 @@ func cgoCheckArg(t *_type, p unsafe.Pointer, indir, top bool, msg string) {
if !top && !isPinned(p) {
panic(errorString(msg))
}
cgoCheckArg(it, p, it.Kind_&abi.KindDirectIface == 0, false, msg)
cgoCheckArg(it, p, !it.IsDirectIface(), false, msg)
case abi.Slice:
st := (*slicetype)(unsafe.Pointer(t))
s := (*slice)(p)
@@ -684,7 +684,7 @@ func cgoCheckArg(t *_type, p unsafe.Pointer, indir, top bool, msg string) {
if len(st.Fields) != 1 {
throw("can't happen")
}
cgoCheckArg(st.Fields[0].Typ, p, st.Fields[0].Typ.Kind_&abi.KindDirectIface == 0, top, msg)
cgoCheckArg(st.Fields[0].Typ, p, !st.Fields[0].Typ.IsDirectIface(), top, msg)
return
}
for _, f := range st.Fields {
@@ -792,5 +792,5 @@ func cgoCheckResult(val any) {
ep := efaceOf(&val)
t := ep._type
cgoCheckArg(t, ep.data, t.Kind_&abi.KindDirectIface == 0, false, cgoResultFail)
cgoCheckArg(t, ep.data, !t.IsDirectIface(), false, cgoResultFail)
}

View File

@@ -327,7 +327,7 @@ func (l *dloggerImpl) p(x any) *dloggerImpl {
l.w.uvarint(0)
} else {
v := efaceOf(&x)
switch v._type.Kind_ & abi.KindMask {
switch v._type.Kind() {
case abi.Chan, abi.Func, abi.Map, abi.Pointer, abi.UnsafePointer:
l.w.uvarint(uint64(uintptr(v.data)))
default:

View File

@@ -260,7 +260,7 @@ func printanycustomtype(i any) {
eface := efaceOf(&i)
typestring := toRType(eface._type).string()
switch eface._type.Kind_ {
switch eface._type.Kind() {
case abi.String:
print(typestring, `("`)
printindented(*(*string)(eface.data))

View File

@@ -33,13 +33,13 @@ func InjectDebugCall(gp *g, fn any, regArgs *abi.RegArgs, stackArgs any, tkill f
}
f := efaceOf(&fn)
if f._type == nil || f._type.Kind_&abi.KindMask != abi.Func {
if f._type == nil || f._type.Kind() != abi.Func {
return nil, plainError("fn must be a function")
}
fv := (*funcval)(f.data)
a := efaceOf(&stackArgs)
if a._type != nil && a._type.Kind_&abi.KindMask != abi.Pointer {
if a._type != nil && a._type.Kind() != abi.Pointer {
return nil, plainError("args must be a pointer or nil")
}
argp := a.data

View File

@@ -1773,7 +1773,7 @@ func NewUserArena() *UserArena {
func (a *UserArena) New(out *any) {
i := efaceOf(out)
typ := i._type
if typ.Kind_&abi.KindMask != abi.Pointer {
if typ.Kind() != abi.Pointer {
panic("new result of non-ptr type")
}
typ = (*ptrtype)(unsafe.Pointer(typ)).Elem

View File

@@ -206,7 +206,7 @@ func dumptype(t *_type) {
dwritebyte('.')
dwrite(unsafe.Pointer(unsafe.StringData(name)), uintptr(len(name)))
}
dumpbool(t.Kind_&abi.KindDirectIface == 0 || t.Pointers())
dumpbool(!t.IsDirectIface() || t.Pointers())
}
// dump an object.

View File

@@ -947,7 +947,7 @@ func doubleCheckTypePointersOfType(s *mspan, typ *_type, addr, size uintptr) {
if typ == nil {
return
}
if typ.Kind_&abi.KindMask == abi.Interface {
if typ.Kind() == abi.Interface {
// Interfaces are unfortunately inconsistently handled
// when it comes to the type pointer, so it's easy to
// produce a lot of false positives here.
@@ -1776,7 +1776,7 @@ func pointerMask(ep any) (mask []byte) {
t := e._type
var et *_type
if t.Kind_&abi.KindMask != abi.Pointer {
if t.Kind() != abi.Pointer {
throw("bad argument to getgcmask: expected type to be a pointer to the value type whose mask is being queried")
}
et = (*ptrtype)(unsafe.Pointer(t)).Elem

View File

@@ -251,7 +251,7 @@ func runFinalizers() {
// confusing the write barrier.
*(*[2]uintptr)(frame) = [2]uintptr{}
}
switch f.fint.Kind_ & abi.KindMask {
switch f.fint.Kind() {
case abi.Pointer:
// direct use of pointer
*(*unsafe.Pointer)(r) = f.arg
@@ -435,7 +435,7 @@ func SetFinalizer(obj any, finalizer any) {
if etyp == nil {
throw("runtime.SetFinalizer: first argument is nil")
}
if etyp.Kind_&abi.KindMask != abi.Pointer {
if etyp.Kind() != abi.Pointer {
throw("runtime.SetFinalizer: first argument is " + toRType(etyp).string() + ", not pointer")
}
ot := (*ptrtype)(unsafe.Pointer(etyp))
@@ -490,7 +490,7 @@ func SetFinalizer(obj any, finalizer any) {
return
}
if ftyp.Kind_&abi.KindMask != abi.Func {
if ftyp.Kind() != abi.Func {
throw("runtime.SetFinalizer: second argument is " + toRType(ftyp).string() + ", not a function")
}
ft := (*functype)(unsafe.Pointer(ftyp))
@@ -505,13 +505,13 @@ func SetFinalizer(obj any, finalizer any) {
case fint == etyp:
// ok - same type
goto okarg
case fint.Kind_&abi.KindMask == abi.Pointer:
case fint.Kind() == abi.Pointer:
if (fint.Uncommon() == nil || etyp.Uncommon() == nil) && (*ptrtype)(unsafe.Pointer(fint)).Elem == ot.Elem {
// ok - not same type, but both pointers,
// one or the other is unnamed, and same element type, so assignable.
goto okarg
}
case fint.Kind_&abi.KindMask == abi.Interface:
case fint.Kind() == abi.Interface:
ityp := (*interfacetype)(unsafe.Pointer(fint))
if len(ityp.Methods) == 0 {
// ok - satisfies empty interface

View File

@@ -108,7 +108,7 @@ func pinnerGetPtr(i *any) unsafe.Pointer {
if etyp == nil {
panic(errorString("runtime.Pinner: argument is nil"))
}
if kind := etyp.Kind_ & abi.KindMask; kind != abi.Pointer && kind != abi.UnsafePointer {
if kind := etyp.Kind(); kind != abi.Pointer && kind != abi.UnsafePointer {
panic(errorString("runtime.Pinner: argument is not a pointer: " + toRType(etyp).string()))
}
if inUserArenaChunk(uintptr(e.data)) {

View File

@@ -88,7 +88,7 @@ func plugin_lastmoduleinit() (path string, syms map[string]any, initTasks []*ini
(*valp)[0] = unsafe.Pointer(t)
name := symName.Name()
if t.Kind_&abi.KindMask == abi.Func {
if t.Kind() == abi.Func {
name = "." + name
}
syms[name] = val

View File

@@ -156,7 +156,7 @@ const raceenabled = true
// callerpc is a return PC of the function that calls this function,
// pc is start PC of the function that calls this function.
func raceReadObjectPC(t *_type, addr unsafe.Pointer, callerpc, pc uintptr) {
kind := t.Kind_ & abi.KindMask
kind := t.Kind()
if kind == abi.Array || kind == abi.Struct {
// for composite objects we have to read every address
// because a write might happen to any subobject.
@@ -174,7 +174,7 @@ func race_ReadObjectPC(t *abi.Type, addr unsafe.Pointer, callerpc, pc uintptr) {
}
func raceWriteObjectPC(t *_type, addr unsafe.Pointer, callerpc, pc uintptr) {
kind := t.Kind_ & abi.KindMask
kind := t.Kind()
if kind == abi.Array || kind == abi.Struct {
// for composite objects we have to write every address
// because a write might happen to any subobject.

View File

@@ -104,7 +104,7 @@ func (p *abiDesc) assignArg(t *_type) {
// registers and the stack.
panic("compileCallback: argument size is larger than uintptr")
}
if k := t.Kind_ & abi.KindMask; GOARCH != "386" && (k == abi.Float32 || k == abi.Float64) {
if k := t.Kind(); GOARCH != "386" && (k == abi.Float32 || k == abi.Float64) {
// In fastcall, floating-point arguments in
// the first four positions are passed in
// floating-point registers, which we don't
@@ -175,7 +175,7 @@ func (p *abiDesc) assignArg(t *_type) {
//
// Returns whether the assignment succeeded.
func (p *abiDesc) tryRegAssignArg(t *_type, offset uintptr) bool {
switch k := t.Kind_ & abi.KindMask; k {
switch k := t.Kind(); k {
case abi.Bool, abi.Int, abi.Int8, abi.Int16, abi.Int32, abi.Uint, abi.Uint8, abi.Uint16, abi.Uint32, abi.Uintptr, abi.Pointer, abi.UnsafePointer:
// Assign a register for all these types.
return p.assignReg(t.Size_, offset)
@@ -270,7 +270,7 @@ func compileCallback(fn eface, cdecl bool) (code uintptr) {
cdecl = false
}
if fn._type == nil || (fn._type.Kind_&abi.KindMask) != abi.Func {
if fn._type == nil || fn._type.Kind() != abi.Func {
panic("compileCallback: expected function with one uintptr-sized result")
}
ft := (*functype)(unsafe.Pointer(fn._type))
@@ -291,7 +291,7 @@ func compileCallback(fn eface, cdecl bool) (code uintptr) {
if ft.OutSlice()[0].Size_ != goarch.PtrSize {
panic("compileCallback: expected function with one uintptr-sized result")
}
if k := ft.OutSlice()[0].Kind_ & abi.KindMask; k == abi.Float32 || k == abi.Float64 {
if k := ft.OutSlice()[0].Kind(); k == abi.Float32 || k == abi.Float64 {
// In cdecl and stdcall, float results are returned in
// ST(0). In fastcall, they're returned in XMM0.
// Either way, it's not AX.

View File

@@ -69,7 +69,7 @@ func (t rtype) pkgpath() string {
if u := t.uncommon(); u != nil {
return t.nameOff(u.PkgPath).Name()
}
switch t.Kind_ & abi.KindMask {
switch t.Kind() {
case abi.Struct:
st := (*structtype)(unsafe.Pointer(t.Type))
return st.PkgPath.Name()
@@ -522,8 +522,8 @@ func typesEqual(t, v *_type, seen map[_typePair]struct{}) bool {
if t == v {
return true
}
kind := t.Kind_ & abi.KindMask
if kind != v.Kind_&abi.KindMask {
kind := t.Kind()
if kind != v.Kind() {
return false
}
rt, rv := toRType(t), toRType(v)

View File

@@ -1,12 +0,0 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package runtime
import "internal/abi"
// isDirectIface reports whether t is stored directly in an interface value.
func isDirectIface(t *_type) bool {
return t.Kind_&abi.KindDirectIface != 0
}