helper_unsafe.go 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869
  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. unsafeFlagAddr = 1 << 8
  30. unsafeFlagKindMask = (1 << 5) - 1 // 5 bits for 27 kinds (up to 31)
  31. // unsafeTypeKindDirectIface = 1 << 5
  32. )
  33. type unsafeString struct {
  34. Data unsafe.Pointer
  35. Len int
  36. }
  37. type unsafeSlice struct {
  38. Data unsafe.Pointer
  39. Len int
  40. Cap int
  41. }
  42. type unsafeIntf struct {
  43. typ unsafe.Pointer
  44. word unsafe.Pointer
  45. }
  46. type unsafeReflectValue struct {
  47. typ unsafe.Pointer
  48. ptr unsafe.Pointer
  49. flag uintptr
  50. }
  51. func stringView(v []byte) string {
  52. if len(v) == 0 {
  53. return ""
  54. }
  55. bx := (*unsafeSlice)(unsafe.Pointer(&v))
  56. return *(*string)(unsafe.Pointer(&unsafeString{bx.Data, bx.Len}))
  57. }
  58. func bytesView(v string) []byte {
  59. if len(v) == 0 {
  60. return zeroByteSlice
  61. }
  62. sx := (*unsafeString)(unsafe.Pointer(&v))
  63. return *(*[]byte)(unsafe.Pointer(&unsafeSlice{sx.Data, sx.Len, sx.Len}))
  64. }
  65. // // isNilRef says whether the interface is a nil reference or not.
  66. // //
  67. // // A reference here is a pointer-sized reference i.e. map, ptr, chan, func, unsafepointer.
  68. // // It is optional to extend this to also check if slices or interfaces are nil also.
  69. // //
  70. // // NOTE: There is no global way of checking if an interface is nil.
  71. // // For true references (map, ptr, func, chan), you can just look
  72. // // at the word of the interface.
  73. // // However, for slices, you have to dereference
  74. // // the word, and get a pointer to the 3-word interface value.
  75. // func isNilRef(v interface{}) (rv reflect.Value, isnil bool) {
  76. // isnil = ((*unsafeIntf)(unsafe.Pointer(&v))).word == nil
  77. // return
  78. // }
  79. func isNil(v interface{}) (rv reflect.Value, isnil bool) {
  80. var ui = (*unsafeIntf)(unsafe.Pointer(&v))
  81. if ui.word == nil {
  82. isnil = true
  83. return
  84. }
  85. rv = rv4i(v) // reflect.value is cheap and inline'able
  86. tk := rv.Kind()
  87. isnil = (tk == reflect.Interface || tk == reflect.Slice) && *(*unsafe.Pointer)(ui.word) == nil
  88. return
  89. // fmt.Printf(">>>> isNil: isnil: %v, TYPE: %T, word: %v, *word: %v, type: %v, nil: %v\n",
  90. // v == nil, v, word, *((*unsafe.Pointer)(word)), ui.typ, nil)
  91. }
  92. func rv2ptr(urv *unsafeReflectValue) (ptr unsafe.Pointer) {
  93. // true references (map, func, chan, ptr - NOT slice) may be double-referenced? as flagIndir
  94. // rv := *((*reflect.Value)(unsafe.Pointer(urv)))
  95. if refBitset.isset(byte(urv.flag&unsafeFlagKindMask)) && urv.flag&unsafeFlagIndir != 0 {
  96. ptr = *(*unsafe.Pointer)(urv.ptr)
  97. } else {
  98. ptr = urv.ptr
  99. }
  100. return
  101. }
  102. func rv4i(i interface{}) (rv reflect.Value) {
  103. // Unfortunately, we cannot get the "kind" of the interface directly here.
  104. // We need the 'rtype', whose structure changes in different go versions.
  105. // Finally, it's not clear that there is benefit to reimplementin it,
  106. // as the "escapes(i)" is not clearly expensive.
  107. //
  108. // urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  109. // ui := (*unsafeIntf)(unsafe.Pointer(&i))
  110. return reflect.ValueOf(i)
  111. }
  112. func rv2i(rv reflect.Value) interface{} {
  113. // TODO: consider a more generally-known optimization for reflect.Value ==> Interface
  114. //
  115. // Currently, we use this fragile method that taps into implememtation details from
  116. // the source go stdlib reflect/value.go, and trims the implementation.
  117. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  118. return *(*interface{})(unsafe.Pointer(&unsafeIntf{typ: urv.typ, word: rv2ptr(urv)}))
  119. }
  120. func rvIsNil(rv reflect.Value) bool {
  121. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  122. if urv.flag&unsafeFlagIndir != 0 {
  123. return *(*unsafe.Pointer)(urv.ptr) == nil
  124. }
  125. return urv.ptr == nil
  126. }
  127. func rvSetSliceLen(rv reflect.Value, length int) {
  128. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  129. (*unsafeString)(urv.ptr).Len = length
  130. }
  131. // func rvzeroaddr(t reflect.Type) (rv reflect.Value) {
  132. // // return reflect.New(t).Elem()
  133. // var ui = (*unsafeIntf)(unsafe.Pointer(&t))
  134. // urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  135. // urv.typ = ui.word
  136. // urv.flag = uintptr(t.Kind()) | unsafeFlagIndir | unsafeFlagAddr
  137. // urv.ptr = unsafe_New(ui.word)
  138. // return
  139. // }
  140. func rvZeroAddrK(t reflect.Type, k reflect.Kind) (rv reflect.Value) {
  141. // return reflect.New(t).Elem()
  142. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  143. urv.flag = uintptr(k) | unsafeFlagIndir | unsafeFlagAddr
  144. urv.typ = ((*unsafeIntf)(unsafe.Pointer(&t))).word
  145. urv.ptr = unsafe_New(urv.typ)
  146. return
  147. }
  148. func rvConvert(v reflect.Value, t reflect.Type) (rv reflect.Value) {
  149. uv := (*unsafeReflectValue)(unsafe.Pointer(&v))
  150. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  151. *urv = *uv
  152. urv.typ = ((*unsafeIntf)(unsafe.Pointer(&t))).word
  153. return
  154. }
  155. // func rvisnilref(rv reflect.Value) bool {
  156. // return (*unsafeReflectValue)(unsafe.Pointer(&rv)).ptr == nil
  157. // }
  158. // func rvslen(rv reflect.Value) int {
  159. // urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  160. // return (*unsafeString)(urv.ptr).Len
  161. // }
  162. // func rv2rtid(rv reflect.Value) uintptr {
  163. // return uintptr((*unsafeReflectValue)(unsafe.Pointer(&rv)).typ)
  164. // }
  165. func rt2id(rt reflect.Type) uintptr {
  166. return uintptr(((*unsafeIntf)(unsafe.Pointer(&rt))).word)
  167. }
  168. func i2rtid(i interface{}) uintptr {
  169. return uintptr(((*unsafeIntf)(unsafe.Pointer(&i))).typ)
  170. }
  171. // --------------------------
  172. func isEmptyValue(v reflect.Value, tinfos *TypeInfos, deref, checkStruct bool) bool {
  173. urv := (*unsafeReflectValue)(unsafe.Pointer(&v))
  174. if urv.flag == 0 {
  175. return true
  176. }
  177. switch v.Kind() {
  178. case reflect.Invalid:
  179. return true
  180. case reflect.String:
  181. return (*unsafeString)(urv.ptr).Len == 0
  182. case reflect.Slice:
  183. return (*unsafeSlice)(urv.ptr).Len == 0
  184. case reflect.Bool:
  185. return !*(*bool)(urv.ptr)
  186. case reflect.Int:
  187. return *(*int)(urv.ptr) == 0
  188. case reflect.Int8:
  189. return *(*int8)(urv.ptr) == 0
  190. case reflect.Int16:
  191. return *(*int16)(urv.ptr) == 0
  192. case reflect.Int32:
  193. return *(*int32)(urv.ptr) == 0
  194. case reflect.Int64:
  195. return *(*int64)(urv.ptr) == 0
  196. case reflect.Uint:
  197. return *(*uint)(urv.ptr) == 0
  198. case reflect.Uint8:
  199. return *(*uint8)(urv.ptr) == 0
  200. case reflect.Uint16:
  201. return *(*uint16)(urv.ptr) == 0
  202. case reflect.Uint32:
  203. return *(*uint32)(urv.ptr) == 0
  204. case reflect.Uint64:
  205. return *(*uint64)(urv.ptr) == 0
  206. case reflect.Uintptr:
  207. return *(*uintptr)(urv.ptr) == 0
  208. case reflect.Float32:
  209. return *(*float32)(urv.ptr) == 0
  210. case reflect.Float64:
  211. return *(*float64)(urv.ptr) == 0
  212. case reflect.Interface:
  213. isnil := urv.ptr == nil || *(*unsafe.Pointer)(urv.ptr) == nil
  214. if deref {
  215. if isnil {
  216. return true
  217. }
  218. return isEmptyValue(v.Elem(), tinfos, deref, checkStruct)
  219. }
  220. return isnil
  221. case reflect.Ptr:
  222. // isnil := urv.ptr == nil (not sufficient, as a pointer value encodes the type)
  223. isnil := urv.ptr == nil || *(*unsafe.Pointer)(urv.ptr) == nil
  224. if deref {
  225. if isnil {
  226. return true
  227. }
  228. return isEmptyValue(v.Elem(), tinfos, deref, checkStruct)
  229. }
  230. return isnil
  231. case reflect.Struct:
  232. return isEmptyStruct(v, tinfos, deref, checkStruct)
  233. case reflect.Map, reflect.Array, reflect.Chan:
  234. return v.Len() == 0
  235. }
  236. return false
  237. }
  238. // --------------------------
  239. // atomicXXX is expected to be 2 words (for symmetry with atomic.Value)
  240. //
  241. // Note that we do not atomically load/store length and data pointer separately,
  242. // as this could lead to some races. Instead, we atomically load/store cappedSlice.
  243. //
  244. // Note: with atomic.(Load|Store)Pointer, we MUST work with an unsafe.Pointer directly.
  245. // ----------------------
  246. type atomicTypeInfoSlice struct {
  247. v unsafe.Pointer // *[]rtid2ti
  248. _ uint64 // padding (atomicXXX expected to be 2 words)
  249. }
  250. func (x *atomicTypeInfoSlice) load() (s []rtid2ti) {
  251. x2 := atomic.LoadPointer(&x.v)
  252. if x2 != nil {
  253. s = *(*[]rtid2ti)(x2)
  254. }
  255. return
  256. }
  257. func (x *atomicTypeInfoSlice) store(p []rtid2ti) {
  258. atomic.StorePointer(&x.v, unsafe.Pointer(&p))
  259. }
  260. // --------------------------
  261. type atomicRtidFnSlice struct {
  262. v unsafe.Pointer // *[]codecRtidFn
  263. _ uint64 // padding (atomicXXX expected to be 2 words) (make 1 word so JsonHandle fits)
  264. }
  265. func (x *atomicRtidFnSlice) load() (s []codecRtidFn) {
  266. x2 := atomic.LoadPointer(&x.v)
  267. if x2 != nil {
  268. s = *(*[]codecRtidFn)(x2)
  269. }
  270. return
  271. }
  272. func (x *atomicRtidFnSlice) store(p []codecRtidFn) {
  273. atomic.StorePointer(&x.v, unsafe.Pointer(&p))
  274. }
  275. // --------------------------
  276. type atomicClsErr struct {
  277. v unsafe.Pointer // *clsErr
  278. _ uint64 // padding (atomicXXX expected to be 2 words)
  279. }
  280. func (x *atomicClsErr) load() (e clsErr) {
  281. x2 := (*clsErr)(atomic.LoadPointer(&x.v))
  282. if x2 != nil {
  283. e = *x2
  284. }
  285. return
  286. }
  287. func (x *atomicClsErr) store(p clsErr) {
  288. atomic.StorePointer(&x.v, unsafe.Pointer(&p))
  289. }
  290. // --------------------------
  291. // to create a reflect.Value for each member field of decNaked,
  292. // we first create a global decNaked, and create reflect.Value
  293. // for them all.
  294. // This way, we have the flags and type in the reflect.Value.
  295. // Then, when a reflect.Value is called, we just copy it,
  296. // update the ptr to the decNaked's, and return it.
  297. type unsafeDecNakedWrapper struct {
  298. decNaked
  299. ru, ri, rf, rl, rs, rb, rt reflect.Value // mapping to the primitives above
  300. }
  301. func (n *unsafeDecNakedWrapper) init() {
  302. n.ru = rv4i(&n.u).Elem()
  303. n.ri = rv4i(&n.i).Elem()
  304. n.rf = rv4i(&n.f).Elem()
  305. n.rl = rv4i(&n.l).Elem()
  306. n.rs = rv4i(&n.s).Elem()
  307. n.rt = rv4i(&n.t).Elem()
  308. n.rb = rv4i(&n.b).Elem()
  309. // n.rr[] = rv4i(&n.)
  310. }
  311. var defUnsafeDecNakedWrapper unsafeDecNakedWrapper
  312. func init() {
  313. defUnsafeDecNakedWrapper.init()
  314. }
  315. func (n *decNaked) ru() (v reflect.Value) {
  316. v = defUnsafeDecNakedWrapper.ru
  317. ((*unsafeReflectValue)(unsafe.Pointer(&v))).ptr = unsafe.Pointer(&n.u)
  318. return
  319. }
  320. func (n *decNaked) ri() (v reflect.Value) {
  321. v = defUnsafeDecNakedWrapper.ri
  322. ((*unsafeReflectValue)(unsafe.Pointer(&v))).ptr = unsafe.Pointer(&n.i)
  323. return
  324. }
  325. func (n *decNaked) rf() (v reflect.Value) {
  326. v = defUnsafeDecNakedWrapper.rf
  327. ((*unsafeReflectValue)(unsafe.Pointer(&v))).ptr = unsafe.Pointer(&n.f)
  328. return
  329. }
  330. func (n *decNaked) rl() (v reflect.Value) {
  331. v = defUnsafeDecNakedWrapper.rl
  332. ((*unsafeReflectValue)(unsafe.Pointer(&v))).ptr = unsafe.Pointer(&n.l)
  333. return
  334. }
  335. func (n *decNaked) rs() (v reflect.Value) {
  336. v = defUnsafeDecNakedWrapper.rs
  337. ((*unsafeReflectValue)(unsafe.Pointer(&v))).ptr = unsafe.Pointer(&n.s)
  338. return
  339. }
  340. func (n *decNaked) rt() (v reflect.Value) {
  341. v = defUnsafeDecNakedWrapper.rt
  342. ((*unsafeReflectValue)(unsafe.Pointer(&v))).ptr = unsafe.Pointer(&n.t)
  343. return
  344. }
  345. func (n *decNaked) rb() (v reflect.Value) {
  346. v = defUnsafeDecNakedWrapper.rb
  347. ((*unsafeReflectValue)(unsafe.Pointer(&v))).ptr = unsafe.Pointer(&n.b)
  348. return
  349. }
  350. // --------------------------
  351. func rvSetBytes(rv reflect.Value, v []byte) {
  352. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  353. *(*[]byte)(urv.ptr) = v
  354. }
  355. func rvSetString(rv reflect.Value, v string) {
  356. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  357. *(*string)(urv.ptr) = v
  358. }
  359. func rvSetBool(rv reflect.Value, v bool) {
  360. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  361. *(*bool)(urv.ptr) = v
  362. }
  363. func rvSetTime(rv reflect.Value, v time.Time) {
  364. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  365. *(*time.Time)(urv.ptr) = v
  366. }
  367. func rvSetFloat32(rv reflect.Value, v float32) {
  368. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  369. *(*float32)(urv.ptr) = v
  370. }
  371. func rvSetFloat64(rv reflect.Value, v float64) {
  372. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  373. *(*float64)(urv.ptr) = v
  374. }
  375. func rvSetInt(rv reflect.Value, v int) {
  376. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  377. *(*int)(urv.ptr) = v
  378. }
  379. func rvSetInt8(rv reflect.Value, v int8) {
  380. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  381. *(*int8)(urv.ptr) = v
  382. }
  383. func rvSetInt16(rv reflect.Value, v int16) {
  384. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  385. *(*int16)(urv.ptr) = v
  386. }
  387. func rvSetInt32(rv reflect.Value, v int32) {
  388. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  389. *(*int32)(urv.ptr) = v
  390. }
  391. func rvSetInt64(rv reflect.Value, v int64) {
  392. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  393. *(*int64)(urv.ptr) = v
  394. }
  395. func rvSetUint(rv reflect.Value, v uint) {
  396. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  397. *(*uint)(urv.ptr) = v
  398. }
  399. func rvSetUintptr(rv reflect.Value, v uintptr) {
  400. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  401. *(*uintptr)(urv.ptr) = v
  402. }
  403. func rvSetUint8(rv reflect.Value, v uint8) {
  404. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  405. *(*uint8)(urv.ptr) = v
  406. }
  407. func rvSetUint16(rv reflect.Value, v uint16) {
  408. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  409. *(*uint16)(urv.ptr) = v
  410. }
  411. func rvSetUint32(rv reflect.Value, v uint32) {
  412. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  413. *(*uint32)(urv.ptr) = v
  414. }
  415. func rvSetUint64(rv reflect.Value, v uint64) {
  416. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  417. *(*uint64)(urv.ptr) = v
  418. }
  419. // ----------------
  420. // rvSetDirect is rv.Set for all kinds except reflect.Interface
  421. func rvSetDirect(rv reflect.Value, v reflect.Value) {
  422. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  423. uv := (*unsafeReflectValue)(unsafe.Pointer(&v))
  424. if uv.flag&unsafeFlagIndir == 0 {
  425. *(*unsafe.Pointer)(urv.ptr) = uv.ptr
  426. } else {
  427. typedmemmove(urv.typ, urv.ptr, uv.ptr)
  428. }
  429. }
  430. // rvSlice returns a slice of the slice of lenth
  431. func rvSlice(rv reflect.Value, length int) (v reflect.Value) {
  432. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  433. uv := (*unsafeReflectValue)(unsafe.Pointer(&v))
  434. *uv = *urv
  435. var x []unsafe.Pointer
  436. uv.ptr = unsafe.Pointer(&x)
  437. *(*unsafeSlice)(uv.ptr) = *(*unsafeSlice)(urv.ptr)
  438. (*unsafeSlice)(uv.ptr).Len = length
  439. // xdebugf("length: %d, slice: from: %#v, to: %#v",
  440. // length, *(*unsafeSlice)(urv.ptr), *(*unsafeSlice)(uv.ptr))
  441. return
  442. }
  443. // ------------
  444. func rvGetSliceLen(rv reflect.Value) int {
  445. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  446. return (*unsafeSlice)(urv.ptr).Len
  447. }
  448. func rvGetSliceCap(rv reflect.Value) int {
  449. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  450. return (*unsafeSlice)(urv.ptr).Cap
  451. }
  452. func rvGetArrayBytesRO(rv reflect.Value, scratch []byte) (bs []byte) {
  453. l := rv.Len()
  454. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  455. bx := (*unsafeSlice)(unsafe.Pointer(&bs))
  456. bx.Data = urv.ptr
  457. bx.Len, bx.Cap = l, l
  458. return
  459. }
  460. func rvGetArray4Slice(rv reflect.Value) (v reflect.Value) {
  461. v = rvZeroAddrK(reflectArrayOf(rvGetSliceLen(rv), rv.Type().Elem()), reflect.Array)
  462. // xdebugf("rvGetArray4Slice: b4 copy: rv: %#v, v: %#v", rv, v)
  463. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  464. uv := (*unsafeReflectValue)(unsafe.Pointer(&v))
  465. uv.ptr = *(*unsafe.Pointer)(urv.ptr) // slice rv has a ptr to the slice.
  466. // xdebugf("rvGetArray4Slice: after copy: v: %#v", v)
  467. return
  468. }
  469. func rvGetSlice4Array(rv reflect.Value, tslice reflect.Type) (v reflect.Value) {
  470. uv := (*unsafeReflectValue)(unsafe.Pointer(&v))
  471. var x []unsafe.Pointer
  472. uv.ptr = unsafe.Pointer(&x)
  473. uv.typ = ((*unsafeIntf)(unsafe.Pointer(&tslice))).word
  474. uv.flag = unsafeFlagIndir | uintptr(reflect.Slice)
  475. s := (*unsafeSlice)(uv.ptr)
  476. s.Data = ((*unsafeReflectValue)(unsafe.Pointer(&rv))).ptr
  477. s.Len = rv.Len()
  478. s.Cap = s.Len
  479. return
  480. }
  481. func rvCopySlice(dest, src reflect.Value) {
  482. t := dest.Type().Elem()
  483. urv := (*unsafeReflectValue)(unsafe.Pointer(&dest))
  484. destPtr := urv.ptr
  485. urv = (*unsafeReflectValue)(unsafe.Pointer(&src))
  486. typedslicecopy((*unsafeIntf)(unsafe.Pointer(&t)).word,
  487. *(*unsafeSlice)(destPtr), *(*unsafeSlice)(urv.ptr))
  488. }
  489. // ------------
  490. func rvGetBool(rv reflect.Value) bool {
  491. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  492. return *(*bool)(v.ptr)
  493. }
  494. func rvGetBytes(rv reflect.Value) []byte {
  495. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  496. return *(*[]byte)(v.ptr)
  497. }
  498. func rvGetTime(rv reflect.Value) time.Time {
  499. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  500. return *(*time.Time)(v.ptr)
  501. }
  502. func rvGetString(rv reflect.Value) string {
  503. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  504. return *(*string)(v.ptr)
  505. }
  506. func rvGetFloat64(rv reflect.Value) float64 {
  507. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  508. return *(*float64)(v.ptr)
  509. }
  510. func rvGetFloat32(rv reflect.Value) float32 {
  511. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  512. return *(*float32)(v.ptr)
  513. }
  514. func rvGetInt(rv reflect.Value) int {
  515. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  516. return *(*int)(v.ptr)
  517. }
  518. func rvGetInt8(rv reflect.Value) int8 {
  519. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  520. return *(*int8)(v.ptr)
  521. }
  522. func rvGetInt16(rv reflect.Value) int16 {
  523. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  524. return *(*int16)(v.ptr)
  525. }
  526. func rvGetInt32(rv reflect.Value) int32 {
  527. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  528. return *(*int32)(v.ptr)
  529. }
  530. func rvGetInt64(rv reflect.Value) int64 {
  531. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  532. return *(*int64)(v.ptr)
  533. }
  534. func rvGetUint(rv reflect.Value) uint {
  535. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  536. return *(*uint)(v.ptr)
  537. }
  538. func rvGetUint8(rv reflect.Value) uint8 {
  539. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  540. return *(*uint8)(v.ptr)
  541. }
  542. func rvGetUint16(rv reflect.Value) uint16 {
  543. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  544. return *(*uint16)(v.ptr)
  545. }
  546. func rvGetUint32(rv reflect.Value) uint32 {
  547. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  548. return *(*uint32)(v.ptr)
  549. }
  550. func rvGetUint64(rv reflect.Value) uint64 {
  551. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  552. return *(*uint64)(v.ptr)
  553. }
  554. func rvGetUintptr(rv reflect.Value) uintptr {
  555. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  556. return *(*uintptr)(v.ptr)
  557. }
  558. // ------------ map range and map indexing ----------
  559. // regular calls to map via reflection: MapKeys, MapIndex, MapRange/MapIter etc
  560. // will always allocate for each map key or value.
  561. //
  562. // It is more performant to provide a value that the map entry is set into,
  563. // and that elides the allocation.
  564. // unsafeMapHashIter
  565. //
  566. // go 1.4+ has runtime/hashmap.go or runtime/map.go which has a
  567. // hIter struct with the first 2 values being key and value
  568. // of the current iteration.
  569. //
  570. // This *hIter is passed to mapiterinit, mapiternext, mapiterkey, mapiterelem.
  571. // We bypass the reflect wrapper functions and just use the *hIter directly.
  572. //
  573. // Though *hIter has many fields, we only care about the first 2.
  574. type unsafeMapHashIter struct {
  575. key, value unsafe.Pointer
  576. // other fields are ignored
  577. }
  578. // type unsafeReflectMapIter struct {
  579. // m unsafeReflectValue
  580. // it unsafe.Pointer
  581. // }
  582. type unsafeMapIter struct {
  583. it *unsafeMapHashIter
  584. // k, v reflect.Value
  585. mtyp, ktyp, vtyp unsafe.Pointer
  586. mptr, kptr, vptr unsafe.Pointer
  587. kisref, visref bool
  588. mapvalues bool
  589. done bool
  590. // _ [2]uint64 // padding (cache-aligned)
  591. }
  592. // // pprof show that 13% of cbor encode time taken in
  593. // // allocation of unsafeMapIter.
  594. // // Options are to try to alloc on stack, or pool it.
  595. // // Easiest to pool it.
  596. // const unsafeMapIterUsePool = false
  597. // var unsafeMapIterPool = sync.Pool{
  598. // New: func() interface{} { return new(unsafeMapIter) },
  599. // }
  600. func (t *unsafeMapIter) Next() (r bool) {
  601. if t == nil || t.done {
  602. return
  603. }
  604. if t.it == nil {
  605. t.it = (*unsafeMapHashIter)(mapiterinit(t.mtyp, t.mptr))
  606. } else {
  607. mapiternext((unsafe.Pointer)(t.it))
  608. }
  609. t.done = t.it.key == nil
  610. if t.done {
  611. return
  612. }
  613. unsafeMapSet(t.kptr, t.ktyp, t.it.key, t.kisref)
  614. if t.mapvalues {
  615. unsafeMapSet(t.vptr, t.vtyp, t.it.value, t.visref)
  616. }
  617. return true
  618. }
  619. func (t *unsafeMapIter) Key() (r reflect.Value) {
  620. // return t.k
  621. return
  622. }
  623. func (t *unsafeMapIter) Value() (r reflect.Value) {
  624. // if t.mapvalues {
  625. // return t.v
  626. // }
  627. return
  628. }
  629. func (t *unsafeMapIter) Done() {
  630. // if unsafeMapIterUsePool && t != nil {
  631. // *t = unsafeMapIter{}
  632. // unsafeMapIterPool.Put(t)
  633. // }
  634. }
  635. func unsafeMapSet(p, ptyp, p2 unsafe.Pointer, isref bool) {
  636. if isref {
  637. *(*unsafe.Pointer)(p) = *(*unsafe.Pointer)(p2) // p2
  638. } else {
  639. typedmemmove(ptyp, p, p2) // *(*unsafe.Pointer)(p2)) // p2)
  640. }
  641. }
  642. func unsafeMapKVPtr(urv *unsafeReflectValue) unsafe.Pointer {
  643. if urv.flag&unsafeFlagIndir == 0 {
  644. return unsafe.Pointer(&urv.ptr)
  645. }
  646. return urv.ptr
  647. }
  648. func mapRange(m, k, v reflect.Value, mapvalues bool) (t *unsafeMapIter) {
  649. if rvIsNil(m) {
  650. // return &unsafeMapIter{done: true}
  651. return
  652. }
  653. // if unsafeMapIterUsePool {
  654. // t = unsafeMapIterPool.Get().(*unsafeMapIter)
  655. // } else {
  656. // t = new(unsafeMapIter)
  657. // }
  658. t = new(unsafeMapIter)
  659. // t.k = k
  660. // t.v = v
  661. t.mapvalues = mapvalues
  662. var urv *unsafeReflectValue
  663. urv = (*unsafeReflectValue)(unsafe.Pointer(&m))
  664. t.mtyp = urv.typ
  665. t.mptr = rv2ptr(urv)
  666. urv = (*unsafeReflectValue)(unsafe.Pointer(&k))
  667. t.ktyp = urv.typ
  668. t.kptr = urv.ptr
  669. t.kisref = refBitset.isset(byte(k.Kind()))
  670. if mapvalues {
  671. urv = (*unsafeReflectValue)(unsafe.Pointer(&v))
  672. t.vtyp = urv.typ
  673. t.vptr = urv.ptr
  674. t.visref = refBitset.isset(byte(v.Kind()))
  675. }
  676. return
  677. }
  678. func mapGet(m, k, v reflect.Value) (vv reflect.Value) {
  679. var urv = (*unsafeReflectValue)(unsafe.Pointer(&k))
  680. var kptr = unsafeMapKVPtr(urv)
  681. urv = (*unsafeReflectValue)(unsafe.Pointer(&m))
  682. vvptr := mapaccess(urv.typ, rv2ptr(urv), kptr)
  683. if vvptr == nil {
  684. return
  685. }
  686. // vvptr = *(*unsafe.Pointer)(vvptr)
  687. urv = (*unsafeReflectValue)(unsafe.Pointer(&v))
  688. unsafeMapSet(urv.ptr, urv.typ, vvptr, refBitset.isset(byte(v.Kind())))
  689. return v
  690. }
  691. func mapSet(m, k, v reflect.Value) {
  692. var urv = (*unsafeReflectValue)(unsafe.Pointer(&k))
  693. var kptr = unsafeMapKVPtr(urv)
  694. urv = (*unsafeReflectValue)(unsafe.Pointer(&v))
  695. var vptr = unsafeMapKVPtr(urv)
  696. urv = (*unsafeReflectValue)(unsafe.Pointer(&m))
  697. mapassign(urv.typ, rv2ptr(urv), kptr, vptr)
  698. }
  699. func mapDelete(m, k reflect.Value) {
  700. var urv = (*unsafeReflectValue)(unsafe.Pointer(&k))
  701. var kptr = unsafeMapKVPtr(urv)
  702. urv = (*unsafeReflectValue)(unsafe.Pointer(&m))
  703. mapdelete(urv.typ, rv2ptr(urv), kptr)
  704. }
  705. // return an addressable reflect value that can be used in mapRange and mapGet operations.
  706. //
  707. // all calls to mapGet or mapRange will call here to get an addressable reflect.Value.
  708. func mapAddressableRV(t reflect.Type, k reflect.Kind) (r reflect.Value) {
  709. // return reflect.New(t).Elem()
  710. return rvZeroAddrK(t, k)
  711. }
  712. //go:linkname mapiterinit reflect.mapiterinit
  713. //go:noescape
  714. func mapiterinit(typ unsafe.Pointer, it unsafe.Pointer) (key unsafe.Pointer)
  715. //go:linkname mapiternext reflect.mapiternext
  716. //go:noescape
  717. func mapiternext(it unsafe.Pointer) (key unsafe.Pointer)
  718. //go:linkname mapaccess reflect.mapaccess
  719. //go:noescape
  720. func mapaccess(typ unsafe.Pointer, m unsafe.Pointer, key unsafe.Pointer) (val unsafe.Pointer)
  721. //go:linkname mapassign reflect.mapassign
  722. //go:noescape
  723. func mapassign(typ unsafe.Pointer, m unsafe.Pointer, key, val unsafe.Pointer)
  724. //go:linkname mapdelete reflect.mapdelete
  725. //go:noescape
  726. func mapdelete(typ unsafe.Pointer, m unsafe.Pointer, key unsafe.Pointer)
  727. //go:linkname typedmemmove reflect.typedmemmove
  728. //go:noescape
  729. func typedmemmove(typ unsafe.Pointer, dst, src unsafe.Pointer)
  730. //go:linkname unsafe_New reflect.unsafe_New
  731. //go:noescape
  732. func unsafe_New(typ unsafe.Pointer) unsafe.Pointer
  733. //go:linkname typedslicecopy reflect.typedslicecopy
  734. //go:noescape
  735. func typedslicecopy(elemType unsafe.Pointer, dst, src unsafeSlice) int