• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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