typedarrays.go 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886
  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 xNan && yNan {
  309. return false
  310. }
  311. if xNan {
  312. return false
  313. }
  314. if yNan {
  315. return true
  316. }
  317. if x >= y {
  318. return false
  319. }
  320. return true
  321. }
  322. func (a *float32Array) less(i, j int) bool {
  323. return typedFloatLess(float64((*a)[i]), float64((*a)[j]))
  324. }
  325. func (a *float32Array) swap(i, j int) {
  326. (*a)[i], (*a)[j] = (*a)[j], (*a)[i]
  327. }
  328. func (a *float32Array) typeMatch(v Value) bool {
  329. switch v.(type) {
  330. case valueInt, valueFloat:
  331. return true
  332. }
  333. return false
  334. }
  335. func (a *float64Array) get(idx int) Value {
  336. return floatToValue((*a)[idx])
  337. }
  338. func (a *float64Array) getRaw(idx int) uint64 {
  339. return math.Float64bits((*a)[idx])
  340. }
  341. func (a *float64Array) set(idx int, value Value) {
  342. (*a)[idx] = value.ToFloat()
  343. }
  344. func (a *float64Array) toRaw(v Value) uint64 {
  345. return math.Float64bits(v.ToFloat())
  346. }
  347. func (a *float64Array) setRaw(idx int, v uint64) {
  348. (*a)[idx] = math.Float64frombits(v)
  349. }
  350. func (a *float64Array) less(i, j int) bool {
  351. return typedFloatLess((*a)[i], (*a)[j])
  352. }
  353. func (a *float64Array) swap(i, j int) {
  354. (*a)[i], (*a)[j] = (*a)[j], (*a)[i]
  355. }
  356. func (a *float64Array) typeMatch(v Value) bool {
  357. switch v.(type) {
  358. case valueInt, valueFloat:
  359. return true
  360. }
  361. return false
  362. }
  363. func (a *typedArrayObject) _getIdx(idx int) Value {
  364. a.viewedArrayBuf.ensureNotDetached()
  365. if 0 <= idx && idx < a.length {
  366. return a.typedArray.get(idx + a.offset)
  367. }
  368. return nil
  369. }
  370. func strToTAIdx(s unistring.String) (int, bool) {
  371. i, err := strconv.ParseInt(string(s), 10, bits.UintSize)
  372. if err != nil {
  373. return 0, false
  374. }
  375. return int(i), true
  376. }
  377. func (a *typedArrayObject) getOwnPropStr(name unistring.String) Value {
  378. if idx, ok := strToTAIdx(name); ok {
  379. v := a._getIdx(idx)
  380. if v != nil {
  381. return &valueProperty{
  382. value: v,
  383. writable: true,
  384. enumerable: true,
  385. }
  386. }
  387. return nil
  388. }
  389. return a.baseObject.getOwnPropStr(name)
  390. }
  391. func (a *typedArrayObject) getOwnPropIdx(idx valueInt) Value {
  392. v := a._getIdx(toIntStrict(int64(idx)))
  393. if v != nil {
  394. return &valueProperty{
  395. value: v,
  396. writable: true,
  397. enumerable: true,
  398. }
  399. }
  400. return nil
  401. }
  402. func (a *typedArrayObject) getStr(name unistring.String, receiver Value) Value {
  403. if idx, ok := strToTAIdx(name); ok {
  404. prop := a._getIdx(idx)
  405. if prop == nil {
  406. if a.prototype != nil {
  407. if receiver == nil {
  408. return a.prototype.self.getStr(name, a.val)
  409. }
  410. return a.prototype.self.getStr(name, receiver)
  411. }
  412. }
  413. return prop
  414. }
  415. return a.baseObject.getStr(name, receiver)
  416. }
  417. func (a *typedArrayObject) getIdx(idx valueInt, receiver Value) Value {
  418. prop := a._getIdx(toIntStrict(int64(idx)))
  419. if prop == nil {
  420. if a.prototype != nil {
  421. if receiver == nil {
  422. return a.prototype.self.getIdx(idx, a.val)
  423. }
  424. return a.prototype.self.getIdx(idx, receiver)
  425. }
  426. }
  427. return prop
  428. }
  429. func (a *typedArrayObject) _putIdx(idx int, v Value, throw bool) bool {
  430. v = v.ToNumber()
  431. a.viewedArrayBuf.ensureNotDetached()
  432. if idx >= 0 && idx < a.length {
  433. a.typedArray.set(idx+a.offset, v)
  434. return true
  435. }
  436. // As far as I understand the specification this should throw, but neither V8 nor SpiderMonkey does
  437. return false
  438. }
  439. func (a *typedArrayObject) _hasIdx(idx int) bool {
  440. a.viewedArrayBuf.ensureNotDetached()
  441. return idx >= 0 && idx < a.length
  442. }
  443. func (a *typedArrayObject) setOwnStr(p unistring.String, v Value, throw bool) bool {
  444. if idx, ok := strToTAIdx(p); ok {
  445. return a._putIdx(idx, v, throw)
  446. }
  447. return a.baseObject.setOwnStr(p, v, throw)
  448. }
  449. func (a *typedArrayObject) setOwnIdx(p valueInt, v Value, throw bool) bool {
  450. return a._putIdx(toIntStrict(int64(p)), v, throw)
  451. }
  452. func (a *typedArrayObject) setForeignStr(p unistring.String, v, receiver Value, throw bool) (res bool, handled bool) {
  453. return a._setForeignStr(p, a.getOwnPropStr(p), v, receiver, throw)
  454. }
  455. func (a *typedArrayObject) setForeignIdx(p valueInt, v, receiver Value, throw bool) (res bool, handled bool) {
  456. return a._setForeignIdx(p, trueValIfPresent(a.hasOwnPropertyIdx(p)), v, receiver, throw)
  457. }
  458. func (a *typedArrayObject) hasOwnPropertyStr(name unistring.String) bool {
  459. if idx, ok := strToTAIdx(name); ok {
  460. a.viewedArrayBuf.ensureNotDetached()
  461. return idx < a.length
  462. }
  463. return a.baseObject.hasOwnPropertyStr(name)
  464. }
  465. func (a *typedArrayObject) hasOwnPropertyIdx(idx valueInt) bool {
  466. return a._hasIdx(toIntStrict(int64(idx)))
  467. }
  468. func (a *typedArrayObject) _defineIdxProperty(idx int, desc PropertyDescriptor, throw bool) bool {
  469. prop, ok := a._defineOwnProperty(unistring.String(strconv.Itoa(idx)), a.getOwnPropIdx(valueInt(idx)), desc, throw)
  470. if ok {
  471. return a._putIdx(idx, prop, throw)
  472. }
  473. return ok
  474. }
  475. func (a *typedArrayObject) defineOwnPropertyStr(name unistring.String, desc PropertyDescriptor, throw bool) bool {
  476. if idx, ok := strToTAIdx(name); ok {
  477. return a._defineIdxProperty(idx, desc, throw)
  478. }
  479. return a.baseObject.defineOwnPropertyStr(name, desc, throw)
  480. }
  481. func (a *typedArrayObject) defineOwnPropertyIdx(name valueInt, desc PropertyDescriptor, throw bool) bool {
  482. return a._defineIdxProperty(toIntStrict(int64(name)), desc, throw)
  483. }
  484. func (a *typedArrayObject) deleteStr(name unistring.String, throw bool) bool {
  485. if idx, ok := strToTAIdx(name); ok {
  486. if idx < a.length {
  487. a.val.runtime.typeErrorResult(throw, "Cannot delete property '%d' of %s", idx, a.val.String())
  488. }
  489. }
  490. return a.baseObject.deleteStr(name, throw)
  491. }
  492. func (a *typedArrayObject) deleteIdx(idx valueInt, throw bool) bool {
  493. if idx >= 0 && int64(idx) < int64(a.length) {
  494. a.val.runtime.typeErrorResult(throw, "Cannot delete property '%d' of %s", idx, a.val.String())
  495. }
  496. return true
  497. }
  498. func (a *typedArrayObject) ownKeys(all bool, accum []Value) []Value {
  499. if accum == nil {
  500. accum = make([]Value, 0, a.length)
  501. }
  502. for i := 0; i < a.length; i++ {
  503. accum = append(accum, asciiString(strconv.Itoa(i)))
  504. }
  505. return a.baseObject.ownKeys(all, accum)
  506. }
  507. type typedArrayPropIter struct {
  508. a *typedArrayObject
  509. idx int
  510. }
  511. func (i *typedArrayPropIter) next() (propIterItem, iterNextFunc) {
  512. if i.idx < i.a.length {
  513. name := strconv.Itoa(i.idx)
  514. prop := i.a._getIdx(i.idx)
  515. i.idx++
  516. return propIterItem{name: unistring.String(name), value: prop}, i.next
  517. }
  518. return i.a.baseObject.enumerateUnfiltered()()
  519. }
  520. func (a *typedArrayObject) enumerateUnfiltered() iterNextFunc {
  521. return (&typedArrayPropIter{
  522. a: a,
  523. }).next
  524. }
  525. func (r *Runtime) _newTypedArrayObject(buf *arrayBufferObject, offset, length, elemSize int, defCtor *Object, arr typedArray, proto *Object) *typedArrayObject {
  526. o := &Object{runtime: r}
  527. a := &typedArrayObject{
  528. baseObject: baseObject{
  529. val: o,
  530. class: classObject,
  531. prototype: proto,
  532. extensible: true,
  533. },
  534. viewedArrayBuf: buf,
  535. offset: offset,
  536. length: length,
  537. elemSize: elemSize,
  538. defaultCtor: defCtor,
  539. typedArray: arr,
  540. }
  541. o.self = a
  542. a.init()
  543. return a
  544. }
  545. func (r *Runtime) newUint8ArrayObject(buf *arrayBufferObject, offset, length int, proto *Object) *typedArrayObject {
  546. return r._newTypedArrayObject(buf, offset, length, 1, r.global.Uint8Array, (*uint8Array)(&buf.data), proto)
  547. }
  548. func (r *Runtime) newUint8ClampedArrayObject(buf *arrayBufferObject, offset, length int, proto *Object) *typedArrayObject {
  549. return r._newTypedArrayObject(buf, offset, length, 1, r.global.Uint8ClampedArray, (*uint8ClampedArray)(&buf.data), proto)
  550. }
  551. func (r *Runtime) newInt8ArrayObject(buf *arrayBufferObject, offset, length int, proto *Object) *typedArrayObject {
  552. return r._newTypedArrayObject(buf, offset, length, 1, r.global.Int8Array, (*int8Array)(unsafe.Pointer(&buf.data)), proto)
  553. }
  554. func (r *Runtime) newUint16ArrayObject(buf *arrayBufferObject, offset, length int, proto *Object) *typedArrayObject {
  555. return r._newTypedArrayObject(buf, offset, length, 2, r.global.Uint16Array, (*uint16Array)(unsafe.Pointer(&buf.data)), proto)
  556. }
  557. func (r *Runtime) newInt16ArrayObject(buf *arrayBufferObject, offset, length int, proto *Object) *typedArrayObject {
  558. return r._newTypedArrayObject(buf, offset, length, 2, r.global.Int16Array, (*int16Array)(unsafe.Pointer(&buf.data)), proto)
  559. }
  560. func (r *Runtime) newUint32ArrayObject(buf *arrayBufferObject, offset, length int, proto *Object) *typedArrayObject {
  561. return r._newTypedArrayObject(buf, offset, length, 4, r.global.Uint32Array, (*uint32Array)(unsafe.Pointer(&buf.data)), proto)
  562. }
  563. func (r *Runtime) newInt32ArrayObject(buf *arrayBufferObject, offset, length int, proto *Object) *typedArrayObject {
  564. return r._newTypedArrayObject(buf, offset, length, 4, r.global.Int32Array, (*int32Array)(unsafe.Pointer(&buf.data)), proto)
  565. }
  566. func (r *Runtime) newFloat32ArrayObject(buf *arrayBufferObject, offset, length int, proto *Object) *typedArrayObject {
  567. return r._newTypedArrayObject(buf, offset, length, 4, r.global.Float32Array, (*float32Array)(unsafe.Pointer(&buf.data)), proto)
  568. }
  569. func (r *Runtime) newFloat64ArrayObject(buf *arrayBufferObject, offset, length int, proto *Object) *typedArrayObject {
  570. return r._newTypedArrayObject(buf, offset, length, 8, r.global.Float64Array, (*float64Array)(unsafe.Pointer(&buf.data)), proto)
  571. }
  572. func (o *dataViewObject) getIdxAndByteOrder(idxVal, littleEndianVal Value, size int) (int, byteOrder) {
  573. getIdx := o.val.runtime.toIndex(idxVal)
  574. o.viewedArrayBuf.ensureNotDetached()
  575. if getIdx+size > o.byteLen {
  576. panic(o.val.runtime.newError(o.val.runtime.global.RangeError, "Index %d is out of bounds", getIdx))
  577. }
  578. getIdx += o.byteOffset
  579. var bo byteOrder
  580. if littleEndianVal != nil {
  581. if littleEndianVal.ToBoolean() {
  582. bo = littleEndian
  583. } else {
  584. bo = bigEndian
  585. }
  586. } else {
  587. bo = nativeEndian
  588. }
  589. return getIdx, bo
  590. }
  591. func (o *arrayBufferObject) ensureNotDetached() {
  592. if o.detached {
  593. panic(o.val.runtime.NewTypeError("ArrayBuffer is detached"))
  594. }
  595. }
  596. func (o *arrayBufferObject) getFloat32(idx int, byteOrder byteOrder) float32 {
  597. return math.Float32frombits(o.getUint32(idx, byteOrder))
  598. }
  599. func (o *arrayBufferObject) setFloat32(idx int, val float32, byteOrder byteOrder) {
  600. o.setUint32(idx, math.Float32bits(val), byteOrder)
  601. }
  602. func (o *arrayBufferObject) getFloat64(idx int, byteOrder byteOrder) float64 {
  603. return math.Float64frombits(o.getUint64(idx, byteOrder))
  604. }
  605. func (o *arrayBufferObject) setFloat64(idx int, val float64, byteOrder byteOrder) {
  606. o.setUint64(idx, math.Float64bits(val), byteOrder)
  607. }
  608. func (o *arrayBufferObject) getUint64(idx int, byteOrder byteOrder) uint64 {
  609. var b []byte
  610. if byteOrder == nativeEndian {
  611. b = o.data[idx : idx+8]
  612. } else {
  613. b = make([]byte, 8)
  614. d := o.data[idx : idx+8]
  615. 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]
  616. }
  617. return *((*uint64)(unsafe.Pointer(&b[0])))
  618. }
  619. func (o *arrayBufferObject) setUint64(idx int, val uint64, byteOrder byteOrder) {
  620. if byteOrder == nativeEndian {
  621. *(*uint64)(unsafe.Pointer(&o.data[idx])) = val
  622. } else {
  623. b := (*[8]byte)(unsafe.Pointer(&val))
  624. d := o.data[idx : idx+8]
  625. 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]
  626. }
  627. }
  628. func (o *arrayBufferObject) getUint32(idx int, byteOrder byteOrder) uint32 {
  629. var b []byte
  630. if byteOrder == nativeEndian {
  631. b = o.data[idx : idx+4]
  632. } else {
  633. b = make([]byte, 4)
  634. d := o.data[idx : idx+4]
  635. b[0], b[1], b[2], b[3] = d[3], d[2], d[1], d[0]
  636. }
  637. return *((*uint32)(unsafe.Pointer(&b[0])))
  638. }
  639. func (o *arrayBufferObject) setUint32(idx int, val uint32, byteOrder byteOrder) {
  640. if byteOrder == nativeEndian {
  641. *(*uint32)(unsafe.Pointer(&o.data[idx])) = val
  642. } else {
  643. b := (*[4]byte)(unsafe.Pointer(&val))
  644. d := o.data[idx : idx+4]
  645. d[0], d[1], d[2], d[3] = b[3], b[2], b[1], b[0]
  646. }
  647. }
  648. func (o *arrayBufferObject) getUint16(idx int, byteOrder byteOrder) uint16 {
  649. var b []byte
  650. if byteOrder == nativeEndian {
  651. b = o.data[idx : idx+2]
  652. } else {
  653. b = make([]byte, 2)
  654. d := o.data[idx : idx+2]
  655. b[0], b[1] = d[1], d[0]
  656. }
  657. return *((*uint16)(unsafe.Pointer(&b[0])))
  658. }
  659. func (o *arrayBufferObject) setUint16(idx int, val uint16, byteOrder byteOrder) {
  660. if byteOrder == nativeEndian {
  661. *(*uint16)(unsafe.Pointer(&o.data[idx])) = val
  662. } else {
  663. b := (*[2]byte)(unsafe.Pointer(&val))
  664. d := o.data[idx : idx+2]
  665. d[0], d[1] = b[1], b[0]
  666. }
  667. }
  668. func (o *arrayBufferObject) getUint8(idx int) uint8 {
  669. return o.data[idx]
  670. }
  671. func (o *arrayBufferObject) setUint8(idx int, val uint8) {
  672. o.data[idx] = val
  673. }
  674. func (o *arrayBufferObject) getInt32(idx int, byteOrder byteOrder) int32 {
  675. return int32(o.getUint32(idx, byteOrder))
  676. }
  677. func (o *arrayBufferObject) setInt32(idx int, val int32, byteOrder byteOrder) {
  678. o.setUint32(idx, uint32(val), byteOrder)
  679. }
  680. func (o *arrayBufferObject) getInt16(idx int, byteOrder byteOrder) int16 {
  681. return int16(o.getUint16(idx, byteOrder))
  682. }
  683. func (o *arrayBufferObject) setInt16(idx int, val int16, byteOrder byteOrder) {
  684. o.setUint16(idx, uint16(val), byteOrder)
  685. }
  686. func (o *arrayBufferObject) getInt8(idx int) int8 {
  687. return int8(o.data[idx])
  688. }
  689. func (o *arrayBufferObject) setInt8(idx int, val int8) {
  690. o.setUint8(idx, uint8(val))
  691. }
  692. func (o *arrayBufferObject) detach() {
  693. o.data = nil
  694. o.detached = true
  695. }
  696. func (o *arrayBufferObject) exportType() reflect.Type {
  697. return arrayBufferType
  698. }
  699. func (o *arrayBufferObject) export(*objectExportCtx) interface{} {
  700. return ArrayBuffer{
  701. buf: o,
  702. }
  703. }
  704. func (r *Runtime) _newArrayBuffer(proto *Object, o *Object) *arrayBufferObject {
  705. if o == nil {
  706. o = &Object{runtime: r}
  707. }
  708. b := &arrayBufferObject{
  709. baseObject: baseObject{
  710. class: classObject,
  711. val: o,
  712. prototype: proto,
  713. extensible: true,
  714. },
  715. }
  716. o.self = b
  717. b.init()
  718. return b
  719. }
  720. func init() {
  721. buf := [2]byte{}
  722. *(*uint16)(unsafe.Pointer(&buf[0])) = uint16(0xCAFE)
  723. switch buf {
  724. case [2]byte{0xFE, 0xCA}:
  725. nativeEndian = littleEndian
  726. case [2]byte{0xCA, 0xFE}:
  727. nativeEndian = bigEndian
  728. default:
  729. panic("Could not determine native endianness.")
  730. }
  731. }