wasm113.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. // +build go1.13
  2. package wasm
  3. import (
  4. "reflect"
  5. "runtime"
  6. "syscall/js"
  7. "unsafe"
  8. )
  9. func sliceToByteSlice(s interface{}) []byte {
  10. switch s := s.(type) {
  11. case []int8:
  12. h := (*reflect.SliceHeader)(unsafe.Pointer(&s))
  13. return *(*[]byte)(unsafe.Pointer(h))
  14. case []int16:
  15. h := (*reflect.SliceHeader)(unsafe.Pointer(&s))
  16. h.Len *= 2
  17. h.Cap *= 2
  18. return *(*[]byte)(unsafe.Pointer(h))
  19. case []int32:
  20. h := (*reflect.SliceHeader)(unsafe.Pointer(&s))
  21. h.Len *= 4
  22. h.Cap *= 4
  23. return *(*[]byte)(unsafe.Pointer(h))
  24. case []int64:
  25. h := (*reflect.SliceHeader)(unsafe.Pointer(&s))
  26. h.Len *= 8
  27. h.Cap *= 8
  28. return *(*[]byte)(unsafe.Pointer(h))
  29. case []uint8:
  30. return s
  31. case []uint16:
  32. h := (*reflect.SliceHeader)(unsafe.Pointer(&s))
  33. h.Len *= 2
  34. h.Cap *= 2
  35. return *(*[]byte)(unsafe.Pointer(h))
  36. case []uint32:
  37. h := (*reflect.SliceHeader)(unsafe.Pointer(&s))
  38. h.Len *= 4
  39. h.Cap *= 4
  40. return *(*[]byte)(unsafe.Pointer(h))
  41. case []uint64:
  42. h := (*reflect.SliceHeader)(unsafe.Pointer(&s))
  43. h.Len *= 8
  44. h.Cap *= 8
  45. return *(*[]byte)(unsafe.Pointer(h))
  46. case []float32:
  47. h := (*reflect.SliceHeader)(unsafe.Pointer(&s))
  48. h.Len *= 4
  49. h.Cap *= 4
  50. return *(*[]byte)(unsafe.Pointer(h))
  51. case []float64:
  52. h := (*reflect.SliceHeader)(unsafe.Pointer(&s))
  53. h.Len *= 8
  54. h.Cap *= 8
  55. return *(*[]byte)(unsafe.Pointer(h))
  56. default:
  57. panic("jsutil: unexpected value at sliceToBytesSlice()")
  58. }
  59. }
  60. func SliceToTypedArray(s interface{}) (val js.Value, free func()) {
  61. free = func(){}
  62. switch s := s.(type) {
  63. case []int8:
  64. a := js.Global().Get("Uint8Array").New(len(s))
  65. js.CopyBytesToJS(a, sliceToByteSlice(s))
  66. runtime.KeepAlive(s)
  67. buf := a.Get("buffer")
  68. return js.Global().Get("Int8Array").New(buf, a.Get("byteOffset"), a.Get("byteLength")), free
  69. case []int16:
  70. a := js.Global().Get("Uint8Array").New(len(s) * 2)
  71. js.CopyBytesToJS(a, sliceToByteSlice(s))
  72. runtime.KeepAlive(s)
  73. buf := a.Get("buffer")
  74. return js.Global().Get("Int16Array").New(buf, a.Get("byteOffset"), a.Get("byteLength").Int()/2), free
  75. case []int32:
  76. a := js.Global().Get("Uint8Array").New(len(s) * 4)
  77. js.CopyBytesToJS(a, sliceToByteSlice(s))
  78. runtime.KeepAlive(s)
  79. buf := a.Get("buffer")
  80. return js.Global().Get("Int32Array").New(buf, a.Get("byteOffset"), a.Get("byteLength").Int()/4), free
  81. case []uint8:
  82. a := js.Global().Get("Uint8Array").New(len(s))
  83. js.CopyBytesToJS(a, s)
  84. runtime.KeepAlive(s)
  85. return a, free
  86. case []uint16:
  87. a := js.Global().Get("Uint8Array").New(len(s) * 2)
  88. js.CopyBytesToJS(a, sliceToByteSlice(s))
  89. runtime.KeepAlive(s)
  90. buf := a.Get("buffer")
  91. return js.Global().Get("Uint16Array").New(buf, a.Get("byteOffset"), a.Get("byteLength").Int()/2), free
  92. case []uint32:
  93. a := js.Global().Get("Uint8Array").New(len(s) * 4)
  94. js.CopyBytesToJS(a, sliceToByteSlice(s))
  95. runtime.KeepAlive(s)
  96. buf := a.Get("buffer")
  97. return js.Global().Get("Uint32Array").New(buf, a.Get("byteOffset"), a.Get("byteLength").Int()/4), free
  98. case []float32:
  99. a := js.Global().Get("Uint8Array").New(len(s) * 4)
  100. js.CopyBytesToJS(a, sliceToByteSlice(s))
  101. runtime.KeepAlive(s)
  102. buf := a.Get("buffer")
  103. return js.Global().Get("Float32Array").New(buf, a.Get("byteOffset"), a.Get("byteLength").Int()/4), free
  104. case []float64:
  105. a := js.Global().Get("Uint8Array").New(len(s) * 8)
  106. js.CopyBytesToJS(a, sliceToByteSlice(s))
  107. runtime.KeepAlive(s)
  108. buf := a.Get("buffer")
  109. return js.Global().Get("Float64Array").New(buf, a.Get("byteOffset"), a.Get("byteLength").Int()/8), free
  110. default:
  111. panic("jsutil: unexpected value at SliceToTypedArray()")
  112. }
  113. }
  114. func Equal(a, b js.Value) bool {
  115. return a.Equal(b)
  116. }