helper_unsafe.go 13 KB

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