helper_unsafe.go 19 KB

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