helper_unsafe.go 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741
  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. // var zeroRTv [4]uintptr
  16. const safeMode = false
  17. const unsafeFlagIndir = 1 << 7 // keep in sync with GO_ROOT/src/reflect/value.go
  18. type unsafeString struct {
  19. Data unsafe.Pointer
  20. Len int
  21. }
  22. type unsafeSlice struct {
  23. Data unsafe.Pointer
  24. Len int
  25. Cap int
  26. }
  27. type unsafeIntf struct {
  28. typ unsafe.Pointer
  29. word unsafe.Pointer
  30. }
  31. type unsafeReflectValue struct {
  32. typ unsafe.Pointer
  33. ptr unsafe.Pointer
  34. flag uintptr
  35. }
  36. func stringView(v []byte) string {
  37. if len(v) == 0 {
  38. return ""
  39. }
  40. bx := (*unsafeSlice)(unsafe.Pointer(&v))
  41. return *(*string)(unsafe.Pointer(&unsafeString{bx.Data, bx.Len}))
  42. }
  43. func bytesView(v string) []byte {
  44. if len(v) == 0 {
  45. return zeroByteSlice
  46. }
  47. sx := (*unsafeString)(unsafe.Pointer(&v))
  48. return *(*[]byte)(unsafe.Pointer(&unsafeSlice{sx.Data, sx.Len, sx.Len}))
  49. }
  50. func definitelyNil(v interface{}) bool {
  51. // There is no global way of checking if an interface is nil.
  52. // For true references (map, ptr, func, chan), you can just look
  53. // at the word of the interface. However, for slices, you have to dereference
  54. // the word, and get a pointer to the 3-word interface value.
  55. //
  56. // However, the following are cheap calls
  57. // - TypeOf(interface): cheap 2-line call.
  58. // - ValueOf(interface{}): expensive
  59. // - type.Kind: cheap call through an interface
  60. // - Value.Type(): cheap call
  61. // except it's a method value (e.g. r.Read, which implies that it is a Func)
  62. return ((*unsafeIntf)(unsafe.Pointer(&v))).word == nil
  63. }
  64. func rv2i(rv reflect.Value) interface{} {
  65. // TODO: consider a more generally-known optimization for reflect.Value ==> Interface
  66. //
  67. // Currently, we use this fragile method that taps into implememtation details from
  68. // the source go stdlib reflect/value.go, and trims the implementation.
  69. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  70. // true references (map, func, chan, ptr - NOT slice) may be double-referenced as flagIndir
  71. var ptr unsafe.Pointer
  72. if refBitset.isset(byte(urv.flag&(1<<5-1))) && urv.flag&unsafeFlagIndir != 0 {
  73. ptr = *(*unsafe.Pointer)(urv.ptr)
  74. } else {
  75. ptr = urv.ptr
  76. }
  77. return *(*interface{})(unsafe.Pointer(&unsafeIntf{typ: urv.typ, word: ptr}))
  78. }
  79. func rt2id(rt reflect.Type) uintptr {
  80. return uintptr(((*unsafeIntf)(unsafe.Pointer(&rt))).word)
  81. }
  82. // func rv2rtid(rv reflect.Value) uintptr {
  83. // return uintptr((*unsafeReflectValue)(unsafe.Pointer(&rv)).typ)
  84. // }
  85. func i2rtid(i interface{}) uintptr {
  86. return uintptr(((*unsafeIntf)(unsafe.Pointer(&i))).typ)
  87. }
  88. // --------------------------
  89. func isEmptyValue(v reflect.Value, tinfos *TypeInfos, deref, checkStruct bool) bool {
  90. urv := (*unsafeReflectValue)(unsafe.Pointer(&v))
  91. if urv.flag == 0 {
  92. return true
  93. }
  94. switch v.Kind() {
  95. case reflect.Invalid:
  96. return true
  97. case reflect.String:
  98. return (*unsafeString)(urv.ptr).Len == 0
  99. case reflect.Slice:
  100. return (*unsafeSlice)(urv.ptr).Len == 0
  101. case reflect.Bool:
  102. return !*(*bool)(urv.ptr)
  103. case reflect.Int:
  104. return *(*int)(urv.ptr) == 0
  105. case reflect.Int8:
  106. return *(*int8)(urv.ptr) == 0
  107. case reflect.Int16:
  108. return *(*int16)(urv.ptr) == 0
  109. case reflect.Int32:
  110. return *(*int32)(urv.ptr) == 0
  111. case reflect.Int64:
  112. return *(*int64)(urv.ptr) == 0
  113. case reflect.Uint:
  114. return *(*uint)(urv.ptr) == 0
  115. case reflect.Uint8:
  116. return *(*uint8)(urv.ptr) == 0
  117. case reflect.Uint16:
  118. return *(*uint16)(urv.ptr) == 0
  119. case reflect.Uint32:
  120. return *(*uint32)(urv.ptr) == 0
  121. case reflect.Uint64:
  122. return *(*uint64)(urv.ptr) == 0
  123. case reflect.Uintptr:
  124. return *(*uintptr)(urv.ptr) == 0
  125. case reflect.Float32:
  126. return *(*float32)(urv.ptr) == 0
  127. case reflect.Float64:
  128. return *(*float64)(urv.ptr) == 0
  129. case reflect.Interface:
  130. isnil := urv.ptr == nil || *(*unsafe.Pointer)(urv.ptr) == nil
  131. if deref {
  132. if isnil {
  133. return true
  134. }
  135. return isEmptyValue(v.Elem(), tinfos, deref, checkStruct)
  136. }
  137. return isnil
  138. case reflect.Ptr:
  139. // isnil := urv.ptr == nil (not sufficient, as a pointer value encodes the type)
  140. isnil := urv.ptr == nil || *(*unsafe.Pointer)(urv.ptr) == nil
  141. if deref {
  142. if isnil {
  143. return true
  144. }
  145. return isEmptyValue(v.Elem(), tinfos, deref, checkStruct)
  146. }
  147. return isnil
  148. case reflect.Struct:
  149. return isEmptyStruct(v, tinfos, deref, checkStruct)
  150. case reflect.Map, reflect.Array, reflect.Chan:
  151. return v.Len() == 0
  152. }
  153. return false
  154. }
  155. // --------------------------
  156. // atomicXXX is expected to be 2 words (for symmetry with atomic.Value)
  157. //
  158. // Note that we do not atomically load/store length and data pointer separately,
  159. // as this could lead to some races. Instead, we atomically load/store cappedSlice.
  160. //
  161. // Note: with atomic.(Load|Store)Pointer, we MUST work with an unsafe.Pointer directly.
  162. // ----------------------
  163. type atomicTypeInfoSlice struct {
  164. v unsafe.Pointer // *[]rtid2ti
  165. _ uint64 // padding (atomicXXX expected to be 2 words)
  166. }
  167. func (x *atomicTypeInfoSlice) load() (s []rtid2ti) {
  168. x2 := atomic.LoadPointer(&x.v)
  169. if x2 != nil {
  170. s = *(*[]rtid2ti)(x2)
  171. }
  172. return
  173. }
  174. func (x *atomicTypeInfoSlice) store(p []rtid2ti) {
  175. atomic.StorePointer(&x.v, unsafe.Pointer(&p))
  176. }
  177. // --------------------------
  178. type atomicRtidFnSlice struct {
  179. v unsafe.Pointer // *[]codecRtidFn
  180. // _ uint64 // padding (atomicXXX expected to be 2 words) (make 1 word so JsonHandle fits)
  181. }
  182. func (x *atomicRtidFnSlice) load() (s []codecRtidFn) {
  183. x2 := atomic.LoadPointer(&x.v)
  184. if x2 != nil {
  185. s = *(*[]codecRtidFn)(x2)
  186. }
  187. return
  188. }
  189. func (x *atomicRtidFnSlice) store(p []codecRtidFn) {
  190. atomic.StorePointer(&x.v, unsafe.Pointer(&p))
  191. }
  192. // --------------------------
  193. type atomicClsErr struct {
  194. v unsafe.Pointer // *clsErr
  195. _ uint64 // padding (atomicXXX expected to be 2 words)
  196. }
  197. func (x *atomicClsErr) load() (e clsErr) {
  198. x2 := (*clsErr)(atomic.LoadPointer(&x.v))
  199. if x2 != nil {
  200. e = *x2
  201. }
  202. return
  203. }
  204. func (x *atomicClsErr) store(p clsErr) {
  205. atomic.StorePointer(&x.v, unsafe.Pointer(&p))
  206. }
  207. // --------------------------
  208. // to create a reflect.Value for each member field of decNaked,
  209. // we first create a global decNaked, and create reflect.Value
  210. // for them all.
  211. // This way, we have the flags and type in the reflect.Value.
  212. // Then, when a reflect.Value is called, we just copy it,
  213. // update the ptr to the decNaked's, and return it.
  214. type unsafeDecNakedWrapper struct {
  215. decNaked
  216. ru, ri, rf, rl, rs, rb, rt reflect.Value // mapping to the primitives above
  217. }
  218. func (n *unsafeDecNakedWrapper) init() {
  219. n.ru = reflect.ValueOf(&n.u).Elem()
  220. n.ri = reflect.ValueOf(&n.i).Elem()
  221. n.rf = reflect.ValueOf(&n.f).Elem()
  222. n.rl = reflect.ValueOf(&n.l).Elem()
  223. n.rs = reflect.ValueOf(&n.s).Elem()
  224. n.rt = reflect.ValueOf(&n.t).Elem()
  225. n.rb = reflect.ValueOf(&n.b).Elem()
  226. // n.rr[] = reflect.ValueOf(&n.)
  227. }
  228. var defUnsafeDecNakedWrapper unsafeDecNakedWrapper
  229. func init() {
  230. defUnsafeDecNakedWrapper.init()
  231. }
  232. func (n *decNaked) ru() (v reflect.Value) {
  233. v = defUnsafeDecNakedWrapper.ru
  234. ((*unsafeReflectValue)(unsafe.Pointer(&v))).ptr = unsafe.Pointer(&n.u)
  235. return
  236. }
  237. func (n *decNaked) ri() (v reflect.Value) {
  238. v = defUnsafeDecNakedWrapper.ri
  239. ((*unsafeReflectValue)(unsafe.Pointer(&v))).ptr = unsafe.Pointer(&n.i)
  240. return
  241. }
  242. func (n *decNaked) rf() (v reflect.Value) {
  243. v = defUnsafeDecNakedWrapper.rf
  244. ((*unsafeReflectValue)(unsafe.Pointer(&v))).ptr = unsafe.Pointer(&n.f)
  245. return
  246. }
  247. func (n *decNaked) rl() (v reflect.Value) {
  248. v = defUnsafeDecNakedWrapper.rl
  249. ((*unsafeReflectValue)(unsafe.Pointer(&v))).ptr = unsafe.Pointer(&n.l)
  250. return
  251. }
  252. func (n *decNaked) rs() (v reflect.Value) {
  253. v = defUnsafeDecNakedWrapper.rs
  254. ((*unsafeReflectValue)(unsafe.Pointer(&v))).ptr = unsafe.Pointer(&n.s)
  255. return
  256. }
  257. func (n *decNaked) rt() (v reflect.Value) {
  258. v = defUnsafeDecNakedWrapper.rt
  259. ((*unsafeReflectValue)(unsafe.Pointer(&v))).ptr = unsafe.Pointer(&n.t)
  260. return
  261. }
  262. func (n *decNaked) rb() (v reflect.Value) {
  263. v = defUnsafeDecNakedWrapper.rb
  264. ((*unsafeReflectValue)(unsafe.Pointer(&v))).ptr = unsafe.Pointer(&n.b)
  265. return
  266. }
  267. // --------------------------
  268. func (d *Decoder) raw(f *codecFnInfo, rv reflect.Value) {
  269. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  270. *(*[]byte)(urv.ptr) = d.rawBytes()
  271. }
  272. func (d *Decoder) kString(f *codecFnInfo, rv reflect.Value) {
  273. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  274. *(*string)(urv.ptr) = d.d.DecodeString()
  275. }
  276. func (d *Decoder) kBool(f *codecFnInfo, rv reflect.Value) {
  277. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  278. *(*bool)(urv.ptr) = d.d.DecodeBool()
  279. }
  280. func (d *Decoder) kTime(f *codecFnInfo, rv reflect.Value) {
  281. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  282. *(*time.Time)(urv.ptr) = d.d.DecodeTime()
  283. }
  284. func (d *Decoder) kFloat32(f *codecFnInfo, rv reflect.Value) {
  285. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  286. *(*float32)(urv.ptr) = float32(d.decodeFloat32())
  287. }
  288. func (d *Decoder) kFloat64(f *codecFnInfo, rv reflect.Value) {
  289. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  290. *(*float64)(urv.ptr) = d.d.DecodeFloat64()
  291. }
  292. func (d *Decoder) kInt(f *codecFnInfo, rv reflect.Value) {
  293. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  294. *(*int)(urv.ptr) = int(chkOvf.IntV(d.d.DecodeInt64(), intBitsize))
  295. }
  296. func (d *Decoder) kInt8(f *codecFnInfo, rv reflect.Value) {
  297. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  298. *(*int8)(urv.ptr) = int8(chkOvf.IntV(d.d.DecodeInt64(), 8))
  299. }
  300. func (d *Decoder) kInt16(f *codecFnInfo, rv reflect.Value) {
  301. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  302. *(*int16)(urv.ptr) = int16(chkOvf.IntV(d.d.DecodeInt64(), 16))
  303. }
  304. func (d *Decoder) kInt32(f *codecFnInfo, rv reflect.Value) {
  305. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  306. *(*int32)(urv.ptr) = int32(chkOvf.IntV(d.d.DecodeInt64(), 32))
  307. }
  308. func (d *Decoder) kInt64(f *codecFnInfo, rv reflect.Value) {
  309. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  310. *(*int64)(urv.ptr) = d.d.DecodeInt64()
  311. }
  312. func (d *Decoder) kUint(f *codecFnInfo, rv reflect.Value) {
  313. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  314. *(*uint)(urv.ptr) = uint(chkOvf.UintV(d.d.DecodeUint64(), uintBitsize))
  315. }
  316. func (d *Decoder) kUintptr(f *codecFnInfo, rv reflect.Value) {
  317. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  318. *(*uintptr)(urv.ptr) = uintptr(chkOvf.UintV(d.d.DecodeUint64(), uintBitsize))
  319. }
  320. func (d *Decoder) kUint8(f *codecFnInfo, rv reflect.Value) {
  321. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  322. *(*uint8)(urv.ptr) = uint8(chkOvf.UintV(d.d.DecodeUint64(), 8))
  323. }
  324. func (d *Decoder) kUint16(f *codecFnInfo, rv reflect.Value) {
  325. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  326. *(*uint16)(urv.ptr) = uint16(chkOvf.UintV(d.d.DecodeUint64(), 16))
  327. }
  328. func (d *Decoder) kUint32(f *codecFnInfo, rv reflect.Value) {
  329. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  330. *(*uint32)(urv.ptr) = uint32(chkOvf.UintV(d.d.DecodeUint64(), 32))
  331. }
  332. func (d *Decoder) kUint64(f *codecFnInfo, rv reflect.Value) {
  333. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  334. *(*uint64)(urv.ptr) = d.d.DecodeUint64()
  335. }
  336. // ------------
  337. func (e *Encoder) kBool(f *codecFnInfo, rv reflect.Value) {
  338. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  339. e.e.EncodeBool(*(*bool)(v.ptr))
  340. }
  341. func (e *Encoder) kTime(f *codecFnInfo, rv reflect.Value) {
  342. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  343. e.e.EncodeTime(*(*time.Time)(v.ptr))
  344. }
  345. func (e *Encoder) kString(f *codecFnInfo, rv reflect.Value) {
  346. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  347. s := *(*string)(v.ptr)
  348. if e.h.StringToRaw {
  349. e.e.EncodeStringBytesRaw(bytesView(s))
  350. } else {
  351. e.e.EncodeStringEnc(cUTF8, s)
  352. }
  353. }
  354. func (e *Encoder) kFloat64(f *codecFnInfo, rv reflect.Value) {
  355. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  356. e.e.EncodeFloat64(*(*float64)(v.ptr))
  357. }
  358. func (e *Encoder) kFloat32(f *codecFnInfo, rv reflect.Value) {
  359. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  360. e.e.EncodeFloat32(*(*float32)(v.ptr))
  361. }
  362. func (e *Encoder) kInt(f *codecFnInfo, rv reflect.Value) {
  363. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  364. e.e.EncodeInt(int64(*(*int)(v.ptr)))
  365. }
  366. func (e *Encoder) kInt8(f *codecFnInfo, rv reflect.Value) {
  367. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  368. e.e.EncodeInt(int64(*(*int8)(v.ptr)))
  369. }
  370. func (e *Encoder) kInt16(f *codecFnInfo, rv reflect.Value) {
  371. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  372. e.e.EncodeInt(int64(*(*int16)(v.ptr)))
  373. }
  374. func (e *Encoder) kInt32(f *codecFnInfo, rv reflect.Value) {
  375. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  376. e.e.EncodeInt(int64(*(*int32)(v.ptr)))
  377. }
  378. func (e *Encoder) kInt64(f *codecFnInfo, rv reflect.Value) {
  379. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  380. e.e.EncodeInt(int64(*(*int64)(v.ptr)))
  381. }
  382. func (e *Encoder) kUint(f *codecFnInfo, rv reflect.Value) {
  383. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  384. e.e.EncodeUint(uint64(*(*uint)(v.ptr)))
  385. }
  386. func (e *Encoder) kUint8(f *codecFnInfo, rv reflect.Value) {
  387. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  388. e.e.EncodeUint(uint64(*(*uint8)(v.ptr)))
  389. }
  390. func (e *Encoder) kUint16(f *codecFnInfo, rv reflect.Value) {
  391. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  392. e.e.EncodeUint(uint64(*(*uint16)(v.ptr)))
  393. }
  394. func (e *Encoder) kUint32(f *codecFnInfo, rv reflect.Value) {
  395. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  396. e.e.EncodeUint(uint64(*(*uint32)(v.ptr)))
  397. }
  398. func (e *Encoder) kUint64(f *codecFnInfo, rv reflect.Value) {
  399. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  400. e.e.EncodeUint(uint64(*(*uint64)(v.ptr)))
  401. }
  402. func (e *Encoder) kUintptr(f *codecFnInfo, rv reflect.Value) {
  403. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  404. e.e.EncodeUint(uint64(*(*uintptr)(v.ptr)))
  405. }
  406. // ------------
  407. // func (d *Decoder) raw(f *codecFnInfo, rv reflect.Value) {
  408. // urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  409. // // if urv.flag&unsafeFlagIndir != 0 {
  410. // // urv.ptr = *(*unsafe.Pointer)(urv.ptr)
  411. // // }
  412. // *(*[]byte)(urv.ptr) = d.rawBytes()
  413. // }
  414. // func rv0t(rt reflect.Type) reflect.Value {
  415. // ut := (*unsafeIntf)(unsafe.Pointer(&rt))
  416. // // we need to determine whether ifaceIndir, and then whether to just pass 0 as the ptr
  417. // uv := unsafeReflectValue{ut.word, &zeroRTv, flag(rt.Kind())}
  418. // return *(*reflect.Value)(unsafe.Pointer(&uv})
  419. // }
  420. // func rv2i(rv reflect.Value) interface{} {
  421. // urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  422. // // true references (map, func, chan, ptr - NOT slice) may be double-referenced as flagIndir
  423. // var ptr unsafe.Pointer
  424. // // kk := reflect.Kind(urv.flag & (1<<5 - 1))
  425. // // if (kk == reflect.Map || kk == reflect.Ptr || kk == reflect.Chan || kk == reflect.Func) && urv.flag&unsafeFlagIndir != 0 {
  426. // if refBitset.isset(byte(urv.flag&(1<<5-1))) && urv.flag&unsafeFlagIndir != 0 {
  427. // ptr = *(*unsafe.Pointer)(urv.ptr)
  428. // } else {
  429. // ptr = urv.ptr
  430. // }
  431. // return *(*interface{})(unsafe.Pointer(&unsafeIntf{typ: urv.typ, word: ptr}))
  432. // // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ}))
  433. // // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
  434. // }
  435. // func definitelyNil(v interface{}) bool {
  436. // var ui *unsafeIntf = (*unsafeIntf)(unsafe.Pointer(&v))
  437. // if ui.word == nil {
  438. // return true
  439. // }
  440. // var tk = reflect.TypeOf(v).Kind()
  441. // return (tk == reflect.Interface || tk == reflect.Slice) && *(*unsafe.Pointer)(ui.word) == nil
  442. // fmt.Printf(">>>> definitely nil: isnil: %v, TYPE: \t%T, word: %v, *word: %v, type: %v, nil: %v\n",
  443. // v == nil, v, word, *((*unsafe.Pointer)(word)), ui.typ, nil)
  444. // }
  445. // func keepAlive4BytesView(v string) {
  446. // runtime.KeepAlive(v)
  447. // }
  448. // func keepAlive4StringView(v []byte) {
  449. // runtime.KeepAlive(v)
  450. // }
  451. // func rt2id(rt reflect.Type) uintptr {
  452. // return uintptr(((*unsafeIntf)(unsafe.Pointer(&rt))).word)
  453. // // var i interface{} = rt
  454. // // // ui := (*unsafeIntf)(unsafe.Pointer(&i))
  455. // // return ((*unsafeIntf)(unsafe.Pointer(&i))).word
  456. // }
  457. // func rv2i(rv reflect.Value) interface{} {
  458. // urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  459. // // non-reference type: already indir
  460. // // reference type: depend on flagIndir property ('cos maybe was double-referenced)
  461. // // const (unsafeRvFlagKindMask = 1<<5 - 1 , unsafeRvFlagIndir = 1 << 7 )
  462. // // rvk := reflect.Kind(urv.flag & (1<<5 - 1))
  463. // // if (rvk == reflect.Chan ||
  464. // // rvk == reflect.Func ||
  465. // // rvk == reflect.Interface ||
  466. // // rvk == reflect.Map ||
  467. // // rvk == reflect.Ptr ||
  468. // // rvk == reflect.UnsafePointer) && urv.flag&(1<<8) != 0 {
  469. // // fmt.Printf(">>>>> ---- double indirect reference: %v, %v\n", rvk, rv.Type())
  470. // // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ}))
  471. // // }
  472. // if urv.flag&(1<<5-1) == uintptr(reflect.Map) && urv.flag&(1<<7) != 0 {
  473. // // fmt.Printf(">>>>> ---- double indirect reference: %v, %v\n", rvk, rv.Type())
  474. // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ}))
  475. // }
  476. // // fmt.Printf(">>>>> ++++ direct reference: %v, %v\n", rvk, rv.Type())
  477. // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
  478. // }
  479. // const (
  480. // unsafeRvFlagKindMask = 1<<5 - 1
  481. // unsafeRvKindDirectIface = 1 << 5
  482. // unsafeRvFlagIndir = 1 << 7
  483. // unsafeRvFlagAddr = 1 << 8
  484. // unsafeRvFlagMethod = 1 << 9
  485. // _USE_RV_INTERFACE bool = false
  486. // _UNSAFE_RV_DEBUG = true
  487. // )
  488. // type unsafeRtype struct {
  489. // _ [2]uintptr
  490. // _ uint32
  491. // _ uint8
  492. // _ uint8
  493. // _ uint8
  494. // kind uint8
  495. // _ [2]uintptr
  496. // _ int32
  497. // }
  498. // func _rv2i(rv reflect.Value) interface{} {
  499. // // Note: From use,
  500. // // - it's never an interface
  501. // // - the only calls here are for ifaceIndir types.
  502. // // (though that conditional is wrong)
  503. // // To know for sure, we need the value of t.kind (which is not exposed).
  504. // //
  505. // // Need to validate the path: type is indirect ==> only value is indirect ==> default (value is direct)
  506. // // - Type indirect, Value indirect: ==> numbers, boolean, slice, struct, array, string
  507. // // - Type Direct, Value indirect: ==> map???
  508. // // - Type Direct, Value direct: ==> pointers, unsafe.Pointer, func, chan, map
  509. // //
  510. // // TRANSLATES TO:
  511. // // if typeIndirect { } else if valueIndirect { } else { }
  512. // //
  513. // // Since we don't deal with funcs, then "flagNethod" is unset, and can be ignored.
  514. // if _USE_RV_INTERFACE {
  515. // return rv.Interface()
  516. // }
  517. // urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  518. // // if urv.flag&unsafeRvFlagMethod != 0 || urv.flag&unsafeRvFlagKindMask == uintptr(reflect.Interface) {
  519. // // println("***** IS flag method or interface: delegating to rv.Interface()")
  520. // // return rv.Interface()
  521. // // }
  522. // // if urv.flag&unsafeRvFlagKindMask == uintptr(reflect.Interface) {
  523. // // println("***** IS Interface: delegate to rv.Interface")
  524. // // return rv.Interface()
  525. // // }
  526. // // if urv.flag&unsafeRvFlagKindMask&unsafeRvKindDirectIface == 0 {
  527. // // if urv.flag&unsafeRvFlagAddr == 0 {
  528. // // println("***** IS ifaceIndir typ")
  529. // // // ui := unsafeIntf{word: urv.ptr, typ: urv.typ}
  530. // // // return *(*interface{})(unsafe.Pointer(&ui))
  531. // // // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
  532. // // }
  533. // // } else if urv.flag&unsafeRvFlagIndir != 0 {
  534. // // println("***** IS flagindir")
  535. // // // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ}))
  536. // // } else {
  537. // // println("***** NOT flagindir")
  538. // // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
  539. // // }
  540. // // println("***** default: delegate to rv.Interface")
  541. // urt := (*unsafeRtype)(unsafe.Pointer(urv.typ))
  542. // if _UNSAFE_RV_DEBUG {
  543. // fmt.Printf(">>>> start: %v: ", rv.Type())
  544. // fmt.Printf("%v - %v\n", *urv, *urt)
  545. // }
  546. // if urt.kind&unsafeRvKindDirectIface == 0 {
  547. // if _UNSAFE_RV_DEBUG {
  548. // fmt.Printf("**** +ifaceIndir type: %v\n", rv.Type())
  549. // }
  550. // // println("***** IS ifaceIndir typ")
  551. // // if true || urv.flag&unsafeRvFlagAddr == 0 {
  552. // // // println(" ***** IS NOT addr")
  553. // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
  554. // // }
  555. // } else if urv.flag&unsafeRvFlagIndir != 0 {
  556. // if _UNSAFE_RV_DEBUG {
  557. // fmt.Printf("**** +flagIndir type: %v\n", rv.Type())
  558. // }
  559. // // println("***** IS flagindir")
  560. // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ}))
  561. // } else {
  562. // if _UNSAFE_RV_DEBUG {
  563. // fmt.Printf("**** -flagIndir type: %v\n", rv.Type())
  564. // }
  565. // // println("***** NOT flagindir")
  566. // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
  567. // }
  568. // // println("***** default: delegating to rv.Interface()")
  569. // // return rv.Interface()
  570. // }
  571. // var staticM0 = make(map[string]uint64)
  572. // var staticI0 = (int32)(-5)
  573. // func staticRv2iTest() {
  574. // i0 := (int32)(-5)
  575. // m0 := make(map[string]uint16)
  576. // m0["1"] = 1
  577. // for _, i := range []interface{}{
  578. // (int)(7),
  579. // (uint)(8),
  580. // (int16)(-9),
  581. // (uint16)(19),
  582. // (uintptr)(77),
  583. // (bool)(true),
  584. // float32(-32.7),
  585. // float64(64.9),
  586. // complex(float32(19), 5),
  587. // complex(float64(-32), 7),
  588. // [4]uint64{1, 2, 3, 4},
  589. // (chan<- int)(nil), // chan,
  590. // rv2i, // func
  591. // io.Writer(ioutil.Discard),
  592. // make(map[string]uint),
  593. // (map[string]uint)(nil),
  594. // staticM0,
  595. // m0,
  596. // &m0,
  597. // i0,
  598. // &i0,
  599. // &staticI0,
  600. // &staticM0,
  601. // []uint32{6, 7, 8},
  602. // "abc",
  603. // Raw{},
  604. // RawExt{},
  605. // &Raw{},
  606. // &RawExt{},
  607. // unsafe.Pointer(&i0),
  608. // } {
  609. // i2 := rv2i(reflect.ValueOf(i))
  610. // eq := reflect.DeepEqual(i, i2)
  611. // fmt.Printf(">>>> %v == %v? %v\n", i, i2, eq)
  612. // }
  613. // // os.Exit(0)
  614. // }
  615. // func init() {
  616. // staticRv2iTest()
  617. // }
  618. // func rv2i(rv reflect.Value) interface{} {
  619. // if _USE_RV_INTERFACE || rv.Kind() == reflect.Interface || rv.CanAddr() {
  620. // return rv.Interface()
  621. // }
  622. // // var i interface{}
  623. // // ui := (*unsafeIntf)(unsafe.Pointer(&i))
  624. // var ui unsafeIntf
  625. // urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  626. // // fmt.Printf("urv: flag: %b, typ: %b, ptr: %b\n", urv.flag, uintptr(urv.typ), uintptr(urv.ptr))
  627. // if (urv.flag&unsafeRvFlagKindMask)&unsafeRvKindDirectIface == 0 {
  628. // if urv.flag&unsafeRvFlagAddr != 0 {
  629. // println("***** indirect and addressable! Needs typed move - delegate to rv.Interface()")
  630. // return rv.Interface()
  631. // }
  632. // println("****** indirect type/kind")
  633. // ui.word = urv.ptr
  634. // } else if urv.flag&unsafeRvFlagIndir != 0 {
  635. // println("****** unsafe rv flag indir")
  636. // ui.word = *(*unsafe.Pointer)(urv.ptr)
  637. // } else {
  638. // println("****** default: assign prt to word directly")
  639. // ui.word = urv.ptr
  640. // }
  641. // // ui.word = urv.ptr
  642. // ui.typ = urv.typ
  643. // // fmt.Printf("(pointers) ui.typ: %p, word: %p\n", ui.typ, ui.word)
  644. // // fmt.Printf("(binary) ui.typ: %b, word: %b\n", uintptr(ui.typ), uintptr(ui.word))
  645. // return *(*interface{})(unsafe.Pointer(&ui))
  646. // // return i
  647. // }