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