1/* 2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15package escompat; 16 17export class Atomics { 18 19 // https://tc39.es/ecma262/multipage/structured-data.html#sec-validateatomicaccess 20 private static validateAtomicAccess(startByteOffset: int, elementSize: int, length: int, index: int): int { 21 if (index < 0 || index >= length) { 22 throw new RangeError("Index out of bounds") 23 } 24 return startByteOffset + (index * elementSize) 25 } 26 27 private static interpretWaitResult(waitResult: int): string { 28 if (waitResult == 0) { 29 return "ok" 30 } else if (waitResult == 1) { 31 return "not-equal" 32 } else if (waitResult == 2) { 33 return "timed-out" 34 } else { 35 throw new Error("unexpected WaitResult") 36 } 37 } 38 39 private static requireSharedMemory(buffer: Buffer): SharedMemory { 40 if (buffer instanceof ArrayBuffer) { 41 throw new TypeError("This method accepts only TypedArrays that view SharedArrayBuffers") 42 } else { 43 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 44 return mem 45 } 46 } 47 48 /** 49 * isLockFree(n) returns true if Atomic operations for typed arrays where "BYTER_PER_ELEMENT == n" 50 * use hardware atomics instructions instead of locks. 51 * 52 * Warning: currently, all Atomic operations use locks, 53 * but isLockFree(1), isLockFree(2), isLockFree(4), isLockFree(8) following the ECMA specification return true. 54 */ 55 public static isLockFree(byteSize: int): boolean { 56 return byteSize == 1 || byteSize == 2 || byteSize == 4 || byteSize == 8 57 } 58 59 public static add(typedArray: Int8Array | Int16Array | Int32Array | BigInt64Array | Uint8Array | Uint16Array | Uint32Array | BigUint64Array, index: int, value: number): number { 60 if (typedArray instanceof Int8Array) { 61 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Int8Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 62 let buffer = typedArray.buffer 63 if (buffer instanceof ArrayBuffer) { 64 let oldValue = typedArray[indexedPosition] 65 let newValue = (oldValue + value) as byte 66 typedArray.set(indexedPosition, newValue) 67 return oldValue 68 } else { 69 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 70 return mem.atomicAddI8(indexedPosition, value as byte) 71 } 72 } else if (typedArray instanceof Int16Array) { 73 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Int16Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 74 let buffer = typedArray.buffer 75 if (buffer instanceof ArrayBuffer) { 76 let oldValue = typedArray[indexedPosition] 77 let newValue = (oldValue + value) as short 78 typedArray.set(indexedPosition, newValue) 79 return oldValue 80 } else { 81 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 82 return mem.atomicAddI16(indexedPosition, value as short) 83 } 84 } else if (typedArray instanceof Int32Array) { 85 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Int32Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 86 let buffer = typedArray.buffer 87 if (buffer instanceof ArrayBuffer) { 88 let oldValue = typedArray[indexedPosition] 89 let newValue = (oldValue + value) as int 90 typedArray.set(indexedPosition, newValue) 91 return oldValue 92 } else { 93 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 94 return mem.atomicAddI32(indexedPosition, value as int) 95 } 96 } else if (typedArray instanceof BigInt64Array) { 97 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, BigInt64Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 98 let buffer = typedArray.buffer 99 if (buffer instanceof ArrayBuffer) { 100 let oldValue = typedArray[indexedPosition].getLong() 101 let newValue = (oldValue + value) as long 102 typedArray.set(indexedPosition, newValue) 103 return oldValue 104 } else { 105 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 106 return mem.atomicAddI64(indexedPosition, value as long) 107 } 108 } else if (typedArray instanceof Uint8Array) { 109 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Uint8Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 110 let buffer = typedArray.buffer 111 if (buffer instanceof ArrayBuffer) { 112 let oldValue = typedArray[indexedPosition] 113 let newValue = (oldValue + value) as byte 114 typedArray.set(indexedPosition, newValue) 115 return oldValue 116 } else { 117 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 118 return mem.atomicAddU8(indexedPosition, value as byte) 119 } 120 } else if (typedArray instanceof Uint16Array) { 121 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Uint16Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 122 let buffer = typedArray.buffer 123 if (buffer instanceof ArrayBuffer) { 124 let oldValue = typedArray[indexedPosition] 125 let newValue = (oldValue + value) as short 126 typedArray.set(indexedPosition, newValue) 127 return oldValue 128 } else { 129 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 130 return mem.atomicAddU16(indexedPosition, value as short) 131 } 132 } else if (typedArray instanceof Uint32Array) { 133 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Uint32Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 134 let buffer = typedArray.buffer 135 if (buffer instanceof ArrayBuffer) { 136 let oldValue = typedArray[indexedPosition] 137 let newValue = (oldValue + value) as int 138 typedArray.set(indexedPosition, newValue) 139 return oldValue 140 } else { 141 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 142 return mem.atomicAddU32(indexedPosition, value as int) 143 } 144 } else if (typedArray instanceof BigUint64Array) { 145 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, BigUint64Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 146 let buffer = typedArray.buffer 147 if (buffer instanceof ArrayBuffer) { 148 let oldValue = typedArray[indexedPosition].getULong() 149 let newValue = (oldValue + value) as long 150 typedArray.set(indexedPosition, new BigInt(newValue)) 151 return oldValue 152 } else { 153 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 154 return mem.atomicAddU64(indexedPosition, value as long) 155 } 156 } else { 157 throw new Error("Unhandled array type!") 158 } 159 } 160 161 public static and(typedArray: Int8Array | Int16Array | Int32Array | BigInt64Array | Uint8Array | Uint16Array | Uint32Array | BigUint64Array, index: int, value: number): number { 162 if (typedArray instanceof Int8Array) { 163 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Int8Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 164 let buffer = typedArray.buffer 165 if (buffer instanceof ArrayBuffer) { 166 let oldValue = typedArray[indexedPosition] 167 let newValue = (oldValue & value) as byte 168 typedArray.set(indexedPosition, newValue) 169 return oldValue 170 } else { 171 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 172 return mem.atomicAndI8(indexedPosition, value as byte) 173 } 174 } else if (typedArray instanceof Int16Array) { 175 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Int16Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 176 let buffer = typedArray.buffer 177 if (buffer instanceof ArrayBuffer) { 178 let oldValue = typedArray[indexedPosition] 179 let newValue = (oldValue & value) as short 180 typedArray.set(indexedPosition, newValue) 181 return oldValue 182 } else { 183 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 184 return mem.atomicAndI16(indexedPosition, value as short) 185 } 186 } else if (typedArray instanceof Int32Array) { 187 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Int32Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 188 let buffer = typedArray.buffer 189 if (buffer instanceof ArrayBuffer) { 190 let oldValue = typedArray[indexedPosition] 191 let newValue = (oldValue & value) as int 192 typedArray.set(indexedPosition, newValue) 193 return oldValue 194 } else { 195 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 196 return mem.atomicAndI32(indexedPosition, value as int) 197 } 198 } else if (typedArray instanceof BigInt64Array) { 199 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, BigInt64Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 200 let buffer = typedArray.buffer 201 if (buffer instanceof ArrayBuffer) { 202 let oldValue = typedArray[indexedPosition].getLong() 203 let newValue = (oldValue & value) as long 204 typedArray.set(indexedPosition, newValue) 205 return oldValue 206 } else { 207 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 208 return mem.atomicAndI64(indexedPosition, value as long) 209 } 210 } else if (typedArray instanceof Uint8Array) { 211 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Uint8Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 212 let buffer = typedArray.buffer 213 if (buffer instanceof ArrayBuffer) { 214 let oldValue = typedArray[indexedPosition] 215 let newValue = (oldValue & value) as byte 216 typedArray.set(indexedPosition, newValue) 217 return oldValue 218 } else { 219 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 220 return mem.atomicAndU8(indexedPosition, value as byte) 221 } 222 } else if (typedArray instanceof Uint16Array) { 223 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Uint16Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 224 let buffer = typedArray.buffer 225 if (buffer instanceof ArrayBuffer) { 226 let oldValue = typedArray[indexedPosition] 227 let newValue = (oldValue & value) as short 228 typedArray.set(indexedPosition, newValue) 229 return oldValue 230 } else { 231 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 232 return mem.atomicAndU16(indexedPosition, value as short) 233 } 234 } else if (typedArray instanceof Uint32Array) { 235 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Uint32Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 236 let buffer = typedArray.buffer 237 if (buffer instanceof ArrayBuffer) { 238 let oldValue = typedArray[indexedPosition] 239 let newValue = (oldValue & value) as int 240 typedArray.set(indexedPosition, newValue) 241 return oldValue 242 } else { 243 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 244 return mem.atomicAndU32(indexedPosition, value as int) 245 } 246 } else if (typedArray instanceof BigUint64Array) { 247 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, BigUint64Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 248 let buffer = typedArray.buffer 249 if (buffer instanceof ArrayBuffer) { 250 let oldValue = typedArray[indexedPosition].getLong() 251 let newValue = (oldValue & value) as long 252 typedArray.set(indexedPosition, new BigInt(newValue)) 253 return oldValue 254 } else { 255 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 256 return mem.atomicAndU64(indexedPosition, value as long) 257 } 258 } else { 259 throw new Error("Unhandled array type!") 260 } 261 } 262 263 public static compareExchange(typedArray: Int8Array | Int16Array | Int32Array | BigInt64Array | Uint8Array | Uint16Array | Uint32Array | BigUint64Array, index: int, expectedValue: number, replacementValue: number): number { 264 if (typedArray instanceof Int8Array) { 265 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Int8Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 266 let buffer = typedArray.buffer 267 if (buffer instanceof ArrayBuffer) { 268 let oldValue = typedArray[indexedPosition] 269 if (oldValue == expectedValue) { 270 typedArray.set(indexedPosition, replacementValue as byte) 271 } 272 return oldValue 273 } else { 274 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 275 return mem.atomicCompareExchangeI8(indexedPosition, expectedValue as byte, replacementValue as byte) 276 } 277 } else if (typedArray instanceof Int16Array) { 278 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Int16Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 279 let buffer = typedArray.buffer 280 if (buffer instanceof ArrayBuffer) { 281 let oldValue = typedArray[indexedPosition] 282 if (oldValue == expectedValue) { 283 typedArray.set(indexedPosition, replacementValue as short) 284 } 285 return oldValue 286 } else { 287 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 288 return mem.atomicCompareExchangeI16(indexedPosition, expectedValue as short, replacementValue as short) 289 } 290 } else if (typedArray instanceof Int32Array) { 291 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Int32Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 292 let buffer = typedArray.buffer 293 if (buffer instanceof ArrayBuffer) { 294 let oldValue = typedArray[indexedPosition] 295 if (oldValue == expectedValue) { 296 typedArray.set(indexedPosition, replacementValue as int) 297 } 298 return oldValue 299 } else { 300 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 301 return mem.atomicCompareExchangeI32(indexedPosition, expectedValue as int, replacementValue as int) 302 } 303 } else if (typedArray instanceof BigInt64Array) { 304 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, BigInt64Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 305 let buffer = typedArray.buffer 306 if (buffer instanceof ArrayBuffer) { 307 let oldValue = typedArray[indexedPosition].getLong() 308 if (oldValue == expectedValue) { 309 typedArray.set(indexedPosition, replacementValue as long) 310 } 311 return oldValue 312 } else { 313 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 314 return mem.atomicCompareExchangeI64(indexedPosition, expectedValue as long, replacementValue as long) 315 } 316 } else if (typedArray instanceof Uint8Array) { 317 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Uint8Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 318 let buffer = typedArray.buffer 319 if (buffer instanceof ArrayBuffer) { 320 let oldValue = typedArray[indexedPosition] 321 if (oldValue == expectedValue) { 322 typedArray.set(indexedPosition, replacementValue as byte) 323 } 324 return oldValue 325 } else { 326 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 327 return mem.atomicCompareExchangeU8(indexedPosition, expectedValue as byte, replacementValue as byte) 328 } 329 } else if (typedArray instanceof Uint16Array) { 330 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Uint16Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 331 let buffer = typedArray.buffer 332 if (buffer instanceof ArrayBuffer) { 333 let oldValue = typedArray[indexedPosition] 334 if (oldValue == expectedValue) { 335 typedArray.set(indexedPosition, replacementValue as short) 336 } 337 return oldValue 338 } else { 339 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 340 return mem.atomicCompareExchangeU16(indexedPosition, expectedValue as short, replacementValue as short) 341 } 342 } else if (typedArray instanceof Uint32Array) { 343 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Uint32Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 344 let buffer = typedArray.buffer 345 if (buffer instanceof ArrayBuffer) { 346 let oldValue = typedArray[indexedPosition] 347 if (oldValue == expectedValue) { 348 typedArray.set(indexedPosition, replacementValue as int) 349 } 350 return oldValue 351 } else { 352 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 353 return mem.atomicCompareExchangeU32(indexedPosition, expectedValue as int, replacementValue as int) 354 } 355 } else if (typedArray instanceof BigUint64Array) { 356 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, BigUint64Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 357 let buffer = typedArray.buffer 358 if (buffer instanceof ArrayBuffer) { 359 let oldValue = typedArray[indexedPosition].getLong() 360 if (oldValue == expectedValue) { 361 typedArray.set(indexedPosition, new BigInt(replacementValue)) 362 } 363 return oldValue 364 } else { 365 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 366 return mem.atomicCompareExchangeU64(indexedPosition, expectedValue as long, replacementValue as long) 367 } 368 } else { 369 throw new Error("Unhandled array type!") 370 } 371 } 372 373 public static exchange(typedArray: Int8Array | Int16Array | Int32Array | BigInt64Array | Uint8Array | Uint16Array | Uint32Array | BigUint64Array, index: int, value: number): number { 374 if (typedArray instanceof Int8Array) { 375 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Int8Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 376 let buffer = typedArray.buffer 377 if (buffer instanceof ArrayBuffer) { 378 let oldValue = typedArray[indexedPosition] 379 typedArray.set(indexedPosition, value as byte) 380 return oldValue 381 } else { 382 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 383 return mem.atomicExchangeI8(indexedPosition, value as byte) 384 } 385 } else if (typedArray instanceof Int16Array) { 386 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Int16Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 387 let buffer = typedArray.buffer 388 if (buffer instanceof ArrayBuffer) { 389 let oldValue = typedArray[indexedPosition] 390 typedArray.set(indexedPosition, value as short) 391 return oldValue 392 } else { 393 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 394 return mem.atomicExchangeI16(indexedPosition, value as short) 395 } 396 } else if (typedArray instanceof Int32Array) { 397 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Int32Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 398 let buffer = typedArray.buffer 399 if (buffer instanceof ArrayBuffer) { 400 let oldValue = typedArray[indexedPosition] 401 typedArray.set(indexedPosition, value as int) 402 return oldValue 403 } else { 404 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 405 return mem.atomicExchangeI32(indexedPosition, value as int) 406 } 407 } else if (typedArray instanceof BigInt64Array) { 408 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, BigInt64Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 409 let buffer = typedArray.buffer 410 if (buffer instanceof ArrayBuffer) { 411 let oldValue = typedArray[indexedPosition].getLong() 412 typedArray.set(indexedPosition, value as long) 413 return oldValue 414 } else { 415 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 416 return mem.atomicExchangeI64(indexedPosition, value as long) 417 } 418 } else if (typedArray instanceof Uint8Array) { 419 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Uint8Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 420 let buffer = typedArray.buffer 421 if (buffer instanceof ArrayBuffer) { 422 let oldValue = typedArray[indexedPosition] 423 typedArray.set(indexedPosition, value as byte) 424 return oldValue 425 } else { 426 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 427 return mem.atomicExchangeU8(indexedPosition, value as byte) 428 } 429 } else if (typedArray instanceof Uint16Array) { 430 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Uint16Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 431 let buffer = typedArray.buffer 432 if (buffer instanceof ArrayBuffer) { 433 let oldValue = typedArray[indexedPosition] 434 typedArray.set(indexedPosition, value as short) 435 return oldValue 436 } else { 437 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 438 return mem.atomicExchangeU16(indexedPosition, value as short) 439 } 440 } else if (typedArray instanceof Uint32Array) { 441 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Uint32Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 442 let buffer = typedArray.buffer 443 if (buffer instanceof ArrayBuffer) { 444 let oldValue = typedArray[indexedPosition] 445 typedArray.set(indexedPosition, value as int) 446 return oldValue 447 } else { 448 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 449 return mem.atomicExchangeU32(indexedPosition, value as int) 450 } 451 } else if (typedArray instanceof BigUint64Array) { 452 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, BigUint64Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 453 let buffer = typedArray.buffer 454 if (buffer instanceof ArrayBuffer) { 455 let oldValue = typedArray[indexedPosition].getLong() 456 typedArray.set(indexedPosition, new BigInt(value)) 457 return oldValue 458 } else { 459 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 460 return mem.atomicExchangeU64(indexedPosition, value as long) 461 } 462 } else { 463 throw new Error("Unhandled array type!") 464 } 465 } 466 467 public static load(typedArray: Int8Array | Int16Array | Int32Array | BigInt64Array | Uint8Array | Uint16Array | Uint32Array | BigUint64Array, index: int): number { 468 if (typedArray instanceof Int8Array) { 469 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Int8Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 470 let buffer = typedArray.buffer 471 if (buffer instanceof ArrayBuffer) { 472 return typedArray[indexedPosition] 473 } else { 474 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 475 return mem.atomicLoadI8(indexedPosition) 476 } 477 } else if (typedArray instanceof Int16Array) { 478 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Int16Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 479 let buffer = typedArray.buffer 480 if (buffer instanceof ArrayBuffer) { 481 return typedArray[indexedPosition] 482 } else { 483 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 484 return mem.atomicLoadI16(indexedPosition) 485 } 486 } else if (typedArray instanceof Int32Array) { 487 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Int32Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 488 let buffer = typedArray.buffer 489 if (buffer instanceof ArrayBuffer) { 490 return typedArray[indexedPosition] 491 } else { 492 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 493 return mem.atomicLoadI32(indexedPosition) 494 } 495 } else if (typedArray instanceof BigInt64Array) { 496 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, BigInt64Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 497 let buffer = typedArray.buffer 498 if (buffer instanceof ArrayBuffer) { 499 return typedArray[indexedPosition].getLong() 500 } else { 501 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 502 return mem.atomicLoadI64(indexedPosition) 503 } 504 } else if (typedArray instanceof Uint8Array) { 505 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Uint8Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 506 let buffer = typedArray.buffer 507 if (buffer instanceof ArrayBuffer) { 508 return typedArray[indexedPosition] 509 } else { 510 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 511 return mem.atomicLoadU8(indexedPosition) 512 } 513 } else if (typedArray instanceof Uint16Array) { 514 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Uint16Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 515 let buffer = typedArray.buffer 516 if (buffer instanceof ArrayBuffer) { 517 return typedArray[indexedPosition] 518 } else { 519 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 520 return mem.atomicLoadU16(indexedPosition) 521 } 522 } else if (typedArray instanceof Uint32Array) { 523 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Uint32Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 524 let buffer = typedArray.buffer 525 if (buffer instanceof ArrayBuffer) { 526 return typedArray[indexedPosition] 527 } else { 528 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 529 return mem.atomicLoadU32(indexedPosition) 530 } 531 } else if (typedArray instanceof BigUint64Array) { 532 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, BigUint64Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 533 let buffer = typedArray.buffer 534 if (buffer instanceof ArrayBuffer) { 535 return typedArray[indexedPosition].getLong() 536 } else { 537 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 538 return mem.atomicLoadU64(indexedPosition) 539 } 540 } else { 541 throw new Error("Unhandled array type!") 542 } 543 } 544 545 public static or(typedArray: Int8Array | Int16Array | Int32Array | BigInt64Array | Uint8Array | Uint16Array | Uint32Array | BigUint64Array, index: int, value: number): number { 546 if (typedArray instanceof Int8Array) { 547 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Int8Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 548 let buffer = typedArray.buffer 549 if (buffer instanceof ArrayBuffer) { 550 let oldValue = typedArray[indexedPosition] 551 let newValue = (oldValue | value) as byte 552 typedArray.set(indexedPosition, newValue) 553 return oldValue 554 } else { 555 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 556 return mem.atomicOrI8(indexedPosition, value as byte) 557 } 558 } else if (typedArray instanceof Int16Array) { 559 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Int16Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 560 let buffer = typedArray.buffer 561 if (buffer instanceof ArrayBuffer) { 562 let oldValue = typedArray[indexedPosition] 563 let newValue = (oldValue | value) as short 564 typedArray.set(indexedPosition, newValue) 565 return oldValue 566 } else { 567 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 568 return mem.atomicOrI16(indexedPosition, value as short) 569 } 570 } else if (typedArray instanceof Int32Array) { 571 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Int32Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 572 let buffer = typedArray.buffer 573 if (buffer instanceof ArrayBuffer) { 574 let oldValue = typedArray[indexedPosition] 575 let newValue = (oldValue | value) as int 576 typedArray.set(indexedPosition, newValue) 577 return oldValue 578 } else { 579 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 580 return mem.atomicOrI32(indexedPosition, value as int) 581 } 582 } else if (typedArray instanceof BigInt64Array) { 583 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, BigInt64Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 584 let buffer = typedArray.buffer 585 if (buffer instanceof ArrayBuffer) { 586 let oldValue = typedArray[indexedPosition].getLong() 587 let newValue = (oldValue | value) as long 588 typedArray.set(indexedPosition, newValue) 589 return oldValue 590 } else { 591 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 592 return mem.atomicOrI64(indexedPosition, value as long) 593 } 594 } else if (typedArray instanceof Uint8Array) { 595 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Uint8Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 596 let buffer = typedArray.buffer 597 if (buffer instanceof ArrayBuffer) { 598 let oldValue = typedArray[indexedPosition] 599 let newValue = (oldValue | value) as byte 600 typedArray.set(indexedPosition, newValue) 601 return oldValue 602 } else { 603 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 604 return mem.atomicOrU8(indexedPosition, value as byte) 605 } 606 } else if (typedArray instanceof Uint16Array) { 607 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Uint16Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 608 let buffer = typedArray.buffer 609 if (buffer instanceof ArrayBuffer) { 610 let oldValue = typedArray[indexedPosition] 611 let newValue = (oldValue | value) as short 612 typedArray.set(indexedPosition, newValue) 613 return oldValue 614 } else { 615 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 616 return mem.atomicOrU16(indexedPosition, value as short) 617 } 618 } else if (typedArray instanceof Uint32Array) { 619 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Uint32Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 620 let buffer = typedArray.buffer 621 if (buffer instanceof ArrayBuffer) { 622 let oldValue = typedArray[indexedPosition] 623 let newValue = (oldValue | value) as int 624 typedArray.set(indexedPosition, newValue) 625 return oldValue 626 } else { 627 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 628 return mem.atomicOrU32(indexedPosition, value as int) 629 } 630 } else if (typedArray instanceof BigUint64Array) { 631 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, BigUint64Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 632 let buffer = typedArray.buffer 633 if (buffer instanceof ArrayBuffer) { 634 let oldValue = typedArray[indexedPosition].getLong() 635 let newValue = (oldValue | value) as long 636 typedArray.set(indexedPosition, new BigInt(newValue)) 637 return oldValue 638 } else { 639 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 640 return mem.atomicOrU64(indexedPosition, value as long) 641 } 642 } else { 643 throw new Error("Unhandled array type!") 644 } 645 } 646 647 public static store(typedArray: Int8Array | Int16Array | Int32Array | BigInt64Array | Uint8Array | Uint16Array | Uint32Array | BigUint64Array, index: int, value: number): number { 648 if (typedArray instanceof Int8Array) { 649 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Int8Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 650 let buffer = typedArray.buffer 651 if (buffer instanceof ArrayBuffer) { 652 typedArray.set(indexedPosition, value as byte) 653 return value 654 } else { 655 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 656 return mem.atomicStoreI8(indexedPosition, value as byte) 657 } 658 } else if (typedArray instanceof Int16Array) { 659 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Int16Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 660 let buffer = typedArray.buffer 661 if (buffer instanceof ArrayBuffer) { 662 typedArray.set(indexedPosition, value as short) 663 return value 664 } else { 665 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 666 return mem.atomicStoreI16(indexedPosition, value as short) 667 } 668 } else if (typedArray instanceof Int32Array) { 669 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Int32Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 670 let buffer = typedArray.buffer 671 if (buffer instanceof ArrayBuffer) { 672 typedArray.set(indexedPosition, value as int) 673 return value 674 } else { 675 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 676 return mem.atomicStoreI32(indexedPosition, value as int) 677 } 678 } else if (typedArray instanceof BigInt64Array) { 679 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, BigInt64Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 680 let buffer = typedArray.buffer 681 if (buffer instanceof ArrayBuffer) { 682 typedArray.set(indexedPosition, value as long) 683 return value 684 } else { 685 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 686 return mem.atomicStoreI64(indexedPosition, value as long) 687 } 688 } else if (typedArray instanceof Uint8Array) { 689 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Uint8Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 690 let buffer = typedArray.buffer 691 if (buffer instanceof ArrayBuffer) { 692 typedArray.set(indexedPosition, value as byte) 693 return value 694 } else { 695 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 696 return mem.atomicStoreU8(indexedPosition, value as byte) 697 } 698 } else if (typedArray instanceof Uint16Array) { 699 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Uint16Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 700 let buffer = typedArray.buffer 701 if (buffer instanceof ArrayBuffer) { 702 typedArray.set(indexedPosition, value as short) 703 return value 704 } else { 705 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 706 return mem.atomicStoreU16(indexedPosition, value as short) 707 } 708 } else if (typedArray instanceof Uint32Array) { 709 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Uint32Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 710 let buffer = typedArray.buffer 711 if (buffer instanceof ArrayBuffer) { 712 typedArray.set(indexedPosition, value as int) 713 return value 714 } else { 715 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 716 return mem.atomicStoreU32(indexedPosition, value as int) 717 } 718 } else if (typedArray instanceof BigUint64Array) { 719 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, BigUint64Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 720 let buffer = typedArray.buffer 721 if (buffer instanceof ArrayBuffer) { 722 typedArray.set(indexedPosition, new BigInt(value)) 723 return value 724 } else { 725 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 726 return mem.atomicStoreU64(indexedPosition, value as long) 727 } 728 } else { 729 throw new Error("Unhandled array type!") 730 } 731 } 732 733 public static sub(typedArray: Int8Array | Int16Array | Int32Array | BigInt64Array | Uint8Array | Uint16Array | Uint32Array | BigUint64Array, index: int, value: number): number { 734 if (typedArray instanceof Int8Array) { 735 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Int8Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 736 let buffer = typedArray.buffer 737 if (buffer instanceof ArrayBuffer) { 738 let oldValue = typedArray[indexedPosition] 739 let newValue = (oldValue - value) 740 typedArray.set(indexedPosition, newValue) 741 return oldValue 742 } else { 743 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 744 return mem.atomicSubI8(indexedPosition, value as byte) 745 } 746 } else if (typedArray instanceof Int16Array) { 747 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Int16Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 748 let buffer = typedArray.buffer 749 if (buffer instanceof ArrayBuffer) { 750 let oldValue = typedArray[indexedPosition] 751 let newValue = (oldValue - value) 752 typedArray.set(indexedPosition, newValue) 753 return oldValue 754 } else { 755 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 756 return mem.atomicSubI16(indexedPosition, value as short) 757 } 758 } else if (typedArray instanceof Int32Array) { 759 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Int32Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 760 let buffer = typedArray.buffer 761 if (buffer instanceof ArrayBuffer) { 762 let oldValue = typedArray[indexedPosition] 763 let newValue = (oldValue - value) 764 typedArray.set(indexedPosition, newValue) 765 return oldValue 766 } else { 767 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 768 return mem.atomicSubI32(indexedPosition, value as int) 769 } 770 } else if (typedArray instanceof BigInt64Array) { 771 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, BigInt64Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 772 let buffer = typedArray.buffer 773 if (buffer instanceof ArrayBuffer) { 774 let oldValue = typedArray[indexedPosition].getLong() 775 let newValue = (oldValue - value) 776 typedArray.set(indexedPosition, newValue as long) 777 return oldValue 778 } else { 779 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 780 return mem.atomicSubI64(indexedPosition, value as long) 781 } 782 } else if (typedArray instanceof Uint8Array) { 783 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Uint8Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 784 let buffer = typedArray.buffer 785 if (buffer instanceof ArrayBuffer) { 786 let oldValue = typedArray[indexedPosition] 787 let newValue = (oldValue - value) 788 typedArray.set(indexedPosition, newValue) 789 return oldValue 790 } else { 791 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 792 return mem.atomicSubU8(indexedPosition, value as byte) 793 } 794 } else if (typedArray instanceof Uint16Array) { 795 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Uint16Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 796 let buffer = typedArray.buffer 797 if (buffer instanceof ArrayBuffer) { 798 let oldValue = typedArray[indexedPosition] 799 let newValue = (oldValue - value) 800 typedArray.set(indexedPosition, newValue) 801 return oldValue 802 } else { 803 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 804 return mem.atomicSubU16(indexedPosition, value as short) 805 } 806 } else if (typedArray instanceof Uint32Array) { 807 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Uint32Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 808 let buffer = typedArray.buffer 809 if (buffer instanceof ArrayBuffer) { 810 let oldValue = typedArray[indexedPosition] 811 let newValue = (oldValue - value) 812 typedArray.set(indexedPosition, newValue) 813 return oldValue 814 } else { 815 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 816 return mem.atomicSubU32(indexedPosition, value as int) 817 } 818 } else if (typedArray instanceof BigUint64Array) { 819 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, BigUint64Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 820 let buffer = typedArray.buffer 821 if (buffer instanceof ArrayBuffer) { 822 let oldValue = typedArray[indexedPosition].getLong() 823 let newValue = (oldValue - value) 824 typedArray.set(indexedPosition, new BigInt(newValue)) 825 return oldValue 826 } else { 827 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 828 return mem.atomicSubU64(indexedPosition, value as long) 829 } 830 } else { 831 throw new Error("Unhandled array type!") 832 } 833 } 834 835 public static xor(typedArray: Int8Array | Int16Array | Int32Array | BigInt64Array | Uint8Array | Uint16Array | Uint32Array | BigUint64Array, index: int, value: number): number { 836 if (typedArray instanceof Int8Array) { 837 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Int8Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 838 let buffer = typedArray.buffer 839 if (buffer instanceof ArrayBuffer) { 840 let oldValue = typedArray[indexedPosition] 841 let newValue = (oldValue ^ value) 842 typedArray.set(indexedPosition, newValue) 843 return oldValue 844 } else { 845 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 846 return mem.atomicXorI8(indexedPosition, value as byte) 847 } 848 } else if (typedArray instanceof Int16Array) { 849 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Int16Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 850 let buffer = typedArray.buffer 851 if (buffer instanceof ArrayBuffer) { 852 let oldValue = typedArray[indexedPosition] 853 let newValue = (oldValue ^ value) 854 typedArray.set(indexedPosition, newValue) 855 return oldValue 856 } else { 857 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 858 return mem.atomicXorI16(indexedPosition, value as short) 859 } 860 } else if (typedArray instanceof Int32Array) { 861 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Int32Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 862 let buffer = typedArray.buffer 863 if (buffer instanceof ArrayBuffer) { 864 let oldValue = typedArray[indexedPosition] 865 let newValue = (oldValue ^ value) 866 typedArray.set(indexedPosition, newValue) 867 return oldValue 868 } else { 869 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 870 return mem.atomicXorI32(indexedPosition, value as int) 871 } 872 } else if (typedArray instanceof BigInt64Array) { 873 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, BigInt64Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 874 let buffer = typedArray.buffer 875 if (buffer instanceof ArrayBuffer) { 876 let oldValue = typedArray[indexedPosition].getLong() 877 let newValue = (oldValue ^ value) 878 typedArray.set(indexedPosition, newValue) 879 return oldValue 880 } else { 881 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 882 return mem.atomicXorI64(indexedPosition, value as long) 883 } 884 } else if (typedArray instanceof Uint8Array) { 885 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Uint8Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 886 let buffer = typedArray.buffer 887 if (buffer instanceof ArrayBuffer) { 888 let oldValue = typedArray[indexedPosition] 889 let newValue = (oldValue ^ value) 890 typedArray.set(indexedPosition, newValue) 891 return oldValue 892 } else { 893 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 894 return mem.atomicXorU8(indexedPosition, value as byte) 895 } 896 } else if (typedArray instanceof Uint16Array) { 897 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Uint16Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 898 let buffer = typedArray.buffer 899 if (buffer instanceof ArrayBuffer) { 900 let oldValue = typedArray[indexedPosition] 901 let newValue = (oldValue ^ value) 902 typedArray.set(indexedPosition, newValue) 903 return oldValue 904 } else { 905 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 906 return mem.atomicXorU16(indexedPosition, value as short) 907 } 908 } else if (typedArray instanceof Uint32Array) { 909 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Uint32Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 910 let buffer = typedArray.buffer 911 if (buffer instanceof ArrayBuffer) { 912 let oldValue = typedArray[indexedPosition] 913 let newValue = (oldValue ^ value) 914 typedArray.set(indexedPosition, newValue) 915 return oldValue 916 } else { 917 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 918 return mem.atomicXorU32(indexedPosition, value as int) 919 } 920 } else if (typedArray instanceof BigUint64Array) { 921 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, BigUint64Array.BYTES_PER_ELEMENT as int, typedArray.length as int, index) 922 let buffer = typedArray.buffer 923 if (buffer instanceof ArrayBuffer) { 924 let oldValue = typedArray[indexedPosition].getLong() 925 let newValue = (oldValue ^ value) 926 typedArray.set(indexedPosition, new BigInt(newValue)) 927 return oldValue 928 } else { 929 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 930 return mem.atomicXorU64(indexedPosition, value as long) 931 } 932 } else { 933 throw new Error("Unhandled array type!") 934 } 935 } 936 937 /** 938 * If "typedArray[offset] != value" suspends the current thread until it is notified by Atomics.notify. 939 * 940 * Note: An Atomics.notify call will wake up this thread even if "typedArray[offset] == value". 941 */ 942 public static wait(typedArray: Int32Array | BigInt64Array, offset: int, value: number): string { 943 if (typedArray instanceof Int32Array) { 944 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Int32Array.BYTES_PER_ELEMENT as int, typedArray.length as int, offset) 945 let mem = Atomics.requireSharedMemory(typedArray.buffer) 946 let result = mem.atomicWaitI32(indexedPosition, value as int) 947 return Atomics.interpretWaitResult(result) 948 } else if (typedArray instanceof BigInt64Array) { 949 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, BigInt64Array.BYTES_PER_ELEMENT as int, typedArray.length as int, offset) 950 let mem = Atomics.requireSharedMemory(typedArray.buffer) 951 let result = mem.atomicWaitI64(indexedPosition, value as long) 952 return Atomics.interpretWaitResult(result) 953 } else { 954 throw new Error("Unhandled array type!") 955 } 956 } 957 958 public static waitAsync(typedArray: Int32Array | BigInt64Array, offset: int, value: number): Promise<string> { 959 return launch Atomics.wait(typedArray, offset, value) 960 } 961 962 /** 963 * If "typedArray[offset] != value" suspends the current thread until it is notified by Atomics.notify 964 * or until the given timeout passes. 965 * 966 * Note: An Atomics.notify call will wake up this thread even if "typedArray[offset] == value". 967 */ 968 public static wait(typedArray: Int32Array | BigInt64Array, offset: int, value: number, timeout: long): string { 969 if (typedArray instanceof Int32Array) { 970 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Int32Array.BYTES_PER_ELEMENT as int, typedArray.length as int, offset) 971 let mem = Atomics.requireSharedMemory(typedArray.buffer) 972 let result = mem.atomicTimedWaitI32(indexedPosition, value as int, timeout) 973 return Atomics.interpretWaitResult(result) 974 } else if (typedArray instanceof BigInt64Array) { 975 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, BigInt64Array.BYTES_PER_ELEMENT as int, typedArray.length as int, offset) 976 let mem = Atomics.requireSharedMemory(typedArray.buffer) 977 let result = mem.atomicTimedWaitI64(indexedPosition, value as long, timeout) 978 return Atomics.interpretWaitResult(result) 979 } else { 980 throw new Error("Unhandled array type!") 981 } 982 } 983 984 public static waitAsync(typedArray: Int32Array | BigInt64Array, offset: int, value: number, timeout: long): Promise<string> { 985 return launch Atomics.wait(typedArray, offset, value, timeout) 986 } 987 988 /** 989 * Notifies (wakes up) threads that are suspended by the Atomics.wait() calls at the given index. 990 * (index = typedArray.byteOffset + offset * sizeof(arrayElement)) 991 */ 992 public static notify(typedArray: Int32Array | BigInt64Array, offset: int): int { 993 if (typedArray instanceof Int32Array) { 994 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Int32Array.BYTES_PER_ELEMENT as int, typedArray.length as int, offset) 995 let buffer = typedArray.buffer 996 if (buffer instanceof ArrayBuffer) { 997 return 0 998 } else { 999 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 1000 return mem.atomicNotify(indexedPosition) 1001 } 1002 } else if (typedArray instanceof BigInt64Array) { 1003 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, BigInt64Array.BYTES_PER_ELEMENT as int, typedArray.length as int, offset) 1004 let buffer = typedArray.buffer 1005 if (buffer instanceof ArrayBuffer) { 1006 return 0 1007 } else { 1008 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 1009 return mem.atomicNotify(indexedPosition) 1010 } 1011 } else { 1012 throw new Error("Unhandled array type!") 1013 } 1014 } 1015 1016 /** 1017 * Operates exactly like Atomics.notify(Int32Array | BigInt64Array, int) but specifies the maximum number of threads to notify using 'count'. 1018 */ 1019 public static notify(typedArray: Int32Array | BigInt64Array, offset: int, count: int): int { 1020 if (typedArray instanceof Int32Array) { 1021 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, Int32Array.BYTES_PER_ELEMENT as int, typedArray.length as int, offset) 1022 let buffer = typedArray.buffer 1023 if (buffer instanceof ArrayBuffer) { 1024 return 0 1025 } else { 1026 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 1027 return mem.atomicBoundedNotify(indexedPosition, count) 1028 } 1029 } else if (typedArray instanceof BigInt64Array) { 1030 let indexedPosition = Atomics.validateAtomicAccess(typedArray.byteOffset as int, BigInt64Array.BYTES_PER_ELEMENT as int, typedArray.length as int, offset) 1031 let buffer = typedArray.buffer 1032 if (buffer instanceof ArrayBuffer) { 1033 return 0 1034 } else { 1035 let mem = (buffer as SharedArrayBuffer).getSharedMemory() 1036 return mem.atomicBoundedNotify(indexedPosition, count) 1037 } 1038 } else { 1039 throw new Error("Unhandled array type!") 1040 } 1041 } 1042} 1043