github.com/goplusjs/reflectx@v0.5.4/type.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package reflect implements run-time reflection, allowing a program to 6 // manipulate objects with arbitrary types. The typical use is to take a value 7 // with static type interface{} and extract its dynamic type information by 8 // calling TypeOf, which returns a Type. 9 // 10 // A call to ValueOf returns a Value representing the run-time data. 11 // Zero takes a Type and returns a Value representing a zero value 12 // for that type. 13 // 14 // See "The Laws of Reflection" for an introduction to reflection in Go: 15 // https://golang.org/doc/articles/laws_of_reflection.html 16 17 package reflectx 18 19 import ( 20 "reflect" 21 "unsafe" 22 ) 23 24 // memmove copies size bytes to dst from src. No write barriers are used. 25 //go:noescape 26 //go:linkname memmove reflect.memmove 27 func memmove(dst, src unsafe.Pointer, size uintptr) 28 29 // typedmemmove copies a value of type t to dst from src. 30 //go:noescape 31 //go:linkname typedmemmove reflect.typedmemmove 32 func typedmemmove(t *rtype, dst, src unsafe.Pointer) 33 34 // resolveNameOff resolves a name offset from a base pointer. 35 // The (*rtype).nameOff method is a convenience wrapper for this function. 36 // Implemented in the runtime package. 37 //go:linkname resolveNameOff reflect.resolveNameOff 38 func resolveNameOff(ptrInModule unsafe.Pointer, off int32) unsafe.Pointer 39 40 // resolveTypeOff resolves an *rtype offset from a base type. 41 // The (*rtype).typeOff method is a convenience wrapper for this function. 42 // Implemented in the runtime package. 43 //go:linkname resolveTypeOff reflect.resolveTypeOff 44 func resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer 45 46 // resolveTextOff resolves a function pointer offset from a base type. 47 // The (*rtype).textOff method is a convenience wrapper for this function. 48 // Implemented in the runtime package. 49 //go:linkname resolveTextOff reflect.resolveTextOff 50 func resolveTextOff(rtype unsafe.Pointer, off int32) unsafe.Pointer 51 52 // addReflectOff adds a pointer to the reflection lookup map in the runtime. 53 // It returns a new ID that can be used as a typeOff or textOff, and will 54 // be resolved correctly. Implemented in the runtime package. 55 //go:linkname addReflectOff reflect.addReflectOff 56 func addReflectOff(ptr unsafe.Pointer) int32 57 58 //go:linkname newName reflect.newName 59 func newName(n, tag string, exported bool) name 60 61 // resolveReflectName adds a name to the reflection lookup map in the runtime. 62 // It returns a new nameOff that can be used to refer to the pointer. 63 //go:linkname resolveReflectName reflect.resolveReflectName 64 func resolveReflectName(n name) nameOff 65 66 //go:linkname toType reflect.toType 67 func toType(t *rtype) reflect.Type 68 69 //go:linkname _nameOff reflect.(*rtype).nameOff 70 func _nameOff(t *rtype, off nameOff) name 71 72 //go:linkname _typeOff reflect.(*rtype).typeOff 73 func _typeOff(t *rtype, off typeOff) *rtype 74 75 //go:linkname _textOff reflect.(*rtype).textOff 76 func _textOff(t *rtype, off textOff) unsafe.Pointer 77 78 func (t *rtype) nameOff(off nameOff) name { 79 return _nameOff(t, off) 80 } 81 82 func (t *rtype) typeOff(off typeOff) *rtype { 83 return _typeOff(t, off) 84 //return (*rtype)(resolveTypeOff(unsafe.Pointer(t), int32(off))) 85 } 86 87 func (t *rtype) textOff(off textOff) unsafe.Pointer { 88 return _textOff(t, off) 89 //return resolveTextOff(unsafe.Pointer(t), int32(off)) 90 } 91 92 // resolveReflectType adds a *rtype to the reflection lookup map in the runtime. 93 // It returns a new typeOff that can be used to refer to the pointer. 94 func resolveReflectType(t *rtype) typeOff { 95 return typeOff(addReflectOff(unsafe.Pointer(t))) 96 } 97 98 // resolveReflectText adds a function pointer to the reflection lookup map in 99 // the runtime. It returns a new textOff that can be used to refer to the 100 // pointer. 101 func resolveReflectText(ptr unsafe.Pointer) textOff { 102 return textOff(addReflectOff(ptr)) 103 } 104 105 type nameOff int32 106 type typeOff int32 107 type textOff int32 108 109 // Method on non-interface type 110 type method struct { 111 name nameOff // name of method 112 mtyp typeOff // method type (without receiver) 113 ifn textOff // fn used in interface call (one-word receiver) 114 tfn textOff // fn used for normal method call 115 } 116 117 type structTypeUncommon struct { 118 structType 119 u uncommonType 120 } 121 122 type tflag uint8 123 124 const ( 125 // tflagUncommon means that there is a pointer, *uncommonType, 126 // just beyond the outer type structure. 127 // 128 // For example, if t.Kind() == Struct and t.tflag&tflagUncommon != 0, 129 // then t has uncommonType data and it can be accessed as: 130 // 131 // type tUncommon struct { 132 // structType 133 // u uncommonType 134 // } 135 // u := &(*tUncommon)(unsafe.Pointer(t)).u 136 tflagUncommon tflag = 1 << 0 137 138 // tflagExtraStar means the name in the str field has an 139 // extraneous '*' prefix. This is because for most types T in 140 // a program, the type *T also exists and reusing the str data 141 // saves binary size. 142 tflagExtraStar tflag = 1 << 1 143 144 // tflagNamed means the type has a name. 145 tflagNamed tflag = 1 << 2 146 147 // tflagRegularMemory means that equal and hash functions can treat 148 // this type as a single region of t.size bytes. 149 tflagRegularMemory tflag = 1 << 3 150 ) 151 152 type rtype struct { 153 size uintptr 154 ptrdata uintptr // number of bytes in the type that can contain pointers 155 hash uint32 // hash of type; avoids computation in hash tables 156 tflag tflag // extra type information flags 157 align uint8 // alignment of variable with this type 158 fieldAlign uint8 // alignment of struct field with this type 159 kind uint8 // enumeration for C 160 // function for comparing objects of this type 161 // (ptr to object A, ptr to object B) -> ==? 162 equal func(unsafe.Pointer, unsafe.Pointer) bool 163 gcdata *byte // garbage collection data 164 str nameOff // string form 165 ptrToThis typeOff // type for pointer to this type, may be zero 166 } 167 168 const ( 169 kindDirectIface = 1 << 5 170 kindGCProg = 1 << 6 // Type.gc points to GC program 171 kindMask = (1 << 5) - 1 172 ) 173 174 func (t *rtype) Kind() reflect.Kind { 175 return reflect.Kind(t.kind & kindMask) 176 } 177 178 // add returns p+x. 179 // 180 // The whySafe string is ignored, so that the function still inlines 181 // as efficiently as p+x, but all call sites should use the string to 182 // record why the addition is safe, which is to say why the addition 183 // does not cause x to advance to the very end of p's allocation 184 // and therefore point incorrectly at the next block in memory. 185 func add(p unsafe.Pointer, x uintptr, whySafe string) unsafe.Pointer { 186 return unsafe.Pointer(uintptr(p) + x) 187 } 188 189 // stringHeader is a safe version of StringHeader used within this package. 190 type stringHeader struct { 191 Data unsafe.Pointer 192 Len int 193 } 194 195 // ChanDir represents a channel type's direction. 196 type ChanDir int 197 198 const ( 199 RecvDir ChanDir = 1 << iota // <-chan 200 SendDir // chan<- 201 BothDir = RecvDir | SendDir // chan 202 ) 203 204 // arrayType represents a fixed array type. 205 type arrayType struct { 206 rtype 207 elem *rtype // array element type 208 slice *rtype // slice type 209 len uintptr 210 } 211 212 // chanType represents a channel type. 213 type chanType struct { 214 rtype 215 elem *rtype // channel element type 216 dir uintptr // channel direction (ChanDir) 217 } 218 219 // imethod represents a method on an interface type 220 type imethod struct { 221 name nameOff // name of method 222 typ typeOff // .(*FuncType) underneath 223 } 224 225 // interfaceType represents an interface type. 226 type interfaceType struct { 227 rtype 228 pkgPath name // import path 229 methods []imethod // sorted by hash 230 } 231 232 // mapType represents a map type. 233 type mapType struct { 234 rtype 235 key *rtype // map key type 236 elem *rtype // map element (value) type 237 bucket *rtype // internal bucket structure 238 // function for hashing keys (ptr to key, seed) -> hash 239 hasher func(unsafe.Pointer, uintptr) uintptr 240 keysize uint8 // size of key slot 241 valuesize uint8 // size of value slot 242 bucketsize uint16 // size of bucket 243 flags uint32 244 } 245 246 // ptrType represents a pointer type. 247 type ptrType struct { 248 rtype 249 elem *rtype // pointer element (pointed at) type 250 } 251 252 // sliceType represents a slice type. 253 type sliceType struct { 254 rtype 255 elem *rtype // slice element type 256 } 257 258 // struct field 259 type structField struct { 260 name name // name is always non-empty 261 typ *rtype // type of field 262 offsetEmbed uintptr // byte offset of field<<1 | isEmbedded 263 } 264 265 func (f *structField) offset() uintptr { 266 return f.offsetEmbed >> 1 267 } 268 269 func (f *structField) embedded() bool { 270 return f.offsetEmbed&1 != 0 271 } 272 273 // structType represents a struct type. 274 type structType struct { 275 rtype 276 pkgPath name 277 fields []structField // sorted by offset 278 }