typedarrays.go 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882
  1. package goja
  2. import (
  3. "math"
  4. "math/bits"
  5. "reflect"
  6. "strconv"
  7. "unsafe"
  8. "github.com/dop251/goja/unistring"
  9. )
  10. type byteOrder bool
  11. const (
  12. bigEndian byteOrder = false
  13. littleEndian byteOrder = true
  14. )
  15. var (
  16. nativeEndian byteOrder
  17. arrayBufferType = reflect.TypeOf(ArrayBuffer{})
  18. )
  19. type typedArrayObjectCtor func(buf *arrayBufferObject, offset, length int, proto *Object) *typedArrayObject
  20. type arrayBufferObject struct {
  21. baseObject
  22. detached bool
  23. data []byte
  24. }
  25. // ArrayBuffer is a Go wrapper around ECMAScript ArrayBuffer. Calling Runtime.ToValue() on it
  26. // returns the underlying ArrayBuffer. Calling Export() on an ECMAScript ArrayBuffer returns a wrapper.
  27. // Use Runtime.NewArrayBuffer([]byte) to create one.
  28. type ArrayBuffer struct {
  29. buf *arrayBufferObject
  30. }
  31. type dataViewObject struct {
  32. baseObject
  33. viewedArrayBuf *arrayBufferObject
  34. byteLen, byteOffset int
  35. }
  36. type typedArray interface {
  37. toRaw(Value) uint64
  38. get(idx int) Value
  39. set(idx int, value Value)
  40. getRaw(idx int) uint64
  41. setRaw(idx int, raw uint64)
  42. less(i, j int) bool
  43. swap(i, j int)
  44. typeMatch(v Value) bool
  45. }
  46. type uint8Array []uint8
  47. type uint8ClampedArray []uint8
  48. type int8Array []int8
  49. type uint16Array []uint16
  50. type int16Array []int16
  51. type uint32Array []uint32
  52. type int32Array []int32
  53. type float32Array []float32
  54. type float64Array []float64
  55. type typedArrayObject struct {
  56. baseObject
  57. viewedArrayBuf *arrayBufferObject
  58. defaultCtor *Object
  59. length, offset int
  60. elemSize int
  61. typedArray typedArray
  62. }
  63. func (a ArrayBuffer) toValue(r *Runtime) Value {
  64. if a.buf == nil {
  65. return _null
  66. }
  67. v := a.buf.val
  68. if v.runtime != r {
  69. panic(r.NewTypeError("Illegal runtime transition of an ArrayBuffer"))
  70. }
  71. return v
  72. }
  73. // Bytes returns the underlying []byte for this ArrayBuffer.
  74. // For detached ArrayBuffers returns nil.
  75. func (a ArrayBuffer) Bytes() []byte {
  76. return a.buf.data
  77. }
  78. // Detach the ArrayBuffer. After this, the underlying []byte becomes unreferenced and any attempt
  79. // to use this ArrayBuffer results in a TypeError.
  80. // Returns false if it was already detached, true otherwise.
  81. // Note, this method may only be called from the goroutine that 'owns' the Runtime, it may not
  82. // be called concurrently.
  83. func (a ArrayBuffer) Detach() bool {
  84. if a.buf.detached {
  85. return false
  86. }
  87. a.buf.detach()
  88. return true
  89. }
  90. // Detached returns true if the ArrayBuffer is detached.
  91. func (a ArrayBuffer) Detached() bool {
  92. return a.buf.detached
  93. }
  94. func (r *Runtime) NewArrayBuffer(data []byte) ArrayBuffer {
  95. buf := r._newArrayBuffer(r.global.ArrayBufferPrototype, nil)
  96. buf.data = data
  97. return ArrayBuffer{
  98. buf: buf,
  99. }
  100. }
  101. func (a *uint8Array) get(idx int) Value {
  102. return intToValue(int64((*a)[idx]))
  103. }
  104. func (a *uint8Array) getRaw(idx int) uint64 {
  105. return uint64((*a)[idx])
  106. }
  107. func (a *uint8Array) set(idx int, value Value) {
  108. (*a)[idx] = toUint8(value)
  109. }
  110. func (a *uint8Array) toRaw(v Value) uint64 {
  111. return uint64(toUint8(v))
  112. }
  113. func (a *uint8Array) setRaw(idx int, v uint64) {
  114. (*a)[idx] = uint8(v)
  115. }
  116. func (a *uint8Array) less(i, j int) bool {
  117. return (*a)[i] < (*a)[j]
  118. }
  119. func (a *uint8Array) swap(i, j int) {
  120. (*a)[i], (*a)[j] = (*a)[j], (*a)[i]
  121. }
  122. func (a *uint8Array) typeMatch(v Value) bool {
  123. if i, ok := v.(valueInt); ok {
  124. return i >= 0 && i <= 255
  125. }
  126. return false
  127. }
  128. func (a *uint8ClampedArray) get(idx int) Value {
  129. return intToValue(int64((*a)[idx]))
  130. }
  131. func (a *uint8ClampedArray) getRaw(idx int) uint64 {
  132. return uint64((*a)[idx])
  133. }
  134. func (a *uint8ClampedArray) set(idx int, value Value) {
  135. (*a)[idx] = toUint8Clamp(value)
  136. }
  137. func (a *uint8ClampedArray) toRaw(v Value) uint64 {
  138. return uint64(toUint8Clamp(v))
  139. }
  140. func (a *uint8ClampedArray) setRaw(idx int, v uint64) {
  141. (*a)[idx] = uint8(v)
  142. }
  143. func (a *uint8ClampedArray) less(i, j int) bool {
  144. return (*a)[i] < (*a)[j]
  145. }
  146. func (a *uint8ClampedArray) swap(i, j int) {
  147. (*a)[i], (*a)[j] = (*a)[j], (*a)[i]
  148. }
  149. func (a *uint8ClampedArray) typeMatch(v Value) bool {
  150. if i, ok := v.(valueInt); ok {
  151. return i >= 0 && i <= 255
  152. }
  153. return false
  154. }
  155. func (a *int8Array) get(idx int) Value {
  156. return intToValue(int64((*a)[idx]))
  157. }
  158. func (a *int8Array) getRaw(idx int) uint64 {
  159. return uint64((*a)[idx])
  160. }
  161. func (a *int8Array) set(idx int, value Value) {
  162. (*a)[idx] = toInt8(value)
  163. }
  164. func (a *int8Array) toRaw(v Value) uint64 {
  165. return uint64(toInt8(v))
  166. }
  167. func (a *int8Array) setRaw(idx int, v uint64) {
  168. (*a)[idx] = int8(v)
  169. }
  170. func (a *int8Array) less(i, j int) bool {
  171. return (*a)[i] < (*a)[j]
  172. }
  173. func (a *int8Array) swap(i, j int) {
  174. (*a)[i], (*a)[j] = (*a)[j], (*a)[i]
  175. }
  176. func (a *int8Array) typeMatch(v Value) bool {
  177. if i, ok := v.(valueInt); ok {
  178. return i >= math.MinInt8 && i <= math.MaxInt8
  179. }
  180. return false
  181. }
  182. func (a *uint16Array) get(idx int) Value {
  183. return intToValue(int64((*a)[idx]))
  184. }
  185. func (a *uint16Array) getRaw(idx int) uint64 {
  186. return uint64((*a)[idx])
  187. }
  188. func (a *uint16Array) set(idx int, value Value) {
  189. (*a)[idx] = toUint16(value)
  190. }
  191. func (a *uint16Array) toRaw(v Value) uint64 {
  192. return uint64(toUint16(v))
  193. }
  194. func (a *uint16Array) setRaw(idx int, v uint64) {
  195. (*a)[idx] = uint16(v)
  196. }
  197. func (a *uint16Array) less(i, j int) bool {
  198. return (*a)[i] < (*a)[j]
  199. }
  200. func (a *uint16Array) swap(i, j int) {
  201. (*a)[i], (*a)[j] = (*a)[j], (*a)[i]
  202. }
  203. func (a *uint16Array) typeMatch(v Value) bool {
  204. if i, ok := v.(valueInt); ok {
  205. return i >= 0 && i <= math.MaxUint16
  206. }
  207. return false
  208. }
  209. func (a *int16Array) get(idx int) Value {
  210. return intToValue(int64((*a)[idx]))
  211. }
  212. func (a *int16Array) getRaw(idx int) uint64 {
  213. return uint64((*a)[idx])
  214. }
  215. func (a *int16Array) set(idx int, value Value) {
  216. (*a)[idx] = toInt16(value)
  217. }
  218. func (a *int16Array) toRaw(v Value) uint64 {
  219. return uint64(toInt16(v))
  220. }
  221. func (a *int16Array) setRaw(idx int, v uint64) {
  222. (*a)[idx] = int16(v)
  223. }
  224. func (a *int16Array) less(i, j int) bool {
  225. return (*a)[i] < (*a)[j]
  226. }
  227. func (a *int16Array) swap(i, j int) {
  228. (*a)[i], (*a)[j] = (*a)[j], (*a)[i]
  229. }
  230. func (a *int16Array) typeMatch(v Value) bool {
  231. if i, ok := v.(valueInt); ok {
  232. return i >= math.MinInt16 && i <= math.MaxInt16
  233. }
  234. return false
  235. }
  236. func (a *uint32Array) get(idx int) Value {
  237. return intToValue(int64((*a)[idx]))
  238. }
  239. func (a *uint32Array) getRaw(idx int) uint64 {
  240. return uint64((*a)[idx])
  241. }
  242. func (a *uint32Array) set(idx int, value Value) {
  243. (*a)[idx] = toUint32(value)
  244. }
  245. func (a *uint32Array) toRaw(v Value) uint64 {
  246. return uint64(toUint32(v))
  247. }
  248. func (a *uint32Array) setRaw(idx int, v uint64) {
  249. (*a)[idx] = uint32(v)
  250. }
  251. func (a *uint32Array) less(i, j int) bool {
  252. return (*a)[i] < (*a)[j]
  253. }
  254. func (a *uint32Array) swap(i, j int) {
  255. (*a)[i], (*a)[j] = (*a)[j], (*a)[i]
  256. }
  257. func (a *uint32Array) typeMatch(v Value) bool {
  258. if i, ok := v.(valueInt); ok {
  259. return i >= 0 && i <= math.MaxUint32
  260. }
  261. return false
  262. }
  263. func (a *int32Array) get(idx int) Value {
  264. return intToValue(int64((*a)[idx]))
  265. }
  266. func (a *int32Array) getRaw(idx int) uint64 {
  267. return uint64((*a)[idx])
  268. }
  269. func (a *int32Array) set(idx int, value Value) {
  270. (*a)[idx] = toInt32(value)
  271. }
  272. func (a *int32Array) toRaw(v Value) uint64 {
  273. return uint64(toInt32(v))
  274. }
  275. func (a *int32Array) setRaw(idx int, v uint64) {
  276. (*a)[idx] = int32(v)
  277. }
  278. func (a *int32Array) less(i, j int) bool {
  279. return (*a)[i] < (*a)[j]
  280. }
  281. func (a *int32Array) swap(i, j int) {
  282. (*a)[i], (*a)[j] = (*a)[j], (*a)[i]
  283. }
  284. func (a *int32Array) typeMatch(v Value) bool {
  285. if i, ok := v.(valueInt); ok {
  286. return i >= math.MinInt32 && i <= math.MaxInt32
  287. }
  288. return false
  289. }
  290. func (a *float32Array) get(idx int) Value {
  291. return floatToValue(float64((*a)[idx]))
  292. }
  293. func (a *float32Array) getRaw(idx int) uint64 {
  294. return uint64(math.Float32bits((*a)[idx]))
  295. }
  296. func (a *float32Array) set(idx int, value Value) {
  297. (*a)[idx] = toFloat32(value)
  298. }
  299. func (a *float32Array) toRaw(v Value) uint64 {
  300. return uint64(math.Float32bits(toFloat32(v)))
  301. }
  302. func (a *float32Array) setRaw(idx int, v uint64) {
  303. (*a)[idx] = math.Float32frombits(uint32(v))
  304. }
  305. func typedFloatLess(x, y float64) bool {
  306. xNan := math.IsNaN(x)
  307. yNan := math.IsNaN(y)
  308. if yNan {
  309. return !xNan
  310. } else if xNan {
  311. return false
  312. }
  313. if x == 0 && y == 0 { // handle neg zero
  314. return math.Signbit(x)
  315. }
  316. return x < y
  317. }
  318. func (a *float32Array) less(i, j int) bool {
  319. return typedFloatLess(float64((*a)[i]), float64((*a)[j]))
  320. }
  321. func (a *float32Array) swap(i, j int) {
  322. (*a)[i], (*a)[j] = (*a)[j], (*a)[i]
  323. }
  324. func (a *float32Array) typeMatch(v Value) bool {
  325. switch v.(type) {
  326. case valueInt, valueFloat:
  327. return true
  328. }
  329. return false
  330. }
  331. func (a *float64Array) get(idx int) Value {
  332. return floatToValue((*a)[idx])
  333. }
  334. func (a *float64Array) getRaw(idx int) uint64 {
  335. return math.Float64bits((*a)[idx])
  336. }
  337. func (a *float64Array) set(idx int, value Value) {
  338. (*a)[idx] = value.ToFloat()
  339. }
  340. func (a *float64Array) toRaw(v Value) uint64 {
  341. return math.Float64bits(v.ToFloat())
  342. }
  343. func (a *float64Array) setRaw(idx int, v uint64) {
  344. (*a)[idx] = math.Float64frombits(v)
  345. }
  346. func (a *float64Array) less(i, j int) bool {
  347. return typedFloatLess((*a)[i], (*a)[j])
  348. }
  349. func (a *float64Array) swap(i, j int) {
  350. (*a)[i], (*a)[j] = (*a)[j], (*a)[i]
  351. }
  352. func (a *float64Array) typeMatch(v Value) bool {
  353. switch v.(type) {
  354. case valueInt, valueFloat:
  355. return true
  356. }
  357. return false
  358. }
  359. func (a *typedArrayObject) _getIdx(idx int) Value {
  360. a.viewedArrayBuf.ensureNotDetached()
  361. if 0 <= idx && idx < a.length {
  362. return a.typedArray.get(idx + a.offset)
  363. }
  364. return nil
  365. }
  366. func strToTAIdx(s unistring.String) (int, bool) {
  367. i, err := strconv.ParseInt(string(s), 10, bits.UintSize)
  368. if err != nil {
  369. return 0, false
  370. }
  371. return int(i), true
  372. }
  373. func (a *typedArrayObject) getOwnPropStr(name unistring.String) Value {
  374. if idx, ok := strToTAIdx(name); ok {
  375. v := a._getIdx(idx)
  376. if v != nil {
  377. return &valueProperty{
  378. value: v,
  379. writable: true,
  380. enumerable: true,
  381. }
  382. }
  383. return nil
  384. }
  385. return a.baseObject.getOwnPropStr(name)
  386. }
  387. func (a *typedArrayObject) getOwnPropIdx(idx valueInt) Value {
  388. v := a._getIdx(toIntStrict(int64(idx)))
  389. if v != nil {
  390. return &valueProperty{
  391. value: v,
  392. writable: true,
  393. enumerable: true,
  394. }
  395. }
  396. return nil
  397. }
  398. func (a *typedArrayObject) getStr(name unistring.String, receiver Value) Value {
  399. if idx, ok := strToTAIdx(name); ok {
  400. prop := a._getIdx(idx)
  401. if prop == nil {
  402. if a.prototype != nil {
  403. if receiver == nil {
  404. return a.prototype.self.getStr(name, a.val)
  405. }
  406. return a.prototype.self.getStr(name, receiver)
  407. }
  408. }
  409. return prop
  410. }
  411. return a.baseObject.getStr(name, receiver)
  412. }
  413. func (a *typedArrayObject) getIdx(idx valueInt, receiver Value) Value {
  414. prop := a._getIdx(toIntStrict(int64(idx)))
  415. if prop == nil {
  416. if a.prototype != nil {
  417. if receiver == nil {
  418. return a.prototype.self.getIdx(idx, a.val)
  419. }
  420. return a.prototype.self.getIdx(idx, receiver)
  421. }
  422. }
  423. return prop
  424. }
  425. func (a *typedArrayObject) _putIdx(idx int, v Value, throw bool) bool {
  426. v = v.ToNumber()
  427. a.viewedArrayBuf.ensureNotDetached()
  428. if idx >= 0 && idx < a.length {
  429. a.typedArray.set(idx+a.offset, v)
  430. return true
  431. }
  432. // As far as I understand the specification this should throw, but neither V8 nor SpiderMonkey does
  433. return false
  434. }
  435. func (a *typedArrayObject) _hasIdx(idx int) bool {
  436. a.viewedArrayBuf.ensureNotDetached()
  437. return idx >= 0 && idx < a.length
  438. }
  439. func (a *typedArrayObject) setOwnStr(p unistring.String, v Value, throw bool) bool {
  440. if idx, ok := strToTAIdx(p); ok {
  441. return a._putIdx(idx, v, throw)
  442. }
  443. return a.baseObject.setOwnStr(p, v, throw)
  444. }
  445. func (a *typedArrayObject) setOwnIdx(p valueInt, v Value, throw bool) bool {
  446. return a._putIdx(toIntStrict(int64(p)), v, throw)
  447. }
  448. func (a *typedArrayObject) setForeignStr(p unistring.String, v, receiver Value, throw bool) (res bool, handled bool) {
  449. return a._setForeignStr(p, a.getOwnPropStr(p), v, receiver, throw)
  450. }
  451. func (a *typedArrayObject) setForeignIdx(p valueInt, v, receiver Value, throw bool) (res bool, handled bool) {
  452. return a._setForeignIdx(p, trueValIfPresent(a.hasOwnPropertyIdx(p)), v, receiver, throw)
  453. }
  454. func (a *typedArrayObject) hasOwnPropertyStr(name unistring.String) bool {
  455. if idx, ok := strToTAIdx(name); ok {
  456. a.viewedArrayBuf.ensureNotDetached()
  457. return idx < a.length
  458. }
  459. return a.baseObject.hasOwnPropertyStr(name)
  460. }
  461. func (a *typedArrayObject) hasOwnPropertyIdx(idx valueInt) bool {
  462. return a._hasIdx(toIntStrict(int64(idx)))
  463. }
  464. func (a *typedArrayObject) _defineIdxProperty(idx int, desc PropertyDescriptor, throw bool) bool {
  465. prop, ok := a._defineOwnProperty(unistring.String(strconv.Itoa(idx)), a.getOwnPropIdx(valueInt(idx)), desc, throw)
  466. if ok {
  467. return a._putIdx(idx, prop, throw)
  468. }
  469. return ok
  470. }
  471. func (a *typedArrayObject) defineOwnPropertyStr(name unistring.String, desc PropertyDescriptor, throw bool) bool {
  472. if idx, ok := strToTAIdx(name); ok {
  473. return a._defineIdxProperty(idx, desc, throw)
  474. }
  475. return a.baseObject.defineOwnPropertyStr(name, desc, throw)
  476. }
  477. func (a *typedArrayObject) defineOwnPropertyIdx(name valueInt, desc PropertyDescriptor, throw bool) bool {
  478. return a._defineIdxProperty(toIntStrict(int64(name)), desc, throw)
  479. }
  480. func (a *typedArrayObject) deleteStr(name unistring.String, throw bool) bool {
  481. if idx, ok := strToTAIdx(name); ok {
  482. if idx < a.length {
  483. a.val.runtime.typeErrorResult(throw, "Cannot delete property '%d' of %s", idx, a.val.String())
  484. }
  485. }
  486. return a.baseObject.deleteStr(name, throw)
  487. }
  488. func (a *typedArrayObject) deleteIdx(idx valueInt, throw bool) bool {
  489. if idx >= 0 && int64(idx) < int64(a.length) {
  490. a.val.runtime.typeErrorResult(throw, "Cannot delete property '%d' of %s", idx, a.val.String())
  491. }
  492. return true
  493. }
  494. func (a *typedArrayObject) ownKeys(all bool, accum []Value) []Value {
  495. if accum == nil {
  496. accum = make([]Value, 0, a.length)
  497. }
  498. for i := 0; i < a.length; i++ {
  499. accum = append(accum, asciiString(strconv.Itoa(i)))
  500. }
  501. return a.baseObject.ownKeys(all, accum)
  502. }
  503. type typedArrayPropIter struct {
  504. a *typedArrayObject
  505. idx int
  506. }
  507. func (i *typedArrayPropIter) next() (propIterItem, iterNextFunc) {
  508. if i.idx < i.a.length {
  509. name := strconv.Itoa(i.idx)
  510. prop := i.a._getIdx(i.idx)
  511. i.idx++
  512. return propIterItem{name: unistring.String(name), value: prop}, i.next
  513. }
  514. return i.a.baseObject.enumerateOwnKeys()()
  515. }
  516. func (a *typedArrayObject) enumerateOwnKeys() iterNextFunc {
  517. return (&typedArrayPropIter{
  518. a: a,
  519. }).next
  520. }
  521. func (r *Runtime) _newTypedArrayObject(buf *arrayBufferObject, offset, length, elemSize int, defCtor *Object, arr typedArray, proto *Object) *typedArrayObject {
  522. o := &Object{runtime: r}
  523. a := &typedArrayObject{
  524. baseObject: baseObject{
  525. val: o,
  526. class: classObject,
  527. prototype: proto,
  528. extensible: true,
  529. },
  530. viewedArrayBuf: buf,
  531. offset: offset,
  532. length: length,
  533. elemSize: elemSize,
  534. defaultCtor: defCtor,
  535. typedArray: arr,
  536. }
  537. o.self = a
  538. a.init()
  539. return a
  540. }
  541. func (r *Runtime) newUint8ArrayObject(buf *arrayBufferObject, offset, length int, proto *Object) *typedArrayObject {
  542. return r._newTypedArrayObject(buf, offset, length, 1, r.global.Uint8Array, (*uint8Array)(&buf.data), proto)
  543. }
  544. func (r *Runtime) newUint8ClampedArrayObject(buf *arrayBufferObject, offset, length int, proto *Object) *typedArrayObject {
  545. return r._newTypedArrayObject(buf, offset, length, 1, r.global.Uint8ClampedArray, (*uint8ClampedArray)(&buf.data), proto)
  546. }
  547. func (r *Runtime) newInt8ArrayObject(buf *arrayBufferObject, offset, length int, proto *Object) *typedArrayObject {
  548. return r._newTypedArrayObject(buf, offset, length, 1, r.global.Int8Array, (*int8Array)(unsafe.Pointer(&buf.data)), proto)
  549. }
  550. func (r *Runtime) newUint16ArrayObject(buf *arrayBufferObject, offset, length int, proto *Object) *typedArrayObject {
  551. return r._newTypedArrayObject(buf, offset, length, 2, r.global.Uint16Array, (*uint16Array)(unsafe.Pointer(&buf.data)), proto)
  552. }
  553. func (r *Runtime) newInt16ArrayObject(buf *arrayBufferObject, offset, length int, proto *Object) *typedArrayObject {
  554. return r._newTypedArrayObject(buf, offset, length, 2, r.global.Int16Array, (*int16Array)(unsafe.Pointer(&buf.data)), proto)
  555. }
  556. func (r *Runtime) newUint32ArrayObject(buf *arrayBufferObject, offset, length int, proto *Object) *typedArrayObject {
  557. return r._newTypedArrayObject(buf, offset, length, 4, r.global.Uint32Array, (*uint32Array)(unsafe.Pointer(&buf.data)), proto)
  558. }
  559. func (r *Runtime) newInt32ArrayObject(buf *arrayBufferObject, offset, length int, proto *Object) *typedArrayObject {
  560. return r._newTypedArrayObject(buf, offset, length, 4, r.global.Int32Array, (*int32Array)(unsafe.Pointer(&buf.data)), proto)
  561. }
  562. func (r *Runtime) newFloat32ArrayObject(buf *arrayBufferObject, offset, length int, proto *Object) *typedArrayObject {
  563. return r._newTypedArrayObject(buf, offset, length, 4, r.global.Float32Array, (*float32Array)(unsafe.Pointer(&buf.data)), proto)
  564. }
  565. func (r *Runtime) newFloat64ArrayObject(buf *arrayBufferObject, offset, length int, proto *Object) *typedArrayObject {
  566. return r._newTypedArrayObject(buf, offset, length, 8, r.global.Float64Array, (*float64Array)(unsafe.Pointer(&buf.data)), proto)
  567. }
  568. func (o *dataViewObject) getIdxAndByteOrder(idxVal, littleEndianVal Value, size int) (int, byteOrder) {
  569. getIdx := o.val.runtime.toIndex(idxVal)
  570. o.viewedArrayBuf.ensureNotDetached()
  571. if getIdx+size > o.byteLen {
  572. panic(o.val.runtime.newError(o.val.runtime.global.RangeError, "Index %d is out of bounds", getIdx))
  573. }
  574. getIdx += o.byteOffset
  575. var bo byteOrder
  576. if littleEndianVal != nil {
  577. if littleEndianVal.ToBoolean() {
  578. bo = littleEndian
  579. } else {
  580. bo = bigEndian
  581. }
  582. } else {
  583. bo = nativeEndian
  584. }
  585. return getIdx, bo
  586. }
  587. func (o *arrayBufferObject) ensureNotDetached() {
  588. if o.detached {
  589. panic(o.val.runtime.NewTypeError("ArrayBuffer is detached"))
  590. }
  591. }
  592. func (o *arrayBufferObject) getFloat32(idx int, byteOrder byteOrder) float32 {
  593. return math.Float32frombits(o.getUint32(idx, byteOrder))
  594. }
  595. func (o *arrayBufferObject) setFloat32(idx int, val float32, byteOrder byteOrder) {
  596. o.setUint32(idx, math.Float32bits(val), byteOrder)
  597. }
  598. func (o *arrayBufferObject) getFloat64(idx int, byteOrder byteOrder) float64 {
  599. return math.Float64frombits(o.getUint64(idx, byteOrder))
  600. }
  601. func (o *arrayBufferObject) setFloat64(idx int, val float64, byteOrder byteOrder) {
  602. o.setUint64(idx, math.Float64bits(val), byteOrder)
  603. }
  604. func (o *arrayBufferObject) getUint64(idx int, byteOrder byteOrder) uint64 {
  605. var b []byte
  606. if byteOrder == nativeEndian {
  607. b = o.data[idx : idx+8]
  608. } else {
  609. b = make([]byte, 8)
  610. d := o.data[idx : idx+8]
  611. b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7] = d[7], d[6], d[5], d[4], d[3], d[2], d[1], d[0]
  612. }
  613. return *((*uint64)(unsafe.Pointer(&b[0])))
  614. }
  615. func (o *arrayBufferObject) setUint64(idx int, val uint64, byteOrder byteOrder) {
  616. if byteOrder == nativeEndian {
  617. *(*uint64)(unsafe.Pointer(&o.data[idx])) = val
  618. } else {
  619. b := (*[8]byte)(unsafe.Pointer(&val))
  620. d := o.data[idx : idx+8]
  621. d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7] = b[7], b[6], b[5], b[4], b[3], b[2], b[1], b[0]
  622. }
  623. }
  624. func (o *arrayBufferObject) getUint32(idx int, byteOrder byteOrder) uint32 {
  625. var b []byte
  626. if byteOrder == nativeEndian {
  627. b = o.data[idx : idx+4]
  628. } else {
  629. b = make([]byte, 4)
  630. d := o.data[idx : idx+4]
  631. b[0], b[1], b[2], b[3] = d[3], d[2], d[1], d[0]
  632. }
  633. return *((*uint32)(unsafe.Pointer(&b[0])))
  634. }
  635. func (o *arrayBufferObject) setUint32(idx int, val uint32, byteOrder byteOrder) {
  636. if byteOrder == nativeEndian {
  637. *(*uint32)(unsafe.Pointer(&o.data[idx])) = val
  638. } else {
  639. b := (*[4]byte)(unsafe.Pointer(&val))
  640. d := o.data[idx : idx+4]
  641. d[0], d[1], d[2], d[3] = b[3], b[2], b[1], b[0]
  642. }
  643. }
  644. func (o *arrayBufferObject) getUint16(idx int, byteOrder byteOrder) uint16 {
  645. var b []byte
  646. if byteOrder == nativeEndian {
  647. b = o.data[idx : idx+2]
  648. } else {
  649. b = make([]byte, 2)
  650. d := o.data[idx : idx+2]
  651. b[0], b[1] = d[1], d[0]
  652. }
  653. return *((*uint16)(unsafe.Pointer(&b[0])))
  654. }
  655. func (o *arrayBufferObject) setUint16(idx int, val uint16, byteOrder byteOrder) {
  656. if byteOrder == nativeEndian {
  657. *(*uint16)(unsafe.Pointer(&o.data[idx])) = val
  658. } else {
  659. b := (*[2]byte)(unsafe.Pointer(&val))
  660. d := o.data[idx : idx+2]
  661. d[0], d[1] = b[1], b[0]
  662. }
  663. }
  664. func (o *arrayBufferObject) getUint8(idx int) uint8 {
  665. return o.data[idx]
  666. }
  667. func (o *arrayBufferObject) setUint8(idx int, val uint8) {
  668. o.data[idx] = val
  669. }
  670. func (o *arrayBufferObject) getInt32(idx int, byteOrder byteOrder) int32 {
  671. return int32(o.getUint32(idx, byteOrder))
  672. }
  673. func (o *arrayBufferObject) setInt32(idx int, val int32, byteOrder byteOrder) {
  674. o.setUint32(idx, uint32(val), byteOrder)
  675. }
  676. func (o *arrayBufferObject) getInt16(idx int, byteOrder byteOrder) int16 {
  677. return int16(o.getUint16(idx, byteOrder))
  678. }
  679. func (o *arrayBufferObject) setInt16(idx int, val int16, byteOrder byteOrder) {
  680. o.setUint16(idx, uint16(val), byteOrder)
  681. }
  682. func (o *arrayBufferObject) getInt8(idx int) int8 {
  683. return int8(o.data[idx])
  684. }
  685. func (o *arrayBufferObject) setInt8(idx int, val int8) {
  686. o.setUint8(idx, uint8(val))
  687. }
  688. func (o *arrayBufferObject) detach() {
  689. o.data = nil
  690. o.detached = true
  691. }
  692. func (o *arrayBufferObject) exportType() reflect.Type {
  693. return arrayBufferType
  694. }
  695. func (o *arrayBufferObject) export(*objectExportCtx) interface{} {
  696. return ArrayBuffer{
  697. buf: o,
  698. }
  699. }
  700. func (r *Runtime) _newArrayBuffer(proto *Object, o *Object) *arrayBufferObject {
  701. if o == nil {
  702. o = &Object{runtime: r}
  703. }
  704. b := &arrayBufferObject{
  705. baseObject: baseObject{
  706. class: classObject,
  707. val: o,
  708. prototype: proto,
  709. extensible: true,
  710. },
  711. }
  712. o.self = b
  713. b.init()
  714. return b
  715. }
  716. func init() {
  717. buf := [2]byte{}
  718. *(*uint16)(unsafe.Pointer(&buf[0])) = uint16(0xCAFE)
  719. switch buf {
  720. case [2]byte{0xFE, 0xCA}:
  721. nativeEndian = littleEndian
  722. case [2]byte{0xCA, 0xFE}:
  723. nativeEndian = bigEndian
  724. default:
  725. panic("Could not determine native endianness.")
  726. }
  727. }