PR-URL: https://github.com/nodejs/node/pull/49639 Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
132 lines
4.1 KiB
JavaScript
132 lines
4.1 KiB
JavaScript
// Copyright 2022 the V8 project authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
//
|
|
// Flags: --shared-string-table --harmony-struct --allow-natives-syntax
|
|
|
|
'use strict';
|
|
|
|
(function TestPrimitivesUsingAtomics() {
|
|
// All primitives can be stored in fields.
|
|
const prims = [42, -0, undefined, null, true, false, 'foo'];
|
|
const arr = new SharedArray(1);
|
|
for (let prim of prims) {
|
|
Atomics.store(arr, 0, prim);
|
|
assertEquals(Atomics.load(arr, 0), prim);
|
|
}
|
|
|
|
for (let prim1 of prims) {
|
|
for (let prim2 of prims) {
|
|
arr[0] = prim1;
|
|
assertEquals(Atomics.exchange(arr, 0, prim2), prim1);
|
|
assertEquals(arr[0], prim2);
|
|
}
|
|
}
|
|
|
|
const primsCopy = [42, -0, undefined, null, true, false, 'foo'];
|
|
for (let i = 0; i < prims.length; i++) {
|
|
const prim = prims[i];
|
|
const primCopy = primsCopy[i];
|
|
arr[0] = prim;
|
|
// Atomics.compareExchange mimics `===` comparison.
|
|
assertEquals(Atomics.compareExchange(arr, 0, '42', 'exchanged'), prim);
|
|
assertEquals(arr[0], prim);
|
|
assertEquals(Atomics.compareExchange(arr, 0, primCopy, 'exchanged'), prim);
|
|
assertEquals(arr[0], 'exchanged');
|
|
}
|
|
})();
|
|
|
|
(function TestObjectsUsingAtomics() {
|
|
let arr = new SharedArray(1);
|
|
// Shared objects cannot point to non-shared objects.
|
|
assertThrows(() => {
|
|
Atomics.store(arr, 0, []);
|
|
});
|
|
assertThrows(() => {
|
|
Atomics.store(arr, 0, {});
|
|
});
|
|
// Shared objects can point to other shared objects.
|
|
let shared_rhs = new SharedArray(10);
|
|
Atomics.store(arr, 0, shared_rhs);
|
|
assertEquals(Atomics.load(arr, 0), shared_rhs);
|
|
|
|
let Struct = new SharedStructType(['field']);
|
|
shared_rhs = new Struct();
|
|
Atomics.store(arr, 0, shared_rhs);
|
|
assertEquals(Atomics.load(arr, 0), shared_rhs);
|
|
|
|
// Test we can exchange shared objects.
|
|
let shared_rhs2 = new SharedArray(10);
|
|
assertEquals(Atomics.exchange(arr, 0, shared_rhs2), shared_rhs);
|
|
assertEquals(arr[0], shared_rhs2);
|
|
|
|
assertEquals(Atomics.exchange(arr, 0, shared_rhs), shared_rhs2);
|
|
assertEquals(arr[0], shared_rhs);
|
|
|
|
// Verify we can compare-exchange shared objects.
|
|
|
|
// Comparing to a different instance of the same type is not succesful.
|
|
assertEquals(
|
|
Atomics.compareExchange(arr, 0, new Struct(), 'exchanged'), shared_rhs);
|
|
assertNotEquals(arr[0], 'exchanged');
|
|
|
|
assertEquals(
|
|
Atomics.compareExchange(arr, 0, shared_rhs, shared_rhs2), shared_rhs);
|
|
assertEquals(arr[0], shared_rhs2);
|
|
|
|
// Comparing to a different instance of the same type is not succesful.
|
|
assertEquals(
|
|
Atomics.compareExchange(arr, 0, new SharedArray(10), 'exchanged'),
|
|
shared_rhs2);
|
|
assertNotEquals(arr[0], 'exchanged');
|
|
|
|
assertEquals(
|
|
Atomics.compareExchange(arr, 0, shared_rhs2, shared_rhs), shared_rhs2);
|
|
assertEquals(arr[0], shared_rhs);
|
|
})();
|
|
|
|
(function TestCompareExchangeNumbers() {
|
|
const arr = new SharedArray(1);
|
|
// We can compare a Smi to a HeapNumber.
|
|
arr[0] = 0;
|
|
assertTrue(%IsSmi(arr[0]));
|
|
let HeapNumber = %AllocateHeapNumber();
|
|
assertEquals(
|
|
Atomics.compareExchange(arr, 0, HeapNumber, 'exchanged'), HeapNumber);
|
|
assertEquals(arr[0], 'exchanged');
|
|
|
|
// We can compare the same value stored in 2 different HeapNumbers;
|
|
arr[0] = 1.5;
|
|
HeapNumber = 1.5;
|
|
assertFalse(%IsSameHeapObject(arr[0], HeapNumber));
|
|
assertEquals(Atomics.compareExchange(arr, 0, HeapNumber, 'exchanged'), 1.5);
|
|
assertEquals(arr[0], 'exchanged');
|
|
})();
|
|
|
|
(function TestOutOfBounds() {
|
|
let arr = new SharedArray(1);
|
|
// Shared structs are non-extensible.
|
|
assertThrows(() => {
|
|
Atomics.store(arr, 2, 42);
|
|
});
|
|
assertThrows(() => {
|
|
Atomics.store(arr, -1, 42);
|
|
});
|
|
assertThrows(() => {
|
|
Atomics.store(arr, 'field', 42);
|
|
});
|
|
})();
|
|
|
|
(function TestLengthReadOnly() {
|
|
let arr = new SharedArray(2);
|
|
assertEquals(2, Atomics.load(arr, 'length'));
|
|
// The 'length' property is read-only. Atomics.store and Atomics.exchange are
|
|
// treated like strict functions, and so an error is always thrown.
|
|
assertThrows(() => {
|
|
Atomics.store(arr, 'length', 42);
|
|
});
|
|
assertThrows(() => {
|
|
Atomics.exchange(arr, 'length', 42);
|
|
});
|
|
})();
|