helper_unsafe.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508
  1. // +build !safe
  2. // +build !appengine
  3. // +build go1.7
  4. // Copyright (c) 2012-2015 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. "unsafe"
  11. )
  12. // This file has unsafe variants of some helper methods.
  13. // NOTE: See helper_not_unsafe.go for the usage information.
  14. // var zeroRTv [4]uintptr
  15. const safeMode = false
  16. const unsafeFlagIndir = 1 << 7 // keep in sync with GO_ROOT/src/reflect/value.go
  17. type unsafeString struct {
  18. Data uintptr
  19. Len int
  20. }
  21. type unsafeSlice struct {
  22. Data uintptr
  23. Len int
  24. Cap int
  25. }
  26. type unsafeIntf struct {
  27. typ unsafe.Pointer
  28. word unsafe.Pointer
  29. }
  30. type unsafeReflectValue struct {
  31. typ unsafe.Pointer
  32. ptr unsafe.Pointer
  33. flag uintptr
  34. }
  35. func stringView(v []byte) string {
  36. if len(v) == 0 {
  37. return ""
  38. }
  39. bx := (*unsafeSlice)(unsafe.Pointer(&v))
  40. sx := unsafeString{bx.Data, bx.Len}
  41. return *(*string)(unsafe.Pointer(&sx))
  42. }
  43. func bytesView(v string) []byte {
  44. if len(v) == 0 {
  45. return zeroByteSlice
  46. }
  47. sx := (*unsafeString)(unsafe.Pointer(&v))
  48. bx := unsafeSlice{sx.Data, sx.Len, sx.Len}
  49. return *(*[]byte)(unsafe.Pointer(&bx))
  50. }
  51. func definitelyNil(v interface{}) bool {
  52. // There is no global way of checking if an interface is nil.
  53. // For true references (map, ptr, func, chan), you can just look
  54. // at the word of the interface. However, for slices, you have to dereference
  55. // the word, and get a pointer to the 3-word interface value.
  56. // var ui *unsafeIntf = (*unsafeIntf)(unsafe.Pointer(&v))
  57. // var word unsafe.Pointer = ui.word
  58. // // fmt.Printf(">>>> definitely nil: isnil: %v, TYPE: \t%T, word: %v, *word: %v, type: %v, nil: %v\n", v == nil, v, word, *((*unsafe.Pointer)(word)), ui.typ, nil)
  59. // return word == nil // || *((*unsafe.Pointer)(word)) == nil
  60. return ((*unsafeIntf)(unsafe.Pointer(&v))).word == nil
  61. }
  62. // func keepAlive4BytesView(v string) {
  63. // runtime.KeepAlive(v)
  64. // }
  65. // func keepAlive4StringView(v []byte) {
  66. // runtime.KeepAlive(v)
  67. // }
  68. // TODO: consider a more generally-known optimization for reflect.Value ==> Interface
  69. //
  70. // Currently, we use this fragile method that taps into implememtation details from
  71. // the source go stdlib reflect/value.go,
  72. // and trims the implementation.
  73. func rv2i(rv reflect.Value) interface{} {
  74. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  75. // true references (map, func, chan, ptr - NOT slice) may be double-referenced as flagIndir
  76. var ptr unsafe.Pointer
  77. // kk := reflect.Kind(urv.flag & (1<<5 - 1))
  78. // if (kk == reflect.Map || kk == reflect.Ptr || kk == reflect.Chan || kk == reflect.Func) && urv.flag&unsafeFlagIndir != 0 {
  79. if refBitset.isset(byte(urv.flag&(1<<5-1))) && urv.flag&unsafeFlagIndir != 0 {
  80. ptr = *(*unsafe.Pointer)(urv.ptr)
  81. } else {
  82. ptr = urv.ptr
  83. }
  84. return *(*interface{})(unsafe.Pointer(&unsafeIntf{typ: urv.typ, word: ptr}))
  85. // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ}))
  86. // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
  87. }
  88. func rt2id(rt reflect.Type) uintptr {
  89. return uintptr(((*unsafeIntf)(unsafe.Pointer(&rt))).word)
  90. }
  91. func rv2rtid(rv reflect.Value) uintptr {
  92. return uintptr((*unsafeReflectValue)(unsafe.Pointer(&rv)).typ)
  93. }
  94. // func rv0t(rt reflect.Type) reflect.Value {
  95. // ut := (*unsafeIntf)(unsafe.Pointer(&rt))
  96. // // we need to determine whether ifaceIndir, and then whether to just pass 0 as the ptr
  97. // uv := unsafeReflectValue{ut.word, &zeroRTv, flag(rt.Kind())}
  98. // return *(*reflect.Value)(unsafe.Pointer(&uv})
  99. // }
  100. // --------------------------
  101. type atomicTypeInfoSlice struct {
  102. v unsafe.Pointer
  103. }
  104. func (x *atomicTypeInfoSlice) load() *[]rtid2ti {
  105. return (*[]rtid2ti)(atomic.LoadPointer(&x.v))
  106. }
  107. func (x *atomicTypeInfoSlice) store(p *[]rtid2ti) {
  108. atomic.StorePointer(&x.v, unsafe.Pointer(p))
  109. }
  110. // --------------------------
  111. func (d *Decoder) raw(f *codecFnInfo, rv reflect.Value) {
  112. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  113. // if urv.flag&unsafeFlagIndir != 0 {
  114. // urv.ptr = *(*unsafe.Pointer)(urv.ptr)
  115. // }
  116. *(*[]byte)(urv.ptr) = d.rawBytes()
  117. }
  118. func (d *Decoder) kString(f *codecFnInfo, rv reflect.Value) {
  119. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  120. *(*string)(urv.ptr) = d.d.DecodeString()
  121. }
  122. func (d *Decoder) kBool(f *codecFnInfo, rv reflect.Value) {
  123. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  124. *(*bool)(urv.ptr) = d.d.DecodeBool()
  125. }
  126. func (d *Decoder) kFloat32(f *codecFnInfo, rv reflect.Value) {
  127. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  128. *(*float32)(urv.ptr) = float32(d.d.DecodeFloat(true))
  129. }
  130. func (d *Decoder) kFloat64(f *codecFnInfo, rv reflect.Value) {
  131. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  132. *(*float64)(urv.ptr) = d.d.DecodeFloat(false)
  133. }
  134. func (d *Decoder) kInt(f *codecFnInfo, rv reflect.Value) {
  135. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  136. *(*int)(urv.ptr) = int(d.d.DecodeInt(intBitsize))
  137. }
  138. func (d *Decoder) kInt8(f *codecFnInfo, rv reflect.Value) {
  139. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  140. *(*int8)(urv.ptr) = int8(d.d.DecodeInt(8))
  141. }
  142. func (d *Decoder) kInt16(f *codecFnInfo, rv reflect.Value) {
  143. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  144. *(*int16)(urv.ptr) = int16(d.d.DecodeInt(16))
  145. }
  146. func (d *Decoder) kInt32(f *codecFnInfo, rv reflect.Value) {
  147. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  148. *(*int32)(urv.ptr) = int32(d.d.DecodeInt(32))
  149. }
  150. func (d *Decoder) kInt64(f *codecFnInfo, rv reflect.Value) {
  151. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  152. *(*int64)(urv.ptr) = d.d.DecodeInt(64)
  153. }
  154. func (d *Decoder) kUint(f *codecFnInfo, rv reflect.Value) {
  155. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  156. *(*uint)(urv.ptr) = uint(d.d.DecodeUint(uintBitsize))
  157. }
  158. func (d *Decoder) kUintptr(f *codecFnInfo, rv reflect.Value) {
  159. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  160. *(*uintptr)(urv.ptr) = uintptr(d.d.DecodeUint(uintBitsize))
  161. }
  162. func (d *Decoder) kUint8(f *codecFnInfo, rv reflect.Value) {
  163. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  164. *(*uint8)(urv.ptr) = uint8(d.d.DecodeUint(8))
  165. }
  166. func (d *Decoder) kUint16(f *codecFnInfo, rv reflect.Value) {
  167. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  168. *(*uint16)(urv.ptr) = uint16(d.d.DecodeUint(16))
  169. }
  170. func (d *Decoder) kUint32(f *codecFnInfo, rv reflect.Value) {
  171. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  172. *(*uint32)(urv.ptr) = uint32(d.d.DecodeUint(32))
  173. }
  174. func (d *Decoder) kUint64(f *codecFnInfo, rv reflect.Value) {
  175. urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  176. *(*uint64)(urv.ptr) = d.d.DecodeUint(64)
  177. }
  178. // ------------
  179. func (e *Encoder) kBool(f *codecFnInfo, rv reflect.Value) {
  180. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  181. e.e.EncodeBool(*(*bool)(v.ptr))
  182. }
  183. func (e *Encoder) kString(f *codecFnInfo, rv reflect.Value) {
  184. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  185. e.e.EncodeString(c_UTF8, *(*string)(v.ptr))
  186. }
  187. func (e *Encoder) kFloat64(f *codecFnInfo, rv reflect.Value) {
  188. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  189. e.e.EncodeFloat64(*(*float64)(v.ptr))
  190. }
  191. func (e *Encoder) kFloat32(f *codecFnInfo, rv reflect.Value) {
  192. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  193. e.e.EncodeFloat32(*(*float32)(v.ptr))
  194. }
  195. func (e *Encoder) kInt(f *codecFnInfo, rv reflect.Value) {
  196. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  197. e.e.EncodeInt(int64(*(*int)(v.ptr)))
  198. }
  199. func (e *Encoder) kInt8(f *codecFnInfo, rv reflect.Value) {
  200. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  201. e.e.EncodeInt(int64(*(*int8)(v.ptr)))
  202. }
  203. func (e *Encoder) kInt16(f *codecFnInfo, rv reflect.Value) {
  204. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  205. e.e.EncodeInt(int64(*(*int16)(v.ptr)))
  206. }
  207. func (e *Encoder) kInt32(f *codecFnInfo, rv reflect.Value) {
  208. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  209. e.e.EncodeInt(int64(*(*int32)(v.ptr)))
  210. }
  211. func (e *Encoder) kInt64(f *codecFnInfo, rv reflect.Value) {
  212. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  213. e.e.EncodeInt(int64(*(*int64)(v.ptr)))
  214. }
  215. func (e *Encoder) kUint(f *codecFnInfo, rv reflect.Value) {
  216. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  217. e.e.EncodeUint(uint64(*(*uint)(v.ptr)))
  218. }
  219. func (e *Encoder) kUint8(f *codecFnInfo, rv reflect.Value) {
  220. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  221. e.e.EncodeUint(uint64(*(*uint8)(v.ptr)))
  222. }
  223. func (e *Encoder) kUint16(f *codecFnInfo, rv reflect.Value) {
  224. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  225. e.e.EncodeUint(uint64(*(*uint16)(v.ptr)))
  226. }
  227. func (e *Encoder) kUint32(f *codecFnInfo, rv reflect.Value) {
  228. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  229. e.e.EncodeUint(uint64(*(*uint32)(v.ptr)))
  230. }
  231. func (e *Encoder) kUint64(f *codecFnInfo, rv reflect.Value) {
  232. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  233. e.e.EncodeUint(uint64(*(*uint64)(v.ptr)))
  234. }
  235. func (e *Encoder) kUintptr(f *codecFnInfo, rv reflect.Value) {
  236. v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  237. e.e.EncodeUint(uint64(*(*uintptr)(v.ptr)))
  238. }
  239. // ------------
  240. // func rt2id(rt reflect.Type) uintptr {
  241. // return uintptr(((*unsafeIntf)(unsafe.Pointer(&rt))).word)
  242. // // var i interface{} = rt
  243. // // // ui := (*unsafeIntf)(unsafe.Pointer(&i))
  244. // // return ((*unsafeIntf)(unsafe.Pointer(&i))).word
  245. // }
  246. // func rv2i(rv reflect.Value) interface{} {
  247. // urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  248. // // non-reference type: already indir
  249. // // reference type: depend on flagIndir property ('cos maybe was double-referenced)
  250. // // const (unsafeRvFlagKindMask = 1<<5 - 1 , unsafeRvFlagIndir = 1 << 7 )
  251. // // rvk := reflect.Kind(urv.flag & (1<<5 - 1))
  252. // // if (rvk == reflect.Chan ||
  253. // // rvk == reflect.Func ||
  254. // // rvk == reflect.Interface ||
  255. // // rvk == reflect.Map ||
  256. // // rvk == reflect.Ptr ||
  257. // // rvk == reflect.UnsafePointer) && urv.flag&(1<<8) != 0 {
  258. // // fmt.Printf(">>>>> ---- double indirect reference: %v, %v\n", rvk, rv.Type())
  259. // // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ}))
  260. // // }
  261. // if urv.flag&(1<<5-1) == uintptr(reflect.Map) && urv.flag&(1<<7) != 0 {
  262. // // fmt.Printf(">>>>> ---- double indirect reference: %v, %v\n", rvk, rv.Type())
  263. // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ}))
  264. // }
  265. // // fmt.Printf(">>>>> ++++ direct reference: %v, %v\n", rvk, rv.Type())
  266. // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
  267. // }
  268. // const (
  269. // unsafeRvFlagKindMask = 1<<5 - 1
  270. // unsafeRvKindDirectIface = 1 << 5
  271. // unsafeRvFlagIndir = 1 << 7
  272. // unsafeRvFlagAddr = 1 << 8
  273. // unsafeRvFlagMethod = 1 << 9
  274. // _USE_RV_INTERFACE bool = false
  275. // _UNSAFE_RV_DEBUG = true
  276. // )
  277. // type unsafeRtype struct {
  278. // _ [2]uintptr
  279. // _ uint32
  280. // _ uint8
  281. // _ uint8
  282. // _ uint8
  283. // kind uint8
  284. // _ [2]uintptr
  285. // _ int32
  286. // }
  287. // func _rv2i(rv reflect.Value) interface{} {
  288. // // Note: From use,
  289. // // - it's never an interface
  290. // // - the only calls here are for ifaceIndir types.
  291. // // (though that conditional is wrong)
  292. // // To know for sure, we need the value of t.kind (which is not exposed).
  293. // //
  294. // // Need to validate the path: type is indirect ==> only value is indirect ==> default (value is direct)
  295. // // - Type indirect, Value indirect: ==> numbers, boolean, slice, struct, array, string
  296. // // - Type Direct, Value indirect: ==> map???
  297. // // - Type Direct, Value direct: ==> pointers, unsafe.Pointer, func, chan, map
  298. // //
  299. // // TRANSLATES TO:
  300. // // if typeIndirect { } else if valueIndirect { } else { }
  301. // //
  302. // // Since we don't deal with funcs, then "flagNethod" is unset, and can be ignored.
  303. // if _USE_RV_INTERFACE {
  304. // return rv.Interface()
  305. // }
  306. // urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  307. // // if urv.flag&unsafeRvFlagMethod != 0 || urv.flag&unsafeRvFlagKindMask == uintptr(reflect.Interface) {
  308. // // println("***** IS flag method or interface: delegating to rv.Interface()")
  309. // // return rv.Interface()
  310. // // }
  311. // // if urv.flag&unsafeRvFlagKindMask == uintptr(reflect.Interface) {
  312. // // println("***** IS Interface: delegate to rv.Interface")
  313. // // return rv.Interface()
  314. // // }
  315. // // if urv.flag&unsafeRvFlagKindMask&unsafeRvKindDirectIface == 0 {
  316. // // if urv.flag&unsafeRvFlagAddr == 0 {
  317. // // println("***** IS ifaceIndir typ")
  318. // // // ui := unsafeIntf{word: urv.ptr, typ: urv.typ}
  319. // // // return *(*interface{})(unsafe.Pointer(&ui))
  320. // // // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
  321. // // }
  322. // // } else if urv.flag&unsafeRvFlagIndir != 0 {
  323. // // println("***** IS flagindir")
  324. // // // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ}))
  325. // // } else {
  326. // // println("***** NOT flagindir")
  327. // // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
  328. // // }
  329. // // println("***** default: delegate to rv.Interface")
  330. // urt := (*unsafeRtype)(unsafe.Pointer(urv.typ))
  331. // if _UNSAFE_RV_DEBUG {
  332. // fmt.Printf(">>>> start: %v: ", rv.Type())
  333. // fmt.Printf("%v - %v\n", *urv, *urt)
  334. // }
  335. // if urt.kind&unsafeRvKindDirectIface == 0 {
  336. // if _UNSAFE_RV_DEBUG {
  337. // fmt.Printf("**** +ifaceIndir type: %v\n", rv.Type())
  338. // }
  339. // // println("***** IS ifaceIndir typ")
  340. // // if true || urv.flag&unsafeRvFlagAddr == 0 {
  341. // // // println(" ***** IS NOT addr")
  342. // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
  343. // // }
  344. // } else if urv.flag&unsafeRvFlagIndir != 0 {
  345. // if _UNSAFE_RV_DEBUG {
  346. // fmt.Printf("**** +flagIndir type: %v\n", rv.Type())
  347. // }
  348. // // println("***** IS flagindir")
  349. // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ}))
  350. // } else {
  351. // if _UNSAFE_RV_DEBUG {
  352. // fmt.Printf("**** -flagIndir type: %v\n", rv.Type())
  353. // }
  354. // // println("***** NOT flagindir")
  355. // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
  356. // }
  357. // // println("***** default: delegating to rv.Interface()")
  358. // // return rv.Interface()
  359. // }
  360. // var staticM0 = make(map[string]uint64)
  361. // var staticI0 = (int32)(-5)
  362. // func staticRv2iTest() {
  363. // i0 := (int32)(-5)
  364. // m0 := make(map[string]uint16)
  365. // m0["1"] = 1
  366. // for _, i := range []interface{}{
  367. // (int)(7),
  368. // (uint)(8),
  369. // (int16)(-9),
  370. // (uint16)(19),
  371. // (uintptr)(77),
  372. // (bool)(true),
  373. // float32(-32.7),
  374. // float64(64.9),
  375. // complex(float32(19), 5),
  376. // complex(float64(-32), 7),
  377. // [4]uint64{1, 2, 3, 4},
  378. // (chan<- int)(nil), // chan,
  379. // rv2i, // func
  380. // io.Writer(ioutil.Discard),
  381. // make(map[string]uint),
  382. // (map[string]uint)(nil),
  383. // staticM0,
  384. // m0,
  385. // &m0,
  386. // i0,
  387. // &i0,
  388. // &staticI0,
  389. // &staticM0,
  390. // []uint32{6, 7, 8},
  391. // "abc",
  392. // Raw{},
  393. // RawExt{},
  394. // &Raw{},
  395. // &RawExt{},
  396. // unsafe.Pointer(&i0),
  397. // } {
  398. // i2 := rv2i(reflect.ValueOf(i))
  399. // eq := reflect.DeepEqual(i, i2)
  400. // fmt.Printf(">>>> %v == %v? %v\n", i, i2, eq)
  401. // }
  402. // // os.Exit(0)
  403. // }
  404. // func init() {
  405. // staticRv2iTest()
  406. // }
  407. // func rv2i(rv reflect.Value) interface{} {
  408. // if _USE_RV_INTERFACE || rv.Kind() == reflect.Interface || rv.CanAddr() {
  409. // return rv.Interface()
  410. // }
  411. // // var i interface{}
  412. // // ui := (*unsafeIntf)(unsafe.Pointer(&i))
  413. // var ui unsafeIntf
  414. // urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
  415. // // fmt.Printf("urv: flag: %b, typ: %b, ptr: %b\n", urv.flag, uintptr(urv.typ), uintptr(urv.ptr))
  416. // if (urv.flag&unsafeRvFlagKindMask)&unsafeRvKindDirectIface == 0 {
  417. // if urv.flag&unsafeRvFlagAddr != 0 {
  418. // println("***** indirect and addressable! Needs typed move - delegate to rv.Interface()")
  419. // return rv.Interface()
  420. // }
  421. // println("****** indirect type/kind")
  422. // ui.word = urv.ptr
  423. // } else if urv.flag&unsafeRvFlagIndir != 0 {
  424. // println("****** unsafe rv flag indir")
  425. // ui.word = *(*unsafe.Pointer)(urv.ptr)
  426. // } else {
  427. // println("****** default: assign prt to word directly")
  428. // ui.word = urv.ptr
  429. // }
  430. // // ui.word = urv.ptr
  431. // ui.typ = urv.typ
  432. // // fmt.Printf("(pointers) ui.typ: %p, word: %p\n", ui.typ, ui.word)
  433. // // fmt.Printf("(binary) ui.typ: %b, word: %b\n", uintptr(ui.typ), uintptr(ui.word))
  434. // return *(*interface{})(unsafe.Pointer(&ui))
  435. // // return i
  436. // }