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