// Copyright 2009 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 reflectlite import ( "internal/abi" "internal/goarch" "internal/unsafeheader" "runtime" "unsafe" ) // Value is the reflection interface to a Go value. // // Not all methods apply to all kinds of values. Restrictions, // if any, are noted in the documentation for each method. // Use the Kind method to find out the kind of value before // calling kind-specific methods. Calling a method // inappropriate to the kind of type causes a run time panic. // // The zero Value represents no value. // Its IsValid method returns false, its Kind method returns Invalid, // its String method returns "", and all other methods panic. // Most functions and methods never return an invalid value. // If one does, its documentation states the conditions explicitly. // // A Value can be used concurrently by multiple goroutines provided that // the underlying Go value can be used concurrently for the equivalent // direct operations. // // To compare two Values, compare the results of the Interface method. // Using == on two Values does not compare the underlying values // they represent. type Value struct { // typ_ holds the type of the value represented by a Value. // Access using the typ method to avoid escape of v. typ_ *abi.Type // Pointer-valued data or, if flagIndir is set, pointer to data. // Valid when either flagIndir is set or typ.pointers() is true. ptr unsafe.Pointer // flag holds metadata about the value. // The lowest bits are flag bits: // - flagStickyRO: obtained via unexported not embedded field, so read-only // - flagEmbedRO: obtained via unexported embedded field, so read-only // - flagIndir: val holds a pointer to the data // - flagAddr: v.CanAddr is true (implies flagIndir) // Value cannot represent method values. // The next five bits give the Kind of the value. // This repeats typ.Kind() except for method values. // The remaining 23+ bits give a method number for method values. // If flag.kind() != Func, code can assume that flagMethod is unset. // If ifaceIndir(typ), code can assume that flagIndir is set. flag // A method value represents a curried method invocation // like r.Read for some receiver r. The typ+val+flag bits describe // the receiver r, but the flag's Kind bits say Func (methods are // functions), and the top bits of the flag give the method number // in r's type's method table. } type flag uintptr const ( flagKindWidth = 5 // there are 27 kinds flagKindMask flag = 1<= len, // because then the result will point outside the array. // whySafe must explain why i < len. (Passing "i < len" is fine; // the benefit is to surface this assumption at the call site.) func arrayAt(p unsafe.Pointer, i int, eltSize uintptr, whySafe string) unsafe.Pointer { return add(p, uintptr(i)*eltSize, "i < len") } func ifaceE2I(t *abi.Type, src any, dst unsafe.Pointer) // typedmemmove copies a value of type t to dst from src. // //go:noescape func typedmemmove(t *abi.Type, dst, src unsafe.Pointer) // Dummy annotation marking that the value x escapes, // for use in cases where the reflect code is so clever that // the compiler cannot follow. func escapes(x any) { if dummy.b { dummy.x = x } } var dummy struct { b bool x any } //go:nosplit func noescape(p unsafe.Pointer) unsafe.Pointer { x := uintptr(p) return unsafe.Pointer(x ^ 0) }