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
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)
"getMCache",
"heapSetTypeNoHeader",
"heapSetTypeSmallHeader",
- "isDirectIface",
"itabHashFunc",
"nextslicecap",
"noescape",
"(*Buffer).tryGrowByReslice",
},
"internal/abi": {
+ "(*Type).IsDirectIface",
"UseInterfaceSwitchCache",
},
"internal/runtime/math": {
// 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
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
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
// 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.
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
// 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 {
}
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}
// - 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.
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")
}
return Value{}
}
f := flag(t.Kind())
- if t.IfaceIndir() {
+ if !t.IsDirectIface() {
f |= flagIndir
}
return Value{t, e.Data, f}
return unhashableTypeError{t}
}
- if t.Kind_&abi.KindDirectIface != 0 {
+ if t.IsDirectIface() {
return mapKeyError2(t, unsafe.Pointer(pdata))
} else {
return mapKeyError2(t, *pdata)
// 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 {
//
//go:linkname unusedIfaceIndir reflect.ifaceIndir
func unusedIfaceIndir(t *abi.Type) bool {
- return t.Kind_&abi.KindDirectIface == 0
+ return !t.IsDirectIface()
}
//go:linkname valueInterface
package reflect
import (
- "internal/abi"
"unsafe"
)
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))
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
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))
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))
// 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() {
}
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))
}
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))
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) {
// - 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.
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")
}
return Value{}
}
f := flag(t.Kind())
- if t.IfaceIndir() {
+ if !t.IsDirectIface() {
f |= flagIndir
}
return Value{t, e.Data, f}
}
// 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 {
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
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
// 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
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.
// 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)
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
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}
}
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])
}
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)")
}
// 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)
// 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)
return memhash(p, h, t.Size_)
}
}
- switch t.Kind_ & abi.KindMask {
+ switch t.Kind() {
case abi.Float32:
return f32hash(p, h)
case abi.Float64:
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 ==.
if eq == nil {
panic(errorString("comparing uncomparable type " + toRType(t).string()))
}
- if isDirectIface(t) {
+ if t.IsDirectIface() {
// See comment in efaceeq.
return x == y
}
//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
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:
}
// 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))
}
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
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
}
// 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
}
}
- 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"
return
}
- switch t.Kind_ & abi.KindMask {
+ switch t.Kind() {
default:
throw("can't happen")
case abi.Array:
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++ {
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)
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 {
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)
}
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:
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))
}
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
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
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.
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.
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
// 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
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))
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))
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
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)) {
(*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
// 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.
}
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.
// 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
//
// 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)
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))
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.
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()
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)
+++ /dev/null
-// 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
-}