github.com/fisco-bcos/crypto@v0.0.0-20200202032121-bd8ab0b5d4f1/internal/reflectlite/value.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 reflectlite 6 7 import ( 8 "runtime" 9 "unsafe" 10 ) 11 12 const ptrSize = 4 << (^uintptr(0) >> 63) // unsafe.Sizeof(uintptr(0)) but an ideal const 13 14 // Value is the reflection interface to a Go value. 15 // 16 // Not all methods apply to all kinds of values. Restrictions, 17 // if any, are noted in the documentation for each method. 18 // Use the Kind method to find out the kind of value before 19 // calling kind-specific methods. Calling a method 20 // inappropriate to the kind of type causes a run time panic. 21 // 22 // The zero Value represents no value. 23 // Its IsValid method returns false, its Kind method returns Invalid, 24 // its String method returns "<invalid Value>", and all other methods panic. 25 // Most functions and methods never return an invalid value. 26 // If one does, its documentation states the conditions explicitly. 27 // 28 // A Value can be used concurrently by multiple goroutines provided that 29 // the underlying Go value can be used concurrently for the equivalent 30 // direct operations. 31 // 32 // To compare two Values, compare the results of the Interface method. 33 // Using == on two Values does not compare the underlying values 34 // they represent. 35 type Value struct { 36 // typ holds the type of the value represented by a Value. 37 typ *rtype 38 39 // Pointer-valued data or, if flagIndir is set, pointer to data. 40 // Valid when either flagIndir is set or typ.pointers() is true. 41 ptr unsafe.Pointer 42 43 // flag holds metadata about the value. 44 // The lowest bits are flag bits: 45 // - flagStickyRO: obtained via unexported not embedded field, so read-only 46 // - flagEmbedRO: obtained via unexported embedded field, so read-only 47 // - flagIndir: val holds a pointer to the data 48 // - flagAddr: v.CanAddr is true (implies flagIndir) 49 // Value cannot represent method values. 50 // The next five bits give the Kind of the value. 51 // This repeats typ.Kind() except for method values. 52 // The remaining 23+ bits give a method number for method values. 53 // If flag.kind() != Func, code can assume that flagMethod is unset. 54 // If ifaceIndir(typ), code can assume that flagIndir is set. 55 flag 56 57 // A method value represents a curried method invocation 58 // like r.Read for some receiver r. The typ+val+flag bits describe 59 // the receiver r, but the flag's Kind bits say Func (methods are 60 // functions), and the top bits of the flag give the method number 61 // in r's type's method table. 62 } 63 64 type flag uintptr 65 66 const ( 67 flagKindWidth = 5 // there are 27 kinds 68 flagKindMask flag = 1<<flagKindWidth - 1 69 flagStickyRO flag = 1 << 5 70 flagEmbedRO flag = 1 << 6 71 flagIndir flag = 1 << 7 72 flagAddr flag = 1 << 8 73 flagMethod flag = 1 << 9 74 flagMethodShift = 10 75 flagRO flag = flagStickyRO | flagEmbedRO 76 ) 77 78 func (f flag) kind() Kind { 79 return Kind(f & flagKindMask) 80 } 81 82 func (f flag) ro() flag { 83 if f&flagRO != 0 { 84 return flagStickyRO 85 } 86 return 0 87 } 88 89 // pointer returns the underlying pointer represented by v. 90 // v.Kind() must be Ptr, Map, Chan, Func, or UnsafePointer 91 func (v Value) pointer() unsafe.Pointer { 92 if v.typ.size != ptrSize || !v.typ.pointers() { 93 panic("can't call pointer on a non-pointer Value") 94 } 95 if v.flag&flagIndir != 0 { 96 return *(*unsafe.Pointer)(v.ptr) 97 } 98 return v.ptr 99 } 100 101 // packEface converts v to the empty interface. 102 func packEface(v Value) interface{} { 103 t := v.typ 104 var i interface{} 105 e := (*emptyInterface)(unsafe.Pointer(&i)) 106 // First, fill in the data portion of the interface. 107 switch { 108 case ifaceIndir(t): 109 if v.flag&flagIndir == 0 { 110 panic("bad indir") 111 } 112 // Value is indirect, and so is the interface we're making. 113 ptr := v.ptr 114 if v.flag&flagAddr != 0 { 115 // TODO: pass safe boolean from valueInterface so 116 // we don't need to copy if safe==true? 117 c := unsafe_New(t) 118 typedmemmove(t, c, ptr) 119 ptr = c 120 } 121 e.word = ptr 122 case v.flag&flagIndir != 0: 123 // Value is indirect, but interface is direct. We need 124 // to load the data at v.ptr into the interface data word. 125 e.word = *(*unsafe.Pointer)(v.ptr) 126 default: 127 // Value is direct, and so is the interface. 128 e.word = v.ptr 129 } 130 // Now, fill in the type portion. We're very careful here not 131 // to have any operation between the e.word and e.typ assignments 132 // that would let the garbage collector observe the partially-built 133 // interface value. 134 e.typ = t 135 return i 136 } 137 138 // unpackEface converts the empty interface i to a Value. 139 func unpackEface(i interface{}) Value { 140 e := (*emptyInterface)(unsafe.Pointer(&i)) 141 // NOTE: don't read e.word until we know whether it is really a pointer or not. 142 t := e.typ 143 if t == nil { 144 return Value{} 145 } 146 f := flag(t.Kind()) 147 if ifaceIndir(t) { 148 f |= flagIndir 149 } 150 return Value{t, e.word, f} 151 } 152 153 // A ValueError occurs when a Value method is invoked on 154 // a Value that does not support it. Such cases are documented 155 // in the description of each method. 156 type ValueError struct { 157 Method string 158 Kind Kind 159 } 160 161 func (e *ValueError) Error() string { 162 return "reflect: call of " + e.Method + " on zero Value" 163 } 164 165 // methodName returns the name of the calling method, 166 // assumed to be two stack frames above. 167 func methodName() string { 168 pc, _, _, _ := runtime.Caller(2) 169 f := runtime.FuncForPC(pc) 170 if f == nil { 171 return "unknown method" 172 } 173 return f.Name() 174 } 175 176 // emptyInterface is the header for an interface{} value. 177 type emptyInterface struct { 178 typ *rtype 179 word unsafe.Pointer 180 } 181 182 // nonEmptyInterface is the header for an interface value with methods. 183 type nonEmptyInterface struct { 184 // see ../runtime/iface.go:/Itab 185 itab *struct { 186 ityp *rtype // static interface type 187 typ *rtype // dynamic concrete type 188 hash uint32 // copy of typ.hash 189 _ [4]byte 190 fun [100000]unsafe.Pointer // method table 191 } 192 word unsafe.Pointer 193 } 194 195 // mustBeExported panics if f records that the value was obtained using 196 // an unexported field. 197 func (f flag) mustBeExported() { 198 if f == 0 { 199 panic(&ValueError{methodName(), 0}) 200 } 201 if f&flagRO != 0 { 202 panic("reflect: " + methodName() + " using value obtained using unexported field") 203 } 204 } 205 206 // mustBeAssignable panics if f records that the value is not assignable, 207 // which is to say that either it was obtained using an unexported field 208 // or it is not addressable. 209 func (f flag) mustBeAssignable() { 210 if f == 0 { 211 panic(&ValueError{methodName(), Invalid}) 212 } 213 // Assignable if addressable and not read-only. 214 if f&flagRO != 0 { 215 panic("reflect: " + methodName() + " using value obtained using unexported field") 216 } 217 if f&flagAddr == 0 { 218 panic("reflect: " + methodName() + " using unaddressable value") 219 } 220 } 221 222 // CanSet reports whether the value of v can be changed. 223 // A Value can be changed only if it is addressable and was not 224 // obtained by the use of unexported struct fields. 225 // If CanSet returns false, calling Set or any type-specific 226 // setter (e.g., SetBool, SetInt) will panic. 227 func (v Value) CanSet() bool { 228 return v.flag&(flagAddr|flagRO) == flagAddr 229 } 230 231 // Elem returns the value that the interface v contains 232 // or that the pointer v points to. 233 // It panics if v's Kind is not Interface or Ptr. 234 // It returns the zero Value if v is nil. 235 func (v Value) Elem() Value { 236 k := v.kind() 237 switch k { 238 case Interface: 239 var eface interface{} 240 if v.typ.NumMethod() == 0 { 241 eface = *(*interface{})(v.ptr) 242 } else { 243 eface = (interface{})(*(*interface { 244 M() 245 })(v.ptr)) 246 } 247 x := unpackEface(eface) 248 if x.flag != 0 { 249 x.flag |= v.flag.ro() 250 } 251 return x 252 case Ptr: 253 ptr := v.ptr 254 if v.flag&flagIndir != 0 { 255 ptr = *(*unsafe.Pointer)(ptr) 256 } 257 // The returned value's address is v's value. 258 if ptr == nil { 259 return Value{} 260 } 261 tt := (*ptrType)(unsafe.Pointer(v.typ)) 262 typ := tt.elem 263 fl := v.flag&flagRO | flagIndir | flagAddr 264 fl |= flag(typ.Kind()) 265 return Value{typ, ptr, fl} 266 } 267 panic(&ValueError{"reflectlite.Value.Elem", v.kind()}) 268 } 269 270 func valueInterface(v Value) interface{} { 271 if v.flag == 0 { 272 panic(&ValueError{"reflectlite.Value.Interface", 0}) 273 } 274 275 if v.kind() == Interface { 276 // Special case: return the element inside the interface. 277 // Empty interface has one layout, all interfaces with 278 // methods have a second layout. 279 if v.numMethod() == 0 { 280 return *(*interface{})(v.ptr) 281 } 282 return *(*interface { 283 M() 284 })(v.ptr) 285 } 286 287 // TODO: pass safe to packEface so we don't need to copy if safe==true? 288 return packEface(v) 289 } 290 291 // IsNil reports whether its argument v is nil. The argument must be 292 // a chan, func, interface, map, pointer, or slice value; if it is 293 // not, IsNil panics. Note that IsNil is not always equivalent to a 294 // regular comparison with nil in Go. For example, if v was created 295 // by calling ValueOf with an uninitialized interface variable i, 296 // i==nil will be true but v.IsNil will panic as v will be the zero 297 // Value. 298 func (v Value) IsNil() bool { 299 k := v.kind() 300 switch k { 301 case Chan, Func, Map, Ptr, UnsafePointer: 302 // if v.flag&flagMethod != 0 { 303 // return false 304 // } 305 ptr := v.ptr 306 if v.flag&flagIndir != 0 { 307 ptr = *(*unsafe.Pointer)(ptr) 308 } 309 return ptr == nil 310 case Interface, Slice: 311 // Both interface and slice are nil if first word is 0. 312 // Both are always bigger than a word; assume flagIndir. 313 return *(*unsafe.Pointer)(v.ptr) == nil 314 } 315 panic(&ValueError{"reflectlite.Value.IsNil", v.kind()}) 316 } 317 318 // IsValid reports whether v represents a value. 319 // It returns false if v is the zero Value. 320 // If IsValid returns false, all other methods except String panic. 321 // Most functions and methods never return an invalid value. 322 // If one does, its documentation states the conditions explicitly. 323 func (v Value) IsValid() bool { 324 return v.flag != 0 325 } 326 327 // Kind returns v's Kind. 328 // If v is the zero Value (IsValid returns false), Kind returns Invalid. 329 func (v Value) Kind() Kind { 330 return v.kind() 331 } 332 333 // implemented in runtime: 334 func chanlen(unsafe.Pointer) int 335 func maplen(unsafe.Pointer) int 336 337 // Len returns v's length. 338 // It panics if v's Kind is not Array, Chan, Map, Slice, or String. 339 func (v Value) Len() int { 340 k := v.kind() 341 switch k { 342 case Array: 343 tt := (*arrayType)(unsafe.Pointer(v.typ)) 344 return int(tt.len) 345 case Chan: 346 return chanlen(v.pointer()) 347 case Map: 348 return maplen(v.pointer()) 349 case Slice: 350 // Slice is bigger than a word; assume flagIndir. 351 return (*sliceHeader)(v.ptr).Len 352 case String: 353 // String is bigger than a word; assume flagIndir. 354 return (*stringHeader)(v.ptr).Len 355 } 356 panic(&ValueError{"reflect.Value.Len", v.kind()}) 357 } 358 359 // NumMethod returns the number of exported methods in the value's method set. 360 func (v Value) numMethod() int { 361 if v.typ == nil { 362 panic(&ValueError{"reflectlite.Value.NumMethod", Invalid}) 363 } 364 return v.typ.NumMethod() 365 } 366 367 // Set assigns x to the value v. 368 // It panics if CanSet returns false. 369 // As in Go, x's value must be assignable to v's type. 370 func (v Value) Set(x Value) { 371 v.mustBeAssignable() 372 x.mustBeExported() // do not let unexported x leak 373 var target unsafe.Pointer 374 if v.kind() == Interface { 375 target = v.ptr 376 } 377 x = x.assignTo("reflectlite.Set", v.typ, target) 378 if x.flag&flagIndir != 0 { 379 typedmemmove(v.typ, v.ptr, x.ptr) 380 } else { 381 *(*unsafe.Pointer)(v.ptr) = x.ptr 382 } 383 } 384 385 // Type returns v's type. 386 func (v Value) Type() Type { 387 f := v.flag 388 if f == 0 { 389 panic(&ValueError{"reflectlite.Value.Type", Invalid}) 390 } 391 // Method values not supported. 392 return v.typ 393 } 394 395 // stringHeader is a safe version of StringHeader used within this package. 396 type stringHeader struct { 397 Data unsafe.Pointer 398 Len int 399 } 400 401 // sliceHeader is a safe version of SliceHeader used within this package. 402 type sliceHeader struct { 403 Data unsafe.Pointer 404 Len int 405 Cap int 406 } 407 408 /* 409 * constructors 410 */ 411 412 // implemented in package runtime 413 func unsafe_New(*rtype) unsafe.Pointer 414 415 // ValueOf returns a new Value initialized to the concrete value 416 // stored in the interface i. ValueOf(nil) returns the zero Value. 417 func ValueOf(i interface{}) Value { 418 if i == nil { 419 return Value{} 420 } 421 422 // TODO: Maybe allow contents of a Value to live on the stack. 423 // For now we make the contents always escape to the heap. It 424 // makes life easier in a few places (see chanrecv/mapassign 425 // comment below). 426 escapes(i) 427 428 return unpackEface(i) 429 } 430 431 // assignTo returns a value v that can be assigned directly to typ. 432 // It panics if v is not assignable to typ. 433 // For a conversion to an interface type, target is a suggested scratch space to use. 434 func (v Value) assignTo(context string, dst *rtype, target unsafe.Pointer) Value { 435 // if v.flag&flagMethod != 0 { 436 // v = makeMethodValue(context, v) 437 // } 438 439 switch { 440 case directlyAssignable(dst, v.typ): 441 // Overwrite type so that they match. 442 // Same memory layout, so no harm done. 443 fl := v.flag&(flagAddr|flagIndir) | v.flag.ro() 444 fl |= flag(dst.Kind()) 445 return Value{dst, v.ptr, fl} 446 447 case implements(dst, v.typ): 448 if target == nil { 449 target = unsafe_New(dst) 450 } 451 if v.Kind() == Interface && v.IsNil() { 452 // A nil ReadWriter passed to nil Reader is OK, 453 // but using ifaceE2I below will panic. 454 // Avoid the panic by returning a nil dst (e.g., Reader) explicitly. 455 return Value{dst, nil, flag(Interface)} 456 } 457 x := valueInterface(v) 458 if dst.NumMethod() == 0 { 459 *(*interface{})(target) = x 460 } else { 461 ifaceE2I(dst, x, target) 462 } 463 return Value{dst, target, flagIndir | flag(Interface)} 464 } 465 466 // Failed. 467 panic(context + ": value of type " + v.typ.String() + " is not assignable to type " + dst.String()) 468 } 469 470 // arrayAt returns the i-th element of p, 471 // an array whose elements are eltSize bytes wide. 472 // The array pointed at by p must have at least i+1 elements: 473 // it is invalid (but impossible to check here) to pass i >= len, 474 // because then the result will point outside the array. 475 // whySafe must explain why i < len. (Passing "i < len" is fine; 476 // the benefit is to surface this assumption at the call site.) 477 func arrayAt(p unsafe.Pointer, i int, eltSize uintptr, whySafe string) unsafe.Pointer { 478 return add(p, uintptr(i)*eltSize, "i < len") 479 } 480 481 func ifaceE2I(t *rtype, src interface{}, dst unsafe.Pointer) 482 483 // typedmemmove copies a value of type t to dst from src. 484 //go:noescape 485 func typedmemmove(t *rtype, dst, src unsafe.Pointer) 486 487 // Dummy annotation marking that the value x escapes, 488 // for use in cases where the reflect code is so clever that 489 // the compiler cannot follow. 490 func escapes(x interface{}) { 491 if dummy.b { 492 dummy.x = x 493 } 494 } 495 496 var dummy struct { 497 b bool 498 x interface{} 499 }