github.com/mymmsc/gox@v1.3.33/util/reflect2/reflect2.go (about)

     1  package reflect2
     2  
     3  import (
     4  	"reflect"
     5  	"runtime"
     6  	"sync"
     7  	"unsafe"
     8  )
     9  
    10  type Type interface {
    11  	Kind() reflect.Kind
    12  	// New return pointer to data of this type
    13  	New() interface{}
    14  	// UnsafeNew return the allocated space pointed by unsafe.Pointer
    15  	UnsafeNew() unsafe.Pointer
    16  	// PackEFace cast a unsafe pointer to object represented pointer
    17  	PackEFace(ptr unsafe.Pointer) interface{}
    18  	// Indirect dereference object represented pointer to this type
    19  	Indirect(obj interface{}) interface{}
    20  	// UnsafeIndirect dereference pointer to this type
    21  	UnsafeIndirect(ptr unsafe.Pointer) interface{}
    22  	// Type1 returns reflect.Type
    23  	Type1() reflect.Type
    24  	Implements(thatType Type) bool
    25  	String() string
    26  	RType() uintptr
    27  	// interface{} of this type has pointer like behavior
    28  	LikePtr() bool
    29  	IsNullable() bool
    30  	IsNil(obj interface{}) bool
    31  	UnsafeIsNil(ptr unsafe.Pointer) bool
    32  	Set(obj interface{}, val interface{})
    33  	UnsafeSet(ptr unsafe.Pointer, val unsafe.Pointer)
    34  	AssignableTo(anotherType Type) bool
    35  }
    36  
    37  type ListType interface {
    38  	Type
    39  	Elem() Type
    40  	SetIndex(obj interface{}, index int, elem interface{})
    41  	UnsafeSetIndex(obj unsafe.Pointer, index int, elem unsafe.Pointer)
    42  	GetIndex(obj interface{}, index int) interface{}
    43  	UnsafeGetIndex(obj unsafe.Pointer, index int) unsafe.Pointer
    44  }
    45  
    46  type ArrayType interface {
    47  	ListType
    48  	Len() int
    49  }
    50  
    51  type SliceType interface {
    52  	ListType
    53  	MakeSlice(length int, cap int) interface{}
    54  	UnsafeMakeSlice(length int, cap int) unsafe.Pointer
    55  	Grow(obj interface{}, newLength int)
    56  	UnsafeGrow(ptr unsafe.Pointer, newLength int)
    57  	Append(obj interface{}, elem interface{})
    58  	UnsafeAppend(obj unsafe.Pointer, elem unsafe.Pointer)
    59  	LengthOf(obj interface{}) int
    60  	UnsafeLengthOf(ptr unsafe.Pointer) int
    61  	SetNil(obj interface{})
    62  	UnsafeSetNil(ptr unsafe.Pointer)
    63  	Cap(obj interface{}) int
    64  	UnsafeCap(ptr unsafe.Pointer) int
    65  }
    66  
    67  type StructType interface {
    68  	Type
    69  	NumField() int
    70  	Field(i int) StructField
    71  	FieldByName(name string) StructField
    72  	FieldByIndex(index []int) StructField
    73  	FieldByNameFunc(match func(string) bool) StructField
    74  }
    75  
    76  type StructField interface {
    77  	Offset() uintptr
    78  	Name() string
    79  	PkgPath() string
    80  	Type() Type
    81  	Tag() reflect.StructTag
    82  	Index() []int
    83  	Anonymous() bool
    84  	Set(obj interface{}, value interface{})
    85  	UnsafeSet(obj unsafe.Pointer, value unsafe.Pointer)
    86  	Get(obj interface{}) interface{}
    87  	UnsafeGet(obj unsafe.Pointer) unsafe.Pointer
    88  }
    89  
    90  type MapType interface {
    91  	Type
    92  	Key() Type
    93  	Elem() Type
    94  	MakeMap(cap int) interface{}
    95  	UnsafeMakeMap(cap int) unsafe.Pointer
    96  	SetIndex(obj interface{}, key interface{}, elem interface{})
    97  	UnsafeSetIndex(obj unsafe.Pointer, key unsafe.Pointer, elem unsafe.Pointer)
    98  	TryGetIndex(obj interface{}, key interface{}) (interface{}, bool)
    99  	GetIndex(obj interface{}, key interface{}) interface{}
   100  	UnsafeGetIndex(obj unsafe.Pointer, key unsafe.Pointer) unsafe.Pointer
   101  	Iterate(obj interface{}) MapIterator
   102  	UnsafeIterate(obj unsafe.Pointer) MapIterator
   103  }
   104  
   105  type MapIterator interface {
   106  	HasNext() bool
   107  	Next() (key interface{}, elem interface{})
   108  	UnsafeNext() (key unsafe.Pointer, elem unsafe.Pointer)
   109  }
   110  
   111  type PtrType interface {
   112  	Type
   113  	Elem() Type
   114  }
   115  
   116  type InterfaceType interface {
   117  	NumMethod() int
   118  }
   119  
   120  type Config struct {
   121  	UseSafeImplementation bool
   122  }
   123  
   124  type API interface {
   125  	TypeOf(obj interface{}) Type
   126  	Type2(type1 reflect.Type) Type
   127  }
   128  
   129  var ConfigUnsafe = Config{UseSafeImplementation: false}.Froze()
   130  var ConfigSafe = Config{UseSafeImplementation: true}.Froze()
   131  
   132  type frozenConfig struct {
   133  	useSafeImplementation bool
   134  	cache                 *sync.Map
   135  }
   136  
   137  func (cfg Config) Froze() *frozenConfig {
   138  	return &frozenConfig{
   139  		useSafeImplementation: cfg.UseSafeImplementation,
   140  		cache:                 new(sync.Map),
   141  	}
   142  }
   143  
   144  func (cfg *frozenConfig) TypeOf(obj interface{}) Type {
   145  	cacheKey := uintptr(unpackEFace(obj).rtype)
   146  	typeObj, found := cfg.cache.Load(cacheKey)
   147  	if found {
   148  		return typeObj.(Type)
   149  	}
   150  	return cfg.Type2(reflect.TypeOf(obj))
   151  }
   152  
   153  func (cfg *frozenConfig) Type2(type1 reflect.Type) Type {
   154  	if type1 == nil {
   155  		return nil
   156  	}
   157  	cacheKey := uintptr(unpackEFace(type1).data)
   158  	typeObj, found := cfg.cache.Load(cacheKey)
   159  	if found {
   160  		return typeObj.(Type)
   161  	}
   162  	type2 := cfg.wrapType(type1)
   163  	cfg.cache.Store(cacheKey, type2)
   164  	return type2
   165  }
   166  
   167  func (cfg *frozenConfig) wrapType(type1 reflect.Type) Type {
   168  	safeType := safeType{Type: type1, cfg: cfg}
   169  	switch type1.Kind() {
   170  	case reflect.Struct:
   171  		if cfg.useSafeImplementation {
   172  			return &safeStructType{safeType}
   173  		}
   174  		return newUnsafeStructType(cfg, type1)
   175  	case reflect.Array:
   176  		if cfg.useSafeImplementation {
   177  			return &safeSliceType{safeType}
   178  		}
   179  		return newUnsafeArrayType(cfg, type1)
   180  	case reflect.Slice:
   181  		if cfg.useSafeImplementation {
   182  			return &safeSliceType{safeType}
   183  		}
   184  		return newUnsafeSliceType(cfg, type1)
   185  	case reflect.Map:
   186  		if cfg.useSafeImplementation {
   187  			return &safeMapType{safeType}
   188  		}
   189  		return newUnsafeMapType(cfg, type1)
   190  	case reflect.Ptr, reflect.Chan, reflect.Func:
   191  		if cfg.useSafeImplementation {
   192  			return &safeMapType{safeType}
   193  		}
   194  		return newUnsafePtrType(cfg, type1)
   195  	case reflect.Interface:
   196  		if cfg.useSafeImplementation {
   197  			return &safeMapType{safeType}
   198  		}
   199  		if type1.NumMethod() == 0 {
   200  			return newUnsafeEFaceType(cfg, type1)
   201  		}
   202  		return newUnsafeIFaceType(cfg, type1)
   203  	default:
   204  		if cfg.useSafeImplementation {
   205  			return &safeType
   206  		}
   207  		return newUnsafeType(cfg, type1)
   208  	}
   209  }
   210  
   211  func TypeOf(obj interface{}) Type {
   212  	return ConfigUnsafe.TypeOf(obj)
   213  }
   214  
   215  func TypeOfPtr(obj interface{}) PtrType {
   216  	return TypeOf(obj).(PtrType)
   217  }
   218  
   219  func Type2(type1 reflect.Type) Type {
   220  	if type1 == nil {
   221  		return nil
   222  	}
   223  	return ConfigUnsafe.Type2(type1)
   224  }
   225  
   226  func PtrTo(typ Type) Type {
   227  	return Type2(reflect.PtrTo(typ.Type1()))
   228  }
   229  
   230  func PtrOf(obj interface{}) unsafe.Pointer {
   231  	return unpackEFace(obj).data
   232  }
   233  
   234  func RTypeOf(obj interface{}) uintptr {
   235  	return uintptr(unpackEFace(obj).rtype)
   236  }
   237  
   238  func IsNil(obj interface{}) bool {
   239  	if obj == nil {
   240  		return true
   241  	}
   242  	return unpackEFace(obj).data == nil
   243  }
   244  
   245  func IsNullable(kind reflect.Kind) bool {
   246  	switch kind {
   247  	case reflect.Ptr, reflect.Map, reflect.Chan, reflect.Func, reflect.Slice, reflect.Interface:
   248  		return true
   249  	}
   250  	return false
   251  }
   252  
   253  func likePtrKind(kind reflect.Kind) bool {
   254  	switch kind {
   255  	case reflect.Ptr, reflect.Map, reflect.Chan, reflect.Func:
   256  		return true
   257  	}
   258  	return false
   259  }
   260  
   261  func likePtrType(typ reflect.Type) bool {
   262  	if likePtrKind(typ.Kind()) {
   263  		return true
   264  	}
   265  	if typ.Kind() == reflect.Struct {
   266  		if typ.NumField() != 1 {
   267  			return false
   268  		}
   269  		return likePtrType(typ.Field(0).Type)
   270  	}
   271  	if typ.Kind() == reflect.Array {
   272  		if typ.Len() != 1 {
   273  			return false
   274  		}
   275  		return likePtrType(typ.Elem())
   276  	}
   277  	return false
   278  }
   279  
   280  // NoEscape hides a pointer from escape analysis.  noescape is
   281  // the identity function but escape analysis doesn't think the
   282  // output depends on the input.  noescape is inlined and currently
   283  // compiles down to zero instructions.
   284  // USE CAREFULLY!
   285  //go:nosplit
   286  func NoEscape(p unsafe.Pointer) unsafe.Pointer {
   287  	x := uintptr(p)
   288  	return unsafe.Pointer(x ^ 0)
   289  }
   290  
   291  func UnsafeCastString(str string) []byte {
   292  	bytes := make([]byte, 0)
   293  	stringHeader := (*reflect.StringHeader)(unsafe.Pointer(&str))
   294  	sliceHeader := (*reflect.SliceHeader)(unsafe.Pointer(&bytes))
   295  	sliceHeader.Data = stringHeader.Data
   296  	sliceHeader.Cap = stringHeader.Len
   297  	sliceHeader.Len = stringHeader.Len
   298  	runtime.KeepAlive(str)
   299  	return bytes
   300  }