123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476 |
- package goja
- import (
- "fmt"
- "math"
- "sort"
- "unsafe"
- "github.com/dop251/goja/unistring"
- )
- type typedArraySortCtx struct {
- ta *typedArrayObject
- compare func(FunctionCall) Value
- needValidate bool
- }
- func (ctx *typedArraySortCtx) Len() int {
- return ctx.ta.length
- }
- func (ctx *typedArraySortCtx) Less(i, j int) bool {
- if ctx.needValidate {
- ctx.ta.viewedArrayBuf.ensureNotDetached(true)
- ctx.needValidate = false
- }
- offset := ctx.ta.offset
- if ctx.compare != nil {
- x := ctx.ta.typedArray.get(offset + i)
- y := ctx.ta.typedArray.get(offset + j)
- res := ctx.compare(FunctionCall{
- This: _undefined,
- Arguments: []Value{x, y},
- }).ToNumber()
- ctx.needValidate = true
- if i, ok := res.(valueInt); ok {
- return i < 0
- }
- f := res.ToFloat()
- if f < 0 {
- return true
- }
- if f > 0 {
- return false
- }
- if math.Signbit(f) {
- return true
- }
- return false
- }
- return ctx.ta.typedArray.less(offset+i, offset+j)
- }
- func (ctx *typedArraySortCtx) Swap(i, j int) {
- if ctx.needValidate {
- ctx.ta.viewedArrayBuf.ensureNotDetached(true)
- ctx.needValidate = false
- }
- offset := ctx.ta.offset
- ctx.ta.typedArray.swap(offset+i, offset+j)
- }
- func allocByteSlice(size int) (b []byte) {
- defer func() {
- if x := recover(); x != nil {
- panic(rangeError(fmt.Sprintf("Buffer size is too large: %d", size)))
- }
- }()
- if size < 0 {
- panic(rangeError(fmt.Sprintf("Invalid buffer size: %d", size)))
- }
- b = make([]byte, size)
- return
- }
- func (r *Runtime) builtin_newArrayBuffer(args []Value, newTarget *Object) *Object {
- if newTarget == nil {
- panic(r.needNew("ArrayBuffer"))
- }
- b := r._newArrayBuffer(r.getPrototypeFromCtor(newTarget, r.global.ArrayBuffer, r.global.ArrayBufferPrototype), nil)
- if len(args) > 0 {
- b.data = allocByteSlice(r.toIndex(args[0]))
- }
- return b.val
- }
- func (r *Runtime) arrayBufferProto_getByteLength(call FunctionCall) Value {
- o := r.toObject(call.This)
- if b, ok := o.self.(*arrayBufferObject); ok {
- if b.ensureNotDetached(false) {
- return intToValue(int64(len(b.data)))
- }
- return intToValue(0)
- }
- panic(r.NewTypeError("Object is not ArrayBuffer: %s", o))
- }
- func (r *Runtime) arrayBufferProto_slice(call FunctionCall) Value {
- o := r.toObject(call.This)
- if b, ok := o.self.(*arrayBufferObject); ok {
- l := int64(len(b.data))
- start := relToIdx(call.Argument(0).ToInteger(), l)
- var stop int64
- if arg := call.Argument(1); arg != _undefined {
- stop = arg.ToInteger()
- } else {
- stop = l
- }
- stop = relToIdx(stop, l)
- newLen := max(stop-start, 0)
- ret := r.speciesConstructor(o, r.global.ArrayBuffer)([]Value{intToValue(newLen)}, nil)
- if ab, ok := ret.self.(*arrayBufferObject); ok {
- if newLen > 0 {
- b.ensureNotDetached(true)
- if ret == o {
- panic(r.NewTypeError("Species constructor returned the same ArrayBuffer"))
- }
- if int64(len(ab.data)) < newLen {
- panic(r.NewTypeError("Species constructor returned an ArrayBuffer that is too small: %d", len(ab.data)))
- }
- ab.ensureNotDetached(true)
- copy(ab.data, b.data[start:stop])
- }
- return ret
- }
- panic(r.NewTypeError("Species constructor did not return an ArrayBuffer: %s", ret.String()))
- }
- panic(r.NewTypeError("Object is not ArrayBuffer: %s", o))
- }
- func (r *Runtime) arrayBuffer_isView(call FunctionCall) Value {
- if o, ok := call.Argument(0).(*Object); ok {
- if _, ok := o.self.(*dataViewObject); ok {
- return valueTrue
- }
- if _, ok := o.self.(*typedArrayObject); ok {
- return valueTrue
- }
- }
- return valueFalse
- }
- func (r *Runtime) newDataView(args []Value, newTarget *Object) *Object {
- if newTarget == nil {
- panic(r.needNew("DataView"))
- }
- proto := r.getPrototypeFromCtor(newTarget, r.global.DataView, r.global.DataViewPrototype)
- var bufArg Value
- if len(args) > 0 {
- bufArg = args[0]
- }
- var buffer *arrayBufferObject
- if o, ok := bufArg.(*Object); ok {
- if b, ok := o.self.(*arrayBufferObject); ok {
- buffer = b
- }
- }
- if buffer == nil {
- panic(r.NewTypeError("First argument to DataView constructor must be an ArrayBuffer"))
- }
- var byteOffset, byteLen int
- if len(args) > 1 {
- offsetArg := nilSafe(args[1])
- byteOffset = r.toIndex(offsetArg)
- buffer.ensureNotDetached(true)
- if byteOffset > len(buffer.data) {
- panic(r.newError(r.global.RangeError, "Start offset %s is outside the bounds of the buffer", offsetArg.String()))
- }
- }
- if len(args) > 2 && args[2] != nil && args[2] != _undefined {
- byteLen = r.toIndex(args[2])
- if byteOffset+byteLen > len(buffer.data) {
- panic(r.newError(r.global.RangeError, "Invalid DataView length %d", byteLen))
- }
- } else {
- byteLen = len(buffer.data) - byteOffset
- }
- o := &Object{runtime: r}
- b := &dataViewObject{
- baseObject: baseObject{
- class: classObject,
- val: o,
- prototype: proto,
- extensible: true,
- },
- viewedArrayBuf: buffer,
- byteOffset: byteOffset,
- byteLen: byteLen,
- }
- o.self = b
- b.init()
- return o
- }
- func (r *Runtime) dataViewProto_getBuffer(call FunctionCall) Value {
- if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
- return dv.viewedArrayBuf.val
- }
- panic(r.NewTypeError("Method get DataView.prototype.buffer called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) dataViewProto_getByteLen(call FunctionCall) Value {
- if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
- dv.viewedArrayBuf.ensureNotDetached(true)
- return intToValue(int64(dv.byteLen))
- }
- panic(r.NewTypeError("Method get DataView.prototype.byteLength called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) dataViewProto_getByteOffset(call FunctionCall) Value {
- if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
- dv.viewedArrayBuf.ensureNotDetached(true)
- return intToValue(int64(dv.byteOffset))
- }
- panic(r.NewTypeError("Method get DataView.prototype.byteOffset called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) dataViewProto_getFloat32(call FunctionCall) Value {
- if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
- return floatToValue(float64(dv.viewedArrayBuf.getFloat32(dv.getIdxAndByteOrder(call.Argument(0), call.Argument(1), 4))))
- }
- panic(r.NewTypeError("Method DataView.prototype.getFloat32 called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) dataViewProto_getFloat64(call FunctionCall) Value {
- if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
- return floatToValue(dv.viewedArrayBuf.getFloat64(dv.getIdxAndByteOrder(call.Argument(0), call.Argument(1), 8)))
- }
- panic(r.NewTypeError("Method DataView.prototype.getFloat64 called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) dataViewProto_getInt8(call FunctionCall) Value {
- if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
- idx, _ := dv.getIdxAndByteOrder(call.Argument(0), call.Argument(1), 1)
- return intToValue(int64(dv.viewedArrayBuf.getInt8(idx)))
- }
- panic(r.NewTypeError("Method DataView.prototype.getInt8 called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) dataViewProto_getInt16(call FunctionCall) Value {
- if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
- return intToValue(int64(dv.viewedArrayBuf.getInt16(dv.getIdxAndByteOrder(call.Argument(0), call.Argument(1), 2))))
- }
- panic(r.NewTypeError("Method DataView.prototype.getInt16 called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) dataViewProto_getInt32(call FunctionCall) Value {
- if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
- return intToValue(int64(dv.viewedArrayBuf.getInt32(dv.getIdxAndByteOrder(call.Argument(0), call.Argument(1), 4))))
- }
- panic(r.NewTypeError("Method DataView.prototype.getInt32 called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) dataViewProto_getUint8(call FunctionCall) Value {
- if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
- idx, _ := dv.getIdxAndByteOrder(call.Argument(0), call.Argument(1), 1)
- return intToValue(int64(dv.viewedArrayBuf.getUint8(idx)))
- }
- panic(r.NewTypeError("Method DataView.prototype.getUint8 called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) dataViewProto_getUint16(call FunctionCall) Value {
- if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
- return intToValue(int64(dv.viewedArrayBuf.getUint16(dv.getIdxAndByteOrder(call.Argument(0), call.Argument(1), 2))))
- }
- panic(r.NewTypeError("Method DataView.prototype.getUint16 called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) dataViewProto_getUint32(call FunctionCall) Value {
- if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
- return intToValue(int64(dv.viewedArrayBuf.getUint32(dv.getIdxAndByteOrder(call.Argument(0), call.Argument(1), 4))))
- }
- panic(r.NewTypeError("Method DataView.prototype.getUint32 called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) dataViewProto_setFloat32(call FunctionCall) Value {
- if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
- val := toFloat32(call.Argument(1))
- idx, bo := dv.getIdxAndByteOrder(call.Argument(0), call.Argument(2), 4)
- dv.viewedArrayBuf.setFloat32(idx, val, bo)
- return _undefined
- }
- panic(r.NewTypeError("Method DataView.prototype.setFloat32 called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) dataViewProto_setFloat64(call FunctionCall) Value {
- if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
- val := call.Argument(1).ToFloat()
- idx, bo := dv.getIdxAndByteOrder(call.Argument(0), call.Argument(2), 8)
- dv.viewedArrayBuf.setFloat64(idx, val, bo)
- return _undefined
- }
- panic(r.NewTypeError("Method DataView.prototype.setFloat64 called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) dataViewProto_setInt8(call FunctionCall) Value {
- if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
- val := toInt8(call.Argument(1))
- idx, _ := dv.getIdxAndByteOrder(call.Argument(0), call.Argument(2), 1)
- dv.viewedArrayBuf.setInt8(idx, val)
- return _undefined
- }
- panic(r.NewTypeError("Method DataView.prototype.setInt8 called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) dataViewProto_setInt16(call FunctionCall) Value {
- if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
- val := toInt16(call.Argument(1))
- idx, bo := dv.getIdxAndByteOrder(call.Argument(0), call.Argument(2), 2)
- dv.viewedArrayBuf.setInt16(idx, val, bo)
- return _undefined
- }
- panic(r.NewTypeError("Method DataView.prototype.setInt16 called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) dataViewProto_setInt32(call FunctionCall) Value {
- if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
- val := toInt32(call.Argument(1))
- idx, bo := dv.getIdxAndByteOrder(call.Argument(0), call.Argument(2), 4)
- dv.viewedArrayBuf.setInt32(idx, val, bo)
- return _undefined
- }
- panic(r.NewTypeError("Method DataView.prototype.setInt32 called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) dataViewProto_setUint8(call FunctionCall) Value {
- if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
- val := toUint8(call.Argument(1))
- idx, _ := dv.getIdxAndByteOrder(call.Argument(0), call.Argument(2), 1)
- dv.viewedArrayBuf.setUint8(idx, val)
- return _undefined
- }
- panic(r.NewTypeError("Method DataView.prototype.setUint8 called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) dataViewProto_setUint16(call FunctionCall) Value {
- if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
- val := toUint16(call.Argument(1))
- idx, bo := dv.getIdxAndByteOrder(call.Argument(0), call.Argument(2), 2)
- dv.viewedArrayBuf.setUint16(idx, val, bo)
- return _undefined
- }
- panic(r.NewTypeError("Method DataView.prototype.setUint16 called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) dataViewProto_setUint32(call FunctionCall) Value {
- if dv, ok := r.toObject(call.This).self.(*dataViewObject); ok {
- val := toUint32(call.Argument(1))
- idx, bo := dv.getIdxAndByteOrder(call.Argument(0), call.Argument(2), 4)
- dv.viewedArrayBuf.setUint32(idx, val, bo)
- return _undefined
- }
- panic(r.NewTypeError("Method DataView.prototype.setUint32 called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) typedArrayProto_getBuffer(call FunctionCall) Value {
- if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
- return ta.viewedArrayBuf.val
- }
- panic(r.NewTypeError("Method get TypedArray.prototype.buffer called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) typedArrayProto_getByteLen(call FunctionCall) Value {
- if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
- if ta.viewedArrayBuf.data == nil {
- return _positiveZero
- }
- return intToValue(int64(ta.length) * int64(ta.elemSize))
- }
- panic(r.NewTypeError("Method get TypedArray.prototype.byteLength called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) typedArrayProto_getLength(call FunctionCall) Value {
- if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
- if ta.viewedArrayBuf.data == nil {
- return _positiveZero
- }
- return intToValue(int64(ta.length))
- }
- panic(r.NewTypeError("Method get TypedArray.prototype.length called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) typedArrayProto_getByteOffset(call FunctionCall) Value {
- if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
- if ta.viewedArrayBuf.data == nil {
- return _positiveZero
- }
- return intToValue(int64(ta.offset) * int64(ta.elemSize))
- }
- panic(r.NewTypeError("Method get TypedArray.prototype.byteOffset called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) typedArrayProto_copyWithin(call FunctionCall) Value {
- if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
- ta.viewedArrayBuf.ensureNotDetached(true)
- l := int64(ta.length)
- var relEnd int64
- to := toIntStrict(relToIdx(call.Argument(0).ToInteger(), l))
- from := toIntStrict(relToIdx(call.Argument(1).ToInteger(), l))
- if end := call.Argument(2); end != _undefined {
- relEnd = end.ToInteger()
- } else {
- relEnd = l
- }
- final := toIntStrict(relToIdx(relEnd, l))
- data := ta.viewedArrayBuf.data
- offset := ta.offset
- elemSize := ta.elemSize
- if final > from {
- ta.viewedArrayBuf.ensureNotDetached(true)
- copy(data[(offset+to)*elemSize:], data[(offset+from)*elemSize:(offset+final)*elemSize])
- }
- return call.This
- }
- panic(r.NewTypeError("Method TypedArray.prototype.copyWithin called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) typedArrayProto_entries(call FunctionCall) Value {
- if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
- ta.viewedArrayBuf.ensureNotDetached(true)
- return r.createArrayIterator(ta.val, iterationKindKeyValue)
- }
- panic(r.NewTypeError("Method TypedArray.prototype.entries called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) typedArrayProto_every(call FunctionCall) Value {
- if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
- ta.viewedArrayBuf.ensureNotDetached(true)
- callbackFn := r.toCallable(call.Argument(0))
- fc := FunctionCall{
- This: call.Argument(1),
- Arguments: []Value{nil, nil, call.This},
- }
- for k := 0; k < ta.length; k++ {
- if ta.isValidIntegerIndex(k) {
- fc.Arguments[0] = ta.typedArray.get(ta.offset + k)
- } else {
- fc.Arguments[0] = _undefined
- }
- fc.Arguments[1] = intToValue(int64(k))
- if !callbackFn(fc).ToBoolean() {
- return valueFalse
- }
- }
- return valueTrue
- }
- panic(r.NewTypeError("Method TypedArray.prototype.every called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) typedArrayProto_fill(call FunctionCall) Value {
- if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
- ta.viewedArrayBuf.ensureNotDetached(true)
- l := int64(ta.length)
- k := toIntStrict(relToIdx(call.Argument(1).ToInteger(), l))
- var relEnd int64
- if endArg := call.Argument(2); endArg != _undefined {
- relEnd = endArg.ToInteger()
- } else {
- relEnd = l
- }
- final := toIntStrict(relToIdx(relEnd, l))
- value := ta.typedArray.toRaw(call.Argument(0))
- ta.viewedArrayBuf.ensureNotDetached(true)
- for ; k < final; k++ {
- ta.typedArray.setRaw(ta.offset+k, value)
- }
- return call.This
- }
- panic(r.NewTypeError("Method TypedArray.prototype.fill called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) typedArrayProto_filter(call FunctionCall) Value {
- o := r.toObject(call.This)
- if ta, ok := o.self.(*typedArrayObject); ok {
- ta.viewedArrayBuf.ensureNotDetached(true)
- callbackFn := r.toCallable(call.Argument(0))
- fc := FunctionCall{
- This: call.Argument(1),
- Arguments: []Value{nil, nil, call.This},
- }
- buf := make([]byte, 0, ta.length*ta.elemSize)
- captured := 0
- rawVal := make([]byte, ta.elemSize)
- for k := 0; k < ta.length; k++ {
- if ta.isValidIntegerIndex(k) {
- fc.Arguments[0] = ta.typedArray.get(ta.offset + k)
- i := (ta.offset + k) * ta.elemSize
- copy(rawVal, ta.viewedArrayBuf.data[i:])
- } else {
- fc.Arguments[0] = _undefined
- for i := range rawVal {
- rawVal[i] = 0
- }
- }
- fc.Arguments[1] = intToValue(int64(k))
- if callbackFn(fc).ToBoolean() {
- buf = append(buf, rawVal...)
- captured++
- }
- }
- c := r.speciesConstructorObj(o, ta.defaultCtor)
- ab := r._newArrayBuffer(r.global.ArrayBufferPrototype, nil)
- ab.data = buf
- kept := r.toConstructor(ta.defaultCtor)([]Value{ab.val}, ta.defaultCtor)
- if c == ta.defaultCtor {
- return kept
- } else {
- ret := r.typedArrayCreate(c, []Value{intToValue(int64(captured))})
- keptTa := kept.self.(*typedArrayObject)
- for i := 0; i < captured; i++ {
- ret.typedArray.set(i, keptTa.typedArray.get(keptTa.offset+i))
- }
- return ret.val
- }
- }
- panic(r.NewTypeError("Method TypedArray.prototype.filter called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) typedArrayProto_find(call FunctionCall) Value {
- if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
- ta.viewedArrayBuf.ensureNotDetached(true)
- predicate := r.toCallable(call.Argument(0))
- fc := FunctionCall{
- This: call.Argument(1),
- Arguments: []Value{nil, nil, call.This},
- }
- for k := 0; k < ta.length; k++ {
- var val Value
- if ta.isValidIntegerIndex(k) {
- val = ta.typedArray.get(ta.offset + k)
- }
- fc.Arguments[0] = val
- fc.Arguments[1] = intToValue(int64(k))
- if predicate(fc).ToBoolean() {
- return val
- }
- }
- return _undefined
- }
- panic(r.NewTypeError("Method TypedArray.prototype.find called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) typedArrayProto_findIndex(call FunctionCall) Value {
- if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
- ta.viewedArrayBuf.ensureNotDetached(true)
- predicate := r.toCallable(call.Argument(0))
- fc := FunctionCall{
- This: call.Argument(1),
- Arguments: []Value{nil, nil, call.This},
- }
- for k := 0; k < ta.length; k++ {
- if ta.isValidIntegerIndex(k) {
- fc.Arguments[0] = ta.typedArray.get(ta.offset + k)
- } else {
- fc.Arguments[0] = _undefined
- }
- fc.Arguments[1] = intToValue(int64(k))
- if predicate(fc).ToBoolean() {
- return fc.Arguments[1]
- }
- }
- return intToValue(-1)
- }
- panic(r.NewTypeError("Method TypedArray.prototype.findIndex called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) typedArrayProto_forEach(call FunctionCall) Value {
- if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
- ta.viewedArrayBuf.ensureNotDetached(true)
- callbackFn := r.toCallable(call.Argument(0))
- fc := FunctionCall{
- This: call.Argument(1),
- Arguments: []Value{nil, nil, call.This},
- }
- for k := 0; k < ta.length; k++ {
- var val Value
- if ta.isValidIntegerIndex(k) {
- val = ta.typedArray.get(ta.offset + k)
- }
- fc.Arguments[0] = val
- fc.Arguments[1] = intToValue(int64(k))
- callbackFn(fc)
- }
- return _undefined
- }
- panic(r.NewTypeError("Method TypedArray.prototype.forEach called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) typedArrayProto_includes(call FunctionCall) Value {
- if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
- ta.viewedArrayBuf.ensureNotDetached(true)
- length := int64(ta.length)
- if length == 0 {
- return valueFalse
- }
- n := call.Argument(1).ToInteger()
- if n >= length {
- return valueFalse
- }
- if n < 0 {
- n = max(length+n, 0)
- }
- searchElement := call.Argument(0)
- if searchElement == _negativeZero {
- searchElement = _positiveZero
- }
- startIdx := toIntStrict(n)
- if !ta.viewedArrayBuf.ensureNotDetached(false) {
- if searchElement == _undefined && startIdx < ta.length {
- return valueTrue
- }
- return valueFalse
- }
- if ta.typedArray.typeMatch(searchElement) {
- se := ta.typedArray.toRaw(searchElement)
- for k := startIdx; k < ta.length; k++ {
- if ta.typedArray.getRaw(ta.offset+k) == se {
- return valueTrue
- }
- }
- }
- return valueFalse
- }
- panic(r.NewTypeError("Method TypedArray.prototype.includes called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) typedArrayProto_indexOf(call FunctionCall) Value {
- if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
- ta.viewedArrayBuf.ensureNotDetached(true)
- length := int64(ta.length)
- if length == 0 {
- return intToValue(-1)
- }
- n := call.Argument(1).ToInteger()
- if n >= length {
- return intToValue(-1)
- }
- if n < 0 {
- n = max(length+n, 0)
- }
- if ta.viewedArrayBuf.ensureNotDetached(false) {
- searchElement := call.Argument(0)
- if searchElement == _negativeZero {
- searchElement = _positiveZero
- }
- if !IsNaN(searchElement) && ta.typedArray.typeMatch(searchElement) {
- se := ta.typedArray.toRaw(searchElement)
- for k := toIntStrict(n); k < ta.length; k++ {
- if ta.typedArray.getRaw(ta.offset+k) == se {
- return intToValue(int64(k))
- }
- }
- }
- }
- return intToValue(-1)
- }
- panic(r.NewTypeError("Method TypedArray.prototype.indexOf called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) typedArrayProto_join(call FunctionCall) Value {
- if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
- ta.viewedArrayBuf.ensureNotDetached(true)
- s := call.Argument(0)
- var sep valueString
- if s != _undefined {
- sep = s.toString()
- } else {
- sep = asciiString(",")
- }
- l := ta.length
- if l == 0 {
- return stringEmpty
- }
- var buf valueStringBuilder
- var element0 Value
- if ta.isValidIntegerIndex(0) {
- element0 = ta.typedArray.get(ta.offset + 0)
- }
- if element0 != nil && element0 != _undefined && element0 != _null {
- buf.WriteString(element0.toString())
- }
- for i := 1; i < l; i++ {
- buf.WriteString(sep)
- if ta.isValidIntegerIndex(i) {
- element := ta.typedArray.get(ta.offset + i)
- if element != nil && element != _undefined && element != _null {
- buf.WriteString(element.toString())
- }
- }
- }
- return buf.String()
- }
- panic(r.NewTypeError("Method TypedArray.prototype.join called on incompatible receiver"))
- }
- func (r *Runtime) typedArrayProto_keys(call FunctionCall) Value {
- if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
- ta.viewedArrayBuf.ensureNotDetached(true)
- return r.createArrayIterator(ta.val, iterationKindKey)
- }
- panic(r.NewTypeError("Method TypedArray.prototype.keys called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) typedArrayProto_lastIndexOf(call FunctionCall) Value {
- if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
- ta.viewedArrayBuf.ensureNotDetached(true)
- length := int64(ta.length)
- if length == 0 {
- return intToValue(-1)
- }
- var fromIndex int64
- if len(call.Arguments) < 2 {
- fromIndex = length - 1
- } else {
- fromIndex = call.Argument(1).ToInteger()
- if fromIndex >= 0 {
- fromIndex = min(fromIndex, length-1)
- } else {
- fromIndex += length
- if fromIndex < 0 {
- fromIndex = -1 // prevent underflow in toIntStrict() on 32-bit platforms
- }
- }
- }
- if ta.viewedArrayBuf.ensureNotDetached(false) {
- searchElement := call.Argument(0)
- if searchElement == _negativeZero {
- searchElement = _positiveZero
- }
- if !IsNaN(searchElement) && ta.typedArray.typeMatch(searchElement) {
- se := ta.typedArray.toRaw(searchElement)
- for k := toIntStrict(fromIndex); k >= 0; k-- {
- if ta.typedArray.getRaw(ta.offset+k) == se {
- return intToValue(int64(k))
- }
- }
- }
- }
- return intToValue(-1)
- }
- panic(r.NewTypeError("Method TypedArray.prototype.lastIndexOf called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) typedArrayProto_map(call FunctionCall) Value {
- if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
- ta.viewedArrayBuf.ensureNotDetached(true)
- callbackFn := r.toCallable(call.Argument(0))
- fc := FunctionCall{
- This: call.Argument(1),
- Arguments: []Value{nil, nil, call.This},
- }
- dst := r.typedArraySpeciesCreate(ta, []Value{intToValue(int64(ta.length))})
- for i := 0; i < ta.length; i++ {
- if ta.isValidIntegerIndex(i) {
- fc.Arguments[0] = ta.typedArray.get(ta.offset + i)
- } else {
- fc.Arguments[0] = _undefined
- }
- fc.Arguments[1] = intToValue(int64(i))
- dst.typedArray.set(i, callbackFn(fc))
- }
- return dst.val
- }
- panic(r.NewTypeError("Method TypedArray.prototype.map called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) typedArrayProto_reduce(call FunctionCall) Value {
- if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
- ta.viewedArrayBuf.ensureNotDetached(true)
- callbackFn := r.toCallable(call.Argument(0))
- fc := FunctionCall{
- This: _undefined,
- Arguments: []Value{nil, nil, nil, call.This},
- }
- k := 0
- if len(call.Arguments) >= 2 {
- fc.Arguments[0] = call.Argument(1)
- } else {
- if ta.length > 0 {
- fc.Arguments[0] = ta.typedArray.get(ta.offset + 0)
- k = 1
- }
- }
- if fc.Arguments[0] == nil {
- panic(r.NewTypeError("Reduce of empty array with no initial value"))
- }
- for ; k < ta.length; k++ {
- if ta.isValidIntegerIndex(k) {
- fc.Arguments[1] = ta.typedArray.get(ta.offset + k)
- } else {
- fc.Arguments[1] = _undefined
- }
- idx := valueInt(k)
- fc.Arguments[2] = idx
- fc.Arguments[0] = callbackFn(fc)
- }
- return fc.Arguments[0]
- }
- panic(r.NewTypeError("Method TypedArray.prototype.reduce called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) typedArrayProto_reduceRight(call FunctionCall) Value {
- if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
- ta.viewedArrayBuf.ensureNotDetached(true)
- callbackFn := r.toCallable(call.Argument(0))
- fc := FunctionCall{
- This: _undefined,
- Arguments: []Value{nil, nil, nil, call.This},
- }
- k := ta.length - 1
- if len(call.Arguments) >= 2 {
- fc.Arguments[0] = call.Argument(1)
- } else {
- if k >= 0 {
- fc.Arguments[0] = ta.typedArray.get(ta.offset + k)
- k--
- }
- }
- if fc.Arguments[0] == nil {
- panic(r.NewTypeError("Reduce of empty array with no initial value"))
- }
- for ; k >= 0; k-- {
- if ta.isValidIntegerIndex(k) {
- fc.Arguments[1] = ta.typedArray.get(ta.offset + k)
- } else {
- fc.Arguments[1] = _undefined
- }
- idx := valueInt(k)
- fc.Arguments[2] = idx
- fc.Arguments[0] = callbackFn(fc)
- }
- return fc.Arguments[0]
- }
- panic(r.NewTypeError("Method TypedArray.prototype.reduceRight called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) typedArrayProto_reverse(call FunctionCall) Value {
- if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
- ta.viewedArrayBuf.ensureNotDetached(true)
- l := ta.length
- middle := l / 2
- for lower := 0; lower != middle; lower++ {
- upper := l - lower - 1
- ta.typedArray.swap(ta.offset+lower, ta.offset+upper)
- }
- return call.This
- }
- panic(r.NewTypeError("Method TypedArray.prototype.reverse called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) typedArrayProto_set(call FunctionCall) Value {
- if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
- srcObj := call.Argument(0).ToObject(r)
- targetOffset := toIntStrict(call.Argument(1).ToInteger())
- if targetOffset < 0 {
- panic(r.newError(r.global.RangeError, "offset should be >= 0"))
- }
- ta.viewedArrayBuf.ensureNotDetached(true)
- targetLen := ta.length
- if src, ok := srcObj.self.(*typedArrayObject); ok {
- src.viewedArrayBuf.ensureNotDetached(true)
- srcLen := src.length
- if x := srcLen + targetOffset; x < 0 || x > targetLen {
- panic(r.newError(r.global.RangeError, "Source is too large"))
- }
- if src.defaultCtor == ta.defaultCtor {
- copy(ta.viewedArrayBuf.data[(ta.offset+targetOffset)*ta.elemSize:],
- src.viewedArrayBuf.data[src.offset*src.elemSize:(src.offset+srcLen)*src.elemSize])
- } else {
- curSrc := uintptr(unsafe.Pointer(&src.viewedArrayBuf.data[src.offset*src.elemSize]))
- endSrc := curSrc + uintptr(srcLen*src.elemSize)
- curDst := uintptr(unsafe.Pointer(&ta.viewedArrayBuf.data[(ta.offset+targetOffset)*ta.elemSize]))
- dstOffset := ta.offset + targetOffset
- srcOffset := src.offset
- if ta.elemSize == src.elemSize {
- if curDst <= curSrc || curDst >= endSrc {
- for i := 0; i < srcLen; i++ {
- ta.typedArray.set(dstOffset+i, src.typedArray.get(srcOffset+i))
- }
- } else {
- for i := srcLen - 1; i >= 0; i-- {
- ta.typedArray.set(dstOffset+i, src.typedArray.get(srcOffset+i))
- }
- }
- } else {
- x := int(curDst-curSrc) / (src.elemSize - ta.elemSize)
- if x < 0 {
- x = 0
- } else if x > srcLen {
- x = srcLen
- }
- if ta.elemSize < src.elemSize {
- for i := x; i < srcLen; i++ {
- ta.typedArray.set(dstOffset+i, src.typedArray.get(srcOffset+i))
- }
- for i := x - 1; i >= 0; i-- {
- ta.typedArray.set(dstOffset+i, src.typedArray.get(srcOffset+i))
- }
- } else {
- for i := 0; i < x; i++ {
- ta.typedArray.set(dstOffset+i, src.typedArray.get(srcOffset+i))
- }
- for i := srcLen - 1; i >= x; i-- {
- ta.typedArray.set(dstOffset+i, src.typedArray.get(srcOffset+i))
- }
- }
- }
- }
- } else {
- targetLen := ta.length
- srcLen := toIntStrict(toLength(srcObj.self.getStr("length", nil)))
- if x := srcLen + targetOffset; x < 0 || x > targetLen {
- panic(r.newError(r.global.RangeError, "Source is too large"))
- }
- for i := 0; i < srcLen; i++ {
- val := nilSafe(srcObj.self.getIdx(valueInt(i), nil))
- ta.viewedArrayBuf.ensureNotDetached(true)
- if ta.isValidIntegerIndex(i) {
- ta.typedArray.set(targetOffset+i, val)
- }
- }
- }
- return _undefined
- }
- panic(r.NewTypeError("Method TypedArray.prototype.set called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) typedArrayProto_slice(call FunctionCall) Value {
- if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
- ta.viewedArrayBuf.ensureNotDetached(true)
- length := int64(ta.length)
- start := toIntStrict(relToIdx(call.Argument(0).ToInteger(), length))
- var e int64
- if endArg := call.Argument(1); endArg != _undefined {
- e = endArg.ToInteger()
- } else {
- e = length
- }
- end := toIntStrict(relToIdx(e, length))
- count := end - start
- if count < 0 {
- count = 0
- }
- dst := r.typedArraySpeciesCreate(ta, []Value{intToValue(int64(count))})
- if dst.defaultCtor == ta.defaultCtor {
- if count > 0 {
- ta.viewedArrayBuf.ensureNotDetached(true)
- offset := ta.offset
- elemSize := ta.elemSize
- copy(dst.viewedArrayBuf.data, ta.viewedArrayBuf.data[(offset+start)*elemSize:(offset+start+count)*elemSize])
- }
- } else {
- for i := 0; i < count; i++ {
- ta.viewedArrayBuf.ensureNotDetached(true)
- dst.typedArray.set(i, ta.typedArray.get(ta.offset+start+i))
- }
- }
- return dst.val
- }
- panic(r.NewTypeError("Method TypedArray.prototype.slice called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) typedArrayProto_some(call FunctionCall) Value {
- if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
- ta.viewedArrayBuf.ensureNotDetached(true)
- callbackFn := r.toCallable(call.Argument(0))
- fc := FunctionCall{
- This: call.Argument(1),
- Arguments: []Value{nil, nil, call.This},
- }
- for k := 0; k < ta.length; k++ {
- if ta.isValidIntegerIndex(k) {
- fc.Arguments[0] = ta.typedArray.get(ta.offset + k)
- } else {
- fc.Arguments[0] = _undefined
- }
- fc.Arguments[1] = intToValue(int64(k))
- if callbackFn(fc).ToBoolean() {
- return valueTrue
- }
- }
- return valueFalse
- }
- panic(r.NewTypeError("Method TypedArray.prototype.some called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) typedArrayProto_sort(call FunctionCall) Value {
- if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
- ta.viewedArrayBuf.ensureNotDetached(true)
- var compareFn func(FunctionCall) Value
- if arg := call.Argument(0); arg != _undefined {
- compareFn = r.toCallable(arg)
- }
- ctx := typedArraySortCtx{
- ta: ta,
- compare: compareFn,
- }
- sort.Stable(&ctx)
- return call.This
- }
- panic(r.NewTypeError("Method TypedArray.prototype.sort called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) typedArrayProto_subarray(call FunctionCall) Value {
- if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
- l := int64(ta.length)
- beginIdx := relToIdx(call.Argument(0).ToInteger(), l)
- var relEnd int64
- if endArg := call.Argument(1); endArg != _undefined {
- relEnd = endArg.ToInteger()
- } else {
- relEnd = l
- }
- endIdx := relToIdx(relEnd, l)
- newLen := max(endIdx-beginIdx, 0)
- return r.typedArraySpeciesCreate(ta, []Value{ta.viewedArrayBuf.val,
- intToValue((int64(ta.offset) + beginIdx) * int64(ta.elemSize)),
- intToValue(newLen),
- }).val
- }
- panic(r.NewTypeError("Method TypedArray.prototype.subarray called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) typedArrayProto_toLocaleString(call FunctionCall) Value {
- if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
- length := ta.length
- var buf valueStringBuilder
- for i := 0; i < length; i++ {
- ta.viewedArrayBuf.ensureNotDetached(true)
- if i > 0 {
- buf.WriteRune(',')
- }
- item := ta.typedArray.get(ta.offset + i)
- r.writeItemLocaleString(item, &buf)
- }
- return buf.String()
- }
- panic(r.NewTypeError("Method TypedArray.prototype.toLocaleString called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) typedArrayProto_values(call FunctionCall) Value {
- if ta, ok := r.toObject(call.This).self.(*typedArrayObject); ok {
- ta.viewedArrayBuf.ensureNotDetached(true)
- return r.createArrayIterator(ta.val, iterationKindValue)
- }
- panic(r.NewTypeError("Method TypedArray.prototype.values called on incompatible receiver %s", call.This.String()))
- }
- func (r *Runtime) typedArrayProto_toStringTag(call FunctionCall) Value {
- if obj, ok := call.This.(*Object); ok {
- if ta, ok := obj.self.(*typedArrayObject); ok {
- return nilSafe(ta.defaultCtor.self.getStr("name", nil))
- }
- }
- return _undefined
- }
- func (r *Runtime) newTypedArray([]Value, *Object) *Object {
- panic(r.NewTypeError("Abstract class TypedArray not directly constructable"))
- }
- func (r *Runtime) typedArray_from(call FunctionCall) Value {
- mapFn := call.Argument(1)
- if mapFn == _undefined {
- mapFn = nil
- }
- return r.typedArrayFrom(r.toObject(call.This), call.Argument(0).ToObject(r), mapFn, call.Argument(2))
- }
- func (r *Runtime) typedArray_of(call FunctionCall) Value {
- ta := r.typedArrayCreate(r.toObject(call.This), []Value{intToValue(int64(len(call.Arguments)))})
- for i, val := range call.Arguments {
- ta.typedArray.set(i, val)
- }
- return ta.val
- }
- func (r *Runtime) allocateTypedArray(newTarget *Object, length int, taCtor typedArrayObjectCtor) *Object {
- buf := r._newArrayBuffer(r.global.ArrayBufferPrototype, nil)
- ta := taCtor(buf, 0, length, r.getPrototypeFromCtor(newTarget, nil, r.global.TypedArrayPrototype))
- if length > 0 {
- buf.data = allocByteSlice(length * ta.elemSize)
- }
- return ta.val
- }
- func (r *Runtime) typedArraySpeciesCreate(ta *typedArrayObject, args []Value) *typedArrayObject {
- return r.typedArrayCreate(r.speciesConstructorObj(ta.val, ta.defaultCtor), args)
- }
- func (r *Runtime) typedArrayCreate(ctor *Object, args []Value) *typedArrayObject {
- o := r.toConstructor(ctor)(args, ctor)
- if ta, ok := o.self.(*typedArrayObject); ok {
- ta.viewedArrayBuf.ensureNotDetached(true)
- if len(args) == 1 {
- if l, ok := args[0].(valueInt); ok {
- if ta.length < int(l) {
- panic(r.NewTypeError("Derived TypedArray constructor created an array which was too small"))
- }
- }
- }
- return ta
- }
- panic(r.NewTypeError("Invalid TypedArray: %s", o))
- }
- func (r *Runtime) typedArrayFrom(ctor, items *Object, mapFn, thisValue Value) *Object {
- var mapFc func(call FunctionCall) Value
- if mapFn != nil {
- mapFc = r.toCallable(mapFn)
- if thisValue == nil {
- thisValue = _undefined
- }
- }
- usingIter := toMethod(items.self.getSym(SymIterator, nil))
- if usingIter != nil {
- values := r.iterableToList(items, usingIter)
- ta := r.typedArrayCreate(ctor, []Value{intToValue(int64(len(values)))})
- if mapFc == nil {
- for idx, val := range values {
- ta.typedArray.set(idx, val)
- }
- } else {
- fc := FunctionCall{
- This: thisValue,
- Arguments: []Value{nil, nil},
- }
- for idx, val := range values {
- fc.Arguments[0], fc.Arguments[1] = val, intToValue(int64(idx))
- val = mapFc(fc)
- ta.typedArray.set(idx, val)
- }
- }
- return ta.val
- }
- length := toIntStrict(toLength(items.self.getStr("length", nil)))
- ta := r.typedArrayCreate(ctor, []Value{intToValue(int64(length))})
- if mapFc == nil {
- for i := 0; i < length; i++ {
- ta.typedArray.set(i, nilSafe(items.self.getIdx(valueInt(i), nil)))
- }
- } else {
- fc := FunctionCall{
- This: thisValue,
- Arguments: []Value{nil, nil},
- }
- for i := 0; i < length; i++ {
- idx := valueInt(i)
- fc.Arguments[0], fc.Arguments[1] = items.self.getIdx(idx, nil), idx
- ta.typedArray.set(i, mapFc(fc))
- }
- }
- return ta.val
- }
- func (r *Runtime) _newTypedArrayFromArrayBuffer(ab *arrayBufferObject, args []Value, newTarget *Object, taCtor typedArrayObjectCtor) *Object {
- ta := taCtor(ab, 0, 0, r.getPrototypeFromCtor(newTarget, nil, r.global.TypedArrayPrototype))
- var byteOffset int
- if len(args) > 1 && args[1] != nil && args[1] != _undefined {
- byteOffset = r.toIndex(args[1])
- if byteOffset%ta.elemSize != 0 {
- panic(r.newError(r.global.RangeError, "Start offset of %s should be a multiple of %d", newTarget.self.getStr("name", nil), ta.elemSize))
- }
- }
- ab.ensureNotDetached(true)
- var length int
- if len(args) > 2 && args[2] != nil && args[2] != _undefined {
- length = r.toIndex(args[2])
- if byteOffset+length*ta.elemSize > len(ab.data) {
- panic(r.newError(r.global.RangeError, "Invalid typed array length: %d", length))
- }
- } else {
- if len(ab.data)%ta.elemSize != 0 {
- panic(r.newError(r.global.RangeError, "Byte length of %s should be a multiple of %d", newTarget.self.getStr("name", nil), ta.elemSize))
- }
- length = (len(ab.data) - byteOffset) / ta.elemSize
- }
- ta.offset = byteOffset / ta.elemSize
- ta.length = length
- return ta.val
- }
- func (r *Runtime) _newTypedArrayFromTypedArray(src *typedArrayObject, newTarget *Object) *Object {
- dst := r.typedArrayCreate(newTarget, []Value{_positiveZero})
- src.viewedArrayBuf.ensureNotDetached(true)
- l := src.length
- dst.viewedArrayBuf.prototype = r.getPrototypeFromCtor(r.toObject(src.viewedArrayBuf.getStr("constructor", nil)), r.global.ArrayBuffer, r.global.ArrayBufferPrototype)
- dst.viewedArrayBuf.data = allocByteSlice(toIntStrict(int64(l) * int64(dst.elemSize)))
- if src.defaultCtor == dst.defaultCtor {
- copy(dst.viewedArrayBuf.data, src.viewedArrayBuf.data[src.offset*src.elemSize:])
- dst.length = src.length
- return dst.val
- }
- dst.length = l
- for i := 0; i < l; i++ {
- dst.typedArray.set(i, src.typedArray.get(src.offset+i))
- }
- return dst.val
- }
- func (r *Runtime) _newTypedArray(args []Value, newTarget *Object, taCtor typedArrayObjectCtor) *Object {
- if newTarget == nil {
- panic(r.needNew("TypedArray"))
- }
- if len(args) > 0 {
- if obj, ok := args[0].(*Object); ok {
- switch o := obj.self.(type) {
- case *arrayBufferObject:
- return r._newTypedArrayFromArrayBuffer(o, args, newTarget, taCtor)
- case *typedArrayObject:
- return r._newTypedArrayFromTypedArray(o, newTarget)
- default:
- return r.typedArrayFrom(newTarget, obj, nil, nil)
- }
- }
- }
- var l int
- if len(args) > 0 {
- if arg0 := args[0]; arg0 != nil {
- l = r.toIndex(arg0)
- }
- }
- return r.allocateTypedArray(newTarget, l, taCtor)
- }
- func (r *Runtime) newUint8Array(args []Value, newTarget *Object) *Object {
- return r._newTypedArray(args, newTarget, r.newUint8ArrayObject)
- }
- func (r *Runtime) newUint8ClampedArray(args []Value, newTarget *Object) *Object {
- return r._newTypedArray(args, newTarget, r.newUint8ClampedArrayObject)
- }
- func (r *Runtime) newInt8Array(args []Value, newTarget *Object) *Object {
- return r._newTypedArray(args, newTarget, r.newInt8ArrayObject)
- }
- func (r *Runtime) newUint16Array(args []Value, newTarget *Object) *Object {
- return r._newTypedArray(args, newTarget, r.newUint16ArrayObject)
- }
- func (r *Runtime) newInt16Array(args []Value, newTarget *Object) *Object {
- return r._newTypedArray(args, newTarget, r.newInt16ArrayObject)
- }
- func (r *Runtime) newUint32Array(args []Value, newTarget *Object) *Object {
- return r._newTypedArray(args, newTarget, r.newUint32ArrayObject)
- }
- func (r *Runtime) newInt32Array(args []Value, newTarget *Object) *Object {
- return r._newTypedArray(args, newTarget, r.newInt32ArrayObject)
- }
- func (r *Runtime) newFloat32Array(args []Value, newTarget *Object) *Object {
- return r._newTypedArray(args, newTarget, r.newFloat32ArrayObject)
- }
- func (r *Runtime) newFloat64Array(args []Value, newTarget *Object) *Object {
- return r._newTypedArray(args, newTarget, r.newFloat64ArrayObject)
- }
- func (r *Runtime) createArrayBufferProto(val *Object) objectImpl {
- b := newBaseObjectObj(val, r.global.ObjectPrototype, classObject)
- byteLengthProp := &valueProperty{
- accessor: true,
- configurable: true,
- getterFunc: r.newNativeFunc(r.arrayBufferProto_getByteLength, nil, "get byteLength", nil, 0),
- }
- b._put("byteLength", byteLengthProp)
- b._putProp("constructor", r.global.ArrayBuffer, true, false, true)
- b._putProp("slice", r.newNativeFunc(r.arrayBufferProto_slice, nil, "slice", nil, 2), true, false, true)
- b._putSym(SymToStringTag, valueProp(asciiString("ArrayBuffer"), false, false, true))
- return b
- }
- func (r *Runtime) createArrayBuffer(val *Object) objectImpl {
- o := r.newNativeConstructOnly(val, r.builtin_newArrayBuffer, r.global.ArrayBufferPrototype, "ArrayBuffer", 1)
- o._putProp("isView", r.newNativeFunc(r.arrayBuffer_isView, nil, "isView", nil, 1), true, false, true)
- r.putSpeciesReturnThis(o)
- return o
- }
- func (r *Runtime) createDataViewProto(val *Object) objectImpl {
- b := newBaseObjectObj(val, r.global.ObjectPrototype, classObject)
- b._put("buffer", &valueProperty{
- accessor: true,
- configurable: true,
- getterFunc: r.newNativeFunc(r.dataViewProto_getBuffer, nil, "get buffer", nil, 0),
- })
- b._put("byteLength", &valueProperty{
- accessor: true,
- configurable: true,
- getterFunc: r.newNativeFunc(r.dataViewProto_getByteLen, nil, "get byteLength", nil, 0),
- })
- b._put("byteOffset", &valueProperty{
- accessor: true,
- configurable: true,
- getterFunc: r.newNativeFunc(r.dataViewProto_getByteOffset, nil, "get byteOffset", nil, 0),
- })
- b._putProp("constructor", r.global.DataView, true, false, true)
- b._putProp("getFloat32", r.newNativeFunc(r.dataViewProto_getFloat32, nil, "getFloat32", nil, 1), true, false, true)
- b._putProp("getFloat64", r.newNativeFunc(r.dataViewProto_getFloat64, nil, "getFloat64", nil, 1), true, false, true)
- b._putProp("getInt8", r.newNativeFunc(r.dataViewProto_getInt8, nil, "getInt8", nil, 1), true, false, true)
- b._putProp("getInt16", r.newNativeFunc(r.dataViewProto_getInt16, nil, "getInt16", nil, 1), true, false, true)
- b._putProp("getInt32", r.newNativeFunc(r.dataViewProto_getInt32, nil, "getInt32", nil, 1), true, false, true)
- b._putProp("getUint8", r.newNativeFunc(r.dataViewProto_getUint8, nil, "getUint8", nil, 1), true, false, true)
- b._putProp("getUint16", r.newNativeFunc(r.dataViewProto_getUint16, nil, "getUint16", nil, 1), true, false, true)
- b._putProp("getUint32", r.newNativeFunc(r.dataViewProto_getUint32, nil, "getUint32", nil, 1), true, false, true)
- b._putProp("setFloat32", r.newNativeFunc(r.dataViewProto_setFloat32, nil, "setFloat32", nil, 2), true, false, true)
- b._putProp("setFloat64", r.newNativeFunc(r.dataViewProto_setFloat64, nil, "setFloat64", nil, 2), true, false, true)
- b._putProp("setInt8", r.newNativeFunc(r.dataViewProto_setInt8, nil, "setInt8", nil, 2), true, false, true)
- b._putProp("setInt16", r.newNativeFunc(r.dataViewProto_setInt16, nil, "setInt16", nil, 2), true, false, true)
- b._putProp("setInt32", r.newNativeFunc(r.dataViewProto_setInt32, nil, "setInt32", nil, 2), true, false, true)
- b._putProp("setUint8", r.newNativeFunc(r.dataViewProto_setUint8, nil, "setUint8", nil, 2), true, false, true)
- b._putProp("setUint16", r.newNativeFunc(r.dataViewProto_setUint16, nil, "setUint16", nil, 2), true, false, true)
- b._putProp("setUint32", r.newNativeFunc(r.dataViewProto_setUint32, nil, "setUint32", nil, 2), true, false, true)
- b._putSym(SymToStringTag, valueProp(asciiString("DataView"), false, false, true))
- return b
- }
- func (r *Runtime) createDataView(val *Object) objectImpl {
- o := r.newNativeConstructOnly(val, r.newDataView, r.global.DataViewPrototype, "DataView", 3)
- return o
- }
- func (r *Runtime) createTypedArrayProto(val *Object) objectImpl {
- b := newBaseObjectObj(val, r.global.ObjectPrototype, classObject)
- b._put("buffer", &valueProperty{
- accessor: true,
- configurable: true,
- getterFunc: r.newNativeFunc(r.typedArrayProto_getBuffer, nil, "get buffer", nil, 0),
- })
- b._put("byteLength", &valueProperty{
- accessor: true,
- configurable: true,
- getterFunc: r.newNativeFunc(r.typedArrayProto_getByteLen, nil, "get byteLength", nil, 0),
- })
- b._put("byteOffset", &valueProperty{
- accessor: true,
- configurable: true,
- getterFunc: r.newNativeFunc(r.typedArrayProto_getByteOffset, nil, "get byteOffset", nil, 0),
- })
- b._putProp("constructor", r.global.TypedArray, true, false, true)
- b._putProp("copyWithin", r.newNativeFunc(r.typedArrayProto_copyWithin, nil, "copyWithin", nil, 2), true, false, true)
- b._putProp("entries", r.newNativeFunc(r.typedArrayProto_entries, nil, "entries", nil, 0), true, false, true)
- b._putProp("every", r.newNativeFunc(r.typedArrayProto_every, nil, "every", nil, 1), true, false, true)
- b._putProp("fill", r.newNativeFunc(r.typedArrayProto_fill, nil, "fill", nil, 1), true, false, true)
- b._putProp("filter", r.newNativeFunc(r.typedArrayProto_filter, nil, "filter", nil, 1), true, false, true)
- b._putProp("find", r.newNativeFunc(r.typedArrayProto_find, nil, "find", nil, 1), true, false, true)
- b._putProp("findIndex", r.newNativeFunc(r.typedArrayProto_findIndex, nil, "findIndex", nil, 1), true, false, true)
- b._putProp("forEach", r.newNativeFunc(r.typedArrayProto_forEach, nil, "forEach", nil, 1), true, false, true)
- b._putProp("includes", r.newNativeFunc(r.typedArrayProto_includes, nil, "includes", nil, 1), true, false, true)
- b._putProp("indexOf", r.newNativeFunc(r.typedArrayProto_indexOf, nil, "indexOf", nil, 1), true, false, true)
- b._putProp("join", r.newNativeFunc(r.typedArrayProto_join, nil, "join", nil, 1), true, false, true)
- b._putProp("keys", r.newNativeFunc(r.typedArrayProto_keys, nil, "keys", nil, 0), true, false, true)
- b._putProp("lastIndexOf", r.newNativeFunc(r.typedArrayProto_lastIndexOf, nil, "lastIndexOf", nil, 1), true, false, true)
- b._put("length", &valueProperty{
- accessor: true,
- configurable: true,
- getterFunc: r.newNativeFunc(r.typedArrayProto_getLength, nil, "get length", nil, 0),
- })
- b._putProp("map", r.newNativeFunc(r.typedArrayProto_map, nil, "map", nil, 1), true, false, true)
- b._putProp("reduce", r.newNativeFunc(r.typedArrayProto_reduce, nil, "reduce", nil, 1), true, false, true)
- b._putProp("reduceRight", r.newNativeFunc(r.typedArrayProto_reduceRight, nil, "reduceRight", nil, 1), true, false, true)
- b._putProp("reverse", r.newNativeFunc(r.typedArrayProto_reverse, nil, "reverse", nil, 0), true, false, true)
- b._putProp("set", r.newNativeFunc(r.typedArrayProto_set, nil, "set", nil, 1), true, false, true)
- b._putProp("slice", r.newNativeFunc(r.typedArrayProto_slice, nil, "slice", nil, 2), true, false, true)
- b._putProp("some", r.newNativeFunc(r.typedArrayProto_some, nil, "some", nil, 1), true, false, true)
- b._putProp("sort", r.newNativeFunc(r.typedArrayProto_sort, nil, "sort", nil, 1), true, false, true)
- b._putProp("subarray", r.newNativeFunc(r.typedArrayProto_subarray, nil, "subarray", nil, 2), true, false, true)
- b._putProp("toLocaleString", r.newNativeFunc(r.typedArrayProto_toLocaleString, nil, "toLocaleString", nil, 0), true, false, true)
- b._putProp("toString", r.global.arrayToString, true, false, true)
- valuesFunc := r.newNativeFunc(r.typedArrayProto_values, nil, "values", nil, 0)
- b._putProp("values", valuesFunc, true, false, true)
- b._putSym(SymIterator, valueProp(valuesFunc, true, false, true))
- b._putSym(SymToStringTag, &valueProperty{
- getterFunc: r.newNativeFunc(r.typedArrayProto_toStringTag, nil, "get [Symbol.toStringTag]", nil, 0),
- accessor: true,
- configurable: true,
- })
- return b
- }
- func (r *Runtime) createTypedArray(val *Object) objectImpl {
- o := r.newNativeConstructOnly(val, r.newTypedArray, r.global.TypedArrayPrototype, "TypedArray", 0)
- o._putProp("from", r.newNativeFunc(r.typedArray_from, nil, "from", nil, 1), true, false, true)
- o._putProp("of", r.newNativeFunc(r.typedArray_of, nil, "of", nil, 0), true, false, true)
- r.putSpeciesReturnThis(o)
- return o
- }
- func (r *Runtime) addPrototype(ctor *Object, proto *Object) *baseObject {
- p := r.newBaseObject(proto, classObject)
- p._putProp("constructor", ctor, true, false, true)
- ctor.self._putProp("prototype", p.val, false, false, false)
- return p
- }
- func (r *Runtime) typedArrayCreator(ctor func(args []Value, newTarget *Object) *Object, name unistring.String, bytesPerElement int) func(val *Object) objectImpl {
- return func(val *Object) objectImpl {
- o := r.newNativeConstructOnly(val, ctor, nil, name, 3)
- o.prototype = r.global.TypedArray
- proto := r.addPrototype(o.val, r.global.TypedArrayPrototype)
- bpe := intToValue(int64(bytesPerElement))
- o._putProp("BYTES_PER_ELEMENT", bpe, false, false, false)
- proto._putProp("BYTES_PER_ELEMENT", bpe, false, false, false)
- return o
- }
- }
- func (r *Runtime) initTypedArrays() {
- r.global.ArrayBufferPrototype = r.newLazyObject(r.createArrayBufferProto)
- r.global.ArrayBuffer = r.newLazyObject(r.createArrayBuffer)
- r.addToGlobal("ArrayBuffer", r.global.ArrayBuffer)
- r.global.DataViewPrototype = r.newLazyObject(r.createDataViewProto)
- r.global.DataView = r.newLazyObject(r.createDataView)
- r.addToGlobal("DataView", r.global.DataView)
- r.global.TypedArrayPrototype = r.newLazyObject(r.createTypedArrayProto)
- r.global.TypedArray = r.newLazyObject(r.createTypedArray)
- r.global.Uint8Array = r.newLazyObject(r.typedArrayCreator(r.newUint8Array, "Uint8Array", 1))
- r.addToGlobal("Uint8Array", r.global.Uint8Array)
- r.global.Uint8ClampedArray = r.newLazyObject(r.typedArrayCreator(r.newUint8ClampedArray, "Uint8ClampedArray", 1))
- r.addToGlobal("Uint8ClampedArray", r.global.Uint8ClampedArray)
- r.global.Int8Array = r.newLazyObject(r.typedArrayCreator(r.newInt8Array, "Int8Array", 1))
- r.addToGlobal("Int8Array", r.global.Int8Array)
- r.global.Uint16Array = r.newLazyObject(r.typedArrayCreator(r.newUint16Array, "Uint16Array", 2))
- r.addToGlobal("Uint16Array", r.global.Uint16Array)
- r.global.Int16Array = r.newLazyObject(r.typedArrayCreator(r.newInt16Array, "Int16Array", 2))
- r.addToGlobal("Int16Array", r.global.Int16Array)
- r.global.Uint32Array = r.newLazyObject(r.typedArrayCreator(r.newUint32Array, "Uint32Array", 4))
- r.addToGlobal("Uint32Array", r.global.Uint32Array)
- r.global.Int32Array = r.newLazyObject(r.typedArrayCreator(r.newInt32Array, "Int32Array", 4))
- r.addToGlobal("Int32Array", r.global.Int32Array)
- r.global.Float32Array = r.newLazyObject(r.typedArrayCreator(r.newFloat32Array, "Float32Array", 4))
- r.addToGlobal("Float32Array", r.global.Float32Array)
- r.global.Float64Array = r.newLazyObject(r.typedArrayCreator(r.newFloat64Array, "Float64Array", 8))
- r.addToGlobal("Float64Array", r.global.Float64Array)
- }
|