builtin_typedarrays.go 55 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567
  1. package goja
  2. import (
  3. "fmt"
  4. "math"
  5. "sort"
  6. "strconv"
  7. "unsafe"
  8. "github.com/dop251/goja/unistring"
  9. )
  10. type typedArraySortCtx struct {
  11. ta *typedArrayObject
  12. compare func(FunctionCall) Value
  13. needValidate bool
  14. }
  15. func (ctx *typedArraySortCtx) Len() int {
  16. return ctx.ta.length
  17. }
  18. func (ctx *typedArraySortCtx) Less(i, j int) bool {
  19. if ctx.needValidate {
  20. ctx.ta.viewedArrayBuf.ensureNotDetached(true)
  21. ctx.needValidate = false
  22. }
  23. offset := ctx.ta.offset
  24. if ctx.compare != nil {
  25. x := ctx.ta.typedArray.get(offset + i)
  26. y := ctx.ta.typedArray.get(offset + j)
  27. res := ctx.compare(FunctionCall{
  28. This: _undefined,
  29. Arguments: []Value{x, y},
  30. }).ToNumber()
  31. ctx.needValidate = true
  32. if i, ok := res.(valueInt); ok {
  33. return i < 0
  34. }
  35. f := res.ToFloat()
  36. if f < 0 {
  37. return true
  38. }
  39. if f > 0 {
  40. return false
  41. }
  42. if math.Signbit(f) {
  43. return true
  44. }
  45. return false
  46. }
  47. return ctx.ta.typedArray.less(offset+i, offset+j)
  48. }
  49. func (ctx *typedArraySortCtx) Swap(i, j int) {
  50. if ctx.needValidate {
  51. ctx.ta.viewedArrayBuf.ensureNotDetached(true)
  52. ctx.needValidate = false
  53. }
  54. offset := ctx.ta.offset
  55. ctx.ta.typedArray.swap(offset+i, offset+j)
  56. }
  57. func allocByteSlice(size int) (b []byte) {
  58. defer func() {
  59. if x := recover(); x != nil {
  60. panic(rangeError(fmt.Sprintf("Buffer size is too large: %d", size)))
  61. }
  62. }()
  63. if size < 0 {
  64. panic(rangeError(fmt.Sprintf("Invalid buffer size: %d", size)))
  65. }
  66. b = make([]byte, size)
  67. return
  68. }
  69. func (r *Runtime) builtin_newArrayBuffer(args []Value, newTarget *Object) *Object {
  70. if newTarget == nil {
  71. panic(r.needNew("ArrayBuffer"))
  72. }
  73. b := r._newArrayBuffer(r.getPrototypeFromCtor(newTarget, r.global.ArrayBuffer, r.global.ArrayBufferPrototype), nil)
  74. if len(args) > 0 {
  75. b.data = allocByteSlice(r.toIndex(args[0]))
  76. }
  77. return b.val
  78. }
  79. func (r *Runtime) arrayBufferProto_getByteLength(call FunctionCall) Value {
  80. o := r.toObject(call.This)
  81. if b, ok := o.self.(*arrayBufferObject); ok {
  82. if b.ensureNotDetached(false) {
  83. return intToValue(int64(len(b.data)))
  84. }
  85. return intToValue(0)
  86. }
  87. panic(r.NewTypeError("Object is not ArrayBuffer: %s", o))
  88. }
  89. func (r *Runtime) arrayBufferProto_slice(call FunctionCall) Value {
  90. o := r.toObject(call.This)
  91. if b, ok := o.self.(*arrayBufferObject); ok {
  92. l := int64(len(b.data))
  93. start := relToIdx(call.Argument(0).ToInteger(), l)
  94. var stop int64
  95. if arg := call.Argument(1); arg != _undefined {
  96. stop = arg.ToInteger()
  97. } else {
  98. stop = l
  99. }
  100. stop = relToIdx(stop, l)
  101. newLen := max(stop-start, 0)
  102. ret := r.speciesConstructor(o, r.global.ArrayBuffer)([]Value{intToValue(newLen)}, nil)
  103. if ab, ok := ret.self.(*arrayBufferObject); ok {
  104. if newLen > 0 {
  105. b.ensureNotDetached(true)
  106. if ret == o {
  107. panic(r.NewTypeError("Species constructor returned the same ArrayBuffer"))
  108. }
  109. if int64(len(ab.data)) < newLen {
  110. panic(r.NewTypeError("Species constructor returned an ArrayBuffer that is too small: %d", len(ab.data)))
  111. }
  112. ab.ensureNotDetached(true)
  113. copy(ab.data, b.data[start:stop])
  114. }
  115. return ret
  116. }
  117. panic(r.NewTypeError("Species constructor did not return an ArrayBuffer: %s", ret.String()))
  118. }
  119. panic(r.NewTypeError("Object is not ArrayBuffer: %s", o))
  120. }
  121. func (r *Runtime) arrayBuffer_isView(call FunctionCall) Value {
  122. if o, ok := call.Argument(0).(*Object); ok {
  123. if _, ok := o.self.(*dataViewObject); ok {
  124. return valueTrue
  125. }
  126. if _, ok := o.self.(*typedArrayObject); ok {
  127. return valueTrue
  128. }
  129. }
  130. return valueFalse
  131. }
  132. func (r *Runtime) newDataView(args []Value, newTarget *Object) *Object {
  133. if newTarget == nil {
  134. panic(r.needNew("DataView"))
  135. }
  136. proto := r.getPrototypeFromCtor(newTarget, r.global.DataView, r.global.DataViewPrototype)
  137. var bufArg Value
  138. if len(args) > 0 {
  139. bufArg = args[0]
  140. }
  141. var buffer *arrayBufferObject
  142. if o, ok := bufArg.(*Object); ok {
  143. if b, ok := o.self.(*arrayBufferObject); ok {
  144. buffer = b
  145. }
  146. }
  147. if buffer == nil {
  148. panic(r.NewTypeError("First argument to DataView constructor must be an ArrayBuffer"))
  149. }
  150. var byteOffset, byteLen int
  151. if len(args) > 1 {
  152. offsetArg := nilSafe(args[1])
  153. byteOffset = r.toIndex(offsetArg)
  154. buffer.ensureNotDetached(true)
  155. if byteOffset > len(buffer.data) {
  156. panic(r.newError(r.global.RangeError, "Start offset %s is outside the bounds of the buffer", offsetArg.String()))
  157. }
  158. }
  159. if len(args) > 2 && args[2] != nil && args[2] != _undefined {
  160. byteLen = r.toIndex(args[2])
  161. if byteOffset+byteLen > len(buffer.data) {
  162. panic(r.newError(r.global.RangeError, "Invalid DataView length %d", byteLen))
  163. }
  164. } else {
  165. byteLen = len(buffer.data) - byteOffset
  166. }
  167. o := &Object{runtime: r}
  168. b := &dataViewObject{
  169. baseObject: baseObject{
  170. class: classObject,
  171. val: o,
  172. prototype: proto,
  173. extensible: true,
  174. },
  175. viewedArrayBuf: buffer,
  176. byteOffset: byteOffset,
  177. byteLen: byteLen,
  178. }
  179. o.self = b
  180. b.init()
  181. return o
  182. }
  183. func (r *Runtime) dataViewProto_getBuffer(call FunctionCall) Value {
  184. if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
  185. return dv.viewedArrayBuf.val
  186. }
  187. panic(r.NewTypeError("Method get DataView.prototype.buffer called on incompatible receiver %s", call.This.String()))
  188. }
  189. func (r *Runtime) dataViewProto_getByteLen(call FunctionCall) Value {
  190. if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
  191. dv.viewedArrayBuf.ensureNotDetached(true)
  192. return intToValue(int64(dv.byteLen))
  193. }
  194. panic(r.NewTypeError("Method get DataView.prototype.byteLength called on incompatible receiver %s", call.This.String()))
  195. }
  196. func (r *Runtime) dataViewProto_getByteOffset(call FunctionCall) Value {
  197. if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
  198. dv.viewedArrayBuf.ensureNotDetached(true)
  199. return intToValue(int64(dv.byteOffset))
  200. }
  201. panic(r.NewTypeError("Method get DataView.prototype.byteOffset called on incompatible receiver %s", call.This.String()))
  202. }
  203. func (r *Runtime) dataViewProto_getFloat32(call FunctionCall) Value {
  204. if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
  205. return floatToValue(float64(dv.viewedArrayBuf.getFloat32(dv.getIdxAndByteOrder(r.toIndex(call.Argument(0)), call.Argument(1), 4))))
  206. }
  207. panic(r.NewTypeError("Method DataView.prototype.getFloat32 called on incompatible receiver %s", call.This.String()))
  208. }
  209. func (r *Runtime) dataViewProto_getFloat64(call FunctionCall) Value {
  210. if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
  211. return floatToValue(dv.viewedArrayBuf.getFloat64(dv.getIdxAndByteOrder(r.toIndex(call.Argument(0)), call.Argument(1), 8)))
  212. }
  213. panic(r.NewTypeError("Method DataView.prototype.getFloat64 called on incompatible receiver %s", call.This.String()))
  214. }
  215. func (r *Runtime) dataViewProto_getInt8(call FunctionCall) Value {
  216. if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
  217. idx, _ := dv.getIdxAndByteOrder(r.toIndex(call.Argument(0)), call.Argument(1), 1)
  218. return intToValue(int64(dv.viewedArrayBuf.getInt8(idx)))
  219. }
  220. panic(r.NewTypeError("Method DataView.prototype.getInt8 called on incompatible receiver %s", call.This.String()))
  221. }
  222. func (r *Runtime) dataViewProto_getInt16(call FunctionCall) Value {
  223. if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
  224. return intToValue(int64(dv.viewedArrayBuf.getInt16(dv.getIdxAndByteOrder(r.toIndex(call.Argument(0)), call.Argument(1), 2))))
  225. }
  226. panic(r.NewTypeError("Method DataView.prototype.getInt16 called on incompatible receiver %s", call.This.String()))
  227. }
  228. func (r *Runtime) dataViewProto_getInt32(call FunctionCall) Value {
  229. if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
  230. return intToValue(int64(dv.viewedArrayBuf.getInt32(dv.getIdxAndByteOrder(r.toIndex(call.Argument(0)), call.Argument(1), 4))))
  231. }
  232. panic(r.NewTypeError("Method DataView.prototype.getInt32 called on incompatible receiver %s", call.This.String()))
  233. }
  234. func (r *Runtime) dataViewProto_getUint8(call FunctionCall) Value {
  235. if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
  236. idx, _ := dv.getIdxAndByteOrder(r.toIndex(call.Argument(0)), call.Argument(1), 1)
  237. return intToValue(int64(dv.viewedArrayBuf.getUint8(idx)))
  238. }
  239. panic(r.NewTypeError("Method DataView.prototype.getUint8 called on incompatible receiver %s", call.This.String()))
  240. }
  241. func (r *Runtime) dataViewProto_getUint16(call FunctionCall) Value {
  242. if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
  243. return intToValue(int64(dv.viewedArrayBuf.getUint16(dv.getIdxAndByteOrder(r.toIndex(call.Argument(0)), call.Argument(1), 2))))
  244. }
  245. panic(r.NewTypeError("Method DataView.prototype.getUint16 called on incompatible receiver %s", call.This.String()))
  246. }
  247. func (r *Runtime) dataViewProto_getUint32(call FunctionCall) Value {
  248. if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
  249. return intToValue(int64(dv.viewedArrayBuf.getUint32(dv.getIdxAndByteOrder(r.toIndex(call.Argument(0)), call.Argument(1), 4))))
  250. }
  251. panic(r.NewTypeError("Method DataView.prototype.getUint32 called on incompatible receiver %s", call.This.String()))
  252. }
  253. func (r *Runtime) dataViewProto_setFloat32(call FunctionCall) Value {
  254. if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
  255. idxVal := r.toIndex(call.Argument(0))
  256. val := toFloat32(call.Argument(1))
  257. idx, bo := dv.getIdxAndByteOrder(idxVal, call.Argument(2), 4)
  258. dv.viewedArrayBuf.setFloat32(idx, val, bo)
  259. return _undefined
  260. }
  261. panic(r.NewTypeError("Method DataView.prototype.setFloat32 called on incompatible receiver %s", call.This.String()))
  262. }
  263. func (r *Runtime) dataViewProto_setFloat64(call FunctionCall) Value {
  264. if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
  265. idxVal := r.toIndex(call.Argument(0))
  266. val := call.Argument(1).ToFloat()
  267. idx, bo := dv.getIdxAndByteOrder(idxVal, call.Argument(2), 8)
  268. dv.viewedArrayBuf.setFloat64(idx, val, bo)
  269. return _undefined
  270. }
  271. panic(r.NewTypeError("Method DataView.prototype.setFloat64 called on incompatible receiver %s", call.This.String()))
  272. }
  273. func (r *Runtime) dataViewProto_setInt8(call FunctionCall) Value {
  274. if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
  275. idxVal := r.toIndex(call.Argument(0))
  276. val := toInt8(call.Argument(1))
  277. idx, _ := dv.getIdxAndByteOrder(idxVal, call.Argument(2), 1)
  278. dv.viewedArrayBuf.setInt8(idx, val)
  279. return _undefined
  280. }
  281. panic(r.NewTypeError("Method DataView.prototype.setInt8 called on incompatible receiver %s", call.This.String()))
  282. }
  283. func (r *Runtime) dataViewProto_setInt16(call FunctionCall) Value {
  284. if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
  285. idxVal := r.toIndex(call.Argument(0))
  286. val := toInt16(call.Argument(1))
  287. idx, bo := dv.getIdxAndByteOrder(idxVal, call.Argument(2), 2)
  288. dv.viewedArrayBuf.setInt16(idx, val, bo)
  289. return _undefined
  290. }
  291. panic(r.NewTypeError("Method DataView.prototype.setInt16 called on incompatible receiver %s", call.This.String()))
  292. }
  293. func (r *Runtime) dataViewProto_setInt32(call FunctionCall) Value {
  294. if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
  295. idxVal := r.toIndex(call.Argument(0))
  296. val := toInt32(call.Argument(1))
  297. idx, bo := dv.getIdxAndByteOrder(idxVal, call.Argument(2), 4)
  298. dv.viewedArrayBuf.setInt32(idx, val, bo)
  299. return _undefined
  300. }
  301. panic(r.NewTypeError("Method DataView.prototype.setInt32 called on incompatible receiver %s", call.This.String()))
  302. }
  303. func (r *Runtime) dataViewProto_setUint8(call FunctionCall) Value {
  304. if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
  305. idxVal := r.toIndex(call.Argument(0))
  306. val := toUint8(call.Argument(1))
  307. idx, _ := dv.getIdxAndByteOrder(idxVal, call.Argument(2), 1)
  308. dv.viewedArrayBuf.setUint8(idx, val)
  309. return _undefined
  310. }
  311. panic(r.NewTypeError("Method DataView.prototype.setUint8 called on incompatible receiver %s", call.This.String()))
  312. }
  313. func (r *Runtime) dataViewProto_setUint16(call FunctionCall) Value {
  314. if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
  315. idxVal := r.toIndex(call.Argument(0))
  316. val := toUint16(call.Argument(1))
  317. idx, bo := dv.getIdxAndByteOrder(idxVal, call.Argument(2), 2)
  318. dv.viewedArrayBuf.setUint16(idx, val, bo)
  319. return _undefined
  320. }
  321. panic(r.NewTypeError("Method DataView.prototype.setUint16 called on incompatible receiver %s", call.This.String()))
  322. }
  323. func (r *Runtime) dataViewProto_setUint32(call FunctionCall) Value {
  324. if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
  325. idxVal := r.toIndex(call.Argument(0))
  326. val := toUint32(call.Argument(1))
  327. idx, bo := dv.getIdxAndByteOrder(idxVal, call.Argument(2), 4)
  328. dv.viewedArrayBuf.setUint32(idx, val, bo)
  329. return _undefined
  330. }
  331. panic(r.NewTypeError("Method DataView.prototype.setUint32 called on incompatible receiver %s", call.This.String()))
  332. }
  333. func (r *Runtime) typedArrayProto_getBuffer(call FunctionCall) Value {
  334. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  335. return ta.viewedArrayBuf.val
  336. }
  337. panic(r.NewTypeError("Method get TypedArray.prototype.buffer called on incompatible receiver %s", call.This.String()))
  338. }
  339. func (r *Runtime) typedArrayProto_getByteLen(call FunctionCall) Value {
  340. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  341. if ta.viewedArrayBuf.data == nil {
  342. return _positiveZero
  343. }
  344. return intToValue(int64(ta.length) * int64(ta.elemSize))
  345. }
  346. panic(r.NewTypeError("Method get TypedArray.prototype.byteLength called on incompatible receiver %s", call.This.String()))
  347. }
  348. func (r *Runtime) typedArrayProto_getLength(call FunctionCall) Value {
  349. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  350. if ta.viewedArrayBuf.data == nil {
  351. return _positiveZero
  352. }
  353. return intToValue(int64(ta.length))
  354. }
  355. panic(r.NewTypeError("Method get TypedArray.prototype.length called on incompatible receiver %s", call.This.String()))
  356. }
  357. func (r *Runtime) typedArrayProto_getByteOffset(call FunctionCall) Value {
  358. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  359. if ta.viewedArrayBuf.data == nil {
  360. return _positiveZero
  361. }
  362. return intToValue(int64(ta.offset) * int64(ta.elemSize))
  363. }
  364. panic(r.NewTypeError("Method get TypedArray.prototype.byteOffset called on incompatible receiver %s", call.This.String()))
  365. }
  366. func (r *Runtime) typedArrayProto_copyWithin(call FunctionCall) Value {
  367. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  368. ta.viewedArrayBuf.ensureNotDetached(true)
  369. l := int64(ta.length)
  370. var relEnd int64
  371. to := toIntStrict(relToIdx(call.Argument(0).ToInteger(), l))
  372. from := toIntStrict(relToIdx(call.Argument(1).ToInteger(), l))
  373. if end := call.Argument(2); end != _undefined {
  374. relEnd = end.ToInteger()
  375. } else {
  376. relEnd = l
  377. }
  378. final := toIntStrict(relToIdx(relEnd, l))
  379. data := ta.viewedArrayBuf.data
  380. offset := ta.offset
  381. elemSize := ta.elemSize
  382. if final > from {
  383. ta.viewedArrayBuf.ensureNotDetached(true)
  384. copy(data[(offset+to)*elemSize:], data[(offset+from)*elemSize:(offset+final)*elemSize])
  385. }
  386. return call.This
  387. }
  388. panic(r.NewTypeError("Method TypedArray.prototype.copyWithin called on incompatible receiver %s", call.This.String()))
  389. }
  390. func (r *Runtime) typedArrayProto_entries(call FunctionCall) Value {
  391. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  392. ta.viewedArrayBuf.ensureNotDetached(true)
  393. return r.createArrayIterator(ta.val, iterationKindKeyValue)
  394. }
  395. panic(r.NewTypeError("Method TypedArray.prototype.entries called on incompatible receiver %s", call.This.String()))
  396. }
  397. func (r *Runtime) typedArrayProto_every(call FunctionCall) Value {
  398. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  399. ta.viewedArrayBuf.ensureNotDetached(true)
  400. callbackFn := r.toCallable(call.Argument(0))
  401. fc := FunctionCall{
  402. This: call.Argument(1),
  403. Arguments: []Value{nil, nil, call.This},
  404. }
  405. for k := 0; k < ta.length; k++ {
  406. if ta.isValidIntegerIndex(k) {
  407. fc.Arguments[0] = ta.typedArray.get(ta.offset + k)
  408. } else {
  409. fc.Arguments[0] = _undefined
  410. }
  411. fc.Arguments[1] = intToValue(int64(k))
  412. if !callbackFn(fc).ToBoolean() {
  413. return valueFalse
  414. }
  415. }
  416. return valueTrue
  417. }
  418. panic(r.NewTypeError("Method TypedArray.prototype.every called on incompatible receiver %s", call.This.String()))
  419. }
  420. func (r *Runtime) typedArrayProto_fill(call FunctionCall) Value {
  421. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  422. ta.viewedArrayBuf.ensureNotDetached(true)
  423. l := int64(ta.length)
  424. k := toIntStrict(relToIdx(call.Argument(1).ToInteger(), l))
  425. var relEnd int64
  426. if endArg := call.Argument(2); endArg != _undefined {
  427. relEnd = endArg.ToInteger()
  428. } else {
  429. relEnd = l
  430. }
  431. final := toIntStrict(relToIdx(relEnd, l))
  432. arg := call.Argument(0)
  433. switch ta.typedArray.(type) {
  434. case *bigInt64Array, *bigUint64Array:
  435. if _, ok := arg.(valueString); !ok {
  436. break
  437. }
  438. _, err := strconv.ParseInt(arg.String(), 0, 64)
  439. if err != nil {
  440. panic(r.newSyntaxError("cannot convert to bigint", -1))
  441. }
  442. }
  443. value := ta.typedArray.toRaw(arg)
  444. ta.viewedArrayBuf.ensureNotDetached(true)
  445. for ; k < final; k++ {
  446. ta.typedArray.setRaw(ta.offset+k, value)
  447. }
  448. return call.This
  449. }
  450. panic(r.NewTypeError("Method TypedArray.prototype.fill called on incompatible receiver %s", call.This.String()))
  451. }
  452. func (r *Runtime) typedArrayProto_filter(call FunctionCall) Value {
  453. o := r.toObject(call.This)
  454. if ta, ok := o.self.(*typedArrayObject); ok {
  455. ta.viewedArrayBuf.ensureNotDetached(true)
  456. callbackFn := r.toCallable(call.Argument(0))
  457. fc := FunctionCall{
  458. This: call.Argument(1),
  459. Arguments: []Value{nil, nil, call.This},
  460. }
  461. buf := make([]byte, 0, ta.length*ta.elemSize)
  462. captured := 0
  463. rawVal := make([]byte, ta.elemSize)
  464. for k := 0; k < ta.length; k++ {
  465. if ta.isValidIntegerIndex(k) {
  466. fc.Arguments[0] = ta.typedArray.get(ta.offset + k)
  467. i := (ta.offset + k) * ta.elemSize
  468. copy(rawVal, ta.viewedArrayBuf.data[i:])
  469. } else {
  470. fc.Arguments[0] = _undefined
  471. for i := range rawVal {
  472. rawVal[i] = 0
  473. }
  474. }
  475. fc.Arguments[1] = intToValue(int64(k))
  476. if callbackFn(fc).ToBoolean() {
  477. buf = append(buf, rawVal...)
  478. captured++
  479. }
  480. }
  481. c := r.speciesConstructorObj(o, ta.defaultCtor)
  482. ab := r._newArrayBuffer(r.global.ArrayBufferPrototype, nil)
  483. ab.data = buf
  484. kept := r.toConstructor(ta.defaultCtor)([]Value{ab.val}, ta.defaultCtor)
  485. if c == ta.defaultCtor {
  486. return kept
  487. } else {
  488. ret := r.typedArrayCreate(c, intToValue(int64(captured)))
  489. keptTa := kept.self.(*typedArrayObject)
  490. for i := 0; i < captured; i++ {
  491. ret.typedArray.set(i, keptTa.typedArray.get(keptTa.offset+i))
  492. }
  493. return ret.val
  494. }
  495. }
  496. panic(r.NewTypeError("Method TypedArray.prototype.filter called on incompatible receiver %s", call.This.String()))
  497. }
  498. func (r *Runtime) typedArrayProto_find(call FunctionCall) Value {
  499. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  500. ta.viewedArrayBuf.ensureNotDetached(true)
  501. predicate := r.toCallable(call.Argument(0))
  502. fc := FunctionCall{
  503. This: call.Argument(1),
  504. Arguments: []Value{nil, nil, call.This},
  505. }
  506. for k := 0; k < ta.length; k++ {
  507. var val Value
  508. if ta.isValidIntegerIndex(k) {
  509. val = ta.typedArray.get(ta.offset + k)
  510. }
  511. fc.Arguments[0] = val
  512. fc.Arguments[1] = intToValue(int64(k))
  513. if predicate(fc).ToBoolean() {
  514. return val
  515. }
  516. }
  517. return _undefined
  518. }
  519. panic(r.NewTypeError("Method TypedArray.prototype.find called on incompatible receiver %s", call.This.String()))
  520. }
  521. func (r *Runtime) typedArrayProto_findIndex(call FunctionCall) Value {
  522. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  523. ta.viewedArrayBuf.ensureNotDetached(true)
  524. predicate := r.toCallable(call.Argument(0))
  525. fc := FunctionCall{
  526. This: call.Argument(1),
  527. Arguments: []Value{nil, nil, call.This},
  528. }
  529. for k := 0; k < ta.length; k++ {
  530. if ta.isValidIntegerIndex(k) {
  531. fc.Arguments[0] = ta.typedArray.get(ta.offset + k)
  532. } else {
  533. fc.Arguments[0] = _undefined
  534. }
  535. fc.Arguments[1] = intToValue(int64(k))
  536. if predicate(fc).ToBoolean() {
  537. return fc.Arguments[1]
  538. }
  539. }
  540. return intToValue(-1)
  541. }
  542. panic(r.NewTypeError("Method TypedArray.prototype.findIndex called on incompatible receiver %s", call.This.String()))
  543. }
  544. func (r *Runtime) typedArrayProto_forEach(call FunctionCall) Value {
  545. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  546. ta.viewedArrayBuf.ensureNotDetached(true)
  547. callbackFn := r.toCallable(call.Argument(0))
  548. fc := FunctionCall{
  549. This: call.Argument(1),
  550. Arguments: []Value{nil, nil, call.This},
  551. }
  552. for k := 0; k < ta.length; k++ {
  553. var val Value
  554. if ta.isValidIntegerIndex(k) {
  555. val = ta.typedArray.get(ta.offset + k)
  556. }
  557. fc.Arguments[0] = val
  558. fc.Arguments[1] = intToValue(int64(k))
  559. callbackFn(fc)
  560. }
  561. return _undefined
  562. }
  563. panic(r.NewTypeError("Method TypedArray.prototype.forEach called on incompatible receiver %s", call.This.String()))
  564. }
  565. func (r *Runtime) typedArrayProto_includes(call FunctionCall) Value {
  566. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  567. ta.viewedArrayBuf.ensureNotDetached(true)
  568. length := int64(ta.length)
  569. if length == 0 {
  570. return valueFalse
  571. }
  572. n := call.Argument(1).ToInteger()
  573. if n >= length {
  574. return valueFalse
  575. }
  576. if n < 0 {
  577. n = max(length+n, 0)
  578. }
  579. searchElement := call.Argument(0)
  580. if searchElement == _negativeZero {
  581. searchElement = _positiveZero
  582. }
  583. startIdx := toIntStrict(n)
  584. if !ta.viewedArrayBuf.ensureNotDetached(false) {
  585. if searchElement == _undefined && startIdx < ta.length {
  586. return valueTrue
  587. }
  588. return valueFalse
  589. }
  590. if ta.typedArray.typeMatch(searchElement) {
  591. se := ta.typedArray.toRaw(searchElement)
  592. for k := startIdx; k < ta.length; k++ {
  593. if ta.typedArray.getRaw(ta.offset+k) == se {
  594. return valueTrue
  595. }
  596. }
  597. }
  598. return valueFalse
  599. }
  600. panic(r.NewTypeError("Method TypedArray.prototype.includes called on incompatible receiver %s", call.This.String()))
  601. }
  602. func (r *Runtime) typedArrayProto_indexOf(call FunctionCall) Value {
  603. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  604. ta.viewedArrayBuf.ensureNotDetached(true)
  605. length := int64(ta.length)
  606. if length == 0 {
  607. return intToValue(-1)
  608. }
  609. n := call.Argument(1).ToInteger()
  610. if n >= length {
  611. return intToValue(-1)
  612. }
  613. if n < 0 {
  614. n = max(length+n, 0)
  615. }
  616. if ta.viewedArrayBuf.ensureNotDetached(false) {
  617. searchElement := call.Argument(0)
  618. if searchElement == _negativeZero {
  619. searchElement = _positiveZero
  620. }
  621. if !IsNaN(searchElement) && ta.typedArray.typeMatch(searchElement) {
  622. se := ta.typedArray.toRaw(searchElement)
  623. for k := toIntStrict(n); k < ta.length; k++ {
  624. if ta.typedArray.getRaw(ta.offset+k) == se {
  625. return intToValue(int64(k))
  626. }
  627. }
  628. }
  629. }
  630. return intToValue(-1)
  631. }
  632. panic(r.NewTypeError("Method TypedArray.prototype.indexOf called on incompatible receiver %s", call.This.String()))
  633. }
  634. func (r *Runtime) typedArrayProto_join(call FunctionCall) Value {
  635. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  636. ta.viewedArrayBuf.ensureNotDetached(true)
  637. s := call.Argument(0)
  638. var sep valueString
  639. if s != _undefined {
  640. sep = s.toString()
  641. } else {
  642. sep = asciiString(",")
  643. }
  644. l := ta.length
  645. if l == 0 {
  646. return stringEmpty
  647. }
  648. var buf valueStringBuilder
  649. var element0 Value
  650. if ta.isValidIntegerIndex(0) {
  651. element0 = ta.typedArray.get(ta.offset + 0)
  652. }
  653. if element0 != nil && element0 != _undefined && element0 != _null {
  654. buf.WriteString(element0.toString())
  655. }
  656. for i := 1; i < l; i++ {
  657. buf.WriteString(sep)
  658. if ta.isValidIntegerIndex(i) {
  659. element := ta.typedArray.get(ta.offset + i)
  660. if element != nil && element != _undefined && element != _null {
  661. buf.WriteString(element.toString())
  662. }
  663. }
  664. }
  665. return buf.String()
  666. }
  667. panic(r.NewTypeError("Method TypedArray.prototype.join called on incompatible receiver"))
  668. }
  669. func (r *Runtime) typedArrayProto_keys(call FunctionCall) Value {
  670. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  671. ta.viewedArrayBuf.ensureNotDetached(true)
  672. return r.createArrayIterator(ta.val, iterationKindKey)
  673. }
  674. panic(r.NewTypeError("Method TypedArray.prototype.keys called on incompatible receiver %s", call.This.String()))
  675. }
  676. func (r *Runtime) typedArrayProto_lastIndexOf(call FunctionCall) Value {
  677. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  678. ta.viewedArrayBuf.ensureNotDetached(true)
  679. length := int64(ta.length)
  680. if length == 0 {
  681. return intToValue(-1)
  682. }
  683. var fromIndex int64
  684. if len(call.Arguments) < 2 {
  685. fromIndex = length - 1
  686. } else {
  687. fromIndex = call.Argument(1).ToInteger()
  688. if fromIndex >= 0 {
  689. fromIndex = min(fromIndex, length-1)
  690. } else {
  691. fromIndex += length
  692. if fromIndex < 0 {
  693. fromIndex = -1 // prevent underflow in toIntStrict() on 32-bit platforms
  694. }
  695. }
  696. }
  697. if ta.viewedArrayBuf.ensureNotDetached(false) {
  698. searchElement := call.Argument(0)
  699. if searchElement == _negativeZero {
  700. searchElement = _positiveZero
  701. }
  702. if !IsNaN(searchElement) && ta.typedArray.typeMatch(searchElement) {
  703. se := ta.typedArray.toRaw(searchElement)
  704. for k := toIntStrict(fromIndex); k >= 0; k-- {
  705. if ta.typedArray.getRaw(ta.offset+k) == se {
  706. return intToValue(int64(k))
  707. }
  708. }
  709. }
  710. }
  711. return intToValue(-1)
  712. }
  713. panic(r.NewTypeError("Method TypedArray.prototype.lastIndexOf called on incompatible receiver %s", call.This.String()))
  714. }
  715. func (r *Runtime) typedArrayProto_map(call FunctionCall) Value {
  716. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  717. ta.viewedArrayBuf.ensureNotDetached(true)
  718. callbackFn := r.toCallable(call.Argument(0))
  719. fc := FunctionCall{
  720. This: call.Argument(1),
  721. Arguments: []Value{nil, nil, call.This},
  722. }
  723. dst := r.typedArraySpeciesCreate(ta, []Value{intToValue(int64(ta.length))})
  724. for i := 0; i < ta.length; i++ {
  725. if ta.isValidIntegerIndex(i) {
  726. fc.Arguments[0] = ta.typedArray.get(ta.offset + i)
  727. } else {
  728. fc.Arguments[0] = _undefined
  729. }
  730. fc.Arguments[1] = intToValue(int64(i))
  731. dst.typedArray.set(i, callbackFn(fc))
  732. }
  733. return dst.val
  734. }
  735. panic(r.NewTypeError("Method TypedArray.prototype.map called on incompatible receiver %s", call.This.String()))
  736. }
  737. func (r *Runtime) typedArrayProto_reduce(call FunctionCall) Value {
  738. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  739. ta.viewedArrayBuf.ensureNotDetached(true)
  740. callbackFn := r.toCallable(call.Argument(0))
  741. fc := FunctionCall{
  742. This: _undefined,
  743. Arguments: []Value{nil, nil, nil, call.This},
  744. }
  745. k := 0
  746. if len(call.Arguments) >= 2 {
  747. fc.Arguments[0] = call.Argument(1)
  748. } else {
  749. if ta.length > 0 {
  750. fc.Arguments[0] = ta.typedArray.get(ta.offset + 0)
  751. k = 1
  752. }
  753. }
  754. if fc.Arguments[0] == nil {
  755. panic(r.NewTypeError("Reduce of empty array with no initial value"))
  756. }
  757. for ; k < ta.length; k++ {
  758. if ta.isValidIntegerIndex(k) {
  759. fc.Arguments[1] = ta.typedArray.get(ta.offset + k)
  760. } else {
  761. fc.Arguments[1] = _undefined
  762. }
  763. idx := valueInt(k)
  764. fc.Arguments[2] = idx
  765. fc.Arguments[0] = callbackFn(fc)
  766. }
  767. return fc.Arguments[0]
  768. }
  769. panic(r.NewTypeError("Method TypedArray.prototype.reduce called on incompatible receiver %s", call.This.String()))
  770. }
  771. func (r *Runtime) typedArrayProto_reduceRight(call FunctionCall) Value {
  772. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  773. ta.viewedArrayBuf.ensureNotDetached(true)
  774. callbackFn := r.toCallable(call.Argument(0))
  775. fc := FunctionCall{
  776. This: _undefined,
  777. Arguments: []Value{nil, nil, nil, call.This},
  778. }
  779. k := ta.length - 1
  780. if len(call.Arguments) >= 2 {
  781. fc.Arguments[0] = call.Argument(1)
  782. } else {
  783. if k >= 0 {
  784. fc.Arguments[0] = ta.typedArray.get(ta.offset + k)
  785. k--
  786. }
  787. }
  788. if fc.Arguments[0] == nil {
  789. panic(r.NewTypeError("Reduce of empty array with no initial value"))
  790. }
  791. for ; k >= 0; k-- {
  792. if ta.isValidIntegerIndex(k) {
  793. fc.Arguments[1] = ta.typedArray.get(ta.offset + k)
  794. } else {
  795. fc.Arguments[1] = _undefined
  796. }
  797. idx := valueInt(k)
  798. fc.Arguments[2] = idx
  799. fc.Arguments[0] = callbackFn(fc)
  800. }
  801. return fc.Arguments[0]
  802. }
  803. panic(r.NewTypeError("Method TypedArray.prototype.reduceRight called on incompatible receiver %s", call.This.String()))
  804. }
  805. func (r *Runtime) typedArrayProto_reverse(call FunctionCall) Value {
  806. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  807. ta.viewedArrayBuf.ensureNotDetached(true)
  808. l := ta.length
  809. middle := l / 2
  810. for lower := 0; lower != middle; lower++ {
  811. upper := l - lower - 1
  812. ta.typedArray.swap(ta.offset+lower, ta.offset+upper)
  813. }
  814. return call.This
  815. }
  816. panic(r.NewTypeError("Method TypedArray.prototype.reverse called on incompatible receiver %s", call.This.String()))
  817. }
  818. func (r *Runtime) typedArrayProto_set(call FunctionCall) Value {
  819. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  820. srcObj := call.Argument(0).ToObject(r)
  821. targetOffset := toIntStrict(call.Argument(1).ToInteger())
  822. if targetOffset < 0 {
  823. panic(r.newError(r.global.RangeError, "offset should be >= 0"))
  824. }
  825. ta.viewedArrayBuf.ensureNotDetached(true)
  826. targetLen := ta.length
  827. if src, ok := srcObj.self.(*typedArrayObject); ok {
  828. src.viewedArrayBuf.ensureNotDetached(true)
  829. srcLen := src.length
  830. if x := srcLen + targetOffset; x < 0 || x > targetLen {
  831. panic(r.newError(r.global.RangeError, "Source is too large"))
  832. }
  833. if src.defaultCtor == ta.defaultCtor {
  834. copy(ta.viewedArrayBuf.data[(ta.offset+targetOffset)*ta.elemSize:],
  835. src.viewedArrayBuf.data[src.offset*src.elemSize:(src.offset+srcLen)*src.elemSize])
  836. } else {
  837. curSrc := uintptr(unsafe.Pointer(&src.viewedArrayBuf.data[src.offset*src.elemSize]))
  838. endSrc := curSrc + uintptr(srcLen*src.elemSize)
  839. curDst := uintptr(unsafe.Pointer(&ta.viewedArrayBuf.data[(ta.offset+targetOffset)*ta.elemSize]))
  840. dstOffset := ta.offset + targetOffset
  841. srcOffset := src.offset
  842. if ta.elemSize == src.elemSize {
  843. if curDst <= curSrc || curDst >= endSrc {
  844. for i := 0; i < srcLen; i++ {
  845. ta.typedArray.set(dstOffset+i, src.typedArray.get(srcOffset+i))
  846. }
  847. } else {
  848. for i := srcLen - 1; i >= 0; i-- {
  849. ta.typedArray.set(dstOffset+i, src.typedArray.get(srcOffset+i))
  850. }
  851. }
  852. } else {
  853. x := int(curDst-curSrc) / (src.elemSize - ta.elemSize)
  854. if x < 0 {
  855. x = 0
  856. } else if x > srcLen {
  857. x = srcLen
  858. }
  859. if ta.elemSize < src.elemSize {
  860. for i := x; i < srcLen; i++ {
  861. ta.typedArray.set(dstOffset+i, src.typedArray.get(srcOffset+i))
  862. }
  863. for i := x - 1; i >= 0; i-- {
  864. ta.typedArray.set(dstOffset+i, src.typedArray.get(srcOffset+i))
  865. }
  866. } else {
  867. for i := 0; i < x; i++ {
  868. ta.typedArray.set(dstOffset+i, src.typedArray.get(srcOffset+i))
  869. }
  870. for i := srcLen - 1; i >= x; i-- {
  871. ta.typedArray.set(dstOffset+i, src.typedArray.get(srcOffset+i))
  872. }
  873. }
  874. }
  875. }
  876. } else {
  877. targetLen := ta.length
  878. srcLen := toIntStrict(toLength(srcObj.self.getStr("length", nil)))
  879. if x := srcLen + targetOffset; x < 0 || x > targetLen {
  880. panic(r.newError(r.global.RangeError, "Source is too large"))
  881. }
  882. for i := 0; i < srcLen; i++ {
  883. val := nilSafe(srcObj.self.getIdx(valueInt(i), nil))
  884. ta.viewedArrayBuf.ensureNotDetached(true)
  885. if ta.isValidIntegerIndex(i) {
  886. if _, ok := val.(asciiString); ok {
  887. switch ta.typedArray.(type) {
  888. case *bigUint64Array:
  889. if _, err := strconv.ParseUint(val.String(), 0, 64); err != nil && val.String() != "" {
  890. panic(r.newError(r.global.SyntaxError, "cannot convert to bigint"))
  891. }
  892. case *bigInt64Array:
  893. if _, err := strconv.ParseInt(val.String(), 0, 64); err != nil && val.String() != "" {
  894. panic(r.newError(r.global.SyntaxError, "cannot convert to bigint"))
  895. }
  896. }
  897. }
  898. ta.typedArray.set(targetOffset+i, val)
  899. }
  900. }
  901. }
  902. return _undefined
  903. }
  904. panic(r.NewTypeError("Method TypedArray.prototype.set called on incompatible receiver %s", call.This.String()))
  905. }
  906. func (r *Runtime) typedArrayProto_slice(call FunctionCall) Value {
  907. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  908. ta.viewedArrayBuf.ensureNotDetached(true)
  909. length := int64(ta.length)
  910. start := toIntStrict(relToIdx(call.Argument(0).ToInteger(), length))
  911. var e int64
  912. if endArg := call.Argument(1); endArg != _undefined {
  913. e = endArg.ToInteger()
  914. } else {
  915. e = length
  916. }
  917. end := toIntStrict(relToIdx(e, length))
  918. count := end - start
  919. if count < 0 {
  920. count = 0
  921. }
  922. dst := r.typedArraySpeciesCreate(ta, []Value{intToValue(int64(count))})
  923. if dst.defaultCtor == ta.defaultCtor {
  924. if count > 0 {
  925. ta.viewedArrayBuf.ensureNotDetached(true)
  926. offset := ta.offset
  927. elemSize := ta.elemSize
  928. copy(dst.viewedArrayBuf.data, ta.viewedArrayBuf.data[(offset+start)*elemSize:(offset+start+count)*elemSize])
  929. }
  930. } else {
  931. for i := 0; i < count; i++ {
  932. ta.viewedArrayBuf.ensureNotDetached(true)
  933. dst.typedArray.set(i, ta.typedArray.get(ta.offset+start+i))
  934. }
  935. }
  936. return dst.val
  937. }
  938. panic(r.NewTypeError("Method TypedArray.prototype.slice called on incompatible receiver %s", call.This.String()))
  939. }
  940. func (r *Runtime) typedArrayProto_some(call FunctionCall) Value {
  941. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  942. ta.viewedArrayBuf.ensureNotDetached(true)
  943. callbackFn := r.toCallable(call.Argument(0))
  944. fc := FunctionCall{
  945. This: call.Argument(1),
  946. Arguments: []Value{nil, nil, call.This},
  947. }
  948. for k := 0; k < ta.length; k++ {
  949. if ta.isValidIntegerIndex(k) {
  950. fc.Arguments[0] = ta.typedArray.get(ta.offset + k)
  951. } else {
  952. fc.Arguments[0] = _undefined
  953. }
  954. fc.Arguments[1] = intToValue(int64(k))
  955. if callbackFn(fc).ToBoolean() {
  956. return valueTrue
  957. }
  958. }
  959. return valueFalse
  960. }
  961. panic(r.NewTypeError("Method TypedArray.prototype.some called on incompatible receiver %s", call.This.String()))
  962. }
  963. func (r *Runtime) typedArrayProto_sort(call FunctionCall) Value {
  964. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  965. ta.viewedArrayBuf.ensureNotDetached(true)
  966. var compareFn func(FunctionCall) Value
  967. if arg := call.Argument(0); arg != _undefined {
  968. compareFn = r.toCallable(arg)
  969. }
  970. ctx := typedArraySortCtx{
  971. ta: ta,
  972. compare: compareFn,
  973. }
  974. sort.Stable(&ctx)
  975. return call.This
  976. }
  977. panic(r.NewTypeError("Method TypedArray.prototype.sort called on incompatible receiver %s", call.This.String()))
  978. }
  979. func (r *Runtime) typedArrayProto_subarray(call FunctionCall) Value {
  980. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  981. l := int64(ta.length)
  982. beginIdx := relToIdx(call.Argument(0).ToInteger(), l)
  983. var relEnd int64
  984. if endArg := call.Argument(1); endArg != _undefined {
  985. relEnd = endArg.ToInteger()
  986. } else {
  987. relEnd = l
  988. }
  989. endIdx := relToIdx(relEnd, l)
  990. newLen := max(endIdx-beginIdx, 0)
  991. return r.typedArraySpeciesCreate(ta, []Value{ta.viewedArrayBuf.val,
  992. intToValue((int64(ta.offset) + beginIdx) * int64(ta.elemSize)),
  993. intToValue(newLen),
  994. }).val
  995. }
  996. panic(r.NewTypeError("Method TypedArray.prototype.subarray called on incompatible receiver %s", call.This.String()))
  997. }
  998. func (r *Runtime) typedArrayProto_toLocaleString(call FunctionCall) Value {
  999. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  1000. length := ta.length
  1001. var buf valueStringBuilder
  1002. for i := 0; i < length; i++ {
  1003. ta.viewedArrayBuf.ensureNotDetached(true)
  1004. if i > 0 {
  1005. buf.WriteRune(',')
  1006. }
  1007. item := ta.typedArray.get(ta.offset + i)
  1008. r.writeItemLocaleString(item, &buf)
  1009. }
  1010. return buf.String()
  1011. }
  1012. panic(r.NewTypeError("Method TypedArray.prototype.toLocaleString called on incompatible receiver %s", call.This.String()))
  1013. }
  1014. func (r *Runtime) typedArrayProto_values(call FunctionCall) Value {
  1015. if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
  1016. ta.viewedArrayBuf.ensureNotDetached(true)
  1017. return r.createArrayIterator(ta.val, iterationKindValue)
  1018. }
  1019. panic(r.NewTypeError("Method TypedArray.prototype.values called on incompatible receiver %s", call.This.String()))
  1020. }
  1021. func (r *Runtime) typedArrayProto_toStringTag(call FunctionCall) Value {
  1022. if obj, ok := call.This.(*Object); ok {
  1023. if ta, ok := obj.self.(*typedArrayObject); ok {
  1024. return nilSafe(ta.defaultCtor.self.getStr("name", nil))
  1025. }
  1026. }
  1027. return _undefined
  1028. }
  1029. func (r *Runtime) newTypedArray([]Value, *Object) *Object {
  1030. panic(r.NewTypeError("Abstract class TypedArray not directly constructable"))
  1031. }
  1032. func (r *Runtime) typedArray_from(call FunctionCall) Value {
  1033. c := r.toObject(call.This)
  1034. var mapFc func(call FunctionCall) Value
  1035. thisValue := call.Argument(2)
  1036. if mapFn := call.Argument(1); mapFn != _undefined {
  1037. mapFc = r.toCallable(mapFn)
  1038. }
  1039. source := r.toObject(call.Argument(0))
  1040. usingIter := toMethod(source.self.getSym(SymIterator, nil))
  1041. if usingIter != nil {
  1042. values := r.iterableToList(source, usingIter)
  1043. ta := r.typedArrayCreate(c, intToValue(int64(len(values))))
  1044. if mapFc == nil {
  1045. for idx, val := range values {
  1046. ta.typedArray.set(idx, val)
  1047. }
  1048. } else {
  1049. fc := FunctionCall{
  1050. This: thisValue,
  1051. Arguments: []Value{nil, nil},
  1052. }
  1053. for idx, val := range values {
  1054. fc.Arguments[0], fc.Arguments[1] = val, intToValue(int64(idx))
  1055. val = mapFc(fc)
  1056. ta.typedArray.set(idx, val)
  1057. }
  1058. }
  1059. return ta.val
  1060. }
  1061. length := toIntStrict(toLength(source.self.getStr("length", nil)))
  1062. ta := r.typedArrayCreate(c, intToValue(int64(length)))
  1063. if mapFc == nil {
  1064. for i := 0; i < length; i++ {
  1065. ta.typedArray.set(i, nilSafe(source.self.getIdx(valueInt(i), nil)))
  1066. }
  1067. } else {
  1068. fc := FunctionCall{
  1069. This: thisValue,
  1070. Arguments: []Value{nil, nil},
  1071. }
  1072. for i := 0; i < length; i++ {
  1073. idx := valueInt(i)
  1074. fc.Arguments[0], fc.Arguments[1] = source.self.getIdx(idx, nil), idx
  1075. ta.typedArray.set(i, mapFc(fc))
  1076. }
  1077. }
  1078. return ta.val
  1079. }
  1080. func (r *Runtime) typedArray_of(call FunctionCall) Value {
  1081. ta := r.typedArrayCreate(r.toObject(call.This), intToValue(int64(len(call.Arguments))))
  1082. for i, val := range call.Arguments {
  1083. ta.typedArray.set(i, val)
  1084. }
  1085. return ta.val
  1086. }
  1087. func (r *Runtime) allocateTypedArray(newTarget *Object, length int, taCtor typedArrayObjectCtor, proto *Object) *typedArrayObject {
  1088. buf := r._newArrayBuffer(r.global.ArrayBufferPrototype, nil)
  1089. ta := taCtor(buf, 0, length, r.getPrototypeFromCtor(newTarget, nil, proto))
  1090. if length > 0 {
  1091. buf.data = allocByteSlice(length * ta.elemSize)
  1092. }
  1093. return ta
  1094. }
  1095. func (r *Runtime) typedArraySpeciesCreate(ta *typedArrayObject, args []Value) *typedArrayObject {
  1096. return r.typedArrayCreate(r.speciesConstructorObj(ta.val, ta.defaultCtor), args...)
  1097. }
  1098. func (r *Runtime) typedArrayCreate(ctor *Object, args ...Value) *typedArrayObject {
  1099. o := r.toConstructor(ctor)(args, ctor)
  1100. if ta, ok := o.self.(*typedArrayObject); ok {
  1101. ta.viewedArrayBuf.ensureNotDetached(true)
  1102. if len(args) == 1 {
  1103. if l, ok := args[0].(valueInt); ok {
  1104. if ta.length < int(l) {
  1105. panic(r.NewTypeError("Derived TypedArray constructor created an array which was too small"))
  1106. }
  1107. }
  1108. }
  1109. return ta
  1110. }
  1111. panic(r.NewTypeError("Invalid TypedArray: %s", o))
  1112. }
  1113. func (r *Runtime) typedArrayFrom(ctor, items *Object, mapFn, thisValue Value, taCtor typedArrayObjectCtor, proto *Object) *Object {
  1114. var mapFc func(call FunctionCall) Value
  1115. if mapFn != nil {
  1116. mapFc = r.toCallable(mapFn)
  1117. if thisValue == nil {
  1118. thisValue = _undefined
  1119. }
  1120. }
  1121. usingIter := toMethod(items.self.getSym(SymIterator, nil))
  1122. if usingIter != nil {
  1123. values := r.iterableToList(items, usingIter)
  1124. ta := r.allocateTypedArray(ctor, len(values), taCtor, proto)
  1125. if mapFc == nil {
  1126. for idx, val := range values {
  1127. ta.typedArray.set(idx, val)
  1128. }
  1129. } else {
  1130. fc := FunctionCall{
  1131. This: thisValue,
  1132. Arguments: []Value{nil, nil},
  1133. }
  1134. for idx, val := range values {
  1135. fc.Arguments[0], fc.Arguments[1] = val, intToValue(int64(idx))
  1136. val = mapFc(fc)
  1137. ta.typedArray.set(idx, val)
  1138. }
  1139. }
  1140. return ta.val
  1141. }
  1142. length := toIntStrict(toLength(items.self.getStr("length", nil)))
  1143. ta := r.allocateTypedArray(ctor, length, taCtor, proto)
  1144. if mapFc == nil {
  1145. for i := 0; i < length; i++ {
  1146. ta.typedArray.set(i, nilSafe(items.self.getIdx(valueInt(i), nil)))
  1147. }
  1148. } else {
  1149. fc := FunctionCall{
  1150. This: thisValue,
  1151. Arguments: []Value{nil, nil},
  1152. }
  1153. for i := 0; i < length; i++ {
  1154. idx := valueInt(i)
  1155. fc.Arguments[0], fc.Arguments[1] = items.self.getIdx(idx, nil), idx
  1156. ta.typedArray.set(i, mapFc(fc))
  1157. }
  1158. }
  1159. return ta.val
  1160. }
  1161. func (r *Runtime) _newTypedArrayFromArrayBuffer(ab *arrayBufferObject, args []Value, newTarget *Object, taCtor typedArrayObjectCtor, proto *Object) *Object {
  1162. ta := taCtor(ab, 0, 0, r.getPrototypeFromCtor(newTarget, nil, proto))
  1163. var byteOffset int
  1164. if len(args) > 1 && args[1] != nil && args[1] != _undefined {
  1165. byteOffset = r.toIndex(args[1])
  1166. if byteOffset%ta.elemSize != 0 {
  1167. panic(r.newError(r.global.RangeError, "Start offset of %s should be a multiple of %d", newTarget.self.getStr("name", nil), ta.elemSize))
  1168. }
  1169. }
  1170. var length int
  1171. if len(args) > 2 && args[2] != nil && args[2] != _undefined {
  1172. length = r.toIndex(args[2])
  1173. ab.ensureNotDetached(true)
  1174. if byteOffset+length*ta.elemSize > len(ab.data) {
  1175. panic(r.newError(r.global.RangeError, "Invalid typed array length: %d", length))
  1176. }
  1177. } else {
  1178. ab.ensureNotDetached(true)
  1179. if len(ab.data)%ta.elemSize != 0 {
  1180. panic(r.newError(r.global.RangeError, "Byte length of %s should be a multiple of %d", newTarget.self.getStr("name", nil), ta.elemSize))
  1181. }
  1182. length = (len(ab.data) - byteOffset) / ta.elemSize
  1183. if length < 0 {
  1184. panic(r.newError(r.global.RangeError, "Start offset %d is outside the bounds of the buffer", byteOffset))
  1185. }
  1186. }
  1187. ta.offset = byteOffset / ta.elemSize
  1188. ta.length = length
  1189. return ta.val
  1190. }
  1191. func (r *Runtime) _newTypedArrayFromTypedArray(src *typedArrayObject, newTarget *Object, taCtor typedArrayObjectCtor, proto *Object) *Object {
  1192. dst := r.allocateTypedArray(newTarget, 0, taCtor, proto)
  1193. src.viewedArrayBuf.ensureNotDetached(true)
  1194. l := src.length
  1195. dst.viewedArrayBuf.prototype = r.getPrototypeFromCtor(r.speciesConstructorObj(src.viewedArrayBuf.val, r.global.ArrayBuffer), r.global.ArrayBuffer, r.global.ArrayBufferPrototype)
  1196. dst.viewedArrayBuf.data = allocByteSlice(toIntStrict(int64(l) * int64(dst.elemSize)))
  1197. src.viewedArrayBuf.ensureNotDetached(true)
  1198. if src.defaultCtor == dst.defaultCtor {
  1199. copy(dst.viewedArrayBuf.data, src.viewedArrayBuf.data[src.offset*src.elemSize:])
  1200. dst.length = src.length
  1201. return dst.val
  1202. }
  1203. dst.length = l
  1204. for i := 0; i < l; i++ {
  1205. dst.typedArray.set(i, src.typedArray.get(src.offset+i))
  1206. }
  1207. return dst.val
  1208. }
  1209. func (r *Runtime) _newTypedArray(args []Value, newTarget *Object, taCtor typedArrayObjectCtor, proto *Object) *Object {
  1210. if newTarget == nil {
  1211. panic(r.needNew("TypedArray"))
  1212. }
  1213. if len(args) > 0 {
  1214. if obj, ok := args[0].(*Object); ok {
  1215. switch o := obj.self.(type) {
  1216. case *arrayBufferObject:
  1217. return r._newTypedArrayFromArrayBuffer(o, args, newTarget, taCtor, proto)
  1218. case *typedArrayObject:
  1219. return r._newTypedArrayFromTypedArray(o, newTarget, taCtor, proto)
  1220. default:
  1221. return r.typedArrayFrom(newTarget, obj, nil, nil, taCtor, proto)
  1222. }
  1223. }
  1224. }
  1225. var l int
  1226. if len(args) > 0 {
  1227. if arg0 := args[0]; arg0 != nil {
  1228. l = r.toIndex(arg0)
  1229. }
  1230. }
  1231. return r.allocateTypedArray(newTarget, l, taCtor, proto).val
  1232. }
  1233. func (r *Runtime) newUint8Array(args []Value, newTarget, proto *Object) *Object {
  1234. return r._newTypedArray(args, newTarget, r.newUint8ArrayObject, proto)
  1235. }
  1236. func (r *Runtime) newUint8ClampedArray(args []Value, newTarget, proto *Object) *Object {
  1237. return r._newTypedArray(args, newTarget, r.newUint8ClampedArrayObject, proto)
  1238. }
  1239. func (r *Runtime) newInt8Array(args []Value, newTarget, proto *Object) *Object {
  1240. return r._newTypedArray(args, newTarget, r.newInt8ArrayObject, proto)
  1241. }
  1242. func (r *Runtime) newUint16Array(args []Value, newTarget, proto *Object) *Object {
  1243. return r._newTypedArray(args, newTarget, r.newUint16ArrayObject, proto)
  1244. }
  1245. func (r *Runtime) newInt16Array(args []Value, newTarget, proto *Object) *Object {
  1246. return r._newTypedArray(args, newTarget, r.newInt16ArrayObject, proto)
  1247. }
  1248. func (r *Runtime) newUint32Array(args []Value, newTarget, proto *Object) *Object {
  1249. return r._newTypedArray(args, newTarget, r.newUint32ArrayObject, proto)
  1250. }
  1251. func (r *Runtime) newInt32Array(args []Value, newTarget, proto *Object) *Object {
  1252. return r._newTypedArray(args, newTarget, r.newInt32ArrayObject, proto)
  1253. }
  1254. func (r *Runtime) newFloat32Array(args []Value, newTarget, proto *Object) *Object {
  1255. return r._newTypedArray(args, newTarget, r.newFloat32ArrayObject, proto)
  1256. }
  1257. func (r *Runtime) newFloat64Array(args []Value, newTarget, proto *Object) *Object {
  1258. return r._newTypedArray(args, newTarget, r.newFloat64ArrayObject, proto)
  1259. }
  1260. func (r *Runtime) newBigInt64Array(args []Value, newTarget, proto *Object) *Object {
  1261. return r._newTypedArray(args, newTarget, r.newBigInt64ArrayObject, proto)
  1262. }
  1263. func (r *Runtime) newBigUint64Array(args []Value, newTarget, proto *Object) *Object {
  1264. return r._newTypedArray(args, newTarget, r.newBigUint64ArrayObject, proto)
  1265. }
  1266. func (r *Runtime) createArrayBufferProto(val *Object) objectImpl {
  1267. b := newBaseObjectObj(val, r.global.ObjectPrototype, classObject)
  1268. byteLengthProp := &valueProperty{
  1269. accessor: true,
  1270. configurable: true,
  1271. getterFunc: r.newNativeFunc(r.arrayBufferProto_getByteLength, nil, "get byteLength", nil, 0),
  1272. }
  1273. b._put("byteLength", byteLengthProp)
  1274. b._putProp("constructor", r.global.ArrayBuffer, true, false, true)
  1275. b._putProp("slice", r.newNativeFunc(r.arrayBufferProto_slice, nil, "slice", nil, 2), true, false, true)
  1276. b._putSym(SymToStringTag, valueProp(asciiString("ArrayBuffer"), false, false, true))
  1277. return b
  1278. }
  1279. func (r *Runtime) createArrayBuffer(val *Object) objectImpl {
  1280. o := r.newNativeConstructOnly(val, r.builtin_newArrayBuffer, r.global.ArrayBufferPrototype, "ArrayBuffer", 1)
  1281. o._putProp("isView", r.newNativeFunc(r.arrayBuffer_isView, nil, "isView", nil, 1), true, false, true)
  1282. r.putSpeciesReturnThis(o)
  1283. return o
  1284. }
  1285. func (r *Runtime) createDataViewProto(val *Object) objectImpl {
  1286. b := newBaseObjectObj(val, r.global.ObjectPrototype, classObject)
  1287. b._put("buffer", &valueProperty{
  1288. accessor: true,
  1289. configurable: true,
  1290. getterFunc: r.newNativeFunc(r.dataViewProto_getBuffer, nil, "get buffer", nil, 0),
  1291. })
  1292. b._put("byteLength", &valueProperty{
  1293. accessor: true,
  1294. configurable: true,
  1295. getterFunc: r.newNativeFunc(r.dataViewProto_getByteLen, nil, "get byteLength", nil, 0),
  1296. })
  1297. b._put("byteOffset", &valueProperty{
  1298. accessor: true,
  1299. configurable: true,
  1300. getterFunc: r.newNativeFunc(r.dataViewProto_getByteOffset, nil, "get byteOffset", nil, 0),
  1301. })
  1302. b._putProp("constructor", r.global.DataView, true, false, true)
  1303. b._putProp("getFloat32", r.newNativeFunc(r.dataViewProto_getFloat32, nil, "getFloat32", nil, 1), true, false, true)
  1304. b._putProp("getFloat64", r.newNativeFunc(r.dataViewProto_getFloat64, nil, "getFloat64", nil, 1), true, false, true)
  1305. b._putProp("getInt8", r.newNativeFunc(r.dataViewProto_getInt8, nil, "getInt8", nil, 1), true, false, true)
  1306. b._putProp("getInt16", r.newNativeFunc(r.dataViewProto_getInt16, nil, "getInt16", nil, 1), true, false, true)
  1307. b._putProp("getInt32", r.newNativeFunc(r.dataViewProto_getInt32, nil, "getInt32", nil, 1), true, false, true)
  1308. b._putProp("getUint8", r.newNativeFunc(r.dataViewProto_getUint8, nil, "getUint8", nil, 1), true, false, true)
  1309. b._putProp("getUint16", r.newNativeFunc(r.dataViewProto_getUint16, nil, "getUint16", nil, 1), true, false, true)
  1310. b._putProp("getUint32", r.newNativeFunc(r.dataViewProto_getUint32, nil, "getUint32", nil, 1), true, false, true)
  1311. b._putProp("setFloat32", r.newNativeFunc(r.dataViewProto_setFloat32, nil, "setFloat32", nil, 2), true, false, true)
  1312. b._putProp("setFloat64", r.newNativeFunc(r.dataViewProto_setFloat64, nil, "setFloat64", nil, 2), true, false, true)
  1313. b._putProp("setInt8", r.newNativeFunc(r.dataViewProto_setInt8, nil, "setInt8", nil, 2), true, false, true)
  1314. b._putProp("setInt16", r.newNativeFunc(r.dataViewProto_setInt16, nil, "setInt16", nil, 2), true, false, true)
  1315. b._putProp("setInt32", r.newNativeFunc(r.dataViewProto_setInt32, nil, "setInt32", nil, 2), true, false, true)
  1316. b._putProp("setUint8", r.newNativeFunc(r.dataViewProto_setUint8, nil, "setUint8", nil, 2), true, false, true)
  1317. b._putProp("setUint16", r.newNativeFunc(r.dataViewProto_setUint16, nil, "setUint16", nil, 2), true, false, true)
  1318. b._putProp("setUint32", r.newNativeFunc(r.dataViewProto_setUint32, nil, "setUint32", nil, 2), true, false, true)
  1319. b._putSym(SymToStringTag, valueProp(asciiString("DataView"), false, false, true))
  1320. return b
  1321. }
  1322. func (r *Runtime) createDataView(val *Object) objectImpl {
  1323. o := r.newNativeConstructOnly(val, r.newDataView, r.global.DataViewPrototype, "DataView", 1)
  1324. return o
  1325. }
  1326. func (r *Runtime) createTypedArrayProto(val *Object) objectImpl {
  1327. b := newBaseObjectObj(val, r.global.ObjectPrototype, classObject)
  1328. b._put("buffer", &valueProperty{
  1329. accessor: true,
  1330. configurable: true,
  1331. getterFunc: r.newNativeFunc(r.typedArrayProto_getBuffer, nil, "get buffer", nil, 0),
  1332. })
  1333. b._put("byteLength", &valueProperty{
  1334. accessor: true,
  1335. configurable: true,
  1336. getterFunc: r.newNativeFunc(r.typedArrayProto_getByteLen, nil, "get byteLength", nil, 0),
  1337. })
  1338. b._put("byteOffset", &valueProperty{
  1339. accessor: true,
  1340. configurable: true,
  1341. getterFunc: r.newNativeFunc(r.typedArrayProto_getByteOffset, nil, "get byteOffset", nil, 0),
  1342. })
  1343. b._putProp("constructor", r.global.TypedArray, true, false, true)
  1344. b._putProp("copyWithin", r.newNativeFunc(r.typedArrayProto_copyWithin, nil, "copyWithin", nil, 2), true, false, true)
  1345. b._putProp("entries", r.newNativeFunc(r.typedArrayProto_entries, nil, "entries", nil, 0), true, false, true)
  1346. b._putProp("every", r.newNativeFunc(r.typedArrayProto_every, nil, "every", nil, 1), true, false, true)
  1347. b._putProp("fill", r.newNativeFunc(r.typedArrayProto_fill, nil, "fill", nil, 1), true, false, true)
  1348. b._putProp("filter", r.newNativeFunc(r.typedArrayProto_filter, nil, "filter", nil, 1), true, false, true)
  1349. b._putProp("find", r.newNativeFunc(r.typedArrayProto_find, nil, "find", nil, 1), true, false, true)
  1350. b._putProp("findIndex", r.newNativeFunc(r.typedArrayProto_findIndex, nil, "findIndex", nil, 1), true, false, true)
  1351. b._putProp("forEach", r.newNativeFunc(r.typedArrayProto_forEach, nil, "forEach", nil, 1), true, false, true)
  1352. b._putProp("includes", r.newNativeFunc(r.typedArrayProto_includes, nil, "includes", nil, 1), true, false, true)
  1353. b._putProp("indexOf", r.newNativeFunc(r.typedArrayProto_indexOf, nil, "indexOf", nil, 1), true, false, true)
  1354. b._putProp("join", r.newNativeFunc(r.typedArrayProto_join, nil, "join", nil, 1), true, false, true)
  1355. b._putProp("keys", r.newNativeFunc(r.typedArrayProto_keys, nil, "keys", nil, 0), true, false, true)
  1356. b._putProp("lastIndexOf", r.newNativeFunc(r.typedArrayProto_lastIndexOf, nil, "lastIndexOf", nil, 1), true, false, true)
  1357. b._put("length", &valueProperty{
  1358. accessor: true,
  1359. configurable: true,
  1360. getterFunc: r.newNativeFunc(r.typedArrayProto_getLength, nil, "get length", nil, 0),
  1361. })
  1362. b._putProp("map", r.newNativeFunc(r.typedArrayProto_map, nil, "map", nil, 1), true, false, true)
  1363. b._putProp("reduce", r.newNativeFunc(r.typedArrayProto_reduce, nil, "reduce", nil, 1), true, false, true)
  1364. b._putProp("reduceRight", r.newNativeFunc(r.typedArrayProto_reduceRight, nil, "reduceRight", nil, 1), true, false, true)
  1365. b._putProp("reverse", r.newNativeFunc(r.typedArrayProto_reverse, nil, "reverse", nil, 0), true, false, true)
  1366. b._putProp("set", r.newNativeFunc(r.typedArrayProto_set, nil, "set", nil, 1), true, false, true)
  1367. b._putProp("slice", r.newNativeFunc(r.typedArrayProto_slice, nil, "slice", nil, 2), true, false, true)
  1368. b._putProp("some", r.newNativeFunc(r.typedArrayProto_some, nil, "some", nil, 1), true, false, true)
  1369. b._putProp("sort", r.newNativeFunc(r.typedArrayProto_sort, nil, "sort", nil, 1), true, false, true)
  1370. b._putProp("subarray", r.newNativeFunc(r.typedArrayProto_subarray, nil, "subarray", nil, 2), true, false, true)
  1371. b._putProp("toLocaleString", r.newNativeFunc(r.typedArrayProto_toLocaleString, nil, "toLocaleString", nil, 0), true, false, true)
  1372. b._putProp("toString", r.global.arrayToString, true, false, true)
  1373. valuesFunc := r.newNativeFunc(r.typedArrayProto_values, nil, "values", nil, 0)
  1374. b._putProp("values", valuesFunc, true, false, true)
  1375. b._putSym(SymIterator, valueProp(valuesFunc, true, false, true))
  1376. b._putSym(SymToStringTag, &valueProperty{
  1377. getterFunc: r.newNativeFunc(r.typedArrayProto_toStringTag, nil, "get [Symbol.toStringTag]", nil, 0),
  1378. accessor: true,
  1379. configurable: true,
  1380. })
  1381. return b
  1382. }
  1383. func (r *Runtime) createTypedArray(val *Object) objectImpl {
  1384. o := r.newNativeConstructOnly(val, r.newTypedArray, r.global.TypedArrayPrototype, "TypedArray", 0)
  1385. o._putProp("from", r.newNativeFunc(r.typedArray_from, nil, "from", nil, 1), true, false, true)
  1386. o._putProp("of", r.newNativeFunc(r.typedArray_of, nil, "of", nil, 0), true, false, true)
  1387. r.putSpeciesReturnThis(o)
  1388. return o
  1389. }
  1390. func (r *Runtime) typedArrayCreator(ctor func(args []Value, newTarget, proto *Object) *Object, name unistring.String, bytesPerElement int) func(val *Object) objectImpl {
  1391. return func(val *Object) objectImpl {
  1392. p := r.newBaseObject(r.global.TypedArrayPrototype, classObject)
  1393. o := r.newNativeConstructOnly(val, func(args []Value, newTarget *Object) *Object {
  1394. return ctor(args, newTarget, p.val)
  1395. }, p.val, name, 3)
  1396. p._putProp("constructor", o.val, true, false, true)
  1397. o.prototype = r.global.TypedArray
  1398. bpe := intToValue(int64(bytesPerElement))
  1399. o._putProp("BYTES_PER_ELEMENT", bpe, false, false, false)
  1400. p._putProp("BYTES_PER_ELEMENT", bpe, false, false, false)
  1401. return o
  1402. }
  1403. }
  1404. func (r *Runtime) initTypedArrays() {
  1405. r.global.ArrayBufferPrototype = r.newLazyObject(r.createArrayBufferProto)
  1406. r.global.ArrayBuffer = r.newLazyObject(r.createArrayBuffer)
  1407. r.addToGlobal("ArrayBuffer", r.global.ArrayBuffer)
  1408. r.global.DataViewPrototype = r.newLazyObject(r.createDataViewProto)
  1409. r.global.DataView = r.newLazyObject(r.createDataView)
  1410. r.addToGlobal("DataView", r.global.DataView)
  1411. r.global.TypedArrayPrototype = r.newLazyObject(r.createTypedArrayProto)
  1412. r.global.TypedArray = r.newLazyObject(r.createTypedArray)
  1413. r.global.Uint8Array = r.newLazyObject(r.typedArrayCreator(r.newUint8Array, "Uint8Array", 1))
  1414. r.addToGlobal("Uint8Array", r.global.Uint8Array)
  1415. r.global.Uint8ClampedArray = r.newLazyObject(r.typedArrayCreator(r.newUint8ClampedArray, "Uint8ClampedArray", 1))
  1416. r.addToGlobal("Uint8ClampedArray", r.global.Uint8ClampedArray)
  1417. r.global.Int8Array = r.newLazyObject(r.typedArrayCreator(r.newInt8Array, "Int8Array", 1))
  1418. r.addToGlobal("Int8Array", r.global.Int8Array)
  1419. r.global.Uint16Array = r.newLazyObject(r.typedArrayCreator(r.newUint16Array, "Uint16Array", 2))
  1420. r.addToGlobal("Uint16Array", r.global.Uint16Array)
  1421. r.global.Int16Array = r.newLazyObject(r.typedArrayCreator(r.newInt16Array, "Int16Array", 2))
  1422. r.addToGlobal("Int16Array", r.global.Int16Array)
  1423. r.global.Uint32Array = r.newLazyObject(r.typedArrayCreator(r.newUint32Array, "Uint32Array", 4))
  1424. r.addToGlobal("Uint32Array", r.global.Uint32Array)
  1425. r.global.Int32Array = r.newLazyObject(r.typedArrayCreator(r.newInt32Array, "Int32Array", 4))
  1426. r.addToGlobal("Int32Array", r.global.Int32Array)
  1427. r.global.Float32Array = r.newLazyObject(r.typedArrayCreator(r.newFloat32Array, "Float32Array", 4))
  1428. r.addToGlobal("Float32Array", r.global.Float32Array)
  1429. r.global.Float64Array = r.newLazyObject(r.typedArrayCreator(r.newFloat64Array, "Float64Array", 8))
  1430. r.addToGlobal("Float64Array", r.global.Float64Array)
  1431. r.global.BigInt64Array = r.newLazyObject(r.typedArrayCreator(r.newBigInt64Array, "BigInt64Array", 8))
  1432. r.addToGlobal("BigInt64Array", r.global.BigInt64Array)
  1433. r.global.BigUint64Array = r.newLazyObject(r.typedArrayCreator(r.newBigUint64Array, "BigUint64Array", 8))
  1434. r.addToGlobal("BigUint64Array", r.global.BigUint64Array)
  1435. }