mirror of
https://github.com/nodejs/node.git
synced 2025-08-18 15:18:46 +02:00

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>
162 lines
5.1 KiB
JavaScript
162 lines
5.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";
|
|
|
|
let S = new SharedStructType(['field', '2']);
|
|
|
|
(function TestPrimitivesUsingAtomics() {
|
|
// All primitives can be stored in fields.
|
|
let s = new S();
|
|
const prims = [42, -0, undefined, null, true, false, "foo"];
|
|
|
|
for (let prim of prims) {
|
|
Atomics.store(s, 'field', prim);
|
|
Atomics.store(s, '2', prim);
|
|
assertEquals(Atomics.load(s, 'field'), prim);
|
|
assertEquals(Atomics.load(s, '2'), prim);
|
|
}
|
|
|
|
for (let prim1 of prims) {
|
|
for (let prim2 of prims) {
|
|
s.field = prim1;
|
|
s[2] = prim1;
|
|
assertEquals(Atomics.exchange(s, 'field', prim2), prim1);
|
|
assertEquals(s.field, prim2);
|
|
assertEquals(Atomics.exchange(s, '2', prim2), prim1);
|
|
assertEquals(s[2], 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];
|
|
s.field = prim;
|
|
// Atomics.compareExchange mimics `===` comparison.
|
|
assertEquals(Atomics.compareExchange(s, 'field', '42', 'exchanged'), prim);
|
|
assertEquals(s.field, prim);
|
|
assertEquals(
|
|
Atomics.compareExchange(s, 'field', primCopy, 'exchanged'), prim);
|
|
assertEquals(s.field, 'exchanged');
|
|
|
|
s[2] = prim;
|
|
assertEquals(Atomics.compareExchange(s, 2, '42', 'exchanged'), prim);
|
|
assertEquals(s[2], prim);
|
|
assertEquals(Atomics.compareExchange(s, 2, primCopy, 'exchanged'), prim);
|
|
assertEquals(s[2], 'exchanged');
|
|
}
|
|
})();
|
|
|
|
(function TestObjectsUsingAtomics() {
|
|
let s = new S();
|
|
// Shared objects cannot point to non-shared objects.
|
|
assertThrows(() => { Atomics.store(s, 'field', []); });
|
|
assertThrows(() => { Atomics.store(s, 'field', {}); });
|
|
// Shared objects can point to other shared objects.
|
|
|
|
let shared_rhs = new S();
|
|
Atomics.store(s, 'field', shared_rhs);
|
|
assertEquals(Atomics.load(s, 'field'), shared_rhs);
|
|
|
|
shared_rhs = new SharedArray(10);
|
|
Atomics.store(s, 'field', shared_rhs);
|
|
assertEquals(Atomics.load(s, 'field'), shared_rhs);
|
|
|
|
let shared_rhs2 = new S();
|
|
assertEquals(Atomics.exchange(s, 'field', shared_rhs2), shared_rhs);
|
|
assertEquals(s.field, shared_rhs2);
|
|
|
|
assertEquals(Atomics.exchange(s, 'field', shared_rhs), shared_rhs2);
|
|
assertEquals(s.field, shared_rhs);
|
|
|
|
assertEquals(
|
|
Atomics.compareExchange(s, 'field', new SharedArray(10), 'exchanged'),
|
|
shared_rhs);
|
|
assertNotEquals(s.field, 'exchanged');
|
|
|
|
assertEquals(
|
|
Atomics.compareExchange(s, 'field', shared_rhs, shared_rhs2), shared_rhs);
|
|
assertEquals(s.field, shared_rhs2);
|
|
|
|
assertEquals(
|
|
Atomics.compareExchange(s, 'field', new S(), 'exchanged'), shared_rhs2);
|
|
assertNotEquals(s.field, 'exchanged');
|
|
|
|
assertEquals(
|
|
Atomics.compareExchange(s, 'field', shared_rhs2, shared_rhs),
|
|
shared_rhs2);
|
|
assertEquals(s.field, shared_rhs);
|
|
|
|
})();
|
|
|
|
(function TestNotExtensibleUsingAtomics() {
|
|
let s = new S();
|
|
// Shared structs are non-extensible.
|
|
assertThrows(() => { Atomics.store(s, 'nonExistent', 42); });
|
|
})();
|
|
|
|
(function TestCompareExchangeNumbers() {
|
|
let fieldNames = new SharedArray(999);
|
|
fieldNames[0] = '2';
|
|
for (let i = 1; i < fieldNames.length; i++) {
|
|
fieldNames[i] = `field${i}`;
|
|
}
|
|
|
|
let ST = new SharedStructType(fieldNames)
|
|
let s = new ST();
|
|
|
|
// Test in-object fields.
|
|
// We can compare a Smi to a HeapNumber.
|
|
s.field1 = 0;
|
|
assertTrue(%IsSmi(s.field1));
|
|
let HeapNumber = %AllocateHeapNumber();
|
|
assertEquals(
|
|
Atomics.compareExchange(s, 'field1', HeapNumber, 'success'), HeapNumber);
|
|
assertEquals(s.field1, 'success');
|
|
|
|
// We can compare the same value stored in 2 different HeapNumbers.
|
|
s.field1 = 1.5;
|
|
HeapNumber = 1.5;
|
|
assertFalse(%IsSameHeapObject(s.field, HeapNumber));
|
|
assertEquals(
|
|
Atomics.compareExchange(s, 'field1', HeapNumber, 'success'), 1.5);
|
|
assertEquals(s.field1, 'success');
|
|
|
|
// Test dictionary element fields.
|
|
// We can compare a Smi to a HeapNumber.
|
|
s[2] = 0;
|
|
assertTrue(%IsSmi(s[2]));
|
|
HeapNumber = %AllocateHeapNumber();
|
|
assertEquals(
|
|
Atomics.compareExchange(s, 2, HeapNumber, 'success'), HeapNumber);
|
|
assertEquals(s[2], 'success');
|
|
|
|
// We can compare the same value stored in 2 different HeapNumbers.
|
|
s[2] = 1.5;
|
|
HeapNumber = 1.5;
|
|
assertFalse(%IsSameHeapObject(s[2], HeapNumber));
|
|
assertEquals(Atomics.compareExchange(s, 2, HeapNumber, 'success'), 1.5);
|
|
assertEquals(s[2], 'success');
|
|
|
|
// Test out-of-object fields.
|
|
// We can compare a Smi to a HeapNumber.
|
|
s.field998 = 0;
|
|
assertTrue(%IsSmi(s.field998));
|
|
HeapNumber = %AllocateHeapNumber();
|
|
assertEquals(
|
|
Atomics.compareExchange(s, 'field998', HeapNumber, 'success'),
|
|
HeapNumber);
|
|
assertEquals(s.field998, 'success');
|
|
|
|
// We can compare the same value stored in 2 different HeapNumbers.
|
|
s.field998 = 1.5;
|
|
HeapNumber = 1.5;
|
|
assertFalse(%IsSameHeapObject(s.field, HeapNumber));
|
|
assertEquals(
|
|
Atomics.compareExchange(s, 'field998', HeapNumber, 'success'), 1.5);
|
|
assertEquals(s.field998, 'success');
|
|
})();
|