github.com/dop251/goja@v0.0.0-20240220182346-e401ed450204/builtin_typedarrays.go (about) 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 }