go.ketch.com/lib/goja@v0.0.1/builtin_typedarrays.go (about)

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