mirror of
https://github.com/tc39/test262.git
synced 2025-05-09 17:30:30 +02:00
Migrating all tests to this API is necessary to prevent tests from hanging indefinitely when a SAB is sent to a worker but the code in the worker attempts to create a non-sharable TypedArray (something that is not Int32Array or BigInt64Array). When that scenario occurs, an exception is thrown and the agent worker can no longer communicate with any other threads that control the SAB. If the main thread happens to be spinning in the $262.agent.waitUntil() while loop, it will never meet its termination condition and the test will hang indefinitely. Because we've defined $262.agent.broadcast(SAB) in https://github.com/tc39/test262/blob/master/INTERPRETING.md, there are host implementations that assume compatibility, which must be maintained.
93 lines
2.2 KiB
JavaScript
93 lines
2.2 KiB
JavaScript
// Copyright (C) 2018 Amal Hussein. All rights reserved.
|
|
// This code is governed by the BSD license found in the LICENSE file.
|
|
|
|
/*---
|
|
esid: sec-atomics.wait
|
|
description: >
|
|
Throws a TypeError if index arg can not be converted to an Integer
|
|
info: |
|
|
Atomics.wait( typedArray, index, value, timeout )
|
|
|
|
2. Let i be ? ValidateAtomicAccess(typedArray, index).
|
|
|
|
ValidateAtomicAccess( typedArray, requestIndex )
|
|
|
|
2. Let accessIndex be ? ToIndex(requestIndex).
|
|
|
|
ToIndex ( value )
|
|
|
|
2. Else,
|
|
a. Let integerIndex be ? ToInteger(value).
|
|
|
|
ToInteger(value)
|
|
|
|
1. Let number be ? ToNumber(argument).
|
|
|
|
Symbol --> Throw a TypeError exception.
|
|
|
|
includes: [atomicsHelper.js]
|
|
features: [Atomics, SharedArrayBuffer, Symbol, Symbol.toPrimitive, TypedArray]
|
|
---*/
|
|
|
|
const RUNNING = 1;
|
|
|
|
$262.agent.start(`
|
|
const poisonedValueOf = {
|
|
valueOf: function() {
|
|
throw new Test262Error('should not evaluate this code');
|
|
}
|
|
};
|
|
|
|
const poisonedToPrimitive = {
|
|
[Symbol.toPrimitive]: function() {
|
|
throw new Test262Error("passing a poisoned object using @@ToPrimitive");
|
|
}
|
|
};
|
|
|
|
$262.agent.receiveBroadcast(function(sab) {
|
|
const i32a = new Int32Array(sab);
|
|
Atomics.add(i32a, ${RUNNING}, 1);
|
|
|
|
let status1 = "";
|
|
let status2 = "";
|
|
|
|
try {
|
|
Atomics.wait(i32a, Symbol("1"), poisonedValueOf, poisonedValueOf);
|
|
} catch (error) {
|
|
status1 = 'Symbol("1")';
|
|
}
|
|
try {
|
|
Atomics.wait(i32a, Symbol("2"), poisonedToPrimitive, poisonedToPrimitive);
|
|
} catch (error) {
|
|
status2 = 'Symbol("2")';
|
|
}
|
|
|
|
$262.agent.report(status1);
|
|
$262.agent.report(status2);
|
|
$262.agent.leaving();
|
|
});
|
|
`);
|
|
|
|
const i32a = new Int32Array(
|
|
new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4)
|
|
);
|
|
|
|
$262.agent.safeBroadcast(i32a);
|
|
$262.agent.waitUntil(i32a, RUNNING, 1);
|
|
|
|
// Try to yield control to ensure the agent actually started to wait.
|
|
$262.agent.tryYield();
|
|
|
|
assert.sameValue(
|
|
$262.agent.getReport(),
|
|
'Symbol("1")',
|
|
'$262.agent.getReport() returns "Symbol("1")"'
|
|
);
|
|
assert.sameValue(
|
|
$262.agent.getReport(),
|
|
'Symbol("2")',
|
|
'$262.agent.getReport() returns "Symbol("2")"'
|
|
);
|
|
|
|
assert.sameValue(Atomics.notify(i32a, 0), 0, 'Atomics.notify(i32a, 0) returns 0');
|