helper_unsafe.go 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710
  1. // +build !safe
  2. // +build !appengine
  3. // +build go1.7
  4. // Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
  5. // Use of this source code is governed by a MIT license found in the LICENSE file.
  6. package codec
  7. import (
  8. "reflect"
  9. "sync/atomic"
  10. "time"
  11. "unsafe"
  12. )
  13. // This file has unsafe variants of some helper methods.
  14. // NOTE: See helper_not_unsafe.go for the usage information.
  15. // For reflect.Value code, we decided to do the following:
  16. // - if we know the kind, we can elide conditional checks for
  17. // - SetXXX (Int, Uint, String, Bool, etc)
  18. // - SetLen
  19. //
  20. // We can also optimize
  21. // - IsNil
  22. //
  23. // We cannot do the same for Cap, Len if we still have to do conditional.
  24. // var zeroRTv [4]uintptr
  25. const safeMode = false
  26. // keep in sync with GO_ROOT/src/reflect/value.go
  27. const (
  28. unsafeFlagIndir = 1 << 7
  29. unsafeFlagKindMask = (1 << 5) - 1 // 5 bits for 27 kinds (up to 31)
  30. // unsafeTypeKindDirectIface = 1 << 5
  31. )
  32. type unsafeString struct {
  33. Data unsafe.Pointer
  34. Len int
  35. }
  36. type unsafeSlice struct {
  37. Data unsafe.Pointer
  38. Len int
  39. Cap int
  40. }
  41. type unsafeIntf struct {
  42. typ unsafe.Pointer
  43. word unsafe.Pointer
  44. }
  45. type unsafeReflectValue struct {
  46. typ unsafe.Pointer
  47. ptr unsafe.Pointer
  48. flag uintptr
  49. }
  50. func stringView(v []byte) string {
  51. if len(v) == 0 {
  52. return ""
  53. }
  54. bx := (*unsafeSlice)(unsafe.Pointer(&v))
  55. return *(*string)(unsafe.Pointer(&unsafeString{bx.Data, bx.Len}))
  56. }
  57. func bytesView(v string) []byte {
  58. if len(v) == 0 {
  59. return zeroByteSlice
  60. }
  61. sx := (*unsafeString)(unsafe.Pointer(&v))
  62. return *(*[]byte)(unsafe.Pointer(&unsafeSlice{sx.Data, sx.Len, sx.Len}))
  63. }
  64. // // isNilRef says whether the interface is a nil reference or not.
  65. // //
  66. // // A reference here is a pointer-sized reference i.e. map, ptr, chan, func, unsafepointer.
  67. // // It is optional to extend this to also check if slices or interfaces are nil also.
  68. // //
  69. // // NOTE: There is no global way of checking if an interface is nil.
  70. // // For true references (map, ptr, func, chan), you can just look
  71. // // at the word of the interface.
  72. // // However, for slices, you have to dereference
  73. // // the word, and get a pointer to the 3-word interface value.
  74. // func isNilRef(v interface{}) (rv reflect.Value, isnil bool) {
  75. // isnil = ((*unsafeIntf)(unsafe.Pointer(&v))).word == nil
  76. // return
  77. // }
  78. func isNil(v interface{}) (rv reflect.Value, isnil bool) {
  79. var ui *unsafeIntf = (*unsafeIntf)(unsafe.Pointer(&v))
  80. if ui.word == nil {
  81. isnil = true
  82. return
  83. }
  84. rv = reflect.ValueOf(v) // reflect.value is cheap and inline'able
  85. tk := rv.Kind()
  86. isnil = (tk == reflect.Interface || tk == reflect.Slice) && *(*unsafe.Pointer)(ui.word) == nil
  87. return
  88. // fmt.Printf(">>>> definitely nil: isnil: %v, TYPE: \t%T, word: %v, *word: %v, type: %v, nil: %v\n",
  89. // v == nil, v, word, *((*unsafe.Pointer)(word)), ui.typ, nil)
  90. }
  91. func rv2ptr(urv *unsafeReflectValue) (ptr unsafe.Pointer) {
  92. // true references (map, func, chan, ptr - NOT slice) may be double-referenced? as flagIndir
  93. // rv := *((*reflect.Value)(unsafe.Pointer(urv)))
  94. if refBitset.isset(byte(urv.flag&unsafeFlagKindMask)) && urv.flag&unsafeFlagIndir != 0 {
  95. ptr = *(*unsafe.Pointer)(urv.ptr)
  96. } else {
  97. ptr = urv.ptr
  98. }
  99. return
  100. }
  101. func rv2i(rv reflect.Value) interface{} {
  102. // TODO: consider a more generally-known optimization for reflect.Value ==> Interface
  103. //
  104. // Currently, we use this fragile method that taps into implememtation details from
  105. // the source go stdlib reflect/value.go, and trims the implementation.
  106. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  107. return *(*interface{})(unsafe.Pointer(&unsafeIntf{typ: urv.typ, word: rv2ptr(urv)}))
  108. }
  109. func rvisnil(rv reflect.Value) bool {
  110. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  111. if urv.flag&unsafeFlagIndir != 0 {
  112. return *(*unsafe.Pointer)(urv.ptr) == nil
  113. }
  114. return urv.ptr == nil
  115. }
  116. func rvssetlen(rv reflect.Value, length int) {
  117. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  118. (*unsafeString)(urv.ptr).Len = length
  119. }
  120. // func rvisnilref(rv reflect.Value) bool {
  121. // return (*unsafeReflectValue)(unsafe.Pointer(&rv)).ptr == nil
  122. // }
  123. // func rvslen(rv reflect.Value) int {
  124. // urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  125. // return (*unsafeString)(urv.ptr).Len
  126. // }
  127. // func rv2rtid(rv reflect.Value) uintptr {
  128. // return uintptr((*unsafeReflectValue)(unsafe.Pointer(&rv)).typ)
  129. // }
  130. func rt2id(rt reflect.Type) uintptr {
  131. return uintptr(((*unsafeIntf)(unsafe.Pointer(&rt))).word)
  132. }
  133. func i2rtid(i interface{}) uintptr {
  134. return uintptr(((*unsafeIntf)(unsafe.Pointer(&i))).typ)
  135. }
  136. // --------------------------
  137. func isEmptyValue(v reflect.Value, tinfos *TypeInfos, deref, checkStruct bool) bool {
  138. urv := (*unsafeReflectValue)(unsafe.Pointer(&v))
  139. if urv.flag == 0 {
  140. return true
  141. }
  142. switch v.Kind() {
  143. case reflect.Invalid:
  144. return true
  145. case reflect.String:
  146. return (*unsafeString)(urv.ptr).Len == 0
  147. case reflect.Slice:
  148. return (*unsafeSlice)(urv.ptr).Len == 0
  149. case reflect.Bool:
  150. return !*(*bool)(urv.ptr)
  151. case reflect.Int:
  152. return *(*int)(urv.ptr) == 0
  153. case reflect.Int8:
  154. return *(*int8)(urv.ptr) == 0
  155. case reflect.Int16:
  156. return *(*int16)(urv.ptr) == 0
  157. case reflect.Int32:
  158. return *(*int32)(urv.ptr) == 0
  159. case reflect.Int64:
  160. return *(*int64)(urv.ptr) == 0
  161. case reflect.Uint:
  162. return *(*uint)(urv.ptr) == 0
  163. case reflect.Uint8:
  164. return *(*uint8)(urv.ptr) == 0
  165. case reflect.Uint16:
  166. return *(*uint16)(urv.ptr) == 0
  167. case reflect.Uint32:
  168. return *(*uint32)(urv.ptr) == 0
  169. case reflect.Uint64:
  170. return *(*uint64)(urv.ptr) == 0
  171. case reflect.Uintptr:
  172. return *(*uintptr)(urv.ptr) == 0
  173. case reflect.Float32:
  174. return *(*float32)(urv.ptr) == 0
  175. case reflect.Float64:
  176. return *(*float64)(urv.ptr) == 0
  177. case reflect.Interface:
  178. isnil := urv.ptr == nil || *(*unsafe.Pointer)(urv.ptr) == nil
  179. if deref {
  180. if isnil {
  181. return true
  182. }
  183. return isEmptyValue(v.Elem(), tinfos, deref, checkStruct)
  184. }
  185. return isnil
  186. case reflect.Ptr:
  187. // isnil := urv.ptr == nil (not sufficient, as a pointer value encodes the type)
  188. isnil := urv.ptr == nil || *(*unsafe.Pointer)(urv.ptr) == nil
  189. if deref {
  190. if isnil {
  191. return true
  192. }
  193. return isEmptyValue(v.Elem(), tinfos, deref, checkStruct)
  194. }
  195. return isnil
  196. case reflect.Struct:
  197. return isEmptyStruct(v, tinfos, deref, checkStruct)
  198. case reflect.Map, reflect.Array, reflect.Chan:
  199. return v.Len() == 0
  200. }
  201. return false
  202. }
  203. // --------------------------
  204. // atomicXXX is expected to be 2 words (for symmetry with atomic.Value)
  205. //
  206. // Note that we do not atomically load/store length and data pointer separately,
  207. // as this could lead to some races. Instead, we atomically load/store cappedSlice.
  208. //
  209. // Note: with atomic.(Load|Store)Pointer, we MUST work with an unsafe.Pointer directly.
  210. // ----------------------
  211. type atomicTypeInfoSlice struct {
  212. v unsafe.Pointer // *[]rtid2ti
  213. _ uint64 // padding (atomicXXX expected to be 2 words)
  214. }
  215. func (x *atomicTypeInfoSlice) load() (s []rtid2ti) {
  216. x2 := atomic.LoadPointer(&x.v)
  217. if x2 != nil {
  218. s = *(*[]rtid2ti)(x2)
  219. }
  220. return
  221. }
  222. func (x *atomicTypeInfoSlice) store(p []rtid2ti) {
  223. atomic.StorePointer(&x.v, unsafe.Pointer(&p))
  224. }
  225. // --------------------------
  226. type atomicRtidFnSlice struct {
  227. v unsafe.Pointer // *[]codecRtidFn
  228. _ uint64 // padding (atomicXXX expected to be 2 words) (make 1 word so JsonHandle fits)
  229. }
  230. func (x *atomicRtidFnSlice) load() (s []codecRtidFn) {
  231. x2 := atomic.LoadPointer(&x.v)
  232. if x2 != nil {
  233. s = *(*[]codecRtidFn)(x2)
  234. }
  235. return
  236. }
  237. func (x *atomicRtidFnSlice) store(p []codecRtidFn) {
  238. atomic.StorePointer(&x.v, unsafe.Pointer(&p))
  239. }
  240. // --------------------------
  241. type atomicClsErr struct {
  242. v unsafe.Pointer // *clsErr
  243. _ uint64 // padding (atomicXXX expected to be 2 words)
  244. }
  245. func (x *atomicClsErr) load() (e clsErr) {
  246. x2 := (*clsErr)(atomic.LoadPointer(&x.v))
  247. if x2 != nil {
  248. e = *x2
  249. }
  250. return
  251. }
  252. func (x *atomicClsErr) store(p clsErr) {
  253. atomic.StorePointer(&x.v, unsafe.Pointer(&p))
  254. }
  255. // --------------------------
  256. // to create a reflect.Value for each member field of decNaked,
  257. // we first create a global decNaked, and create reflect.Value
  258. // for them all.
  259. // This way, we have the flags and type in the reflect.Value.
  260. // Then, when a reflect.Value is called, we just copy it,
  261. // update the ptr to the decNaked's, and return it.
  262. type unsafeDecNakedWrapper struct {
  263. decNaked
  264. ru, ri, rf, rl, rs, rb, rt reflect.Value // mapping to the primitives above
  265. }
  266. func (n *unsafeDecNakedWrapper) init() {
  267. n.ru = reflect.ValueOf(&n.u).Elem()
  268. n.ri = reflect.ValueOf(&n.i).Elem()
  269. n.rf = reflect.ValueOf(&n.f).Elem()
  270. n.rl = reflect.ValueOf(&n.l).Elem()
  271. n.rs = reflect.ValueOf(&n.s).Elem()
  272. n.rt = reflect.ValueOf(&n.t).Elem()
  273. n.rb = reflect.ValueOf(&n.b).Elem()
  274. // n.rr[] = reflect.ValueOf(&n.)
  275. }
  276. var defUnsafeDecNakedWrapper unsafeDecNakedWrapper
  277. func init() {
  278. defUnsafeDecNakedWrapper.init()
  279. }
  280. func (n *decNaked) ru() (v reflect.Value) {
  281. v = defUnsafeDecNakedWrapper.ru
  282. ((*unsafeReflectValue)(unsafe.Pointer(&v))).ptr = unsafe.Pointer(&n.u)
  283. return
  284. }
  285. func (n *decNaked) ri() (v reflect.Value) {
  286. v = defUnsafeDecNakedWrapper.ri
  287. ((*unsafeReflectValue)(unsafe.Pointer(&v))).ptr = unsafe.Pointer(&n.i)
  288. return
  289. }
  290. func (n *decNaked) rf() (v reflect.Value) {
  291. v = defUnsafeDecNakedWrapper.rf
  292. ((*unsafeReflectValue)(unsafe.Pointer(&v))).ptr = unsafe.Pointer(&n.f)
  293. return
  294. }
  295. func (n *decNaked) rl() (v reflect.Value) {
  296. v = defUnsafeDecNakedWrapper.rl
  297. ((*unsafeReflectValue)(unsafe.Pointer(&v))).ptr = unsafe.Pointer(&n.l)
  298. return
  299. }
  300. func (n *decNaked) rs() (v reflect.Value) {
  301. v = defUnsafeDecNakedWrapper.rs
  302. ((*unsafeReflectValue)(unsafe.Pointer(&v))).ptr = unsafe.Pointer(&n.s)
  303. return
  304. }
  305. func (n *decNaked) rt() (v reflect.Value) {
  306. v = defUnsafeDecNakedWrapper.rt
  307. ((*unsafeReflectValue)(unsafe.Pointer(&v))).ptr = unsafe.Pointer(&n.t)
  308. return
  309. }
  310. func (n *decNaked) rb() (v reflect.Value) {
  311. v = defUnsafeDecNakedWrapper.rb
  312. ((*unsafeReflectValue)(unsafe.Pointer(&v))).ptr = unsafe.Pointer(&n.b)
  313. return
  314. }
  315. // --------------------------
  316. func (d *Decoder) raw(f *codecFnInfo, rv reflect.Value) {
  317. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  318. *(*[]byte)(urv.ptr) = d.rawBytes()
  319. }
  320. func (d *Decoder) kString(f *codecFnInfo, rv reflect.Value) {
  321. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  322. *(*string)(urv.ptr) = string(d.d.DecodeStringAsBytes())
  323. }
  324. func (d *Decoder) kBool(f *codecFnInfo, rv reflect.Value) {
  325. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  326. *(*bool)(urv.ptr) = d.d.DecodeBool()
  327. }
  328. func (d *Decoder) kTime(f *codecFnInfo, rv reflect.Value) {
  329. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  330. *(*time.Time)(urv.ptr) = d.d.DecodeTime()
  331. }
  332. func (d *Decoder) kFloat32(f *codecFnInfo, rv reflect.Value) {
  333. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  334. *(*float32)(urv.ptr) = d.decodeFloat32()
  335. }
  336. func (d *Decoder) kFloat64(f *codecFnInfo, rv reflect.Value) {
  337. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  338. *(*float64)(urv.ptr) = d.d.DecodeFloat64()
  339. }
  340. func (d *Decoder) kInt(f *codecFnInfo, rv reflect.Value) {
  341. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  342. *(*int)(urv.ptr) = int(chkOvf.IntV(d.d.DecodeInt64(), intBitsize))
  343. }
  344. func (d *Decoder) kInt8(f *codecFnInfo, rv reflect.Value) {
  345. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  346. *(*int8)(urv.ptr) = int8(chkOvf.IntV(d.d.DecodeInt64(), 8))
  347. }
  348. func (d *Decoder) kInt16(f *codecFnInfo, rv reflect.Value) {
  349. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  350. *(*int16)(urv.ptr) = int16(chkOvf.IntV(d.d.DecodeInt64(), 16))
  351. }
  352. func (d *Decoder) kInt32(f *codecFnInfo, rv reflect.Value) {
  353. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  354. *(*int32)(urv.ptr) = int32(chkOvf.IntV(d.d.DecodeInt64(), 32))
  355. }
  356. func (d *Decoder) kInt64(f *codecFnInfo, rv reflect.Value) {
  357. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  358. *(*int64)(urv.ptr) = d.d.DecodeInt64()
  359. }
  360. func (d *Decoder) kUint(f *codecFnInfo, rv reflect.Value) {
  361. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  362. *(*uint)(urv.ptr) = uint(chkOvf.UintV(d.d.DecodeUint64(), uintBitsize))
  363. }
  364. func (d *Decoder) kUintptr(f *codecFnInfo, rv reflect.Value) {
  365. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  366. *(*uintptr)(urv.ptr) = uintptr(chkOvf.UintV(d.d.DecodeUint64(), uintBitsize))
  367. }
  368. func (d *Decoder) kUint8(f *codecFnInfo, rv reflect.Value) {
  369. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  370. *(*uint8)(urv.ptr) = uint8(chkOvf.UintV(d.d.DecodeUint64(), 8))
  371. }
  372. func (d *Decoder) kUint16(f *codecFnInfo, rv reflect.Value) {
  373. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  374. *(*uint16)(urv.ptr) = uint16(chkOvf.UintV(d.d.DecodeUint64(), 16))
  375. }
  376. func (d *Decoder) kUint32(f *codecFnInfo, rv reflect.Value) {
  377. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  378. *(*uint32)(urv.ptr) = uint32(chkOvf.UintV(d.d.DecodeUint64(), 32))
  379. }
  380. func (d *Decoder) kUint64(f *codecFnInfo, rv reflect.Value) {
  381. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  382. *(*uint64)(urv.ptr) = d.d.DecodeUint64()
  383. }
  384. // ------------
  385. func (e *Encoder) kBool(f *codecFnInfo, rv reflect.Value) {
  386. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  387. e.e.EncodeBool(*(*bool)(v.ptr))
  388. }
  389. func (e *Encoder) kTime(f *codecFnInfo, rv reflect.Value) {
  390. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  391. e.e.EncodeTime(*(*time.Time)(v.ptr))
  392. }
  393. func (e *Encoder) kStringToRaw(f *codecFnInfo, rv reflect.Value) {
  394. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  395. s := *(*string)(v.ptr)
  396. e.e.EncodeStringBytesRaw(bytesView(s))
  397. }
  398. func (e *Encoder) kStringEnc(f *codecFnInfo, rv reflect.Value) {
  399. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  400. s := *(*string)(v.ptr)
  401. e.e.EncodeStringEnc(cUTF8, s)
  402. }
  403. func (e *Encoder) kFloat64(f *codecFnInfo, rv reflect.Value) {
  404. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  405. e.e.EncodeFloat64(*(*float64)(v.ptr))
  406. }
  407. func (e *Encoder) kFloat32(f *codecFnInfo, rv reflect.Value) {
  408. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  409. e.e.EncodeFloat32(*(*float32)(v.ptr))
  410. }
  411. func (e *Encoder) kInt(f *codecFnInfo, rv reflect.Value) {
  412. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  413. e.e.EncodeInt(int64(*(*int)(v.ptr)))
  414. }
  415. func (e *Encoder) kInt8(f *codecFnInfo, rv reflect.Value) {
  416. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  417. e.e.EncodeInt(int64(*(*int8)(v.ptr)))
  418. }
  419. func (e *Encoder) kInt16(f *codecFnInfo, rv reflect.Value) {
  420. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  421. e.e.EncodeInt(int64(*(*int16)(v.ptr)))
  422. }
  423. func (e *Encoder) kInt32(f *codecFnInfo, rv reflect.Value) {
  424. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  425. e.e.EncodeInt(int64(*(*int32)(v.ptr)))
  426. }
  427. func (e *Encoder) kInt64(f *codecFnInfo, rv reflect.Value) {
  428. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  429. e.e.EncodeInt(int64(*(*int64)(v.ptr)))
  430. }
  431. func (e *Encoder) kUint(f *codecFnInfo, rv reflect.Value) {
  432. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  433. e.e.EncodeUint(uint64(*(*uint)(v.ptr)))
  434. }
  435. func (e *Encoder) kUint8(f *codecFnInfo, rv reflect.Value) {
  436. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  437. e.e.EncodeUint(uint64(*(*uint8)(v.ptr)))
  438. }
  439. func (e *Encoder) kUint16(f *codecFnInfo, rv reflect.Value) {
  440. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  441. e.e.EncodeUint(uint64(*(*uint16)(v.ptr)))
  442. }
  443. func (e *Encoder) kUint32(f *codecFnInfo, rv reflect.Value) {
  444. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  445. e.e.EncodeUint(uint64(*(*uint32)(v.ptr)))
  446. }
  447. func (e *Encoder) kUint64(f *codecFnInfo, rv reflect.Value) {
  448. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  449. e.e.EncodeUint(uint64(*(*uint64)(v.ptr)))
  450. }
  451. func (e *Encoder) kUintptr(f *codecFnInfo, rv reflect.Value) {
  452. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  453. e.e.EncodeUint(uint64(*(*uintptr)(v.ptr)))
  454. }
  455. // ------------ map range and map indexing ----------
  456. // unsafeMapHashIter
  457. //
  458. // go 1.4+ has runtime/hashmap.go or runtime/map.go which has a
  459. // hIter struct with the first 2 values being key and value
  460. // of the current iteration.
  461. //
  462. // This *hIter is passed to mapiterinit, mapiternext, mapiterkey, mapiterelem.
  463. // We bypass the reflect wrapper functions and just use the *hIter directly.
  464. //
  465. // Though *hIter has many fields, we only care about the first 2.
  466. type unsafeMapHashIter struct {
  467. key, value unsafe.Pointer
  468. // other fields are ignored
  469. }
  470. // type unsafeReflectMapIter struct {
  471. // m unsafeReflectValue
  472. // it unsafe.Pointer
  473. // }
  474. type unsafeMapIter struct {
  475. it *unsafeMapHashIter
  476. k, v reflect.Value
  477. mtyp, ktyp, vtyp unsafe.Pointer
  478. mptr, kptr, vptr unsafe.Pointer
  479. kisref, visref bool
  480. mapvalues bool
  481. done bool
  482. // _ [2]uint64 // padding (cache-aligned)
  483. }
  484. func (t *unsafeMapIter) Next() (r bool) {
  485. if t.done {
  486. return
  487. }
  488. if t.it == nil {
  489. t.it = (*unsafeMapHashIter)(mapiterinit(t.mtyp, t.mptr))
  490. } else {
  491. mapiternext((unsafe.Pointer)(t.it))
  492. }
  493. t.done = t.it.key == nil
  494. if t.done {
  495. return
  496. }
  497. unsafeSet(t.kptr, t.ktyp, t.it.key, t.kisref)
  498. if t.mapvalues {
  499. unsafeSet(t.vptr, t.vtyp, t.it.value, t.visref)
  500. }
  501. return true
  502. }
  503. func (t *unsafeMapIter) Key() reflect.Value {
  504. return t.k
  505. }
  506. func (t *unsafeMapIter) Value() (r reflect.Value) {
  507. if t.mapvalues {
  508. return t.v
  509. }
  510. return
  511. }
  512. func unsafeSet(p, ptyp, p2 unsafe.Pointer, isref bool) {
  513. if isref {
  514. *(*unsafe.Pointer)(p) = *(*unsafe.Pointer)(p2) // p2
  515. } else {
  516. typedmemmove(ptyp, p, p2) // *(*unsafe.Pointer)(p2)) // p2)
  517. }
  518. }
  519. func mapRange(m, k, v reflect.Value, mapvalues bool) *unsafeMapIter {
  520. if m.IsNil() {
  521. return &unsafeMapIter{done: true}
  522. }
  523. t := &unsafeMapIter{
  524. k: k, v: v,
  525. mapvalues: mapvalues,
  526. }
  527. var urv *unsafeReflectValue
  528. urv = (*unsafeReflectValue)(unsafe.Pointer(&m))
  529. t.mtyp = urv.typ
  530. t.mptr = rv2ptr(urv)
  531. urv = (*unsafeReflectValue)(unsafe.Pointer(&k))
  532. t.ktyp = urv.typ
  533. t.kptr = urv.ptr
  534. t.kisref = refBitset.isset(byte(k.Kind()))
  535. if mapvalues {
  536. urv = (*unsafeReflectValue)(unsafe.Pointer(&v))
  537. t.vtyp = urv.typ
  538. t.vptr = urv.ptr
  539. t.visref = refBitset.isset(byte(v.Kind()))
  540. }
  541. return t
  542. }
  543. func unsafeMapKVPtr(urv *unsafeReflectValue) unsafe.Pointer {
  544. if urv.flag&unsafeFlagIndir == 0 {
  545. return unsafe.Pointer(&urv.ptr)
  546. }
  547. return urv.ptr
  548. }
  549. func mapGet(m, k, v reflect.Value) (vv reflect.Value) {
  550. var urv = (*unsafeReflectValue)(unsafe.Pointer(&k))
  551. var kptr = unsafeMapKVPtr(urv)
  552. urv = (*unsafeReflectValue)(unsafe.Pointer(&m))
  553. vvptr := mapaccess(urv.typ, rv2ptr(urv), kptr)
  554. if vvptr == nil {
  555. return
  556. }
  557. // vvptr = *(*unsafe.Pointer)(vvptr)
  558. urv = (*unsafeReflectValue)(unsafe.Pointer(&v))
  559. unsafeSet(urv.ptr, urv.typ, vvptr, refBitset.isset(byte(v.Kind())))
  560. return v
  561. }
  562. func mapSet(m, k, v reflect.Value) {
  563. var urv = (*unsafeReflectValue)(unsafe.Pointer(&k))
  564. var kptr = unsafeMapKVPtr(urv)
  565. urv = (*unsafeReflectValue)(unsafe.Pointer(&v))
  566. var vptr = unsafeMapKVPtr(urv)
  567. urv = (*unsafeReflectValue)(unsafe.Pointer(&m))
  568. mapassign(urv.typ, rv2ptr(urv), kptr, vptr)
  569. }
  570. func mapDelete(m, k reflect.Value) {
  571. var urv = (*unsafeReflectValue)(unsafe.Pointer(&k))
  572. var kptr = unsafeMapKVPtr(urv)
  573. urv = (*unsafeReflectValue)(unsafe.Pointer(&m))
  574. mapdelete(urv.typ, rv2ptr(urv), kptr)
  575. }
  576. // return an addressable reflect value that can be used in mapRange and mapGet operations.
  577. //
  578. // all calls to mapGet or mapRange will call here to get an addressable reflect.Value.
  579. func mapAddressableRV(t reflect.Type) (r reflect.Value) {
  580. return reflect.New(t).Elem()
  581. }
  582. //go:linkname mapiterinit reflect.mapiterinit
  583. //go:noescape
  584. func mapiterinit(typ unsafe.Pointer, it unsafe.Pointer) (key unsafe.Pointer)
  585. //go:linkname mapiternext reflect.mapiternext
  586. //go:noescape
  587. func mapiternext(it unsafe.Pointer) (key unsafe.Pointer)
  588. //go:linkname mapaccess reflect.mapaccess
  589. //go:noescape
  590. func mapaccess(typ unsafe.Pointer, m unsafe.Pointer, key unsafe.Pointer) (val unsafe.Pointer)
  591. //go:linkname mapassign reflect.mapassign
  592. //go:noescape
  593. func mapassign(typ unsafe.Pointer, m unsafe.Pointer, key, val unsafe.Pointer)
  594. //go:linkname mapdelete reflect.mapdelete
  595. //go:noescape
  596. func mapdelete(typ unsafe.Pointer, m unsafe.Pointer, key unsafe.Pointer)
  597. //go:linkname typedmemmove reflect.typedmemmove
  598. //go:noescape
  599. func typedmemmove(typ unsafe.Pointer, dst, src unsafe.Pointer)