package runtime
import (
)
type tflag uint8
const (
tflagUncommon tflag = 1 << 0
tflagExtraStar tflag = 1 << 1
tflagNamed tflag = 1 << 2
tflagRegularMemory tflag = 1 << 3
)
type _type struct {
size uintptr
ptrdata uintptr
hash uint32
tflag tflag
align uint8
fieldAlign uint8
kind uint8
equal func(unsafe.Pointer, unsafe.Pointer) bool
gcdata *byte
str nameOff
ptrToThis typeOff
}
func ( *_type) () string {
:= .nameOff(.str).name()
if .tflag&tflagExtraStar != 0 {
return [1:]
}
return
}
func ( *_type) () *uncommontype {
if .tflag&tflagUncommon == 0 {
return nil
}
switch .kind & kindMask {
case kindStruct:
type struct {
structtype
uncommontype
}
return &(*)(unsafe.Pointer()).
case kindPtr:
type struct {
ptrtype
uncommontype
}
return &(*)(unsafe.Pointer()).
case kindFunc:
type struct {
functype
uncommontype
}
return &(*)(unsafe.Pointer()).
case kindSlice:
type struct {
slicetype
uncommontype
}
return &(*)(unsafe.Pointer()).
case kindArray:
type struct {
arraytype
uncommontype
}
return &(*)(unsafe.Pointer()).
case kindChan:
type struct {
chantype
uncommontype
}
return &(*)(unsafe.Pointer()).
case kindMap:
type struct {
maptype
uncommontype
}
return &(*)(unsafe.Pointer()).
case kindInterface:
type struct {
interfacetype
uncommontype
}
return &(*)(unsafe.Pointer()).
default:
type struct {
_type
uncommontype
}
return &(*)(unsafe.Pointer()).
}
}
func ( *_type) () string {
if .tflag&tflagNamed == 0 {
return ""
}
:= .string()
:= len() - 1
for >= 0 && [] != '.' {
--
}
return [+1:]
}
func ( *_type) () string {
if := .uncommon(); != nil {
return .nameOff(.pkgpath).name()
}
switch .kind & kindMask {
case kindStruct:
:= (*structtype)(unsafe.Pointer())
return .pkgPath.name()
case kindInterface:
:= (*interfacetype)(unsafe.Pointer())
return .pkgpath.name()
}
return ""
}
var reflectOffs struct {
lock mutex
next int32
m map[int32]unsafe.Pointer
minv map[unsafe.Pointer]int32
}
func () {
lock(&reflectOffs.lock)
if raceenabled {
raceacquire(unsafe.Pointer(&reflectOffs.lock))
}
}
func () {
if raceenabled {
racerelease(unsafe.Pointer(&reflectOffs.lock))
}
unlock(&reflectOffs.lock)
}
func ( unsafe.Pointer, nameOff) name {
if == 0 {
return name{}
}
:= uintptr()
for := &firstmoduledata; != nil; = .next {
if >= .types && < .etypes {
:= .types + uintptr()
if > .etypes {
println("runtime: nameOff", hex(), "out of range", hex(.types), "-", hex(.etypes))
throw("runtime: name offset out of range")
}
return name{(*byte)(unsafe.Pointer())}
}
}
reflectOffsLock()
, := reflectOffs.m[int32()]
reflectOffsUnlock()
if ! {
println("runtime: nameOff", hex(), "base", hex(), "not in ranges:")
for := &firstmoduledata; != nil; = .next {
println("\ttypes", hex(.types), "etypes", hex(.etypes))
}
throw("runtime: name offset base pointer out of range")
}
return name{(*byte)()}
}
func ( *_type) ( nameOff) name {
return resolveNameOff(unsafe.Pointer(), )
}
func ( unsafe.Pointer, typeOff) *_type {
if == 0 || == -1 {
return nil
}
:= uintptr()
var *moduledata
for := &firstmoduledata; != nil; = .next {
if >= .types && < .etypes {
=
break
}
}
if == nil {
reflectOffsLock()
:= reflectOffs.m[int32()]
reflectOffsUnlock()
if == nil {
println("runtime: typeOff", hex(), "base", hex(), "not in ranges:")
for := &firstmoduledata; != nil; = .next {
println("\ttypes", hex(.types), "etypes", hex(.etypes))
}
throw("runtime: type offset base pointer out of range")
}
return (*_type)()
}
if := .typemap[]; != nil {
return
}
:= .types + uintptr()
if > .etypes {
println("runtime: typeOff", hex(), "out of range", hex(.types), "-", hex(.etypes))
throw("runtime: type offset out of range")
}
return (*_type)(unsafe.Pointer())
}
func ( *_type) ( typeOff) *_type {
return resolveTypeOff(unsafe.Pointer(), )
}
func ( *_type) ( textOff) unsafe.Pointer {
if == -1 {
return unsafe.Pointer(abi.FuncPCABIInternal(unreachableMethod))
}
:= uintptr(unsafe.Pointer())
var *moduledata
for := &firstmoduledata; != nil; = .next {
if >= .types && < .etypes {
=
break
}
}
if == nil {
reflectOffsLock()
:= reflectOffs.m[int32()]
reflectOffsUnlock()
if == nil {
println("runtime: textOff", hex(), "base", hex(), "not in ranges:")
for := &firstmoduledata; != nil; = .next {
println("\ttypes", hex(.types), "etypes", hex(.etypes))
}
throw("runtime: text offset base pointer out of range")
}
return
}
:= .textAddr(uint32())
return unsafe.Pointer()
}
func ( *functype) () []*_type {
:= uintptr(unsafe.Sizeof(functype{}))
if .typ.tflag&tflagUncommon != 0 {
+= unsafe.Sizeof(uncommontype{})
}
return (*[1 << 20]*_type)(add(unsafe.Pointer(), ))[:.inCount]
}
func ( *functype) () []*_type {
:= uintptr(unsafe.Sizeof(functype{}))
if .typ.tflag&tflagUncommon != 0 {
+= unsafe.Sizeof(uncommontype{})
}
:= .outCount & (1<<15 - 1)
return (*[1 << 20]*_type)(add(unsafe.Pointer(), ))[.inCount : .inCount+]
}
func ( *functype) () bool {
return .outCount&(1<<15) != 0
}
type nameOff int32
type typeOff int32
type textOff int32
type method struct {
name nameOff
mtyp typeOff
ifn textOff
tfn textOff
}
type uncommontype struct {
pkgpath nameOff
mcount uint16
xcount uint16
moff uint32
_ uint32
}
type imethod struct {
name nameOff
ityp typeOff
}
type interfacetype struct {
typ _type
pkgpath name
mhdr []imethod
}
type maptype struct {
typ _type
key *_type
elem *_type
bucket *_type
hasher func(unsafe.Pointer, uintptr) uintptr
keysize uint8
elemsize uint8
bucketsize uint16
flags uint32
}
func ( *maptype) () bool {
return .flags&1 != 0
}
func ( *maptype) () bool {
return .flags&2 != 0
}
func ( *maptype) () bool {
return .flags&4 != 0
}
func ( *maptype) () bool {
return .flags&8 != 0
}
func ( *maptype) () bool {
return .flags&16 != 0
}
type arraytype struct {
typ _type
elem *_type
slice *_type
len uintptr
}
type chantype struct {
typ _type
elem *_type
dir uintptr
}
type slicetype struct {
typ _type
elem *_type
}
type functype struct {
typ _type
inCount uint16
outCount uint16
}
type ptrtype struct {
typ _type
elem *_type
}
type structfield struct {
name name
typ *_type
offsetAnon uintptr
}
func ( *structfield) () uintptr {
return .offsetAnon >> 1
}
type structtype struct {
typ _type
pkgPath name
fields []structfield
}
type name struct {
bytes *byte
}
func ( name) ( int) *byte {
return (*byte)(add(unsafe.Pointer(.bytes), uintptr()))
}
func ( name) () bool {
return (*.bytes)&(1<<0) != 0
}
func ( name) ( int) (int, int) {
:= 0
for := 0; ; ++ {
:= *.data( + )
+= int(&0x7f) << (7 * )
if &0x80 == 0 {
return + 1,
}
}
}
func ( name) () ( string) {
if .bytes == nil {
return ""
}
, := .readvarint(1)
if == 0 {
return ""
}
:= (*stringStruct)(unsafe.Pointer(&))
.str = unsafe.Pointer(.data(1 + ))
.len =
return
}
func ( name) () ( string) {
if *.data(0)&(1<<1) == 0 {
return ""
}
, := .readvarint(1)
, := .readvarint(1 + + )
:= (*stringStruct)(unsafe.Pointer(&))
.str = unsafe.Pointer(.data(1 + + + ))
.len =
return
}
func ( name) () string {
if .bytes == nil || *.data(0)&(1<<2) == 0 {
return ""
}
, := .readvarint(1)
:= 1 + +
if *.data(0)&(1<<1) != 0 {
, := .readvarint()
+= +
}
var nameOff
copy((*[4]byte)(unsafe.Pointer(&))[:], (*[4]byte)(unsafe.Pointer(.data()))[:])
:= resolveNameOff(unsafe.Pointer(.bytes), )
return .name()
}
func ( name) () bool {
if .bytes == nil {
return false
}
, := .readvarint(1)
return == 1 && *.data(2) == '_'
}
func () {
if firstmoduledata.next == nil {
return
}
:= make(map[uint32][]*_type, len(firstmoduledata.typelinks))
:= activeModules()
:= [0]
for , := range [1:] {
:
for , := range .typelinks {
var *_type
if .typemap == nil {
= (*_type)(unsafe.Pointer(.types + uintptr()))
} else {
= .typemap[typeOff()]
}
:= [.hash]
for , := range {
if == {
continue
}
}
[.hash] = append(, )
}
if .typemap == nil {
:= make(map[typeOff]*_type, len(.typelinks))
pinnedTypemaps = append(pinnedTypemaps, )
.typemap =
for , := range .typelinks {
:= (*_type)(unsafe.Pointer(.types + uintptr()))
for , := range [.hash] {
:= map[_typePair]struct{}{}
if typesEqual(, , ) {
=
break
}
}
.typemap[typeOff()] =
}
}
=
}
}
type _typePair struct {
t1 *_type
t2 *_type
}
func (, *_type, map[_typePair]struct{}) bool {
:= _typePair{, }
if , := []; {
return true
}
[] = struct{}{}
if == {
return true
}
:= .kind & kindMask
if != .kind&kindMask {
return false
}
if .string() != .string() {
return false
}
:= .uncommon()
:= .uncommon()
if != nil || != nil {
if == nil || == nil {
return false
}
:= .nameOff(.pkgpath).name()
:= .nameOff(.pkgpath).name()
if != {
return false
}
}
if kindBool <= && <= kindComplex128 {
return true
}
switch {
case kindString, kindUnsafePointer:
return true
case kindArray:
:= (*arraytype)(unsafe.Pointer())
:= (*arraytype)(unsafe.Pointer())
return (.elem, .elem, ) && .len == .len
case kindChan:
:= (*chantype)(unsafe.Pointer())
:= (*chantype)(unsafe.Pointer())
return .dir == .dir && (.elem, .elem, )
case kindFunc:
:= (*functype)(unsafe.Pointer())
:= (*functype)(unsafe.Pointer())
if .outCount != .outCount || .inCount != .inCount {
return false
}
, := .in(), .in()
for := 0; < len(); ++ {
if !([], [], ) {
return false
}
}
, := .out(), .out()
for := 0; < len(); ++ {
if !([], [], ) {
return false
}
}
return true
case kindInterface:
:= (*interfacetype)(unsafe.Pointer())
:= (*interfacetype)(unsafe.Pointer())
if .pkgpath.name() != .pkgpath.name() {
return false
}
if len(.mhdr) != len(.mhdr) {
return false
}
for := range .mhdr {
:= &.mhdr[]
:= &.mhdr[]
:= resolveNameOff(unsafe.Pointer(), .name)
:= resolveNameOff(unsafe.Pointer(), .name)
if .name() != .name() {
return false
}
if .pkgPath() != .pkgPath() {
return false
}
:= resolveTypeOff(unsafe.Pointer(), .ityp)
:= resolveTypeOff(unsafe.Pointer(), .ityp)
if !(, , ) {
return false
}
}
return true
case kindMap:
:= (*maptype)(unsafe.Pointer())
:= (*maptype)(unsafe.Pointer())
return (.key, .key, ) && (.elem, .elem, )
case kindPtr:
:= (*ptrtype)(unsafe.Pointer())
:= (*ptrtype)(unsafe.Pointer())
return (.elem, .elem, )
case kindSlice:
:= (*slicetype)(unsafe.Pointer())
:= (*slicetype)(unsafe.Pointer())
return (.elem, .elem, )
case kindStruct:
:= (*structtype)(unsafe.Pointer())
:= (*structtype)(unsafe.Pointer())
if len(.fields) != len(.fields) {
return false
}
if .pkgPath.name() != .pkgPath.name() {
return false
}
for := range .fields {
:= &.fields[]
:= &.fields[]
if .name.name() != .name.name() {
return false
}
if !(.typ, .typ, ) {
return false
}
if .name.tag() != .name.tag() {
return false
}
if .offsetAnon != .offsetAnon {
return false
}
}
return true
default:
println("runtime: impossible type kind", )
throw("runtime: impossible type kind")
return false
}
}