http urls monitor.

type_map.go 3.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. package reflect2
  2. import (
  3. "reflect"
  4. "runtime"
  5. "strings"
  6. "sync"
  7. "unsafe"
  8. )
  9. // typelinks1 for 1.5 ~ 1.6
  10. //go:linkname typelinks1 reflect.typelinks
  11. func typelinks1() [][]unsafe.Pointer
  12. // typelinks2 for 1.7 ~
  13. //go:linkname typelinks2 reflect.typelinks
  14. func typelinks2() (sections []unsafe.Pointer, offset [][]int32)
  15. // initOnce guards initialization of types and packages
  16. var initOnce sync.Once
  17. var types map[string]reflect.Type
  18. var packages map[string]map[string]reflect.Type
  19. // discoverTypes initializes types and packages
  20. func discoverTypes() {
  21. types = make(map[string]reflect.Type)
  22. packages = make(map[string]map[string]reflect.Type)
  23. ver := runtime.Version()
  24. if ver == "go1.5" || strings.HasPrefix(ver, "go1.5.") {
  25. loadGo15Types()
  26. } else if ver == "go1.6" || strings.HasPrefix(ver, "go1.6.") {
  27. loadGo15Types()
  28. } else {
  29. loadGo17Types()
  30. }
  31. }
  32. func loadGo15Types() {
  33. var obj interface{} = reflect.TypeOf(0)
  34. typePtrss := typelinks1()
  35. for _, typePtrs := range typePtrss {
  36. for _, typePtr := range typePtrs {
  37. (*emptyInterface)(unsafe.Pointer(&obj)).word = typePtr
  38. typ := obj.(reflect.Type)
  39. if typ.Kind() == reflect.Ptr && typ.Elem().Kind() == reflect.Struct {
  40. loadedType := typ.Elem()
  41. pkgTypes := packages[loadedType.PkgPath()]
  42. if pkgTypes == nil {
  43. pkgTypes = map[string]reflect.Type{}
  44. packages[loadedType.PkgPath()] = pkgTypes
  45. }
  46. types[loadedType.String()] = loadedType
  47. pkgTypes[loadedType.Name()] = loadedType
  48. }
  49. if typ.Kind() == reflect.Slice && typ.Elem().Kind() == reflect.Ptr &&
  50. typ.Elem().Elem().Kind() == reflect.Struct {
  51. loadedType := typ.Elem().Elem()
  52. pkgTypes := packages[loadedType.PkgPath()]
  53. if pkgTypes == nil {
  54. pkgTypes = map[string]reflect.Type{}
  55. packages[loadedType.PkgPath()] = pkgTypes
  56. }
  57. types[loadedType.String()] = loadedType
  58. pkgTypes[loadedType.Name()] = loadedType
  59. }
  60. }
  61. }
  62. }
  63. func loadGo17Types() {
  64. var obj interface{} = reflect.TypeOf(0)
  65. sections, offset := typelinks2()
  66. for i, offs := range offset {
  67. rodata := sections[i]
  68. for _, off := range offs {
  69. (*emptyInterface)(unsafe.Pointer(&obj)).word = resolveTypeOff(unsafe.Pointer(rodata), off)
  70. typ := obj.(reflect.Type)
  71. if typ.Kind() == reflect.Ptr && typ.Elem().Kind() == reflect.Struct {
  72. loadedType := typ.Elem()
  73. pkgTypes := packages[loadedType.PkgPath()]
  74. if pkgTypes == nil {
  75. pkgTypes = map[string]reflect.Type{}
  76. packages[loadedType.PkgPath()] = pkgTypes
  77. }
  78. types[loadedType.String()] = loadedType
  79. pkgTypes[loadedType.Name()] = loadedType
  80. }
  81. }
  82. }
  83. }
  84. type emptyInterface struct {
  85. typ unsafe.Pointer
  86. word unsafe.Pointer
  87. }
  88. // TypeByName return the type by its name, just like Class.forName in java
  89. func TypeByName(typeName string) Type {
  90. initOnce.Do(discoverTypes)
  91. return Type2(types[typeName])
  92. }
  93. // TypeByPackageName return the type by its package and name
  94. func TypeByPackageName(pkgPath string, name string) Type {
  95. initOnce.Do(discoverTypes)
  96. pkgTypes := packages[pkgPath]
  97. if pkgTypes == nil {
  98. return nil
  99. }
  100. return Type2(pkgTypes[name])
  101. }