Coverage Report

Created: 2025-11-16 07:46

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/serenity/Userland/Libraries/LibJS/Runtime/AtomicsObject.cpp
Line
Count
Source
1
/*
2
 * Copyright (c) 2021, Tim Flynn <trflynn89@serenityos.org>
3
 *
4
 * SPDX-License-Identifier: BSD-2-Clause
5
 */
6
7
// This file explicitly implements support for JS Atomics API, which can
8
// involve slow (non-lock-free) atomic ops.
9
#include <AK/Platform.h>
10
11
#ifdef AK_COMPILER_CLANG
12
#    pragma clang diagnostic ignored "-Watomic-alignment"
13
#endif
14
15
#include <AK/Atomic.h>
16
#include <AK/ByteBuffer.h>
17
#include <AK/Endian.h>
18
#include <AK/TypeCasts.h>
19
#include <LibJS/Runtime/Agent.h>
20
#include <LibJS/Runtime/AtomicsObject.h>
21
#include <LibJS/Runtime/GlobalObject.h>
22
#include <LibJS/Runtime/TypedArray.h>
23
#include <LibJS/Runtime/Value.h>
24
#include <LibJS/Runtime/ValueInlines.h>
25
26
namespace JS {
27
28
JS_DEFINE_ALLOCATOR(AtomicsObject);
29
30
// 25.4.2.1 ValidateIntegerTypedArray ( typedArray, waitable ), https://tc39.es/ecma262/#sec-validateintegertypedarray
31
static ThrowCompletionOr<TypedArrayWithBufferWitness> validate_integer_typed_array(VM& vm, TypedArrayBase const& typed_array, bool waitable)
32
0
{
33
    // 1. Let taRecord be ? ValidateTypedArray(typedArray, unordered).
34
0
    auto typed_array_record = TRY(validate_typed_array(vm, typed_array, ArrayBuffer::Order::Unordered));
35
36
    // 2. NOTE: Bounds checking is not a synchronizing operation when typedArray's backing buffer is a growable SharedArrayBuffer.
37
38
0
    auto const& type_name = typed_array.element_name();
39
40
    // 3. If waitable is true, then
41
0
    if (waitable) {
42
        // a. If typedArray.[[TypedArrayName]] is neither "Int32Array" nor "BigInt64Array", throw a TypeError exception.
43
0
        if ((type_name != vm.names.Int32Array.as_string()) && (type_name != vm.names.BigInt64Array.as_string()))
44
0
            return vm.throw_completion<TypeError>(ErrorType::TypedArrayTypeIsNot, type_name, "Int32 or BigInt64"sv);
45
0
    }
46
    // 4. Else,
47
0
    else {
48
        // a. Let type be TypedArrayElementType(typedArray).
49
50
        // b. If IsUnclampedIntegerElementType(type) is false and IsBigIntElementType(type) is false, throw a TypeError exception.
51
0
        if (!typed_array.is_unclamped_integer_element_type() && !typed_array.is_bigint_element_type())
52
0
            return vm.throw_completion<TypeError>(ErrorType::TypedArrayTypeIsNot, type_name, "an unclamped integer or BigInt"sv);
53
0
    }
54
55
    // 5. Return taRecord.
56
0
    return typed_array_record;
57
0
}
58
59
// 25.4.2.2 ValidateAtomicAccess ( taRecord, requestIndex ), https://tc39.es/ecma262/#sec-validateatomicaccess
60
static ThrowCompletionOr<size_t> validate_atomic_access(VM& vm, TypedArrayWithBufferWitness const& typed_array_record, Value request_index)
61
0
{
62
    // 1. Let length be TypedArrayLength(taRecord).
63
0
    auto length = typed_array_length(typed_array_record);
64
65
    // 2. Let accessIndex be ? ToIndex(requestIndex).
66
    // 3. Assert: accessIndex ≥ 0.
67
0
    auto access_index = TRY(request_index.to_index(vm));
68
69
    // 4. If accessIndex ≥ length, throw a RangeError exception.
70
0
    if (access_index >= length)
71
0
        return vm.throw_completion<RangeError>(ErrorType::IndexOutOfRange, access_index, length);
72
73
    // 5. Let typedArray be taRecord.[[Object]].
74
0
    auto const& typed_array = *typed_array_record.object;
75
76
    // 6. Let elementSize be TypedArrayElementSize(typedArray).
77
0
    auto element_size = typed_array.element_size();
78
79
    // 7. Let offset be typedArray.[[ByteOffset]].
80
0
    auto offset = typed_array.byte_offset();
81
82
    // 8. Return (accessIndex × elementSize) + offset.
83
0
    return (access_index * element_size) + offset;
84
0
}
85
86
// 25.4.3.3 ValidateAtomicAccessOnIntegerTypedArray ( typedArray, requestIndex [ , waitable ] ), https://tc39.es/ecma262/#sec-validateatomicaccessonintegertypedarray
87
static ThrowCompletionOr<size_t> validate_atomic_access_on_integer_typed_array(VM& vm, TypedArrayBase const& typed_array, Value request_index, bool waitable = false)
88
0
{
89
    // 1. If waitable is not present, set waitable to false.
90
91
    // 2. Let taRecord be ? ValidateIntegerTypedArray(typedArray, waitable).
92
0
    auto typed_array_record = TRY(validate_integer_typed_array(vm, typed_array, waitable));
93
94
    // 3. Return ? ValidateAtomicAccess(taRecord, requestIndex).
95
0
    return TRY(validate_atomic_access(vm, typed_array_record, request_index));
96
0
}
97
98
// 25.4.3.4 RevalidateAtomicAccess ( typedArray, byteIndexInBuffer ), https://tc39.es/ecma262/#sec-revalidateatomicaccess
99
static ThrowCompletionOr<void> revalidate_atomic_access(VM& vm, TypedArrayBase const& typed_array, size_t byte_index_in_buffer)
100
0
{
101
    // 1. Let taRecord be MakeTypedArrayWithBufferWitnessRecord(typedArray, unordered).
102
0
    auto typed_array_record = make_typed_array_with_buffer_witness_record(typed_array, ArrayBuffer::Order::Unordered);
103
104
    // 2. NOTE: Bounds checking is not a synchronizing operation when typedArray's backing buffer is a growable SharedArrayBuffer.
105
    // 3. If IsTypedArrayOutOfBounds(taRecord) is true, throw a TypeError exception.
106
0
    if (is_typed_array_out_of_bounds(typed_array_record))
107
0
        return vm.throw_completion<TypeError>(ErrorType::BufferOutOfBounds, "TypedArray"sv);
108
109
    // 4. Assert: byteIndexInBuffer ≥ typedArray.[[ByteOffset]].
110
0
    VERIFY(byte_index_in_buffer >= typed_array.byte_offset());
111
112
    // 5. If byteIndexInBuffer ≥ taRecord.[[CachedBufferByteLength]], throw a RangeError exception.
113
0
    if (byte_index_in_buffer >= typed_array_record.cached_buffer_byte_length.length())
114
0
        return vm.throw_completion<RangeError>(ErrorType::IndexOutOfRange, byte_index_in_buffer, typed_array_record.cached_buffer_byte_length.length());
115
116
    // 6. Return unused.
117
0
    return {};
118
0
}
119
120
// 25.4.2.17 AtomicReadModifyWrite ( typedArray, index, value, op ), https://tc39.es/ecma262/#sec-atomicreadmodifywrite
121
static ThrowCompletionOr<Value> atomic_read_modify_write(VM& vm, TypedArrayBase& typed_array, Value index, Value value, ReadWriteModifyFunction operation)
122
0
{
123
    // 1. Let byteIndexInBuffer be ? ValidateAtomicAccessOnIntegerTypedArray(typedArray, index).
124
0
    auto byte_index_in_buffer = TRY(validate_atomic_access_on_integer_typed_array(vm, typed_array, index));
125
126
0
    Value value_to_set;
127
128
    // 2. If typedArray.[[ContentType]] is bigint, let v be ? ToBigInt(value).
129
0
    if (typed_array.content_type() == TypedArrayBase::ContentType::BigInt)
130
0
        value_to_set = TRY(value.to_bigint(vm));
131
    // 3. Otherwise, let v be 𝔽(? ToIntegerOrInfinity(value)).
132
0
    else
133
0
        value_to_set = Value(TRY(value.to_integer_or_infinity(vm)));
134
135
    // 4. Perform ? RevalidateAtomicAccess(typedArray, byteIndexInBuffer).
136
0
    TRY(revalidate_atomic_access(vm, typed_array, byte_index_in_buffer));
137
138
    // 5. Let buffer be typedArray.[[ViewedArrayBuffer]].
139
    // 6. Let elementType be TypedArrayElementType(typedArray).
140
    // 7. Return GetModifySetValueInBuffer(buffer, byteIndexInBuffer, elementType, v, op).
141
0
    return typed_array.get_modify_set_value_in_buffer(byte_index_in_buffer, value_to_set, move(operation));
142
0
}
143
144
enum class WaitMode {
145
    Sync,
146
    Async,
147
};
148
149
// 25.4.3.14 DoWait ( mode, typedArray, index, value, timeout ), https://tc39.es/ecma262/#sec-dowait
150
static ThrowCompletionOr<Value> do_wait(VM& vm, WaitMode mode, TypedArrayBase& typed_array, Value index_value, Value expected_value, Value timeout_value)
151
0
{
152
    // 1. Let taRecord be ? ValidateIntegerTypedArray(typedArray, true).
153
0
    auto typed_array_record = TRY(validate_integer_typed_array(vm, typed_array, true));
154
155
    // 2. Let buffer be taRecord.[[Object]].[[ViewedArrayBuffer]].
156
0
    auto* buffer = typed_array_record.object->viewed_array_buffer();
157
158
    // 3. If IsSharedArrayBuffer(buffer) is false, throw a TypeError exception.
159
0
    if (!buffer->is_shared_array_buffer())
160
0
        return vm.throw_completion<TypeError>(ErrorType::NotASharedArrayBuffer);
161
162
    // 4. Let i be ? ValidateAtomicAccess(taRecord, index).
163
0
    auto index = TRY(validate_atomic_access(vm, typed_array_record, index_value));
164
165
    // 5. Let arrayTypeName be typedArray.[[TypedArrayName]].
166
0
    auto const& array_type_name = typed_array.element_name();
167
168
    // 6. If arrayTypeName is "BigInt64Array", let v be ? ToBigInt64(value).
169
0
    i64 value = 0;
170
0
    if (array_type_name == vm.names.BigInt64Array.as_string())
171
0
        value = TRY(expected_value.to_bigint_int64(vm));
172
    // 7. Else, let v be ? ToInt32(value).
173
0
    else
174
0
        value = TRY(expected_value.to_i32(vm));
175
176
    // 8. Let q be ? ToNumber(timeout).
177
0
    auto timeout_number = TRY(timeout_value.to_number(vm));
178
179
    // 9. If q is either NaN or +∞𝔽, let t be +∞; else if q is -∞𝔽, let t be 0; else let t be max(ℝ(q), 0).
180
0
    double timeout = 0;
181
0
    if (timeout_number.is_nan() || timeout_number.is_positive_infinity())
182
0
        timeout = js_infinity().as_double();
183
0
    else if (timeout_number.is_negative_infinity())
184
0
        timeout = 0.0;
185
0
    else
186
0
        timeout = max(timeout_number.as_double(), 0.0);
187
188
    // 10. If mode is sync and AgentCanSuspend() is false, throw a TypeError exception.
189
0
    if (mode == WaitMode::Sync && !agent_can_suspend())
190
0
        return vm.throw_completion<TypeError>(ErrorType::AgentCannotSuspend);
191
192
    // FIXME: Implement the remaining steps when we support SharedArrayBuffer.
193
0
    (void)index;
194
0
    (void)value;
195
0
    (void)timeout;
196
197
0
    return vm.throw_completion<InternalError>(ErrorType::NotImplemented, "SharedArrayBuffer"sv);
198
0
}
199
200
template<typename T, typename AtomicFunction>
201
static ThrowCompletionOr<Value> perform_atomic_operation(VM& vm, TypedArrayBase& typed_array, AtomicFunction&& operation)
202
0
{
203
0
    auto index = vm.argument(1);
204
0
    auto value = vm.argument(2);
205
206
0
    auto operation_wrapper = [&, operation = forward<AtomicFunction>(operation)](ByteBuffer x_bytes, ByteBuffer y_bytes) -> ByteBuffer {
207
0
        if constexpr (IsFloatingPoint<T>) {
208
0
            (void)operation;
209
0
            VERIFY_NOT_REACHED();
210
0
        } else {
211
0
            using U = Conditional<IsSame<ClampedU8, T>, u8, T>;
212
213
0
            auto* x = reinterpret_cast<U*>(x_bytes.data());
214
0
            auto* y = reinterpret_cast<U*>(y_bytes.data());
215
0
            operation(x, *y);
216
217
0
            return x_bytes;
218
0
        }
219
0
    };
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<unsigned char, JS::AtomicsObject::add(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::add(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<JS::ClampedU8, JS::AtomicsObject::add(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::add(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<unsigned short, JS::AtomicsObject::add(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::add(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<unsigned int, JS::AtomicsObject::add(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::add(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<unsigned long, JS::AtomicsObject::add(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::add(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<signed char, JS::AtomicsObject::add(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::add(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<short, JS::AtomicsObject::add(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::add(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<int, JS::AtomicsObject::add(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::add(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<long, JS::AtomicsObject::add(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::add(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<float, JS::AtomicsObject::add(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::add(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<double, JS::AtomicsObject::add(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::add(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<unsigned char, JS::AtomicsObject::and_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::and_(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<JS::ClampedU8, JS::AtomicsObject::and_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::and_(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<unsigned short, JS::AtomicsObject::and_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::and_(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<unsigned int, JS::AtomicsObject::and_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::and_(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<unsigned long, JS::AtomicsObject::and_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::and_(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<signed char, JS::AtomicsObject::and_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::and_(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<short, JS::AtomicsObject::and_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::and_(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<int, JS::AtomicsObject::and_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::and_(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<long, JS::AtomicsObject::and_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::and_(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<float, JS::AtomicsObject::and_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::and_(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<double, JS::AtomicsObject::and_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::and_(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<unsigned char, JS::AtomicsObject::exchange(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::exchange(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<JS::ClampedU8, JS::AtomicsObject::exchange(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::exchange(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<unsigned short, JS::AtomicsObject::exchange(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::exchange(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<unsigned int, JS::AtomicsObject::exchange(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::exchange(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<unsigned long, JS::AtomicsObject::exchange(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::exchange(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<signed char, JS::AtomicsObject::exchange(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::exchange(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<short, JS::AtomicsObject::exchange(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::exchange(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<int, JS::AtomicsObject::exchange(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::exchange(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<long, JS::AtomicsObject::exchange(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::exchange(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<float, JS::AtomicsObject::exchange(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::exchange(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<double, JS::AtomicsObject::exchange(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::exchange(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<unsigned char, JS::AtomicsObject::or_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::or_(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<JS::ClampedU8, JS::AtomicsObject::or_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::or_(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<unsigned short, JS::AtomicsObject::or_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::or_(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<unsigned int, JS::AtomicsObject::or_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::or_(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<unsigned long, JS::AtomicsObject::or_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::or_(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<signed char, JS::AtomicsObject::or_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::or_(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<short, JS::AtomicsObject::or_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::or_(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<int, JS::AtomicsObject::or_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::or_(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<long, JS::AtomicsObject::or_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::or_(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<float, JS::AtomicsObject::or_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::or_(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<double, JS::AtomicsObject::or_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::or_(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<unsigned char, JS::AtomicsObject::sub(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::sub(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<JS::ClampedU8, JS::AtomicsObject::sub(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::sub(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<unsigned short, JS::AtomicsObject::sub(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::sub(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<unsigned int, JS::AtomicsObject::sub(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::sub(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<unsigned long, JS::AtomicsObject::sub(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::sub(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<signed char, JS::AtomicsObject::sub(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::sub(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<short, JS::AtomicsObject::sub(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::sub(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<int, JS::AtomicsObject::sub(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::sub(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<long, JS::AtomicsObject::sub(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::sub(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<float, JS::AtomicsObject::sub(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::sub(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<double, JS::AtomicsObject::sub(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::sub(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<unsigned char, JS::AtomicsObject::xor_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::xor_(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<JS::ClampedU8, JS::AtomicsObject::xor_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::xor_(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<unsigned short, JS::AtomicsObject::xor_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::xor_(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<unsigned int, JS::AtomicsObject::xor_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::xor_(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<unsigned long, JS::AtomicsObject::xor_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::xor_(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<signed char, JS::AtomicsObject::xor_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::xor_(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<short, JS::AtomicsObject::xor_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::xor_(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<int, JS::AtomicsObject::xor_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::xor_(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<long, JS::AtomicsObject::xor_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::xor_(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<float, JS::AtomicsObject::xor_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::xor_(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
Unexecuted instantiation: AtomicsObject.cpp:JS::perform_atomic_operation<double, JS::AtomicsObject::xor_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::xor_(JS::VM&)::$_0&&)::{lambda(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>)#1}::operator()(AK::Detail::ByteBuffer<32ul>, AK::Detail::ByteBuffer<32ul>) const
220
221
0
    return atomic_read_modify_write(vm, typed_array, index, value, move(operation_wrapper));
222
0
}
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<unsigned char, JS::AtomicsObject::add(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::add(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<JS::ClampedU8, JS::AtomicsObject::add(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::add(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<unsigned short, JS::AtomicsObject::add(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::add(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<unsigned int, JS::AtomicsObject::add(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::add(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<unsigned long, JS::AtomicsObject::add(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::add(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<signed char, JS::AtomicsObject::add(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::add(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<short, JS::AtomicsObject::add(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::add(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<int, JS::AtomicsObject::add(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::add(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<long, JS::AtomicsObject::add(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::add(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<float, JS::AtomicsObject::add(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::add(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<double, JS::AtomicsObject::add(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::add(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<unsigned char, JS::AtomicsObject::and_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::and_(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<JS::ClampedU8, JS::AtomicsObject::and_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::and_(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<unsigned short, JS::AtomicsObject::and_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::and_(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<unsigned int, JS::AtomicsObject::and_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::and_(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<unsigned long, JS::AtomicsObject::and_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::and_(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<signed char, JS::AtomicsObject::and_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::and_(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<short, JS::AtomicsObject::and_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::and_(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<int, JS::AtomicsObject::and_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::and_(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<long, JS::AtomicsObject::and_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::and_(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<float, JS::AtomicsObject::and_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::and_(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<double, JS::AtomicsObject::and_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::and_(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<unsigned char, JS::AtomicsObject::exchange(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::exchange(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<JS::ClampedU8, JS::AtomicsObject::exchange(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::exchange(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<unsigned short, JS::AtomicsObject::exchange(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::exchange(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<unsigned int, JS::AtomicsObject::exchange(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::exchange(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<unsigned long, JS::AtomicsObject::exchange(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::exchange(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<signed char, JS::AtomicsObject::exchange(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::exchange(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<short, JS::AtomicsObject::exchange(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::exchange(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<int, JS::AtomicsObject::exchange(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::exchange(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<long, JS::AtomicsObject::exchange(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::exchange(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<float, JS::AtomicsObject::exchange(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::exchange(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<double, JS::AtomicsObject::exchange(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::exchange(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<unsigned char, JS::AtomicsObject::or_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::or_(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<JS::ClampedU8, JS::AtomicsObject::or_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::or_(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<unsigned short, JS::AtomicsObject::or_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::or_(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<unsigned int, JS::AtomicsObject::or_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::or_(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<unsigned long, JS::AtomicsObject::or_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::or_(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<signed char, JS::AtomicsObject::or_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::or_(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<short, JS::AtomicsObject::or_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::or_(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<int, JS::AtomicsObject::or_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::or_(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<long, JS::AtomicsObject::or_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::or_(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<float, JS::AtomicsObject::or_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::or_(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<double, JS::AtomicsObject::or_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::or_(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<unsigned char, JS::AtomicsObject::sub(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::sub(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<JS::ClampedU8, JS::AtomicsObject::sub(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::sub(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<unsigned short, JS::AtomicsObject::sub(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::sub(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<unsigned int, JS::AtomicsObject::sub(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::sub(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<unsigned long, JS::AtomicsObject::sub(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::sub(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<signed char, JS::AtomicsObject::sub(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::sub(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<short, JS::AtomicsObject::sub(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::sub(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<int, JS::AtomicsObject::sub(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::sub(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<long, JS::AtomicsObject::sub(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::sub(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<float, JS::AtomicsObject::sub(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::sub(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<double, JS::AtomicsObject::sub(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::sub(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<unsigned char, JS::AtomicsObject::xor_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::xor_(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<JS::ClampedU8, JS::AtomicsObject::xor_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::xor_(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<unsigned short, JS::AtomicsObject::xor_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::xor_(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<unsigned int, JS::AtomicsObject::xor_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::xor_(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<unsigned long, JS::AtomicsObject::xor_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::xor_(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<signed char, JS::AtomicsObject::xor_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::xor_(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<short, JS::AtomicsObject::xor_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::xor_(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<int, JS::AtomicsObject::xor_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::xor_(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<long, JS::AtomicsObject::xor_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::xor_(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<float, JS::AtomicsObject::xor_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::xor_(JS::VM&)::$_0&&)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::perform_atomic_operation<double, JS::AtomicsObject::xor_(JS::VM&)::$_0>(JS::VM&, JS::TypedArrayBase&, JS::AtomicsObject::xor_(JS::VM&)::$_0&&)
223
224
AtomicsObject::AtomicsObject(Realm& realm)
225
0
    : Object(ConstructWithPrototypeTag::Tag, realm.intrinsics().object_prototype())
226
0
{
227
0
}
228
229
void AtomicsObject::initialize(Realm& realm)
230
0
{
231
0
    Base::initialize(realm);
232
0
    auto& vm = this->vm();
233
234
0
    u8 attr = Attribute::Writable | Attribute::Configurable;
235
0
    define_native_function(realm, vm.names.add, add, 3, attr);
236
0
    define_native_function(realm, vm.names.and_, and_, 3, attr);
237
0
    define_native_function(realm, vm.names.compareExchange, compare_exchange, 4, attr);
238
0
    define_native_function(realm, vm.names.exchange, exchange, 3, attr);
239
0
    define_native_function(realm, vm.names.isLockFree, is_lock_free, 1, attr);
240
0
    define_native_function(realm, vm.names.load, load, 2, attr);
241
0
    define_native_function(realm, vm.names.or_, or_, 3, attr);
242
0
    define_native_function(realm, vm.names.store, store, 3, attr);
243
0
    define_native_function(realm, vm.names.sub, sub, 3, attr);
244
0
    define_native_function(realm, vm.names.wait, wait, 4, attr);
245
0
    define_native_function(realm, vm.names.waitAsync, wait_async, 4, attr);
246
0
    define_native_function(realm, vm.names.notify, notify, 3, attr);
247
0
    define_native_function(realm, vm.names.xor_, xor_, 3, attr);
248
249
    // 25.4.17 Atomics [ @@toStringTag ], https://tc39.es/ecma262/#sec-atomics-@@tostringtag
250
0
    define_direct_property(vm.well_known_symbol_to_string_tag(), PrimitiveString::create(vm, "Atomics"_string), Attribute::Configurable);
251
0
}
252
253
// 25.4.4 Atomics.add ( typedArray, index, value ), https://tc39.es/ecma262/#sec-atomics.add
254
JS_DEFINE_NATIVE_FUNCTION(AtomicsObject::add)
255
0
{
256
0
    auto* typed_array = TRY(typed_array_from(vm, vm.argument(0)));
257
258
0
    auto atomic_add = [](auto* storage, auto value) { return AK::atomic_fetch_add(storage, value); };
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::add(JS::VM&)::$_0::operator()<unsigned char, unsigned char>(unsigned char*, unsigned char) const
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::add(JS::VM&)::$_0::operator()<unsigned short, unsigned short>(unsigned short*, unsigned short) const
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::add(JS::VM&)::$_0::operator()<unsigned int, unsigned int>(unsigned int*, unsigned int) const
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::add(JS::VM&)::$_0::operator()<unsigned long, unsigned long>(unsigned long*, unsigned long) const
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::add(JS::VM&)::$_0::operator()<signed char, signed char>(signed char*, signed char) const
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::add(JS::VM&)::$_0::operator()<short, short>(short*, short) const
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::add(JS::VM&)::$_0::operator()<int, int>(int*, int) const
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::add(JS::VM&)::$_0::operator()<long, long>(long*, long) const
259
260
0
#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName, Type) \
261
0
    if (is<ClassName>(typed_array))                                                 \
262
0
        return TRY(perform_atomic_operation<Type>(vm, *typed_array, move(atomic_add)));
263
0
    JS_ENUMERATE_TYPED_ARRAYS
264
0
#undef __JS_ENUMERATE
265
266
0
    VERIFY_NOT_REACHED();
267
0
}
268
269
// 25.4.5 Atomics.and ( typedArray, index, value ), https://tc39.es/ecma262/#sec-atomics.and
270
JS_DEFINE_NATIVE_FUNCTION(AtomicsObject::and_)
271
0
{
272
0
    auto* typed_array = TRY(typed_array_from(vm, vm.argument(0)));
273
274
0
    auto atomic_and = [](auto* storage, auto value) { return AK::atomic_fetch_and(storage, value); };
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::and_(JS::VM&)::$_0::operator()<unsigned char, unsigned char>(unsigned char*, unsigned char) const
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::and_(JS::VM&)::$_0::operator()<unsigned short, unsigned short>(unsigned short*, unsigned short) const
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::and_(JS::VM&)::$_0::operator()<unsigned int, unsigned int>(unsigned int*, unsigned int) const
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::and_(JS::VM&)::$_0::operator()<unsigned long, unsigned long>(unsigned long*, unsigned long) const
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::and_(JS::VM&)::$_0::operator()<signed char, signed char>(signed char*, signed char) const
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::and_(JS::VM&)::$_0::operator()<short, short>(short*, short) const
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::and_(JS::VM&)::$_0::operator()<int, int>(int*, int) const
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::and_(JS::VM&)::$_0::operator()<long, long>(long*, long) const
275
276
0
#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName, Type) \
277
0
    if (is<ClassName>(typed_array))                                                 \
278
0
        return TRY(perform_atomic_operation<Type>(vm, *typed_array, move(atomic_and)));
279
0
    JS_ENUMERATE_TYPED_ARRAYS
280
0
#undef __JS_ENUMERATE
281
282
0
    VERIFY_NOT_REACHED();
283
0
}
284
285
// 25.4.6 Atomics.compareExchange ( typedArray, index, expectedValue, replacementValue ), https://tc39.es/ecma262/#sec-atomics.compareexchange
286
template<typename T>
287
static ThrowCompletionOr<Value> atomic_compare_exchange_impl(VM& vm, TypedArrayBase& typed_array, Value index, Value expected_value, Value replacement_value)
288
0
{
289
    // 1. Let byteIndexInBuffer be ? ValidateAtomicAccessOnIntegerTypedArray(typedArray, index).
290
0
    auto byte_index_in_buffer = TRY(validate_atomic_access_on_integer_typed_array(vm, typed_array, index));
291
292
0
    Value expected;
293
0
    Value replacement;
294
295
    // 4. If typedArray.[[ContentType]] is bigint, then
296
0
    if (typed_array.content_type() == TypedArrayBase::ContentType::BigInt) {
297
        // a. Let expected be ? ToBigInt(expectedValue).
298
0
        expected = TRY(expected_value.to_bigint(vm));
299
300
        // b. Let replacement be ? ToBigInt(replacementValue).
301
0
        replacement = TRY(replacement_value.to_bigint(vm));
302
0
    }
303
    // 5. Else,
304
0
    else {
305
        // a. Let expected be 𝔽(? ToIntegerOrInfinity(expectedValue)).
306
0
        expected = Value(TRY(expected_value.to_integer_or_infinity(vm)));
307
308
        // b. Let replacement be 𝔽(? ToIntegerOrInfinity(replacementValue)).
309
0
        replacement = Value(TRY(replacement_value.to_integer_or_infinity(vm)));
310
0
    }
311
312
    // 6. Perform ? RevalidateAtomicAccess(typedArray, byteIndexInBuffer).
313
0
    TRY(revalidate_atomic_access(vm, typed_array, byte_index_in_buffer));
314
315
    // NOTE: We defer steps 2 and 3 to ensure we have revalidated the TA before accessing these internal slots.
316
    //       In our implementation, accessing [[ArrayBufferData]] on a detached buffer will fail assertions.
317
318
    // 2. Let buffer be typedArray.[[ViewedArrayBuffer]].
319
0
    auto* buffer = typed_array.viewed_array_buffer();
320
321
    // 3. Let block be buffer.[[ArrayBufferData]].
322
0
    auto& block = buffer->buffer();
323
324
    // 7. Let elementType be TypedArrayElementType(typedArray).
325
    // 8. Let elementSize be TypedArrayElementSize(typedArray).
326
327
    // 9. Let isLittleEndian be the value of the [[LittleEndian]] field of the surrounding agent's Agent Record.
328
0
    static constexpr bool is_little_endian = AK::HostIsLittleEndian;
329
330
    // 10. Let expectedBytes be NumericToRawBytes(elementType, expected, isLittleEndian).
331
0
    auto expected_bytes = MUST(ByteBuffer::create_uninitialized(sizeof(T)));
332
0
    numeric_to_raw_bytes<T>(vm, expected, is_little_endian, expected_bytes);
333
334
    // 11. Let replacementBytes be NumericToRawBytes(elementType, replacement, isLittleEndian).
335
0
    auto replacement_bytes = MUST(ByteBuffer::create_uninitialized(sizeof(T)));
336
0
    numeric_to_raw_bytes<T>(vm, replacement, is_little_endian, replacement_bytes);
337
338
    // FIXME: Implement SharedArrayBuffer case.
339
    // 12. If IsSharedArrayBuffer(buffer) is true, then
340
    //     a. Let rawBytesRead be AtomicCompareExchangeInSharedBlock(block, byteIndexInBuffer, elementSize, expectedBytes, replacementBytes).
341
    // 13. Else,
342
343
    // a. Let rawBytesRead be a List of length elementSize whose elements are the sequence of elementSize bytes starting with block[byteIndexInBuffer].
344
    // FIXME: Propagate errors.
345
0
    auto raw_bytes_read = MUST(block.slice(byte_index_in_buffer, sizeof(T)));
346
347
    // b. If ByteListEqual(rawBytesRead, expectedBytes) is true, then
348
    //    i. Store the individual bytes of replacementBytes into block, starting at block[byteIndexInBuffer].
349
0
    if constexpr (IsFloatingPoint<T>) {
350
0
        VERIFY_NOT_REACHED();
351
0
    } else {
352
0
        using U = Conditional<IsSame<ClampedU8, T>, u8, T>;
353
354
0
        auto* v = reinterpret_cast<U*>(block.span().slice(byte_index_in_buffer).data());
355
0
        auto* e = reinterpret_cast<U*>(expected_bytes.data());
356
0
        auto* r = reinterpret_cast<U*>(replacement_bytes.data());
357
0
        (void)AK::atomic_compare_exchange_strong(v, *e, *r);
358
0
    }
359
360
    // 14. Return RawBytesToNumeric(elementType, rawBytesRead, isLittleEndian).
361
0
    return raw_bytes_to_numeric<T>(vm, raw_bytes_read, is_little_endian);
362
0
}
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::atomic_compare_exchange_impl<unsigned char>(JS::VM&, JS::TypedArrayBase&, JS::Value, JS::Value, JS::Value)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::atomic_compare_exchange_impl<JS::ClampedU8>(JS::VM&, JS::TypedArrayBase&, JS::Value, JS::Value, JS::Value)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::atomic_compare_exchange_impl<unsigned short>(JS::VM&, JS::TypedArrayBase&, JS::Value, JS::Value, JS::Value)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::atomic_compare_exchange_impl<unsigned int>(JS::VM&, JS::TypedArrayBase&, JS::Value, JS::Value, JS::Value)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::atomic_compare_exchange_impl<unsigned long>(JS::VM&, JS::TypedArrayBase&, JS::Value, JS::Value, JS::Value)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::atomic_compare_exchange_impl<signed char>(JS::VM&, JS::TypedArrayBase&, JS::Value, JS::Value, JS::Value)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::atomic_compare_exchange_impl<short>(JS::VM&, JS::TypedArrayBase&, JS::Value, JS::Value, JS::Value)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::atomic_compare_exchange_impl<int>(JS::VM&, JS::TypedArrayBase&, JS::Value, JS::Value, JS::Value)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::atomic_compare_exchange_impl<long>(JS::VM&, JS::TypedArrayBase&, JS::Value, JS::Value, JS::Value)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::atomic_compare_exchange_impl<float>(JS::VM&, JS::TypedArrayBase&, JS::Value, JS::Value, JS::Value)
Unexecuted instantiation: AtomicsObject.cpp:JS::ThrowCompletionOr<JS::Value> JS::atomic_compare_exchange_impl<double>(JS::VM&, JS::TypedArrayBase&, JS::Value, JS::Value, JS::Value)
363
364
// 25.4.6 Atomics.compareExchange ( typedArray, index, expectedValue, replacementValue ), https://tc39.es/ecma262/#sec-atomics.compareexchange
365
JS_DEFINE_NATIVE_FUNCTION(AtomicsObject::compare_exchange)
366
0
{
367
0
    auto* typed_array = TRY(typed_array_from(vm, vm.argument(0)));
368
0
    auto index = vm.argument(1);
369
0
    auto expected_value = vm.argument(2);
370
0
    auto replacement_value = vm.argument(3);
371
372
0
#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName, Type) \
373
0
    if (is<ClassName>(typed_array))                                                 \
374
0
        return TRY(atomic_compare_exchange_impl<Type>(vm, *typed_array, index, expected_value, replacement_value));
375
0
    JS_ENUMERATE_TYPED_ARRAYS
376
0
#undef __JS_ENUMERATE
377
378
0
    VERIFY_NOT_REACHED();
379
0
}
380
381
// 25.4.7 Atomics.exchange ( typedArray, index, value ), https://tc39.es/ecma262/#sec-atomics.exchange
382
JS_DEFINE_NATIVE_FUNCTION(AtomicsObject::exchange)
383
0
{
384
0
    auto* typed_array = TRY(typed_array_from(vm, vm.argument(0)));
385
386
0
    auto atomic_exchange = [](auto* storage, auto value) { return AK::atomic_exchange(storage, value); };
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::exchange(JS::VM&)::$_0::operator()<unsigned char, unsigned char>(unsigned char*, unsigned char) const
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::exchange(JS::VM&)::$_0::operator()<unsigned short, unsigned short>(unsigned short*, unsigned short) const
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::exchange(JS::VM&)::$_0::operator()<unsigned int, unsigned int>(unsigned int*, unsigned int) const
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::exchange(JS::VM&)::$_0::operator()<unsigned long, unsigned long>(unsigned long*, unsigned long) const
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::exchange(JS::VM&)::$_0::operator()<signed char, signed char>(signed char*, signed char) const
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::exchange(JS::VM&)::$_0::operator()<short, short>(short*, short) const
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::exchange(JS::VM&)::$_0::operator()<int, int>(int*, int) const
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::exchange(JS::VM&)::$_0::operator()<long, long>(long*, long) const
387
388
0
#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName, Type) \
389
0
    if (is<ClassName>(typed_array))                                                 \
390
0
        return TRY(perform_atomic_operation<Type>(vm, *typed_array, move(atomic_exchange)));
391
0
    JS_ENUMERATE_TYPED_ARRAYS
392
0
#undef __JS_ENUMERATE
393
394
0
    VERIFY_NOT_REACHED();
395
0
}
396
397
// 25.4.8 Atomics.isLockFree ( size ), https://tc39.es/ecma262/#sec-atomics.islockfree
398
JS_DEFINE_NATIVE_FUNCTION(AtomicsObject::is_lock_free)
399
0
{
400
0
    auto size = TRY(vm.argument(0).to_integer_or_infinity(vm));
401
0
    if (size == 1)
402
0
        return Value(AK::atomic_is_lock_free<u8>());
403
0
    if (size == 2)
404
0
        return Value(AK::atomic_is_lock_free<u16>());
405
0
    if (size == 4)
406
0
        return Value(true);
407
0
    if (size == 8)
408
0
        return Value(AK::atomic_is_lock_free<u64>());
409
0
    return Value(false);
410
0
}
411
412
// 25.4.9 Atomics.load ( typedArray, index ), https://tc39.es/ecma262/#sec-atomics.load
413
JS_DEFINE_NATIVE_FUNCTION(AtomicsObject::load)
414
0
{
415
0
    auto* typed_array = TRY(typed_array_from(vm, vm.argument(0)));
416
0
    auto index = vm.argument(1);
417
418
    // 1. Let byteIndexInBuffer be ? ValidateAtomicAccessOnIntegerTypedArray(typedArray, index).
419
0
    auto byte_index_in_buffer = TRY(validate_atomic_access_on_integer_typed_array(vm, *typed_array, index));
420
421
    // 2. Perform ? RevalidateAtomicAccess(typedArray, byteIndexInBuffer).
422
0
    TRY(revalidate_atomic_access(vm, *typed_array, byte_index_in_buffer));
423
424
    // 3. Let buffer be typedArray.[[ViewedArrayBuffer]].
425
    // 4. Let elementType be TypedArrayElementType(typedArray).
426
    // 5. Return GetValueFromBuffer(buffer, byteIndexInBuffer, elementType, true, seq-cst).
427
0
    return typed_array->get_value_from_buffer(byte_index_in_buffer, ArrayBuffer::Order::SeqCst, true);
428
0
}
429
430
// 25.4.10 Atomics.or ( typedArray, index, value ), https://tc39.es/ecma262/#sec-atomics.or
431
JS_DEFINE_NATIVE_FUNCTION(AtomicsObject::or_)
432
0
{
433
0
    auto* typed_array = TRY(typed_array_from(vm, vm.argument(0)));
434
435
0
    auto atomic_or = [](auto* storage, auto value) { return AK::atomic_fetch_or(storage, value); };
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::or_(JS::VM&)::$_0::operator()<unsigned char, unsigned char>(unsigned char*, unsigned char) const
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::or_(JS::VM&)::$_0::operator()<unsigned short, unsigned short>(unsigned short*, unsigned short) const
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::or_(JS::VM&)::$_0::operator()<unsigned int, unsigned int>(unsigned int*, unsigned int) const
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::or_(JS::VM&)::$_0::operator()<unsigned long, unsigned long>(unsigned long*, unsigned long) const
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::or_(JS::VM&)::$_0::operator()<signed char, signed char>(signed char*, signed char) const
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::or_(JS::VM&)::$_0::operator()<short, short>(short*, short) const
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::or_(JS::VM&)::$_0::operator()<int, int>(int*, int) const
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::or_(JS::VM&)::$_0::operator()<long, long>(long*, long) const
436
437
0
#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName, Type) \
438
0
    if (is<ClassName>(typed_array))                                                 \
439
0
        return TRY(perform_atomic_operation<Type>(vm, *typed_array, move(atomic_or)));
440
0
    JS_ENUMERATE_TYPED_ARRAYS
441
0
#undef __JS_ENUMERATE
442
443
0
    VERIFY_NOT_REACHED();
444
0
}
445
446
// 25.4.11 Atomics.store ( typedArray, index, value ), https://tc39.es/ecma262/#sec-atomics.store
447
JS_DEFINE_NATIVE_FUNCTION(AtomicsObject::store)
448
0
{
449
0
    auto* typed_array = TRY(typed_array_from(vm, vm.argument(0)));
450
0
    auto index = vm.argument(1);
451
0
    auto value = vm.argument(2);
452
453
    // 1. Let byteIndexInBuffer be ? ValidateAtomicAccessOnIntegerTypedArray(typedArray, index).
454
0
    auto byte_index_in_buffer = TRY(validate_atomic_access_on_integer_typed_array(vm, *typed_array, index));
455
456
    // 2. If typedArray.[[ContentType]] is bigint, let v be ? ToBigInt(value).
457
0
    if (typed_array->content_type() == TypedArrayBase::ContentType::BigInt)
458
0
        value = TRY(value.to_bigint(vm));
459
    // 3. Otherwise, let v be 𝔽(? ToIntegerOrInfinity(value)).
460
0
    else
461
0
        value = Value(TRY(value.to_integer_or_infinity(vm)));
462
463
    // 4. Perform ? RevalidateAtomicAccess(typedArray, byteIndexInBuffer).
464
0
    TRY(revalidate_atomic_access(vm, *typed_array, byte_index_in_buffer));
465
466
    // 5. Let buffer be typedArray.[[ViewedArrayBuffer]].
467
    // 6. Let elementType be TypedArrayElementType(typedArray).
468
    // 7. Perform SetValueInBuffer(buffer, byteIndexInBuffer, elementType, v, true, seq-cst).
469
0
    typed_array->set_value_in_buffer(byte_index_in_buffer, value, ArrayBuffer::Order::SeqCst, true);
470
471
    // 8. Return v.
472
0
    return value;
473
0
}
474
475
// 25.4.12 Atomics.sub ( typedArray, index, value ), https://tc39.es/ecma262/#sec-atomics.sub
476
JS_DEFINE_NATIVE_FUNCTION(AtomicsObject::sub)
477
0
{
478
0
    auto* typed_array = TRY(typed_array_from(vm, vm.argument(0)));
479
480
0
    auto atomic_sub = [](auto* storage, auto value) { return AK::atomic_fetch_sub(storage, value); };
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::sub(JS::VM&)::$_0::operator()<unsigned char, unsigned char>(unsigned char*, unsigned char) const
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::sub(JS::VM&)::$_0::operator()<unsigned short, unsigned short>(unsigned short*, unsigned short) const
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::sub(JS::VM&)::$_0::operator()<unsigned int, unsigned int>(unsigned int*, unsigned int) const
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::sub(JS::VM&)::$_0::operator()<unsigned long, unsigned long>(unsigned long*, unsigned long) const
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::sub(JS::VM&)::$_0::operator()<signed char, signed char>(signed char*, signed char) const
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::sub(JS::VM&)::$_0::operator()<short, short>(short*, short) const
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::sub(JS::VM&)::$_0::operator()<int, int>(int*, int) const
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::sub(JS::VM&)::$_0::operator()<long, long>(long*, long) const
481
482
0
#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName, Type) \
483
0
    if (is<ClassName>(typed_array))                                                 \
484
0
        return TRY(perform_atomic_operation<Type>(vm, *typed_array, move(atomic_sub)));
485
0
    JS_ENUMERATE_TYPED_ARRAYS
486
0
#undef __JS_ENUMERATE
487
488
0
    VERIFY_NOT_REACHED();
489
0
}
490
491
// 25.4.13 Atomics.wait ( typedArray, index, value, timeout ), https://tc39.es/ecma262/#sec-atomics.wait
492
JS_DEFINE_NATIVE_FUNCTION(AtomicsObject::wait)
493
0
{
494
0
    auto* typed_array = TRY(typed_array_from(vm, vm.argument(0)));
495
0
    auto index = vm.argument(1);
496
0
    auto value = vm.argument(2);
497
0
    auto timeout = vm.argument(3);
498
499
    // 1. Return ? DoWait(sync, typedArray, index, value, timeout).
500
0
    return TRY(do_wait(vm, WaitMode::Sync, *typed_array, index, value, timeout));
501
0
}
502
503
// 25.4.14 Atomics.waitAsync ( typedArray, index, value, timeout ), https://tc39.es/ecma262/#sec-atomics.waitasync
504
JS_DEFINE_NATIVE_FUNCTION(AtomicsObject::wait_async)
505
0
{
506
0
    auto* typed_array = TRY(typed_array_from(vm, vm.argument(0)));
507
0
    auto index = vm.argument(1);
508
0
    auto value = vm.argument(2);
509
0
    auto timeout = vm.argument(3);
510
511
    // 1. Return ? DoWait(async, typedArray, index, value, timeout).
512
0
    return TRY(do_wait(vm, WaitMode::Async, *typed_array, index, value, timeout));
513
0
}
514
515
// 25.4.15 Atomics.notify ( typedArray, index, count ), https://tc39.es/ecma262/#sec-atomics.notify
516
JS_DEFINE_NATIVE_FUNCTION(AtomicsObject::notify)
517
0
{
518
0
    auto* typed_array = TRY(typed_array_from(vm, vm.argument(0)));
519
0
    auto index = vm.argument(1);
520
0
    auto count_value = vm.argument(2);
521
522
    // 1. Let byteIndexInBuffer be ? ValidateAtomicAccessOnIntegerTypedArray(typedArray, index, true).
523
0
    auto byte_index_in_buffer = TRY(validate_atomic_access_on_integer_typed_array(vm, *typed_array, index, true));
524
525
    // 2. If count is undefined, then
526
0
    double count = 0.0;
527
0
    if (count_value.is_undefined()) {
528
        // a. Let c be +∞.
529
0
        count = js_infinity().as_double();
530
0
    }
531
    // 3. Else,
532
0
    else {
533
        // a. Let intCount be ? ToIntegerOrInfinity(count).
534
0
        auto int_count = TRY(count_value.to_integer_or_infinity(vm));
535
536
        // b. Let c be max(intCount, 0).
537
0
        count = max(int_count, 0.0);
538
0
    }
539
540
    // 4. Let buffer be typedArray.[[ViewedArrayBuffer]].
541
0
    auto* buffer = typed_array->viewed_array_buffer();
542
543
    // 5. Let block be buffer.[[ArrayBufferData]].
544
0
    auto& block = buffer->buffer();
545
546
    // 6. If IsSharedArrayBuffer(buffer) is false, return +0𝔽.
547
0
    if (!buffer->is_shared_array_buffer())
548
0
        return Value { 0 };
549
550
    // FIXME: Implement the remaining steps when we support SharedArrayBuffer.
551
0
    (void)byte_index_in_buffer;
552
0
    (void)count;
553
0
    (void)block;
554
555
0
    return vm.throw_completion<InternalError>(ErrorType::NotImplemented, "SharedArrayBuffer"sv);
556
0
}
557
558
// 25.4.16 Atomics.xor ( typedArray, index, value ), https://tc39.es/ecma262/#sec-atomics.xor
559
JS_DEFINE_NATIVE_FUNCTION(AtomicsObject::xor_)
560
0
{
561
0
    auto* typed_array = TRY(typed_array_from(vm, vm.argument(0)));
562
563
0
    auto atomic_xor = [](auto* storage, auto value) { return AK::atomic_fetch_xor(storage, value); };
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::xor_(JS::VM&)::$_0::operator()<unsigned char, unsigned char>(unsigned char*, unsigned char) const
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::xor_(JS::VM&)::$_0::operator()<unsigned short, unsigned short>(unsigned short*, unsigned short) const
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::xor_(JS::VM&)::$_0::operator()<unsigned int, unsigned int>(unsigned int*, unsigned int) const
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::xor_(JS::VM&)::$_0::operator()<unsigned long, unsigned long>(unsigned long*, unsigned long) const
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::xor_(JS::VM&)::$_0::operator()<signed char, signed char>(signed char*, signed char) const
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::xor_(JS::VM&)::$_0::operator()<short, short>(short*, short) const
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::xor_(JS::VM&)::$_0::operator()<int, int>(int*, int) const
Unexecuted instantiation: AtomicsObject.cpp:auto JS::AtomicsObject::xor_(JS::VM&)::$_0::operator()<long, long>(long*, long) const
564
565
0
#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName, Type) \
566
0
    if (is<ClassName>(typed_array))                                                 \
567
0
        return TRY(perform_atomic_operation<Type>(vm, *typed_array, move(atomic_xor)));
568
0
    JS_ENUMERATE_TYPED_ARRAYS
569
0
#undef __JS_ENUMERATE
570
571
0
    VERIFY_NOT_REACHED();
572
0
}
573
574
}