builtin_typedarrays.go 51 KB

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