...

Source file src/github.com/dop251/goja/builtin_typedarrays.go

Documentation: github.com/dop251/goja

     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 // prevent underflow in toIntStrict() on 32-bit platforms
   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