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